diff --git a/backend/CLAUDE.md b/backend/CLAUDE.md
index 29d5ca4..b5353c2 100644
--- a/backend/CLAUDE.md
+++ b/backend/CLAUDE.md
@@ -114,23 +114,21 @@ class FooServiceTest {
```
### Integration Tests (`*IntegrationTest.java`)
+
+All integration tests extend `AbstractIntegrationTest`, which provides:
+- **Shared containers** — `SharedContainers` starts a single MySQL and Mailpit container per JVM (singleton pattern), shared by all test classes
+- **`@Transactional` rollback** — each test runs in a transaction that rolls back automatically, restoring the DataInitializer-seeded state without needing `@DirtiesContext`
+- **Common annotations** — `@SpringBootTest`, `@AutoConfigureMockMvc`, `@ActiveProfiles("dev")`, `@Tag("integration")`
+
```java
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Foo API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-public class FooIntegrationTest {
+public class FooIntegrationTest extends AbstractIntegrationTest {
@Autowired MockMvc mockMvc;
@Autowired JsonMapper jsonMapper;
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
String adminToken;
String studentToken;
@@ -153,4 +151,4 @@ public class FooIntegrationTest {
}
```
-Integration tests use Testcontainers (MySQL 8.0), seed data from `DataInitializer`, and authenticate via HTTP Basic to get JWT tokens for subsequent requests. Tests verify both the `flag` and `code` fields in the `Result` response. Use `@DirtiesContext` on tests that modify state and could affect other tests.
+Integration tests use Testcontainers (MySQL 8.0), seed data from `DataInitializer`, and authenticate via HTTP Basic to get JWT tokens for subsequent requests. Tests verify both the `flag` and `code` fields in the `Result` response. Do **not** use `@DirtiesContext` — the `@Transactional` rollback on the base class handles database reset automatically.
diff --git a/backend/src/test/java/team/projectpulse/AbstractIntegrationTest.java b/backend/src/test/java/team/projectpulse/AbstractIntegrationTest.java
new file mode 100644
index 0000000..3ab0fb5
--- /dev/null
+++ b/backend/src/test/java/team/projectpulse/AbstractIntegrationTest.java
@@ -0,0 +1,40 @@
+package team.projectpulse;
+
+import org.junit.jupiter.api.Tag;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.transaction.annotation.Transactional;
+import org.testcontainers.containers.MySQLContainer;
+
+/**
+ * Base class for all integration tests. Provides:
+ *
+ * - Shared MySQL and Mailpit containers via {@link SharedContainers} (started once per JVM)
+ * - {@code @Transactional} rollback after each test — restores DataInitializer-seeded state
+ * without the cost of {@code @DirtiesContext} (which would recreate the entire Spring context)
+ * - Common annotations: {@code @SpringBootTest}, {@code @AutoConfigureMockMvc},
+ * {@code @ActiveProfiles("dev")}, {@code @Tag("integration")}
+ *
+ */
+@SpringBootTest
+@AutoConfigureMockMvc
+@ActiveProfiles("dev")
+@Tag("integration")
+@Transactional
+public abstract class AbstractIntegrationTest {
+
+ @ServiceConnection
+ static final MySQLContainer> mysql = SharedContainers.MYSQL;
+
+
+ @DynamicPropertySource
+ static void setProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.mail.host", SharedContainers.MAILPIT::getHost);
+ registry.add("spring.mail.port", () -> SharedContainers.MAILPIT.getMappedPort(1025));
+ }
+
+}
diff --git a/backend/src/test/java/team/projectpulse/ProjectPulseApplicationTests.java b/backend/src/test/java/team/projectpulse/ProjectPulseApplicationTests.java
index 69e409b..f685c22 100644
--- a/backend/src/test/java/team/projectpulse/ProjectPulseApplicationTests.java
+++ b/backend/src/test/java/team/projectpulse/ProjectPulseApplicationTests.java
@@ -1,21 +1,8 @@
package team.projectpulse;
import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
-@SpringBootTest
-@Testcontainers
-class ProjectPulseApplicationTests {
-
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
+class ProjectPulseApplicationTests extends AbstractIntegrationTest {
@Test
void contextLoads() {
diff --git a/backend/src/test/java/team/projectpulse/SharedContainers.java b/backend/src/test/java/team/projectpulse/SharedContainers.java
new file mode 100644
index 0000000..9832def
--- /dev/null
+++ b/backend/src/test/java/team/projectpulse/SharedContainers.java
@@ -0,0 +1,27 @@
+package team.projectpulse;
+
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.MySQLContainer;
+import org.testcontainers.utility.DockerImageName;
+
+/**
+ * Singleton containers shared by all integration tests. Started once per JVM — avoids
+ * spinning up a new MySQL/Mailpit container per test class.
+ */
+public final class SharedContainers {
+
+ public static final MySQLContainer> MYSQL = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
+
+ public static final GenericContainer> MAILPIT = new GenericContainer<>(DockerImageName.parse("axllent/mailpit"))
+ .withExposedPorts(1025, 8025);
+
+ static {
+ MYSQL.start();
+ MAILPIT.start();
+ }
+
+
+ private SharedContainers() {
+ }
+
+}
diff --git a/backend/src/test/java/team/projectpulse/activity/ActivityIntegrationTest.java b/backend/src/test/java/team/projectpulse/activity/ActivityIntegrationTest.java
index 1cb2eaa..04b9b4a 100644
--- a/backend/src/test/java/team/projectpulse/activity/ActivityIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/activity/ActivityIntegrationTest.java
@@ -1,26 +1,17 @@
package team.projectpulse.activity;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
@@ -36,13 +27,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Activity API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-public class ActivityIntegrationTest {
+public class ActivityIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -61,10 +47,6 @@ public class ActivityIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -228,7 +210,6 @@ void testStudentJanaFindActivityById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testStudentJohnAddActivity() throws Exception {
// Given
Map activityDto = new HashMap<>();
@@ -259,7 +240,6 @@ void testStudentJohnAddActivity() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testStudentJohnUpdatesOwnActivity() throws Exception {
// Given
Map activityDto = new HashMap<>();
@@ -310,7 +290,6 @@ void testStudentUpdatesAnotherStudentsActivity() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testStudentJohnDeletesOwnActivity() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/activities/1").accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.studentJohnToken))
.andExpect(jsonPath("$.flag").value(true))
diff --git a/backend/src/test/java/team/projectpulse/course/CourseIntegrationTest.java b/backend/src/test/java/team/projectpulse/course/CourseIntegrationTest.java
index bd4ca7f..ac1f44d 100644
--- a/backend/src/test/java/team/projectpulse/course/CourseIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/course/CourseIntegrationTest.java
@@ -1,34 +1,22 @@
package team.projectpulse.course;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
import java.util.HashMap;
import java.util.Map;
@@ -38,13 +26,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Course API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class CourseIntegrationTest {
+class CourseIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -61,21 +44,6 @@ class CourseIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
- @Container
- static final GenericContainer> mailpit = new GenericContainer<>(DockerImageName.parse("axllent/mailpit"))
- .withExposedPorts(1025, 8025);
-
-
- @DynamicPropertySource
- static void setMailpitProperties(DynamicPropertyRegistry registry) {
- registry.add("spring.mail.host", mailpit::getHost);
- registry.add("spring.mail.port", () -> mailpit.getMappedPort(1025));
- }
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -185,7 +153,7 @@ void adminTimFindCourseById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void adminBingyangAddCourse() throws Exception {
// Given
Map courseDto = new HashMap<>();
@@ -219,7 +187,7 @@ void instructorBillAddCourse() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void adminBingyangUpdateCourse() throws Exception {
// Given
Map courseDto = new HashMap<>();
diff --git a/backend/src/test/java/team/projectpulse/evaluation/EvaluationIntegrationTest.java b/backend/src/test/java/team/projectpulse/evaluation/EvaluationIntegrationTest.java
index 82546e9..106a88f 100644
--- a/backend/src/test/java/team/projectpulse/evaluation/EvaluationIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/evaluation/EvaluationIntegrationTest.java
@@ -1,12 +1,8 @@
package team.projectpulse.evaluation;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.evaluation.dto.PeerEvaluationDto;
import team.projectpulse.evaluation.dto.RatingDto;
import team.projectpulse.system.StatusCode;
@@ -14,16 +10,11 @@
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
@@ -41,13 +32,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Evaluation API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-public class EvaluationIntegrationTest {
+public class EvaluationIntegrationTest extends AbstractIntegrationTest {
/**
* @MockitoSpyBean creates a Mockito spy and registers it as the active Spring bean.
@@ -74,10 +60,6 @@ public class EvaluationIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
@@ -101,7 +83,7 @@ void setUp() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void testStudentJohnAddEvaluation() throws Exception {
List ratingDtos = List.of(
new RatingDto(null, 1, 4.0),
@@ -265,7 +247,7 @@ void testEvaluatorJohnGetsEvaluationsByWrongEvaluatorIdAndWeek() throws Exceptio
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void testEvaluatorJohnUpdatesOwnEvaluation() throws Exception {
List ratingDtos = List.of(
new RatingDto(1, 1, 4.0),
diff --git a/backend/src/test/java/team/projectpulse/instructor/InstructorIntegrationTest.java b/backend/src/test/java/team/projectpulse/instructor/InstructorIntegrationTest.java
index 254c13f..9393b1c 100644
--- a/backend/src/test/java/team/projectpulse/instructor/InstructorIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/instructor/InstructorIntegrationTest.java
@@ -1,31 +1,22 @@
package team.projectpulse.instructor;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
import java.util.HashMap;
import java.util.Map;
@@ -35,13 +26,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Instructor API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class InstructorIntegrationTest {
+class InstructorIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -58,10 +44,6 @@ class InstructorIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
@@ -140,7 +122,6 @@ void testInstructorFindAnotherInstructorsInfoById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testAddInstructor() throws Exception {
Map instructorDto = new HashMap<>();
instructorDto.put("username", "e.musk@abc.edu");
@@ -243,7 +224,6 @@ void testAddInstructorWithWrongRole() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testAdminBingyangUpdatesOwnInfo() throws Exception {
Map instructorDto = new HashMap<>();
instructorDto.put("username", "b.wei@abc.edu");
@@ -271,7 +251,6 @@ void testAdminBingyangUpdatesOwnInfo() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testInstructorBillUpdatesOwnInfo() throws Exception {
Map instructorDto = new HashMap<>();
instructorDto.put("username", "b.gates@abc.edu");
@@ -317,7 +296,6 @@ void testInstructorBillUpdatesAnotherInstructorsInfo() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testAdminBingyangSetDefaultSection() throws Exception {
// When and then
this.mockMvc.perform(put(this.baseUrl + "/instructors/sections/1/default").accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
@@ -360,7 +338,6 @@ void testInstructorBillSetDefaultSectionDoesNotBelongToInstructor() throws Excep
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testAdminBingyangSetDefaultCourse() throws Exception {
// When and then
this.mockMvc.perform(put(this.baseUrl + "/instructors/courses/2/default").accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
@@ -386,4 +363,4 @@ void testInstructorBillSetDefaultCourseDoesNotBelongToInstructor() throws Except
.andExpect(jsonPath("$.data").value("Access Denied"));
}
-}
\ No newline at end of file
+}
diff --git a/backend/src/test/java/team/projectpulse/ram/collabration/CommentControllerTest.java b/backend/src/test/java/team/projectpulse/ram/collabration/CommentControllerTest.java
index 1ecc176..3dc24f5 100644
--- a/backend/src/test/java/team/projectpulse/ram/collabration/CommentControllerTest.java
+++ b/backend/src/test/java/team/projectpulse/ram/collabration/CommentControllerTest.java
@@ -6,20 +6,12 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
@@ -27,11 +19,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
-@ActiveProfiles(value = "dev")
-public class CommentControllerTest {
+public class CommentControllerTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -48,10 +36,6 @@ public class CommentControllerTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -107,7 +91,6 @@ void listCommentThreadsForDocument_NotSameTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void createCommentThreadForDocument() throws Exception {
String json = """
{
@@ -141,7 +124,6 @@ void listCommentThreadsForDocumentSection() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void createCommentThreadForDocumentSection() throws Exception {
String json = """
{
@@ -206,7 +188,6 @@ void getCommentThread() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void addCommentToACommentThread() throws Exception {
String addCommentJson = """
{ "content": "Sure - but let's define it in the glossary." }
@@ -293,7 +274,6 @@ void updateComment_NotSameTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void deleteComment() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/teams/1/comment-threads/1/comments/2")
.accept(MediaType.APPLICATION_JSON)
@@ -311,7 +291,6 @@ void deleteComment() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void deleteCommentThread() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/teams/1/comment-threads/1")
.accept(MediaType.APPLICATION_JSON)
diff --git a/backend/src/test/java/team/projectpulse/ram/document/DocumentControllerTest.java b/backend/src/test/java/team/projectpulse/ram/document/DocumentControllerTest.java
index 34c1666..aa32afe 100644
--- a/backend/src/test/java/team/projectpulse/ram/document/DocumentControllerTest.java
+++ b/backend/src/test/java/team/projectpulse/ram/document/DocumentControllerTest.java
@@ -6,17 +6,12 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
@@ -24,9 +19,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@AutoConfigureMockMvc
-public class DocumentControllerTest {
+public class DocumentControllerTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -44,10 +37,6 @@ public class DocumentControllerTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
diff --git a/backend/src/test/java/team/projectpulse/ram/document/DocumentSectionControllerTest.java b/backend/src/test/java/team/projectpulse/ram/document/DocumentSectionControllerTest.java
index 3ee5bd1..89b5d9b 100644
--- a/backend/src/test/java/team/projectpulse/ram/document/DocumentSectionControllerTest.java
+++ b/backend/src/test/java/team/projectpulse/ram/document/DocumentSectionControllerTest.java
@@ -6,18 +6,12 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
@@ -25,9 +19,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@AutoConfigureMockMvc
-public class DocumentSectionControllerTest {
+public class DocumentSectionControllerTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -45,10 +37,6 @@ public class DocumentSectionControllerTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -95,7 +83,7 @@ void findDocumentSectionById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateDocumentSectionContent1() throws Exception {
String json = """
{
@@ -165,7 +153,7 @@ void updateDocumentSectionContent1() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateDocumentSectionContent2() throws Exception {
String json = """
{
@@ -214,7 +202,7 @@ void updateDocumentSectionContent2() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateDocumentSectionWithoutRequirementsArtifacts() throws Exception {
String json = """
{
@@ -250,7 +238,7 @@ void updateDocumentSectionWithoutRequirementsArtifacts() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateDocumentSectionWithoutRequirementsArtifacts_LockedByAnotherUser() throws Exception {
String json = """
{
@@ -284,7 +272,7 @@ void updateDocumentSectionWithoutRequirementsArtifacts_LockedByAnotherUser() thr
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateDocumentSectionWithoutRequirementsArtifacts_NotLocked() throws Exception {
int version = fetchSectionVersion(1, 1, 2, this.studentJohnToken);
String json = """
@@ -383,7 +371,7 @@ void lockDocumentSection_AlreadyLocked() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void unlockDocumentSection() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/teams/1/documents/1/document-sections/1/lock").accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.studentJohnToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -400,7 +388,7 @@ void unlockDocumentSection_DifferentOwner() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void unlockDocumentSection_Instructor() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/teams/1/documents/1/document-sections/1/lock").accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
diff --git a/backend/src/test/java/team/projectpulse/ram/requirement/ArtifactLinkControllerTest.java b/backend/src/test/java/team/projectpulse/ram/requirement/ArtifactLinkControllerTest.java
index 60142bf..7d30cb8 100644
--- a/backend/src/test/java/team/projectpulse/ram/requirement/ArtifactLinkControllerTest.java
+++ b/backend/src/test/java/team/projectpulse/ram/requirement/ArtifactLinkControllerTest.java
@@ -6,18 +6,12 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import static org.hamcrest.Matchers.hasSize;
@@ -26,9 +20,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@AutoConfigureMockMvc
-public class ArtifactLinkControllerTest {
+public class ArtifactLinkControllerTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -45,10 +37,6 @@ public class ArtifactLinkControllerTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -117,7 +105,6 @@ void findArtifactLinkById_NotSameTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void addArtifactLink() throws Exception {
String json = """
{
@@ -169,7 +156,6 @@ void updateArtifactLink() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void deleteArtifactLink() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/teams/1/artifact-links/1").accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.studentEricToken))
.andExpect(jsonPath("$.flag").value(true))
diff --git a/backend/src/test/java/team/projectpulse/ram/requirement/RequirementArtifactControllerTest.java b/backend/src/test/java/team/projectpulse/ram/requirement/RequirementArtifactControllerTest.java
index 9ba0c03..235cb3f 100644
--- a/backend/src/test/java/team/projectpulse/ram/requirement/RequirementArtifactControllerTest.java
+++ b/backend/src/test/java/team/projectpulse/ram/requirement/RequirementArtifactControllerTest.java
@@ -6,18 +6,12 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
@@ -25,9 +19,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@AutoConfigureMockMvc
-public class RequirementArtifactControllerTest {
+public class RequirementArtifactControllerTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -45,10 +37,6 @@ public class RequirementArtifactControllerTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -83,7 +71,7 @@ void setUp() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+
void findRequirementArtifactsByCriteria1() throws Exception {
String json = """
{
@@ -101,7 +89,7 @@ void findRequirementArtifactsByCriteria1() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+
void findRequirementArtifactsByCriteria2() throws Exception {
String json = """
{
@@ -116,7 +104,7 @@ void findRequirementArtifactsByCriteria2() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+
void findRequirementArtifactsByCriteria3() throws Exception {
String json = """
{
@@ -201,7 +189,7 @@ void addRequirementArtifact_NotSameTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateRequirementArtifact() throws Exception {
String json = """
{
diff --git a/backend/src/test/java/team/projectpulse/ram/usecase/UseCaseControllerTest.java b/backend/src/test/java/team/projectpulse/ram/usecase/UseCaseControllerTest.java
index 6962bc3..08d9b12 100644
--- a/backend/src/test/java/team/projectpulse/ram/usecase/UseCaseControllerTest.java
+++ b/backend/src/test/java/team/projectpulse/ram/usecase/UseCaseControllerTest.java
@@ -6,18 +6,12 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import static org.hamcrest.Matchers.hasSize;
@@ -26,9 +20,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@AutoConfigureMockMvc
-class UseCaseControllerTest {
+class UseCaseControllerTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -46,10 +38,6 @@ class UseCaseControllerTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -95,7 +83,7 @@ void findUseCaseById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void addUseCase() throws Exception {
// Given
String json = """
@@ -233,7 +221,7 @@ void addUseCase() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void addUseCase_NotSameTeam() throws Exception {
// Given
String json = """
@@ -368,7 +356,7 @@ void addUseCase_NotSameTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateUseCaseWithRewordedContent() throws Exception {
lockUseCase(1, 3, this.studentEricToken);
int version = fetchUseCaseVersion(1, 3, this.studentEricToken);
@@ -543,7 +531,7 @@ void updateUseCaseWithRewordedContent() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateUseCaseWithNewSteps() throws Exception {
lockUseCase(1, 3, this.studentJohnToken);
int version = fetchUseCaseVersion(1, 3, this.studentJohnToken);
@@ -742,7 +730,7 @@ void updateUseCaseWithNewSteps() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateUseCaseWithDeletedSteps() throws Exception {
lockUseCase(1, 3, this.adminBingyangToken);
int version = fetchUseCaseVersion(1, 3, this.adminBingyangToken);
@@ -906,7 +894,7 @@ void updateUseCaseWithDeletedSteps() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void updateUseCaseWithDeletedSteps_NotSameTeam() throws Exception {
// Given
String json = """
@@ -1073,7 +1061,7 @@ void getUseCaseLockStatus() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void lockUseCase() throws Exception {
lockUseCase(1, 3, this.studentJohnToken);
@@ -1087,7 +1075,7 @@ void lockUseCase() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void lockUseCase_AlreadyLocked() throws Exception {
lockUseCase(1, 3, this.studentJohnToken);
@@ -1107,7 +1095,7 @@ void lockUseCase_AlreadyLocked() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void unlockUseCase() throws Exception {
lockUseCase(1, 3, this.studentJohnToken);
@@ -1120,7 +1108,7 @@ void unlockUseCase() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void unlockUseCase_DifferentOwner() throws Exception {
lockUseCase(1, 3, this.studentJohnToken);
@@ -1133,7 +1121,7 @@ void unlockUseCase_DifferentOwner() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void unlockUseCase_Instructor() throws Exception {
lockUseCase(1, 3, this.studentJohnToken);
diff --git a/backend/src/test/java/team/projectpulse/rubric/CriterionIntegrationTest.java b/backend/src/test/java/team/projectpulse/rubric/CriterionIntegrationTest.java
index a88507c..53bb07e 100644
--- a/backend/src/test/java/team/projectpulse/rubric/CriterionIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/rubric/CriterionIntegrationTest.java
@@ -1,26 +1,17 @@
package team.projectpulse.rubric;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
@@ -35,13 +26,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Criterion API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class CriterionIntegrationTest {
+class CriterionIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -57,10 +43,6 @@ class CriterionIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
@@ -136,7 +118,6 @@ void adminTimFindCriterionById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminBingyangAddCriterion() throws Exception {
// Given
Map criterionDto = new HashMap<>();
@@ -159,7 +140,6 @@ void adminBingyangAddCriterion() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminBingyangUpdateCriterion() throws Exception {
// Given
Map criterionDto = new HashMap<>();
@@ -181,7 +161,6 @@ void adminBingyangUpdateCriterion() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminTimUpdateCriterion() throws Exception {
// Given
Map criterionDto = new HashMap<>();
@@ -205,4 +184,4 @@ void adminTimUpdateCriterion() throws Exception {
// .andExpect(jsonPath("$.message").value("Delete peer evaluation criterion successfully"));
// }
-}
\ No newline at end of file
+}
diff --git a/backend/src/test/java/team/projectpulse/rubric/RubricIntegrationTest.java b/backend/src/test/java/team/projectpulse/rubric/RubricIntegrationTest.java
index 533a5e1..ac54ad6 100644
--- a/backend/src/test/java/team/projectpulse/rubric/RubricIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/rubric/RubricIntegrationTest.java
@@ -1,26 +1,17 @@
package team.projectpulse.rubric;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
@@ -35,13 +26,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Rubric API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class RubricIntegrationTest {
+class RubricIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -60,10 +46,6 @@ class RubricIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
@@ -171,7 +153,6 @@ void studentJanaFindRubricById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void addRubric() throws Exception {
// Given
Map rubricDto = new HashMap<>();
@@ -190,7 +171,6 @@ void addRubric() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminBingyangUpdateRubric() throws Exception {
// Given
Map rubricDto = new HashMap<>();
@@ -209,7 +189,6 @@ void adminBingyangUpdateRubric() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminTimUpdateRubric() throws Exception {
// Given
Map rubricDto = new HashMap<>();
@@ -229,7 +208,6 @@ void adminTimUpdateRubric() throws Exception {
// }
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void assignCriterionToRubric() throws Exception {
this.mockMvc.perform(put(this.baseUrl + "/rubrics/1/criteria/7").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -254,7 +232,6 @@ void assignCriterionToRubricNotInSameCourse() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void removeCriterionFromRubric() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/rubrics/1/criteria/6").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -279,4 +256,4 @@ void removeCriterionFromRubricNotInSameCourse() throws Exception {
}
-}
\ No newline at end of file
+}
diff --git a/backend/src/test/java/team/projectpulse/section/SectionIntegrationTest.java b/backend/src/test/java/team/projectpulse/section/SectionIntegrationTest.java
index 6f1037b..6a3e6fc 100644
--- a/backend/src/test/java/team/projectpulse/section/SectionIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/section/SectionIntegrationTest.java
@@ -1,34 +1,22 @@
package team.projectpulse.section;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
import java.util.HashMap;
import java.util.List;
@@ -39,13 +27,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Section API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class SectionIntegrationTest {
+class SectionIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -64,21 +47,6 @@ class SectionIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
- @Container
- static final GenericContainer> mailpit = new GenericContainer<>(DockerImageName.parse("axllent/mailpit"))
- .withExposedPorts(1025, 8025);
-
-
- @DynamicPropertySource
- static void setMailpitProperties(DynamicPropertyRegistry registry) {
- registry.add("spring.mail.host", mailpit::getHost);
- registry.add("spring.mail.port", () -> mailpit.getMappedPort(1025));
- }
-
@BeforeEach
void setUp() throws Exception {
ResultActions resultActions = this.mockMvc.perform(post(this.baseUrl + "/users/login").with(httpBasic("b.wei@abc.edu", "123456"))); // httpBasic() is from spring-security-test.
@@ -222,7 +190,7 @@ void instructorBillFindSectionById3() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+
void instructorBillFindSectionById2() throws Exception {
this.mockMvc.perform(get(this.baseUrl + "/sections/2").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.instructorBillToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -244,7 +212,7 @@ void adminTimFindSectionById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void adminBingyangAddSection() throws Exception {
// Given
Map sectionDto = new HashMap<>();
@@ -310,7 +278,7 @@ void instructorBillAddSection() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void adminBingyangUpdateSection() throws Exception {
// Given
Map sectionDto = new HashMap<>();
@@ -419,7 +387,7 @@ void adminTimAssignRubric() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
+
void adminBingyangAssignInstructor() throws Exception {
this.mockMvc.perform(put(this.baseUrl + "/sections/1/instructors/2").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
diff --git a/backend/src/test/java/team/projectpulse/student/StudentIntegrationTest.java b/backend/src/test/java/team/projectpulse/student/StudentIntegrationTest.java
index 297e2e1..9429a33 100644
--- a/backend/src/test/java/team/projectpulse/student/StudentIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/student/StudentIntegrationTest.java
@@ -1,31 +1,22 @@
package team.projectpulse.student;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
-import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.HashMap;
import java.util.Map;
@@ -36,13 +27,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Instructor API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class StudentIntegrationTest {
+class StudentIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -63,10 +49,6 @@ class StudentIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
@@ -166,7 +148,6 @@ void testStudentJohnFindAnotherStudentsInfoById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testAddStudent() throws Exception {
Map studentDto = new HashMap<>();
studentDto.put("username", "lucas");
@@ -245,7 +226,6 @@ void testAddStudentWithNoWrongUserInvitation() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void testStudentJohnUpdatesOwnInfo() throws Exception {
Map studentDto = new HashMap<>();
studentDto.put("username", "john");
@@ -327,4 +307,4 @@ void testStudentJohnFindStudentsInAnotherTeam() throws Exception {
.andExpect(jsonPath("$.data").value("Access Denied"));
}
-}
\ No newline at end of file
+}
diff --git a/backend/src/test/java/team/projectpulse/system/WebConfigSpaForwardingTest.java b/backend/src/test/java/team/projectpulse/system/WebConfigSpaForwardingTest.java
index c125dda..9b6f53d 100644
--- a/backend/src/test/java/team/projectpulse/system/WebConfigSpaForwardingTest.java
+++ b/backend/src/test/java/team/projectpulse/system/WebConfigSpaForwardingTest.java
@@ -5,11 +5,12 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.SharedContainers;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -17,15 +18,20 @@
@SpringBootTest
@AutoConfigureMockMvc(addFilters = false)
-@Testcontainers
+@ActiveProfiles("dev")
class WebConfigSpaForwardingTest {
@Autowired
MockMvc mockMvc;
- @Container
@ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
+ static final MySQLContainer> mysql = SharedContainers.MYSQL;
+
+ @DynamicPropertySource
+ static void setProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.mail.host", SharedContainers.MAILPIT::getHost);
+ registry.add("spring.mail.port", () -> SharedContainers.MAILPIT.getMappedPort(1025));
+ }
@Test
void shouldForwardThreeSegmentSpaRouteToIndexHtml() throws Exception {
diff --git a/backend/src/test/java/team/projectpulse/team/TeamIntegrationTest.java b/backend/src/test/java/team/projectpulse/team/TeamIntegrationTest.java
index 818f49d..75064ee 100644
--- a/backend/src/test/java/team/projectpulse/team/TeamIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/team/TeamIntegrationTest.java
@@ -1,26 +1,17 @@
package team.projectpulse.team;
import tools.jackson.databind.json.JsonMapper;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
+import team.projectpulse.AbstractIntegrationTest;
import team.projectpulse.system.StatusCode;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
@@ -35,13 +26,8 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for Team API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class TeamIntegrationTest {
+class TeamIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -60,10 +46,6 @@ class TeamIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@BeforeEach
void setUp() throws Exception {
@@ -183,7 +165,6 @@ void adminTimFindTeamById() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminBingyangAddTeam() throws Exception {
// Given
Map teamDto = new HashMap<>();
@@ -225,7 +206,6 @@ void instructorBillAddTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void adminBingyangUpdateTeam() throws Exception {
// Given
Map teamDto = new HashMap<>();
@@ -290,7 +270,6 @@ void adminTimUpdateTeam() throws Exception {
// }
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void assignStudentToTeam() throws Exception {
this.mockMvc.perform(put(this.baseUrl + "/teams/1/students/14").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -307,7 +286,6 @@ void assignStudentToTeamNotInSameSection() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void removeStudentFromTeam() throws Exception {
this.mockMvc.perform(delete(this.baseUrl + "/teams/1/students/4").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -316,7 +294,6 @@ void removeStudentFromTeam() throws Exception {
}
@Test
- @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
void assignInstructorToTeam() throws Exception {
this.mockMvc.perform(put(this.baseUrl + "/teams/3/instructors/2").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, this.adminBingyangToken))
.andExpect(jsonPath("$.flag").value(true))
@@ -387,4 +364,4 @@ void transferTeamToAnotherSectionAsNonCourseAdmin() throws Exception {
.andExpect(jsonPath("$.message").value("No permission."));
}
-}
\ No newline at end of file
+}
diff --git a/backend/src/test/java/team/projectpulse/user/UserIntegrationTest.java b/backend/src/test/java/team/projectpulse/user/UserIntegrationTest.java
index b81cc66..f7c9677 100644
--- a/backend/src/test/java/team/projectpulse/user/UserIntegrationTest.java
+++ b/backend/src/test/java/team/projectpulse/user/UserIntegrationTest.java
@@ -1,33 +1,20 @@
package team.projectpulse.user;
+import team.projectpulse.AbstractIntegrationTest;
import tools.jackson.databind.json.JsonMapper;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.http.MediaType;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
-import org.testcontainers.containers.MySQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.utility.DockerImageName;
import team.projectpulse.system.StatusCode;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-@SpringBootTest
-@Testcontainers
-@AutoConfigureMockMvc
@DisplayName("Integration tests for User API endpoints")
-@Tag("integration")
-@ActiveProfiles(value = "dev")
-class UserIntegrationTest {
+class UserIntegrationTest extends AbstractIntegrationTest {
@Autowired
MockMvc mockMvc;
@@ -38,10 +25,6 @@ class UserIntegrationTest {
@Value("${api.endpoint.base-url}")
String baseUrl;
- @Container
- @ServiceConnection
- static MySQLContainer> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"));
-
@Test
void testCheckUserExists1() throws Exception {
this.mockMvc.perform(get(this.baseUrl + "/users/exists/j.smith@abc.edu").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
@@ -60,4 +43,4 @@ void testCheckUserExists2() throws Exception {
.andExpect(jsonPath("$.data").value(false));
}
-}
\ No newline at end of file
+}