From f109f5e9d771d68b848e7acb0ca1d8c327be6b5e Mon Sep 17 00:00:00 2001 From: Julien WITTOUCK Date: Thu, 18 Jun 2020 19:05:52 +0200 Subject: [PATCH] :zap: : use singleton container pattern using a singleton container with emptyDatabase between tests instead of reloading a new spring-context for each integration test. now spring is reloaded only if necessary, not when some data must change in the database. --- src/test/java/io/gaia_app/GaiaIT.java | 11 +- .../AuthenticationRestControllerIT.kt | 22 ++- .../config/security/SecurityConfigIT.kt | 1 - .../security/StateApiSecurityConfigIT.java | 12 +- .../actuator/ActuatorSecurityConfigIT.java | 12 +- .../security/ldap/LdapSecurityConfigIT.java | 12 +- .../oauth2/OAuth2ClientSecurityConfigIT.kt | 18 +- src/test/java/io/gaia_app/e2e/SeleniumIT.java | 29 ++-- .../DockerRegistryRestControllerIT.kt | 19 +- .../controller/ModuleRestControllerIT.java | 20 +-- .../TerraformModuleRepositoryIT.java | 16 +- .../controller/GithubRegistryControllerIT.kt | 21 +-- .../controller/GitlabRegistryControllerIT.kt | 21 +-- .../repository/SettingsRepositoryIT.java | 13 +- .../controller/StackRestControllerIT.java | 163 +++++++++--------- .../stacks/repository/StackRepositoryIT.java | 12 +- .../stacks/repository/StepRepositoryIT.java | 16 +- .../controller/TeamsRestControllerIT.java | 28 ++- .../controller/UsersRestControllerIT.java | 76 ++++---- .../teams/repository/UserRepositoryIT.kt | 14 +- .../java/io/gaia_app/test/MongoContainer.java | 47 ++--- .../test/SharedMongoContainerTest.java | 19 ++ 22 files changed, 235 insertions(+), 367 deletions(-) create mode 100644 src/test/java/io/gaia_app/test/SharedMongoContainerTest.java diff --git a/src/test/java/io/gaia_app/GaiaIT.java b/src/test/java/io/gaia_app/GaiaIT.java index bb68083bc..c5503379c 100644 --- a/src/test/java/io/gaia_app/GaiaIT.java +++ b/src/test/java/io/gaia_app/GaiaIT.java @@ -1,21 +1,14 @@ package io.gaia_app; -import io.gaia_app.test.MongoContainer; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.junit.jupiter.api.Assertions.assertNotNull; @SpringBootTest -@Testcontainers -class GaiaIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer(); +class GaiaIT extends SharedMongoContainerTest { @Autowired private Gaia gaia; diff --git a/src/test/java/io/gaia_app/client/controller/AuthenticationRestControllerIT.kt b/src/test/java/io/gaia_app/client/controller/AuthenticationRestControllerIT.kt index 2b4d64c67..60837785d 100644 --- a/src/test/java/io/gaia_app/client/controller/AuthenticationRestControllerIT.kt +++ b/src/test/java/io/gaia_app/client/controller/AuthenticationRestControllerIT.kt @@ -1,35 +1,33 @@ package io.gaia_app.client.controller -import io.gaia_app.test.MongoContainer +import io.gaia_app.test.SharedMongoContainerTest import org.hamcrest.Matchers.equalTo import org.hamcrest.Matchers.hasSize +import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status -import org.testcontainers.junit.jupiter.Container -import org.testcontainers.junit.jupiter.Testcontainers @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureMockMvc -class AuthenticationRestControllerIT { +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class AuthenticationRestControllerIT: SharedMongoContainerTest() { @Autowired lateinit var mockMvc: MockMvc - companion object { - @Container - val mongoContainer = MongoContainer() - .withScript("src/test/resources/db/00_team.js") - .withScript("src/test/resources/db/10_user.js") + @BeforeAll + fun setUp() { + mongo.emptyDatabase() + mongo.runScript("src/test/resources/db/00_team.js") + mongo.runScript("src/test/resources/db/10_user.js") } @Test diff --git a/src/test/java/io/gaia_app/config/security/SecurityConfigIT.kt b/src/test/java/io/gaia_app/config/security/SecurityConfigIT.kt index 2c0a9c11f..2b170afb0 100644 --- a/src/test/java/io/gaia_app/config/security/SecurityConfigIT.kt +++ b/src/test/java/io/gaia_app/config/security/SecurityConfigIT.kt @@ -24,7 +24,6 @@ import org.springframework.web.bind.annotation.RestController @SpringBootTest(classes = [SecurityConfig::class, SecurityConfigIT.FakeRestController::class]) @AutoConfigureMockMvc -@DirtiesContext @TestPropertySource(properties = ["gaia.admin-password=admin456"]) class SecurityConfigIT { diff --git a/src/test/java/io/gaia_app/config/security/StateApiSecurityConfigIT.java b/src/test/java/io/gaia_app/config/security/StateApiSecurityConfigIT.java index 5770fb1e2..33d3272bc 100644 --- a/src/test/java/io/gaia_app/config/security/StateApiSecurityConfigIT.java +++ b/src/test/java/io/gaia_app/config/security/StateApiSecurityConfigIT.java @@ -1,14 +1,11 @@ package io.gaia_app.config.security; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; @@ -18,12 +15,7 @@ @SpringBootTest @AutoConfigureMockMvc -@DirtiesContext -@Testcontainers -public class StateApiSecurityConfigIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer(); +public class StateApiSecurityConfigIT extends SharedMongoContainerTest { @Autowired private StateApiSecurityConfig.StateApiSecurityProperties props; diff --git a/src/test/java/io/gaia_app/config/security/actuator/ActuatorSecurityConfigIT.java b/src/test/java/io/gaia_app/config/security/actuator/ActuatorSecurityConfigIT.java index a95d75f47..b624c9820 100644 --- a/src/test/java/io/gaia_app/config/security/actuator/ActuatorSecurityConfigIT.java +++ b/src/test/java/io/gaia_app/config/security/actuator/ActuatorSecurityConfigIT.java @@ -1,14 +1,11 @@ package io.gaia_app.config.security.actuator; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -18,16 +15,11 @@ @SpringBootTest @AutoConfigureMockMvc -@DirtiesContext -@Testcontainers -class ActuatorSecurityConfigIT { +class ActuatorSecurityConfigIT extends SharedMongoContainerTest { @Autowired private MockMvc mockMvc; - @Container - private static MongoContainer mongo = new MongoContainer(); - @Test void actuatorHealth_shouldNotNeedAuthentication() throws Exception { this.mockMvc.perform(get("/admin/health")).andDo(print()).andExpect(status().isOk()) diff --git a/src/test/java/io/gaia_app/config/security/ldap/LdapSecurityConfigIT.java b/src/test/java/io/gaia_app/config/security/ldap/LdapSecurityConfigIT.java index 0028e714d..209b4da44 100644 --- a/src/test/java/io/gaia_app/config/security/ldap/LdapSecurityConfigIT.java +++ b/src/test/java/io/gaia_app/config/security/ldap/LdapSecurityConfigIT.java @@ -1,27 +1,21 @@ package io.gaia_app.config.security.ldap; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -@DirtiesContext @Testcontainers class LdapSecurityConfigIT { - @Container - private static MongoContainer mongoContainer = new MongoContainer(); - @Nested @SpringBootTest(properties = "gaia.ldap.enabled=false") - class LdapSecurityConfigNotLoadedTest { + class LdapSecurityConfigNotLoadedTest extends SharedMongoContainerTest { @Test void ldapSecurityConfig_shouldNotBeInstantiated( @Autowired(required = false) LdapSecurityConfig ldapSecurityConfig) { @@ -35,7 +29,7 @@ void ldapSecurityConfig_shouldNotBeInstantiated( "gaia.ldap.userDnPatterns=test_dn", "gaia.ldap.url=ldap://test_url", }) - class LdapSecurityConfigLoadedTest { + class LdapSecurityConfigLoadedTest extends SharedMongoContainerTest { @Test void ldapSecurityConfig_shouldBeInstantiated( @Autowired(required = false) LdapSecurityConfig ldapSecurityConfig) { diff --git a/src/test/java/io/gaia_app/config/security/oauth2/OAuth2ClientSecurityConfigIT.kt b/src/test/java/io/gaia_app/config/security/oauth2/OAuth2ClientSecurityConfigIT.kt index 748b46d13..c210e00a6 100644 --- a/src/test/java/io/gaia_app/config/security/oauth2/OAuth2ClientSecurityConfigIT.kt +++ b/src/test/java/io/gaia_app/config/security/oauth2/OAuth2ClientSecurityConfigIT.kt @@ -1,6 +1,6 @@ package io.gaia_app.config.security.oauth2 -import io.gaia_app.test.MongoContainer +import io.gaia_app.test.SharedMongoContainerTest import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Nested @@ -8,27 +8,17 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status -import org.testcontainers.junit.jupiter.Container -import org.testcontainers.junit.jupiter.Testcontainers -@DirtiesContext -@Testcontainers class OAuth2ClientSecurityConfigIT { - companion object { - @Container - val mongoContainer = MongoContainer() - } - @Nested @SpringBootTest - inner class OAuth2ClientSecurityConfigNotLoadedTest { + inner class OAuth2ClientSecurityConfigNotLoadedTest: SharedMongoContainerTest() { @Test fun `oauth2ClientSecurityConfig should not be instantiated`( @@ -47,7 +37,7 @@ class OAuth2ClientSecurityConfigIT { @Nested @SpringBootTest @ActiveProfiles("oauth2") - inner class OAuth2ClientSecurityConfigLoadedTest { + inner class OAuth2ClientSecurityConfigLoadedTest: SharedMongoContainerTest() { @Test fun `oauth2ClientSecurityConfig should be instantiated`( @@ -75,7 +65,7 @@ class OAuth2ClientSecurityConfigIT { "spring.security.oauth2.client.provider.dummy.token-uri=https://dummy.com/oauth/token", "spring.security.oauth2.client.provider.dummy.user-info-uri=https://dummy.com/api/v4/user", "spring.security.oauth2.client.provider.dummy.user-name-attribute=username"]) - inner class OAuth2ClientSecurityTest { + inner class OAuth2ClientSecurityTest: SharedMongoContainerTest() { @Autowired lateinit var mockMvc: MockMvc diff --git a/src/test/java/io/gaia_app/e2e/SeleniumIT.java b/src/test/java/io/gaia_app/e2e/SeleniumIT.java index f75ff0d44..04524878e 100644 --- a/src/test/java/io/gaia_app/e2e/SeleniumIT.java +++ b/src/test/java/io/gaia_app/e2e/SeleniumIT.java @@ -1,7 +1,6 @@ package io.gaia_app.e2e; -import io.gaia_app.test.MongoContainer; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import io.percy.selenium.Percy; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.*; @@ -15,9 +14,6 @@ import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.annotation.DirtiesContext; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import java.io.File; import java.io.IOException; @@ -27,25 +23,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@DirtiesContext -@Testcontainers @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @Tag("e2e") -public class SeleniumIT { +public class SeleniumIT extends SharedMongoContainerTest { @LocalServerPort private int serverPort; - @Container - private static MongoContainer mongoContainer = new MongoContainer() - .withScript("src/test/resources/db/00_team.js") - .withScript("src/test/resources/db/10_user.js") - .withScript("src/test/resources/db/20_module.js") - .withScript("src/test/resources/db/30_stack.js") - .withScript("src/test/resources/db/40_job.js") - .withScript("src/test/resources/db/50_step.js") - .withScript("src/test/resources/db/60_terraformState.js"); - private static WebDriver driver; private static Percy percy; @@ -65,6 +49,15 @@ public static void openServerAndBrowser() throws IOException { percy = new Percy(driver); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); + + mongo.emptyDatabase(); + mongo.runScript("src/test/resources/db/00_team.js"); + mongo.runScript("src/test/resources/db/10_user.js"); + mongo.runScript("src/test/resources/db/20_module.js"); + mongo.runScript("src/test/resources/db/30_stack.js"); + mongo.runScript("src/test/resources/db/40_job.js"); + mongo.runScript("src/test/resources/db/50_step.js"); + mongo.runScript("src/test/resources/db/60_terraformState.js"); } @AfterAll diff --git a/src/test/java/io/gaia_app/modules/controller/DockerRegistryRestControllerIT.kt b/src/test/java/io/gaia_app/modules/controller/DockerRegistryRestControllerIT.kt index ce4031e18..d18dbb9c1 100644 --- a/src/test/java/io/gaia_app/modules/controller/DockerRegistryRestControllerIT.kt +++ b/src/test/java/io/gaia_app/modules/controller/DockerRegistryRestControllerIT.kt @@ -1,8 +1,10 @@ package io.gaia_app.modules.controller; -import io.gaia_app.test.MongoContainer +import io.gaia_app.test.SharedMongoContainerTest import org.hamcrest.Matchers.* +import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc @@ -10,7 +12,6 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.io.ClassPathResource import org.springframework.http.MediaType import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.web.client.MockRestServiceServer.bindTo import org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo import org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess @@ -19,15 +20,12 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.springframework.web.client.RestTemplate -import org.testcontainers.junit.jupiter.Container -import org.testcontainers.junit.jupiter.Testcontainers @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureWebClient @AutoConfigureMockMvc -class DockerRegistryRestControllerIT { +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class DockerRegistryRestControllerIT: SharedMongoContainerTest() { @Autowired lateinit var mockMvc: MockMvc @@ -35,9 +33,10 @@ class DockerRegistryRestControllerIT { @Autowired lateinit var restTemplate: RestTemplate - companion object { - @Container - val mongoContainer = MongoContainer().withScript("src/test/resources/db/10_user.js") + @BeforeAll + internal fun setUp() { + mongo.emptyDatabase() + mongo.runScript("src/test/resources/db/10_user.js") } @Test diff --git a/src/test/java/io/gaia_app/modules/controller/ModuleRestControllerIT.java b/src/test/java/io/gaia_app/modules/controller/ModuleRestControllerIT.java index 103993f85..c72370165 100644 --- a/src/test/java/io/gaia_app/modules/controller/ModuleRestControllerIT.java +++ b/src/test/java/io/gaia_app/modules/controller/ModuleRestControllerIT.java @@ -1,6 +1,6 @@ package io.gaia_app.modules.controller; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -8,10 +8,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.hamcrest.Matchers.*; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; @@ -24,24 +21,19 @@ * Simple integration test that validates the security configuration of the TeamsRestController, and its http routes */ @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureMockMvc @WithMockUser(value = "admin", roles = "ADMIN") -class ModuleRestControllerIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer() - .withScript("src/test/resources/db/00_team.js") - .withScript("src/test/resources/db/10_user.js") - .withScript("src/test/resources/db/20_module.js"); +class ModuleRestControllerIT extends SharedMongoContainerTest { @Autowired private MockMvc mockMvc; @BeforeEach void setup() { - mongoContainer.resetDatabase(); + mongo.emptyDatabase(); + mongo.runScript("src/test/resources/db/00_team.js"); + mongo.runScript("src/test/resources/db/10_user.js"); + mongo.runScript("src/test/resources/db/20_module.js"); } @Test diff --git a/src/test/java/io/gaia_app/modules/repository/TerraformModuleRepositoryIT.java b/src/test/java/io/gaia_app/modules/repository/TerraformModuleRepositoryIT.java index 1ab60dd5c..f9c86aad0 100644 --- a/src/test/java/io/gaia_app/modules/repository/TerraformModuleRepositoryIT.java +++ b/src/test/java/io/gaia_app/modules/repository/TerraformModuleRepositoryIT.java @@ -3,30 +3,18 @@ import io.gaia_app.modules.bo.TerraformModule; import io.gaia_app.teams.Team; import io.gaia_app.teams.User; -import io.gaia_app.test.MongoContainer; -import io.gaia_app.modules.bo.TerraformModule; -import io.gaia_app.teams.Team; -import io.gaia_app.teams.User; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; -import org.springframework.test.annotation.DirtiesContext; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @DataMongoTest -@Testcontainers -@DirtiesContext -class TerraformModuleRepositoryIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer(); +class TerraformModuleRepositoryIT extends SharedMongoContainerTest { @Autowired private TerraformModuleRepository terraformModuleRepository; diff --git a/src/test/java/io/gaia_app/registries/controller/GithubRegistryControllerIT.kt b/src/test/java/io/gaia_app/registries/controller/GithubRegistryControllerIT.kt index 6bc33d91c..bac7d6d9d 100644 --- a/src/test/java/io/gaia_app/registries/controller/GithubRegistryControllerIT.kt +++ b/src/test/java/io/gaia_app/registries/controller/GithubRegistryControllerIT.kt @@ -7,8 +7,9 @@ import io.gaia_app.registries.RegistryDetails import io.gaia_app.registries.RegistryType import io.gaia_app.teams.OAuth2User import io.gaia_app.teams.User -import io.gaia_app.test.MongoContainer +import io.gaia_app.test.SharedMongoContainerTest import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient @@ -17,7 +18,6 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.io.ClassPathResource import org.springframework.http.MediaType import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.web.client.MockRestServiceServer import org.springframework.test.web.client.match.MockRestRequestMatchers import org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo @@ -27,16 +27,12 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.springframework.web.client.RestTemplate -import org.testcontainers.junit.jupiter.Container -import org.testcontainers.junit.jupiter.Testcontainers import java.time.LocalDateTime @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureWebClient @AutoConfigureMockMvc -class GithubRegistryControllerIT { +class GithubRegistryControllerIT: SharedMongoContainerTest() { @Autowired private lateinit var objectMapper: ObjectMapper @@ -50,14 +46,15 @@ class GithubRegistryControllerIT { @Autowired private lateinit var mockMvc: MockMvc - companion object { - @Container - private val mongoContainer = MongoContainer().withScript("src/test/resources/db/10_user.js") - } - @Autowired private lateinit var githubRegistryController: GithubRegistryController + @BeforeEach + internal fun setUp() { + mongo.emptyDatabase() + mongo.runScript("src/test/resources/db/10_user.js") + } + @Test fun validateTestConfiguration() { assertThat(mockMvc).isNotNull diff --git a/src/test/java/io/gaia_app/registries/controller/GitlabRegistryControllerIT.kt b/src/test/java/io/gaia_app/registries/controller/GitlabRegistryControllerIT.kt index 1bcb2d284..dbb48128d 100644 --- a/src/test/java/io/gaia_app/registries/controller/GitlabRegistryControllerIT.kt +++ b/src/test/java/io/gaia_app/registries/controller/GitlabRegistryControllerIT.kt @@ -7,8 +7,9 @@ import io.gaia_app.registries.RegistryDetails import io.gaia_app.registries.RegistryType import io.gaia_app.teams.OAuth2User import io.gaia_app.teams.User -import io.gaia_app.test.MongoContainer +import io.gaia_app.test.SharedMongoContainerTest import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient @@ -17,7 +18,6 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.io.ClassPathResource import org.springframework.http.MediaType import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.web.client.MockRestServiceServer import org.springframework.test.web.client.match.MockRestRequestMatchers import org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo @@ -26,16 +26,12 @@ import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders import org.springframework.test.web.servlet.result.MockMvcResultMatchers import org.springframework.web.client.RestTemplate -import org.testcontainers.junit.jupiter.Container -import org.testcontainers.junit.jupiter.Testcontainers import java.time.LocalDateTime @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureWebClient @AutoConfigureMockMvc -class GitlabRegistryControllerIT { +class GitlabRegistryControllerIT: SharedMongoContainerTest() { @Autowired private lateinit var objectMapper: ObjectMapper @@ -49,14 +45,15 @@ class GitlabRegistryControllerIT { @Autowired private lateinit var mockMvc: MockMvc - companion object { - @Container - private val mongoContainer = MongoContainer().withScript("src/test/resources/db/10_user.js") - } - @Autowired private lateinit var gitlabRegistryController: GitlabRegistryController + @BeforeEach + internal fun setUp() { + mongo.emptyDatabase() + mongo.runScript("src/test/resources/db/10_user.js") + } + @Test fun validateTestConfiguration() { assertThat(objectMapper).isNotNull diff --git a/src/test/java/io/gaia_app/settings/repository/SettingsRepositoryIT.java b/src/test/java/io/gaia_app/settings/repository/SettingsRepositoryIT.java index 1578decc3..9350521c1 100644 --- a/src/test/java/io/gaia_app/settings/repository/SettingsRepositoryIT.java +++ b/src/test/java/io/gaia_app/settings/repository/SettingsRepositoryIT.java @@ -1,28 +1,19 @@ package io.gaia_app.settings.repository; import io.gaia_app.settings.bo.Settings; -import io.gaia_app.test.MongoContainer; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest -@Testcontainers @TestPropertySource(properties = {"gaia.externalUrl=http://gaia.io", "gaia.dockerDaemonUrl=unix:///var/run/docker.sock"}) -@DirtiesContext -class SettingsRepositoryIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer(); +class SettingsRepositoryIT extends SharedMongoContainerTest { @Autowired private MongoTemplate mongoTemplate; diff --git a/src/test/java/io/gaia_app/stacks/controller/StackRestControllerIT.java b/src/test/java/io/gaia_app/stacks/controller/StackRestControllerIT.java index 1ad932151..61bedf1ca 100644 --- a/src/test/java/io/gaia_app/stacks/controller/StackRestControllerIT.java +++ b/src/test/java/io/gaia_app/stacks/controller/StackRestControllerIT.java @@ -1,7 +1,6 @@ package io.gaia_app.stacks.controller; -import io.gaia_app.test.MongoContainer; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -9,10 +8,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.hamcrest.Matchers.*; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; @@ -24,164 +20,159 @@ * Simple integration test that validates the security configuration of the TeamsRestController, and its http routes */ @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureMockMvc @WithMockUser(value = "admin", roles = "ADMIN") -class StackRestControllerIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer() - .withScript("src/test/resources/db/00_team.js") - .withScript("src/test/resources/db/10_user.js") - .withScript("src/test/resources/db/20_module.js") - .withScript("src/test/resources/db/30_stack.js"); +class StackRestControllerIT extends SharedMongoContainerTest { @Autowired private MockMvc mockMvc; @BeforeEach - void setup() { - mongoContainer.resetDatabase(); + void setUp() { + mongo.emptyDatabase(); + mongo.runScript("src/test/resources/db/00_team.js"); + mongo.runScript("src/test/resources/db/10_user.js"); + mongo.runScript("src/test/resources/db/20_module.js"); + mongo.runScript("src/test/resources/db/30_stack.js"); } @Test @WithMockUser("Mary J") void listStacks_shouldReturnLimitedStacks_forStandardUsers() throws Exception { mockMvc.perform(get("/api/stacks")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(1))) - .andExpect(jsonPath("$[0]name", is("mongo-instance-limited"))) - .andExpect(jsonPath("$[0]ownerTeam.id", is("Not Ze Team"))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0]name", is("mongo-instance-limited"))) + .andExpect(jsonPath("$[0]ownerTeam.id", is("Not Ze Team"))); } @Test void listStacks_shouldReturnAllStacks_forAdmin() throws Exception { mockMvc.perform(get("/api/stacks")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(4))) - .andExpect(jsonPath("$..name", contains("mongo-instance-1", "mongo-instance-2", "mongo-instance-limited", "local-mongo"))) - .andExpect(jsonPath("$..ownerTeam.id", contains("Ze Team", "Ze Team", "Not Ze Team"))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(4))) + .andExpect(jsonPath("$..name", contains("mongo-instance-1", "mongo-instance-2", "mongo-instance-limited", "local-mongo"))) + .andExpect(jsonPath("$..ownerTeam.id", contains("Ze Team", "Ze Team", "Not Ze Team"))); } @Test @WithMockUser("Mary J") void getStacks_shouldReturnStack_forStandardUsers() throws Exception { mockMvc.perform(get("/api/stacks/845543d0-20a5-466c-8978-33c9a4661606")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.name", is("mongo-instance-limited"))) - .andExpect(jsonPath("$.ownerTeam.id", is("Not Ze Team"))) - .andExpect(jsonPath("$.estimatedRunningCost", is(0))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.name", is("mongo-instance-limited"))) + .andExpect(jsonPath("$.ownerTeam.id", is("Not Ze Team"))) + .andExpect(jsonPath("$.estimatedRunningCost", is(0))); } @Test @WithMockUser("Mary J") void getStacks_shouldNotReturnStackOfOtherTeams_forStandardUsers() throws Exception { mockMvc.perform(get("/api/stacks/5a215b6b-fe53-4afa-85f0-a10175a7f264")) - .andExpect(status().isNotFound()); + .andExpect(status().isNotFound()); } @Test void getStacks_shouldReturnStack_forAdmin() throws Exception { mockMvc.perform(get("/api/stacks/5a215b6b-fe53-4afa-85f0-a10175a7f264")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.name", is("mongo-instance-1"))) - .andExpect(jsonPath("$.ownerTeam.id", is("Ze Team"))) - .andExpect(jsonPath("$.estimatedRunningCost", is(0))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.name", is("mongo-instance-1"))) + .andExpect(jsonPath("$.ownerTeam.id", is("Ze Team"))) + .andExpect(jsonPath("$.estimatedRunningCost", is(0))); } @Test @WithMockUser("Mary J") void saveStack_shouldBeAccessible_forStandardUser() throws Exception { mockMvc.perform(post("/api/stacks") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"stack-test\", \"moduleId\": \"e01f9925-a559-45a2-8a55-f93dc434c676\"}")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", notNullValue())) - .andExpect(jsonPath("$.ownerTeam.id", is("Not Ze Team"))) - .andExpect(jsonPath("$.createdBy.username", is("Mary J"))) - .andExpect(jsonPath("$.createdAt", notNullValue())); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"stack-test\", \"moduleId\": \"e01f9925-a559-45a2-8a55-f93dc434c676\"}")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", notNullValue())) + .andExpect(jsonPath("$.ownerTeam.id", is("Not Ze Team"))) + .andExpect(jsonPath("$.createdBy.username", is("Mary J"))) + .andExpect(jsonPath("$.createdAt", notNullValue())); } @Test @WithMockUser("Mary J") void updateStack_shouldBeAccessible_forStandardUser() throws Exception { mockMvc.perform(put("/api/stacks/test") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"stack-test\", \"moduleId\": \"e01f9925-a559-45a2-8a55-f93dc434c676\"}")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.updatedBy.username", is("Mary J"))) - .andExpect(jsonPath("$.updatedAt", notNullValue())); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"stack-test\", \"moduleId\": \"e01f9925-a559-45a2-8a55-f93dc434c676\"}")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.updatedBy.username", is("Mary J"))) + .andExpect(jsonPath("$.updatedAt", notNullValue())); } @Test void saveStack_shouldValidateStackContent() throws Exception { mockMvc.perform(post("/api/stacks") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - // empty name and module id - .content("{}")) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", containsString("name must not be blank"))) - .andExpect(jsonPath("$.message", containsString("moduleId must not be blank"))); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + // empty name and module id + .content("{}")) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message", containsString("name must not be blank"))) + .andExpect(jsonPath("$.message", containsString("moduleId must not be blank"))); } @Test void saveStack_shouldValidateStackContent_forBlankFields() throws Exception { mockMvc.perform(post("/api/stacks") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - // empty name and module id - .content("{\"name\":\" \",\"moduleId\":\" \"}")) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", containsString("name must not be blank"))) - .andExpect(jsonPath("$.message", containsString("moduleId must not be blank"))); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + // empty name and module id + .content("{\"name\":\" \",\"moduleId\":\" \"}")) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message", containsString("name must not be blank"))) + .andExpect(jsonPath("$.message", containsString("moduleId must not be blank"))); } @Test void updateStack_shouldValidateStackContent() throws Exception { mockMvc.perform(put("/api/stacks/test") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - // empty name and module id - .content("{\"name\":\"\", \"moduleId\": \"\"}")) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", containsString("name must not be blank"))) - .andExpect(jsonPath("$.message", containsString("moduleId must not be blank"))); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + // empty name and module id + .content("{\"name\":\"\", \"moduleId\": \"\"}")) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message", containsString("name must not be blank"))) + .andExpect(jsonPath("$.message", containsString("moduleId must not be blank"))); } @Test void saveStack_shouldValidateStackVariables() throws Exception { mockMvc.perform(post("/api/stacks") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - // null variable - .content("{\"name\":\"stack-test\", \"moduleId\": \"b39ccd07-80f5-455f-a6b3-b94f915738c4\", \"variableValues\":{}}")) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", is("mandatory variables should not be blank"))); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + // null variable + .content("{\"name\":\"stack-test\", \"moduleId\": \"b39ccd07-80f5-455f-a6b3-b94f915738c4\", \"variableValues\":{}}")) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message", is("mandatory variables should not be blank"))); } @Test void saveStack_shouldWork_stackIsValid() throws Exception { mockMvc.perform(post("/api/stacks") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - // empty name - .content("{\"name\":\"stack-test\", \"moduleId\": \"b39ccd07-80f5-455f-a6b3-b94f915738c4\", \"variableValues\":{\"mongo_container_name\":\"someContainerName\"}}")) - .andExpect(status().isOk()); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + // empty name + .content("{\"name\":\"stack-test\", \"moduleId\": \"b39ccd07-80f5-455f-a6b3-b94f915738c4\", \"variableValues\":{\"mongo_container_name\":\"someContainerName\"}}")) + .andExpect(status().isOk()); } @Test void saveStack_shouldValidateStackVariablesRegex() throws Exception { mockMvc.perform(post("/api/stacks") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - // null variable - .content("{\"name\":\"stack-test\", \"moduleId\": \"b39ccd07-80f5-455f-a6b3-b94f915738c4\", \"variableValues\":{\"mongo_container_name\":\"someContainerName\",\"mongo_exposed_port\":\"toto\"}}")) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", is("variables should match the regex"))); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + // null variable + .content("{\"name\":\"stack-test\", \"moduleId\": \"b39ccd07-80f5-455f-a6b3-b94f915738c4\", \"variableValues\":{\"mongo_container_name\":\"someContainerName\",\"mongo_exposed_port\":\"toto\"}}")) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message", is("variables should match the regex"))); } } diff --git a/src/test/java/io/gaia_app/stacks/repository/StackRepositoryIT.java b/src/test/java/io/gaia_app/stacks/repository/StackRepositoryIT.java index 5d1331307..2831c8d0a 100644 --- a/src/test/java/io/gaia_app/stacks/repository/StackRepositoryIT.java +++ b/src/test/java/io/gaia_app/stacks/repository/StackRepositoryIT.java @@ -3,14 +3,11 @@ import io.gaia_app.stacks.bo.Stack; import io.gaia_app.stacks.bo.StackState; import io.gaia_app.teams.Team; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; -import org.springframework.test.annotation.DirtiesContext; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; @@ -19,16 +16,11 @@ @DataMongoTest -@Testcontainers -@DirtiesContext -class StackRepositoryIT { +class StackRepositoryIT extends SharedMongoContainerTest { @Autowired StackRepository stackRepository; - @Container - private static MongoContainer mongo = new MongoContainer(); - @BeforeEach void setUp() { stackRepository.deleteAll(); diff --git a/src/test/java/io/gaia_app/stacks/repository/StepRepositoryIT.java b/src/test/java/io/gaia_app/stacks/repository/StepRepositoryIT.java index 7763c7605..aa399d16b 100644 --- a/src/test/java/io/gaia_app/stacks/repository/StepRepositoryIT.java +++ b/src/test/java/io/gaia_app/stacks/repository/StepRepositoryIT.java @@ -3,18 +3,11 @@ import io.gaia_app.stacks.bo.Step; import io.gaia_app.stacks.bo.StepStatus; import io.gaia_app.stacks.bo.StepType; -import io.gaia_app.test.MongoContainer; -import io.gaia_app.stacks.bo.Step; -import io.gaia_app.stacks.bo.StepStatus; -import io.gaia_app.stacks.bo.StepType; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; -import org.springframework.test.annotation.DirtiesContext; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import java.io.IOException; @@ -22,16 +15,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @DataMongoTest -@Testcontainers -@DirtiesContext -class StepRepositoryIT { +class StepRepositoryIT extends SharedMongoContainerTest { @Autowired StepRepository stepRepository; - @Container - private static MongoContainer mongo = new MongoContainer(); - @Test void jobShouldBeSavedWithLogs() throws IOException { var step = new Step(StepType.PLAN, "42"); diff --git a/src/test/java/io/gaia_app/teams/controller/TeamsRestControllerIT.java b/src/test/java/io/gaia_app/teams/controller/TeamsRestControllerIT.java index ac3e783ea..0c48cb59c 100644 --- a/src/test/java/io/gaia_app/teams/controller/TeamsRestControllerIT.java +++ b/src/test/java/io/gaia_app/teams/controller/TeamsRestControllerIT.java @@ -1,16 +1,14 @@ package io.gaia_app.teams.controller; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasSize; @@ -23,16 +21,9 @@ * Simple integration test that validates the security configuration of the TeamsRestController, and its http routes */ @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureMockMvc @WithMockUser(value = "admin", roles = "ADMIN") -class TeamsRestControllerIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer() - .withScript("src/test/resources/db/00_team.js") - .withScript("src/test/resources/db/10_user.js"); +class TeamsRestControllerIT extends SharedMongoContainerTest { @Autowired private TeamsRestController teamsRestController; @@ -40,6 +31,13 @@ class TeamsRestControllerIT { @Autowired private MockMvc mockMvc; + @BeforeEach + void setUp() { + mongo.emptyDatabase(); + mongo.runScript("src/test/resources/db/00_team.js"); + mongo.runScript("src/test/resources/db/10_user.js"); + } + @Test @WithMockUser("Mary J") void teams_shouldBeAccessible_forStandardUsers() { @@ -54,9 +52,9 @@ void teams_shouldBeAccessible_forAdminUser() { @Test void teams_shouldBeExposed_atSpecificUrl() throws Exception { mockMvc.perform(get("/api/teams")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(3))) - .andExpect(jsonPath("$..id", contains("Ze Team", "Not Ze Team", "Sith"))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(3))) + .andExpect(jsonPath("$..id", contains("Ze Team", "Not Ze Team", "Sith"))); } } diff --git a/src/test/java/io/gaia_app/teams/controller/UsersRestControllerIT.java b/src/test/java/io/gaia_app/teams/controller/UsersRestControllerIT.java index 98f26b2fc..a5b115c76 100644 --- a/src/test/java/io/gaia_app/teams/controller/UsersRestControllerIT.java +++ b/src/test/java/io/gaia_app/teams/controller/UsersRestControllerIT.java @@ -3,8 +3,9 @@ import io.gaia_app.teams.Team; import io.gaia_app.teams.User; import io.gaia_app.teams.repository.UserRepository; -import io.gaia_app.test.MongoContainer; +import io.gaia_app.test.SharedMongoContainerTest; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -12,10 +13,7 @@ import org.springframework.http.MediaType; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.*; @@ -32,16 +30,9 @@ * Simple integration test that validates the security configuration of the UsersRestController, and its http routes */ @SpringBootTest -@DirtiesContext -@Testcontainers @AutoConfigureMockMvc @WithMockUser(value = "admin", roles = "ADMIN") -class UsersRestControllerIT { - - @Container - private static MongoContainer mongoContainer = new MongoContainer() - .withScript("src/test/resources/db/00_team.js") - .withScript("src/test/resources/db/10_user.js"); +class UsersRestControllerIT extends SharedMongoContainerTest { @Autowired private UsersRestController usersRestController; @@ -52,6 +43,13 @@ class UsersRestControllerIT { @Autowired private MockMvc mockMvc; + @BeforeEach + void setUp() { + mongo.emptyDatabase(); + mongo.runScript("src/test/resources/db/00_team.js"); + mongo.runScript("src/test/resources/db/10_user.js"); + } + @Test @WithMockUser("Matthew Bellamy") void users_shouldNotBeAccessible_forStandardUsers() { @@ -66,23 +64,23 @@ void users_shouldBeAccessible_forAdminUser() { @Test void users_shouldBeExposed_atSpecificUrl() throws Exception { mockMvc.perform(get("/api/users")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", hasSize(4))) - .andExpect(jsonPath("$..username", contains("admin", "Mary J", "Darth Vader", "selmak"))) - .andExpect(jsonPath("$..admin", contains(true, false, false, false))) - .andExpect(jsonPath("$..team.id", contains("Ze Team", "Not Ze Team"))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(4))) + .andExpect(jsonPath("$..username", contains("admin", "Mary J", "Darth Vader", "selmak"))) + .andExpect(jsonPath("$..admin", contains(true, false, false, false))) + .andExpect(jsonPath("$..team.id", contains("Ze Team", "Not Ze Team"))); } @Test void saveUser_shouldBeExposed_atSpecificUrl() throws Exception { mockMvc.perform(put("/api/users/test") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"username\":\"Bob\"}")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.username", is("Bob"))) - .andExpect(jsonPath("$.admin", is(false))) - .andExpect(jsonPath("$.team", isEmptyOrNullString())); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"username\":\"Bob\"}")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username", is("Bob"))) + .andExpect(jsonPath("$.admin", is(false))) + .andExpect(jsonPath("$.team", isEmptyOrNullString())); assertThat(userRepository.existsById("Bob")).isTrue(); } @@ -91,28 +89,26 @@ void saveUser_shouldBeExposed_atSpecificUrl() throws Exception { void users_canBeChangedOfTeam() throws Exception { // given assertThat(userRepository.findById("Darth Vader")) - .isPresent() - .map(User::getTeam) - .isNotPresent(); + .isPresent() + .map(User::getTeam) + .isNotPresent(); // when mockMvc.perform(put("/api/users/Darth Vader") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"username\": \"Darth Vader\",\"team\": {\"id\": \"Sith\"}}")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.username", is("Darth Vader"))) - .andExpect(jsonPath("$.admin", is(false))) - .andExpect(jsonPath("$.team.id", is("Sith"))); + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"username\": \"Darth Vader\",\"team\": {\"id\": \"Sith\"}}")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username", is("Darth Vader"))) + .andExpect(jsonPath("$.admin", is(false))) + .andExpect(jsonPath("$.team.id", is("Sith"))); // then assertThat(userRepository.findById("Darth Vader")) - .isPresent() - .map(User::getTeam) - .hasValue(new Team("Sith")); - - mongoContainer.resetDatabase(); + .isPresent() + .map(User::getTeam) + .hasValue(new Team("Sith")); } @Test diff --git a/src/test/java/io/gaia_app/teams/repository/UserRepositoryIT.kt b/src/test/java/io/gaia_app/teams/repository/UserRepositoryIT.kt index 4a22fbb4b..43e9f4ec6 100644 --- a/src/test/java/io/gaia_app/teams/repository/UserRepositoryIT.kt +++ b/src/test/java/io/gaia_app/teams/repository/UserRepositoryIT.kt @@ -2,28 +2,18 @@ package io.gaia_app.teams.repository import io.gaia_app.teams.Team import io.gaia_app.teams.User -import io.gaia_app.test.MongoContainer +import io.gaia_app.test.SharedMongoContainerTest import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest -import org.springframework.test.annotation.DirtiesContext -import org.testcontainers.junit.jupiter.Container -import org.testcontainers.junit.jupiter.Testcontainers @DataMongoTest -@Testcontainers -@DirtiesContext -class UserRepositoryIT { +class UserRepositoryIT: SharedMongoContainerTest() { @Autowired lateinit var userRepository: UserRepository - companion object { - @Container - val mongoContainer = MongoContainer() - } - @Test fun user_shouldBeSaved() { // given diff --git a/src/test/java/io/gaia_app/test/MongoContainer.java b/src/test/java/io/gaia_app/test/MongoContainer.java index fecb78ba1..96ea5f8f6 100644 --- a/src/test/java/io/gaia_app/test/MongoContainer.java +++ b/src/test/java/io/gaia_app/test/MongoContainer.java @@ -11,9 +11,7 @@ import java.io.FileInputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.Objects; /** * A helper class to start a mongodb container @@ -23,7 +21,6 @@ public class MongoContainer extends GenericContainer { private static final Logger LOG = LoggerFactory.getLogger(MongoContainer.class); private static final int MONGO_PORT = 27017; - private final List scripts = new ArrayList<>(); private MongoClient client; private MongoDatabase database; @@ -32,21 +29,6 @@ public MongoContainer() { setExposedPorts(List.of(MONGO_PORT)); } - public MongoContainer withScript(String resource) { - scripts.add(resource); - return this; - } - - @Override - public void start() { - super.start(); - var mappedPort = getMappedPort(MONGO_PORT); - // register the port as property for spring - System.setProperty("gaia.mongodb.uri", String.format("mongodb://localhost:%d/gaia", mappedPort)); - - resetDatabase(); - } - public MongoClient getClient() { if (client == null) { client = MongoClients.create(connectionURL()); @@ -55,7 +37,7 @@ public MongoClient getClient() { } public String connectionURL(){ - return String.format("mongodb://%s:%d",this.getContainerIpAddress(), getMappedPort(MONGO_PORT)); + return String.format("mongodb://%s:%d/gaia",this.getContainerIpAddress(), getMappedPort(MONGO_PORT)); } public MongoDatabase getDatabase() { @@ -65,22 +47,19 @@ public MongoDatabase getDatabase() { return database; } - public void resetDatabase() { - var nbScripts = scripts.stream() - .map(script -> { - try (final FileInputStream fis = new FileInputStream(script)) { - return IOUtils.toString(fis, "UTF-8"); - } catch (IOException e) { - LOG.warn("Unable to read file: {} skipped.", script); - return null; - } - }) - .filter(Objects::nonNull) - .map(content -> new Document("$eval", content)) - .map(getDatabase()::runCommand) - .count(); + public void runScript(String resource){ + try (final FileInputStream fis = new FileInputStream(resource)) { + var content = IOUtils.toString(fis, "UTF-8"); + + var document = new Document("$eval", content); - LOG.info("Number of scripts executed: {}", nbScripts); + getDatabase().runCommand(document); + } catch (IOException e) { + LOG.warn("Unable to read file: {} skipped.", resource); + } } + public void emptyDatabase() { + getDatabase().drop(); + } } diff --git a/src/test/java/io/gaia_app/test/SharedMongoContainerTest.java b/src/test/java/io/gaia_app/test/SharedMongoContainerTest.java new file mode 100644 index 000000000..852fb4654 --- /dev/null +++ b/src/test/java/io/gaia_app/test/SharedMongoContainerTest.java @@ -0,0 +1,19 @@ +package io.gaia_app.test; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +public abstract class SharedMongoContainerTest { + + protected static MongoContainer mongo = new MongoContainer(); + + static { + mongo.start(); + } + + @DynamicPropertySource + static void mongoProperties(DynamicPropertyRegistry registry) { + registry.add("gaia.mongodb.uri", mongo::connectionURL); + } + +}