diff --git a/pom.xml b/pom.xml
index f07d625..e192968 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,6 +110,22 @@
spring-boot-starter-test
test
+
+ org.mockito
+ mockito-core
+ 5.12.0
+
+
+ com.github.mvysny.kaributesting
+ karibu-testing-v23
+ 2.1.8
+
+
+ com.github.mvysny.kaributesting
+ karibu-testing-v10-spring
+ 2.1.8
+ test
+
org.hibernate.validator
hibernate-validator
@@ -200,6 +216,11 @@
commons-lang3
3.14.0
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.3.1
+
@@ -243,6 +264,11 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.3.1
+
diff --git a/src/main/java/com/primefactorsolutions/model/Assessment.java b/src/main/java/com/primefactorsolutions/model/Assessment.java
index ff495b6..29d763f 100644
--- a/src/main/java/com/primefactorsolutions/model/Assessment.java
+++ b/src/main/java/com/primefactorsolutions/model/Assessment.java
@@ -27,7 +27,8 @@ public class Assessment extends BaseEntity {
@ManyToOne
private Candidate candidate;
- @OneToMany(fetch = FetchType.EAGER, mappedBy = "assessment", cascade = {CascadeType.ALL})
+ @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
+ @JoinColumn(name="ASSESSMENT_ID")
private List assessmentEvents = new ArrayList<>();
public Submission getCurrentSubmission() {
diff --git a/src/main/java/com/primefactorsolutions/model/AssessmentEvent.java b/src/main/java/com/primefactorsolutions/model/AssessmentEvent.java
index 8da7084..aa07c7a 100644
--- a/src/main/java/com/primefactorsolutions/model/AssessmentEvent.java
+++ b/src/main/java/com/primefactorsolutions/model/AssessmentEvent.java
@@ -1,7 +1,6 @@
package com.primefactorsolutions.model;
import jakarta.persistence.Entity;
-import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -17,7 +16,4 @@ import java.time.Instant;
public class AssessmentEvent extends BaseEntity {
private Instant timestamp;
private AssessmentStatus status;
-
- @ManyToOne
- private Assessment assessment;
}
diff --git a/src/main/java/com/primefactorsolutions/service/AssessmentService.java b/src/main/java/com/primefactorsolutions/service/AssessmentService.java
index a5bfa87..ef865ab 100644
--- a/src/main/java/com/primefactorsolutions/service/AssessmentService.java
+++ b/src/main/java/com/primefactorsolutions/service/AssessmentService.java
@@ -71,7 +71,7 @@ public class AssessmentService {
return assessment;
}
- assessment.getAssessmentEvents().add(new AssessmentEvent(Instant.now(), AssessmentStatus.STARTED, assessment));
+ assessment.getAssessmentEvents().add(new AssessmentEvent(Instant.now(), AssessmentStatus.STARTED));
return assessmentRepository.save(assessment);
}
@@ -169,8 +169,7 @@ public class AssessmentService {
return assessment;
}
- assessment.getAssessmentEvents().add(new AssessmentEvent(Instant.now(), AssessmentStatus.COMPLETED,
- assessment));
+ assessment.getAssessmentEvents().add(new AssessmentEvent(Instant.now(), AssessmentStatus.COMPLETED));
Assessment saved = assessmentRepository.save(assessment);
return saved;
diff --git a/src/test/java/com/primefactorsolutions/service/AssessmentServiceTests.java b/src/test/java/com/primefactorsolutions/service/AssessmentServiceTests.java
new file mode 100644
index 0000000..6199445
--- /dev/null
+++ b/src/test/java/com/primefactorsolutions/service/AssessmentServiceTests.java
@@ -0,0 +1,50 @@
+package com.primefactorsolutions.service;
+
+import com.primefactorsolutions.model.Assessment;
+import com.primefactorsolutions.model.AssessmentEvent;
+import com.primefactorsolutions.model.AssessmentStatus;
+import com.primefactorsolutions.repositories.AssessmentRepository;
+import jakarta.persistence.EntityManager;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.mail.javamail.JavaMailSender;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class AssessmentServiceTests {
+
+ @Mock
+ private AssessmentRepository assessmentRepository;
+ @Mock
+ private EntityManager entityManager;
+ @Mock
+ private JavaMailSender emailSender;
+ @InjectMocks
+ private AssessmentService assessmentService;
+
+ @Test
+ public void testAlreadyStartedAssessment() {
+ final var aid = UUID.randomUUID();
+ final var assessment = new Assessment();
+ assessment.setId(aid);
+ assessment.setAssessmentEvents(List.of(new AssessmentEvent(Instant.now(), AssessmentStatus.STARTED)));
+
+ when(assessmentRepository.findById(eq(aid)))
+ .thenReturn(Optional.of(assessment));
+
+ final var started = assessmentService.startAssessment(aid);
+
+ Assertions.assertThat(assessment).isEqualTo(started);
+ }
+}
diff --git a/src/test/java/com/primefactorsolutions/service/CompilerServiceTests.java b/src/test/java/com/primefactorsolutions/service/CompilerServiceTests.java
new file mode 100644
index 0000000..2630503
--- /dev/null
+++ b/src/test/java/com/primefactorsolutions/service/CompilerServiceTests.java
@@ -0,0 +1,22 @@
+package com.primefactorsolutions.service;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Optional;
+
+@ExtendWith(MockitoExtension.class)
+public class CompilerServiceTests {
+ @InjectMocks
+ private CompilerService compilerService;
+
+ @Test
+ public void testDoCompile() {
+ final var result = compilerService.doCompile("package com.primefactorsolutions; import java.util.*; public class TestClass { public static Map run() { return Map.of(\"test\", true); } }");
+
+ Assertions.assertThat(result).isEqualTo(Optional.of(String.format("%-50s ... %4s", "test", "OK")));
+ }
+}
diff --git a/src/test/java/com/primefactorsolutions/views/AbstractAppTests.java b/src/test/java/com/primefactorsolutions/views/AbstractAppTests.java
new file mode 100644
index 0000000..f05c2ef
--- /dev/null
+++ b/src/test/java/com/primefactorsolutions/views/AbstractAppTests.java
@@ -0,0 +1,73 @@
+package com.primefactorsolutions.views;
+
+import com.github.mvysny.fakeservlet.FakeRequest;
+import com.github.mvysny.kaributesting.v10.MockVaadin;
+import com.github.mvysny.kaributesting.v10.spring.MockSpringServlet;
+import com.vaadin.flow.component.UI;
+import com.vaadin.flow.server.VaadinServletRequest;
+import com.vaadin.flow.spring.SpringServlet;
+
+import kotlin.jvm.functions.Function0;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import com.github.mvysny.kaributesting.v10.MockVaadin;
+import com.github.mvysny.kaributesting.v10.Routes;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@SpringBootTest
+public class AbstractAppTests {
+ private static final Routes routes = new Routes().autoDiscoverViews("com.primefactorsolutions");
+
+ @Autowired
+ protected ApplicationContext ctx;
+
+ protected void login(String user, String pass, final List roles) {
+ final List authorities =
+ roles.stream().map(it -> new SimpleGrantedAuthority("ROLE_" + it)).collect(Collectors.toList());
+ UsernamePasswordAuthenticationToken authReq
+ = new UsernamePasswordAuthenticationToken(new User(user, pass, authorities), pass, authorities);
+ SecurityContext sc = SecurityContextHolder.getContext();
+ sc.setAuthentication(authReq);
+
+ // however, you also need to make sure that ViewAccessChecker works properly;
+ // that requires a correct MockRequest.userPrincipal and MockRequest.isUserInRole()
+ final FakeRequest request = (FakeRequest) VaadinServletRequest.getCurrent().getRequest();
+ request.setUserPrincipalInt(authReq);
+ request.setUserInRole((principal, role) -> roles.contains(role));
+ }
+
+ protected void logout() {
+ if (VaadinServletRequest.getCurrent() != null) {
+ final FakeRequest request = (FakeRequest) VaadinServletRequest.getCurrent().getRequest();
+ request.setUserPrincipalInt(null);
+ request.setUserInRole((principal, role) -> false);
+ }
+ }
+
+ @BeforeEach
+ public void setup() {
+ final Function0 uiFactory = UI::new;
+ final SpringServlet servlet = new MockSpringServlet(routes, ctx, uiFactory);
+ MockVaadin.setup(uiFactory, servlet);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ logout();
+ MockVaadin.tearDown();
+ }
+}
diff --git a/src/test/java/com/primefactorsolutions/views/CandidateViewTests.java b/src/test/java/com/primefactorsolutions/views/CandidateViewTests.java
new file mode 100644
index 0000000..25bdfbc
--- /dev/null
+++ b/src/test/java/com/primefactorsolutions/views/CandidateViewTests.java
@@ -0,0 +1,25 @@
+package com.primefactorsolutions.views;
+
+import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.textfield.EmailField;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static com.github.mvysny.kaributesting.v10.LocatorJ.*;
+
+public class CandidateViewTests extends AbstractAppTests {
+ @BeforeEach
+ public void login() {
+ login("user", "user", List.of("user"));
+ }
+
+ @Test
+ public void sayHelloWithMockBean() {
+ UI.getCurrent().navigate(CandidateView.class, "new");
+ _setValue(_get(EmailField.class, spec -> spec.withLabel("Email")), "foo@test.com");
+ _click(_get(Button.class, spec -> spec.withText("Save")));
+ }
+}