Skip to content
Snippets Groups Projects
Commit 2d7c5948 authored by OZGCloud's avatar OZGCloud
Browse files

OZG-7000 OZG-7219 Implement feature toggles

parent e12ac2e6
Branches
Tags
No related merge requests found
Showing
with 165 additions and 24 deletions
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;
}
......@@ -34,4 +34,5 @@ public class Environment {
private String authServer;
private String clientId;
private String realm;
private Features features;
}
......@@ -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();
}
}
package de.ozgcloud.admin.environment;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class Features {
private final boolean postfach;
private final boolean benutzerRollen;
}
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);
}
......@@ -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
@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));
}
}
......@@ -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,19 +77,6 @@ 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
......@@ -95,7 +87,6 @@ class EnvironmentControllerTest {
response.andExpect(jsonPath("$.production").value(production));
}
}
@Test
@SneakyThrows
......@@ -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));
......
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);
}
}
}
......@@ -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);
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment