diff --git a/src/main/java/de/ozgcloud/admin/common/FeatureToggleProperties.java b/src/main/java/de/ozgcloud/admin/common/FeatureToggleProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..75ab7ba16c52807514442a6a48be9e2d80c54086 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/common/FeatureToggleProperties.java @@ -0,0 +1,18 @@ +package de.ozgcloud.admin.common; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Configuration +@ConfigurationProperties(prefix = "ozgcloud.feature") +public class FeatureToggleProperties { + + private boolean postfach; + private boolean benutzerRollen; + private boolean organisationsEinheiten; +} diff --git a/src/main/java/de/ozgcloud/admin/environment/Environment.java b/src/main/java/de/ozgcloud/admin/environment/Environment.java index 0ee031564ac123327cd663d982e98a2e2ec1ea87..79c6775f9a86126394ff10142cf70babcebd14af 100644 --- a/src/main/java/de/ozgcloud/admin/environment/Environment.java +++ b/src/main/java/de/ozgcloud/admin/environment/Environment.java @@ -34,4 +34,5 @@ public class Environment { private String authServer; private String clientId; private String realm; + private Features features; } diff --git a/src/main/java/de/ozgcloud/admin/environment/EnvironmentController.java b/src/main/java/de/ozgcloud/admin/environment/EnvironmentController.java index cd1c0417bdf97f51ba49b41f1ec23edadd4d4560..ea3d58e1ee4a5fb027b610a407121a2d70a650e0 100644 --- a/src/main/java/de/ozgcloud/admin/environment/EnvironmentController.java +++ b/src/main/java/de/ozgcloud/admin/environment/EnvironmentController.java @@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import de.ozgcloud.admin.RootController; +import de.ozgcloud.admin.common.FeatureToggleProperties; import lombok.RequiredArgsConstructor; @RestController("ozgCloudEnvironmentController") @@ -43,6 +44,9 @@ public class EnvironmentController { private final OAuth2Properties oAuthProperties; + private final FeatureToggleProperties featureToggleProperties; + private final FeaturesMapper featuresMapper; + @GetMapping public Environment getEnvironment() { return Environment.builder() @@ -51,6 +55,7 @@ public class EnvironmentController { .authServer(oAuthProperties.getAuthServerUrl()) .realm(oAuthProperties.getRealm()) .clientId(oAuthProperties.getResource()) + .features(featuresMapper.fromFeatureToggleProperties(featureToggleProperties)) .build(); } } diff --git a/src/main/java/de/ozgcloud/admin/environment/Features.java b/src/main/java/de/ozgcloud/admin/environment/Features.java new file mode 100644 index 0000000000000000000000000000000000000000..1f63a6e88be1cd2415b720916e60730bc3b3a41e --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/environment/Features.java @@ -0,0 +1,12 @@ +package de.ozgcloud.admin.environment; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class Features { + + private final boolean postfach; + private final boolean benutzerRollen; +} diff --git a/src/main/java/de/ozgcloud/admin/environment/FeaturesMapper.java b/src/main/java/de/ozgcloud/admin/environment/FeaturesMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..2a7e9d4c3b0614824eb0d35fb4dd004e876327a0 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/environment/FeaturesMapper.java @@ -0,0 +1,12 @@ +package de.ozgcloud.admin.environment; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +import de.ozgcloud.admin.common.FeatureToggleProperties; + +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +interface FeaturesMapper { + + Features fromFeatureToggleProperties(FeatureToggleProperties featureToggleProperties); +} diff --git a/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessor.java b/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessor.java index 41dd7c0d08898f2b8e4a4036627521d030b198bb..1cb98fd649ac08564bb8f9da24e5419c0e930016 100644 --- a/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessor.java +++ b/src/main/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessor.java @@ -30,14 +30,20 @@ import org.springframework.hateoas.server.RepresentationModelProcessor; import org.springframework.stereotype.Component; import de.ozgcloud.admin.Root; +import de.ozgcloud.admin.common.FeatureToggleProperties; +import lombok.RequiredArgsConstructor; @Component -class OrganisationsEinheitRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> { +@RequiredArgsConstructor +class OrganisationsEinheitRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> { static final String REL_ORGANISATIONS_EINHEITEN = "organisationsEinheiten"; + private final FeatureToggleProperties featureToggleProperties; + @Override public EntityModel<Root> process(EntityModel<Root> model) { - return model.add(linkTo(methodOn(OrganisationsEinheitController.class).getAll()).withRel(REL_ORGANISATIONS_EINHEITEN)); + return model.addIf(featureToggleProperties.isOrganisationsEinheiten(), + () -> linkTo(methodOn(OrganisationsEinheitController.class).getAll()).withRel(REL_ORGANISATIONS_EINHEITEN)); } } diff --git a/src/test/java/de/ozgcloud/admin/environment/EnvironmentControllerTest.java b/src/test/java/de/ozgcloud/admin/environment/EnvironmentControllerTest.java index 92c63c3900e746fbac7be80a46206c593dcbb4c4..f9337f4197236106c70df9639e0620b08f4157a7 100644 --- a/src/test/java/de/ozgcloud/admin/environment/EnvironmentControllerTest.java +++ b/src/test/java/de/ozgcloud/admin/environment/EnvironmentControllerTest.java @@ -40,6 +40,7 @@ import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import de.ozgcloud.admin.RootController; +import de.ozgcloud.admin.common.FeatureToggleProperties; import lombok.SneakyThrows; class EnvironmentControllerTest { @@ -52,6 +53,10 @@ class EnvironmentControllerTest { private ProductionProperties environmentProperties; @Mock private OAuth2Properties oAuth2Properties; + @Mock + private FeatureToggleProperties featureToggleProperties; + @Mock + private FeaturesMapper featuresMapper; private MockMvc mockMvc; @@ -72,29 +77,15 @@ class EnvironmentControllerTest { response.andExpect(status().isOk()); } - @Nested - class TestBody { - - @Test - @SneakyThrows - void shouldCallIsProduction() { - when(environmentProperties.isProduction()).thenReturn(true); - - doRequest(); - - verify(environmentProperties).isProduction(); - } - - @ParameterizedTest - @ValueSource(booleans = { true, false }) - @SneakyThrows - void shouldContainProduction(boolean production) { - when(environmentProperties.isProduction()).thenReturn(production); + @ParameterizedTest + @ValueSource(booleans = { true, false }) + @SneakyThrows + void shouldContainProduction(boolean production) { + when(environmentProperties.isProduction()).thenReturn(production); - var response = doRequest(); + var response = doRequest(); - response.andExpect(jsonPath("$.production").value(production)); - } + response.andExpect(jsonPath("$.production").value(production)); } @Test @@ -138,6 +129,35 @@ class EnvironmentControllerTest { response.andExpect(jsonPath("$.clientId").value(clientId)); } + @Test + void shouldCallFeaturesMapper() { + doRequest(); + + verify(featuresMapper).fromFeatureToggleProperties(featureToggleProperties); + } + + @SneakyThrows + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldContainPostfach(boolean postfach) { + when(featuresMapper.fromFeatureToggleProperties(featureToggleProperties)).thenReturn(Features.builder().postfach(postfach).build()); + + var response = doRequest(); + + response.andExpect(jsonPath("$.features.postfach").value(postfach)); + } + + @SneakyThrows + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldContainBenutzerRollen(boolean benutzerRollen) { + when(featuresMapper.fromFeatureToggleProperties(featureToggleProperties)).thenReturn(Features.builder().benutzerRollen(benutzerRollen).build()); + + var response = doRequest(); + + response.andExpect(jsonPath("$.features.benutzerRollen").value(benutzerRollen)); + } + @SneakyThrows private ResultActions doRequest() { return mockMvc.perform(get(EnvironmentController.PATH)); diff --git a/src/test/java/de/ozgcloud/admin/environment/FeaturesMapperTest.java b/src/test/java/de/ozgcloud/admin/environment/FeaturesMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..30742c8a4a0cf0e14822d100f2f7e4e4faff7ddf --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/environment/FeaturesMapperTest.java @@ -0,0 +1,41 @@ +package de.ozgcloud.admin.environment; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mapstruct.factory.Mappers; + +import de.ozgcloud.admin.common.FeatureToggleProperties; + +class FeaturesMapperTest { + + private FeaturesMapper mapper = Mappers.getMapper(FeaturesMapper.class); + + @Nested + class TestFromFeatureToggleProperties { + + private final FeatureToggleProperties props = new FeatureToggleProperties(); + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void shouldMapPostfach(boolean postfach) { + props.setPostfach(postfach); + + var features = mapper.fromFeatureToggleProperties(props); + + assertThat(features.isPostfach()).isEqualTo(postfach); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void shouldMapBenutzerRollen(boolean benutzerRollen) { + props.setBenutzerRollen(benutzerRollen); + + var features = mapper.fromFeatureToggleProperties(props); + + assertThat(features.isBenutzerRollen()).isEqualTo(benutzerRollen); + } + } +} diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessorTest.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessorTest.java index 6fbea1e4216267ce9ded626a10926f013d10339c..f147d68e37d851e374f7376a2e84c34374c1f271 100644 --- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessorTest.java +++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitRootProcessorTest.java @@ -24,19 +24,24 @@ package de.ozgcloud.admin.organisationseinheit; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; +import org.mockito.Mock; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; import de.ozgcloud.admin.RootTestFactory; +import de.ozgcloud.admin.common.FeatureToggleProperties; class OrganisationsEinheitRootProcessorTest { @InjectMocks private OrganisationsEinheitRootProcessor organisationsEinheitRootProcessor; + @Mock + private FeatureToggleProperties featureToggleProperties; @Nested class TestProcess { @@ -45,14 +50,27 @@ class OrganisationsEinheitRootProcessorTest { class OrganisationsEinheitenLinkRelation { @Test - void shouldExists() { + void shouldExistsIfFeatureEnabled() { + givenFeatureIsEnabled(); + var model = organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create())); assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATIONS_EINHEITEN)).isNotEmpty(); } + @Test + void shouldNotExistIfFeatureDisabled() { + givenFeatureIsDisabled(); + + var model = organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create())); + + assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATIONS_EINHEITEN)).isEmpty(); + } + @Test void shouldHaveHref() { + givenFeatureIsEnabled(); + var model = organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create())); assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATIONS_EINHEITEN)) @@ -60,6 +78,14 @@ class OrganisationsEinheitRootProcessorTest { .extracting(Link::getHref) .isEqualTo(OrganisationsEinheitController.PATH); } + + private void givenFeatureIsEnabled() { + when(featureToggleProperties.isOrganisationsEinheiten()).thenReturn(true); + } + + private void givenFeatureIsDisabled() { + when(featureToggleProperties.isOrganisationsEinheiten()).thenReturn(false); + } } }