Skip to content
Snippets Groups Projects
Commit 19c96dfe authored by Felix Reichenbach's avatar Felix Reichenbach
Browse files

Merge branch 'OZG-6741-Organisationseinheit-link' into 'main'

Ozg 6741 organisationseinheit link

See merge request !1
parents 53c55fee 9cad8798
No related branches found
No related tags found
1 merge request!1Ozg 6741 organisationseinheit link
...@@ -226,7 +226,7 @@ String getHelmRepository(){ ...@@ -226,7 +226,7 @@ String getHelmRepository(){
} }
String validateBranchName(branchName) { String validateBranchName(branchName) {
int maxLength = 30 int maxLength = 20
if (branchName.length() > maxLength) { if (branchName.length() > maxLength) {
String originalBranchName = branchName String originalBranchName = branchName
branchName = branchName.substring(0, maxLength) branchName = branchName.substring(0, maxLength)
......
...@@ -123,6 +123,10 @@ spec: ...@@ -123,6 +123,10 @@ spec:
- name: ozgcloud_feature_organisationsEinheiten - name: ozgcloud_feature_organisationsEinheiten
value: {{ .Values.ozgcloud.feature.organisationsEinheiten | quote }} value: {{ .Values.ozgcloud.feature.organisationsEinheiten | quote }}
{{- end }} {{- end }}
{{- if eq ((.Values.ozgcloud).feature).organisationsEinheiten "true" }}
- name: ozgcloud_organisationeinheit_zufisearchuri
value: {{ required "ozgcloud.organisationEinheit.zufiSearchUri must be set if feature organisationsEinheiten is activated" ((.Values.ozgcloud).organisationEinheit).zufiSearchUri}}
{{- end }}
envFrom: envFrom:
{{- if (.Values.database).useExternal }} {{- if (.Values.database).useExternal }}
- secretRef: - secretRef:
......
...@@ -34,7 +34,7 @@ ozgcloud: ...@@ -34,7 +34,7 @@ ozgcloud:
user: administrationApiUser user: administrationApiUser
zufiManager: zufiManager:
address: zufi-server.zufi:9090 address: dns:///zufi-server.zufi:9090
image: image:
repo: docker.ozg-sh.de repo: docker.ozg-sh.de
......
/*
* Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.organisationseinheit;
import jakarta.validation.constraints.NotBlank;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import de.ozgcloud.admin.common.FeatureToggleProperties;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix = OrganisationEinheitProperties.ORGANISATION_EINHEIT_PROPERTIES_PREFIX)
@ConditionalOnProperty(prefix = FeatureToggleProperties.FEATURE_TOGGLE_PREFIX, name = "organisations-einheiten", havingValue = "true")
class OrganisationEinheitProperties {
static final String ORGANISATION_EINHEIT_PROPERTIES_PREFIX = "ozgcloud.organisation-einheit";
/*
* Uri pointing to the endpoint in Alfa that searches for Organisationseinheiten
* in Zufi
*/
@NotBlank
private String zufiSearchUri;
}
...@@ -25,25 +25,42 @@ package de.ozgcloud.admin.organisationseinheit; ...@@ -25,25 +25,42 @@ package de.ozgcloud.admin.organisationseinheit;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import java.util.List;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.RepresentationModelProcessor; import org.springframework.hateoas.server.RepresentationModelProcessor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.ozgcloud.admin.Root; import de.ozgcloud.admin.Root;
import de.ozgcloud.admin.common.FeatureToggleProperties; import de.ozgcloud.admin.common.FeatureToggleProperties;
import de.ozgcloud.admin.common.user.CurrentUserService;
import de.ozgcloud.admin.common.user.UserRole;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@ConditionalOnProperty(prefix = FeatureToggleProperties.FEATURE_TOGGLE_PREFIX, name = "organisations-einheiten", havingValue = "true")
class OrganisationsEinheitRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> { class OrganisationsEinheitRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> {
static final String REL_ORGANISATIONS_EINHEITEN = "organisationsEinheiten"; static final String REL_ORGANISATION_EINHEITEN = "organisationsEinheiten";
static final String REL_SEARCH_ORGANISATION_EINHEIT = "searchOrganisationEinheit";
private final FeatureToggleProperties featureToggleProperties; private final OrganisationEinheitProperties organisationsEinheitProperties;
private final CurrentUserService currentUserService;
@Override @Override
public EntityModel<Root> process(EntityModel<Root> model) { public EntityModel<Root> process(EntityModel<Root> model) {
return model.addIf(featureToggleProperties.isOrganisationsEinheiten(), return model.addAllIf(currentUserService.hasRole(UserRole.ADMIN_ADMIN),
() -> linkTo(methodOn(OrganisationsEinheitController.class).getAll()).withRel(REL_ORGANISATIONS_EINHEITEN)); () -> List.of(buildGetAllOrganisationEinheitenLink(), buildSearchOrganisationEinheitLink()));
}
private Link buildGetAllOrganisationEinheitenLink() {
return linkTo(methodOn(OrganisationsEinheitController.class).getAll()).withRel(REL_ORGANISATION_EINHEITEN);
}
private Link buildSearchOrganisationEinheitLink() {
return Link.of(organisationsEinheitProperties.getZufiSearchUri(), REL_SEARCH_ORGANISATION_EINHEIT);
} }
} }
...@@ -60,6 +60,8 @@ tests: ...@@ -60,6 +60,8 @@ tests:
postfach: "true" postfach: "true"
benutzerRollen: "true" benutzerRollen: "true"
organisationsEinheiten: "true" organisationsEinheiten: "true"
organisationEinheit:
zufiSearchUri: alfa/zufi/search/endpoint?searchBy={searchBy}
asserts: asserts:
- contains: - contains:
path: spec.template.spec.containers[0].env path: spec.template.spec.containers[0].env
......
#
# Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
# Ministerpräsidenten des Landes Schleswig-Holstein
# Staatskanzlei
# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
#
# Lizenziert unter der EUPL, Version 1.2 oder - sobald
# diese von der Europäischen Kommission genehmigt wurden -
# Folgeversionen der EUPL ("Lizenz");
# Sie dürfen dieses Werk ausschließlich gemäß
# dieser Lizenz nutzen.
# Eine Kopie der Lizenz finden Sie hier:
#
# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
#
# Sofern nicht durch anwendbare Rechtsvorschriften
# gefordert oder in schriftlicher Form vereinbart, wird
# die unter der Lizenz verbreitete Software "so wie sie
# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
# ausdrücklich oder stillschweigend - verbreitet.
# Die sprachspezifischen Genehmigungen und Beschränkungen
# unter der Lizenz sind dem Lizenztext zu entnehmen.
#
suite: test zufi search property
release:
name: administration
namespace: sh-helm-test
templates:
- templates/deployment.yaml
set:
ozgcloud:
bundesland: sh
bezeichner: helm
sso:
serverUrl: https://sso.company.local
imagePullSecret: image-pull-secret
tests:
- it: should not contain zufi search uri if organisationseinheit feature toggle not set
set:
ozgcloud:
feature:
organisationsEinheiten: "false"
organisationEinheit:
zufiSearchUri: alfa/zufi/search/endpoint?searchBy={searchBy}
asserts:
- notContains:
path: spec.template.spec.containers[0].env
content:
name: ozgcloud_organisationeinheit_zufisearchuri
any: true
- it: should not contain zufi search uri if organisationseinheit feature toggle is disabled
set:
ozgcloud:
organisationEinheit:
zufiSearchUri: alfa/zufi/search/endpoint?searchBy={searchBy}
asserts:
- notContains:
path: spec.template.spec.containers[0].env
content:
name: ozgcloud_organisationeinheit_zufisearchuri
any: true
- it: should set zufi search uri
set:
ozgcloud:
feature:
organisationsEinheiten: "true"
organisationEinheit:
zufiSearchUri: alfa/zufi/search/endpoint?searchBy={searchBy}
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: ozgcloud_organisationeinheit_zufisearchuri
value: alfa/zufi/search/endpoint?searchBy={searchBy}
- it: should fail if zufi search uri is not set
set:
ozgcloud:
feature:
organisationsEinheiten: "true"
asserts:
- failedTemplate:
errorMessage: "ozgcloud.organisationEinheit.zufiSearchUri must be set if feature organisationsEinheiten is activated"
/*
* Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.organisationseinheit;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import de.ozgcloud.common.test.ITCase;
class OrganisationsEinheitRootProcessorITCase {
@Nested
@SpringBootTest(properties = {
"ozgcloud.feature.organisations-einheiten=true",
"ozgcloud.organisation-einheit.zufi-search-url=foo"
})
@ITCase
class TestFeatureEnabled {
@Autowired
private ApplicationContext applicationContext;
@Test
void shouldHaveOrganisationsEinheitRootProcessorBean() {
assertDoesNotThrow(() -> applicationContext.getBean(OrganisationsEinheitRootProcessor.class));
}
}
@Nested
@SpringBootTest(properties = { "ozgcloud.feature.organisations-einheiten=false", "ozgcloud.organisation-einheit.zufi-search-url=foo" })
@ITCase
class TestFeatureDisabled {
@Autowired
private ApplicationContext applicationContext;
@Test
void shouldHaveOrganisationsEinheitRootProcessorBean() {
assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(OrganisationsEinheitRootProcessor.class));
}
}
}
\ No newline at end of file
...@@ -24,8 +24,10 @@ ...@@ -24,8 +24,10 @@
package de.ozgcloud.admin.organisationseinheit; package de.ozgcloud.admin.organisationseinheit;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
...@@ -33,61 +35,122 @@ import org.mockito.Mock; ...@@ -33,61 +35,122 @@ import org.mockito.Mock;
import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import com.thedeanda.lorem.LoremIpsum;
import de.ozgcloud.admin.Root;
import de.ozgcloud.admin.RootTestFactory; import de.ozgcloud.admin.RootTestFactory;
import de.ozgcloud.admin.common.FeatureToggleProperties; import de.ozgcloud.admin.common.user.CurrentUserService;
import de.ozgcloud.admin.common.user.UserRole;
class OrganisationsEinheitRootProcessorTest { class OrganisationsEinheitRootProcessorTest {
@InjectMocks @InjectMocks
private OrganisationsEinheitRootProcessor organisationsEinheitRootProcessor; private OrganisationsEinheitRootProcessor organisationsEinheitRootProcessor;
@Mock @Mock
private FeatureToggleProperties featureToggleProperties; private OrganisationEinheitProperties organisationsEinheitProperties;
@Mock
private CurrentUserService currentUserService;
@Nested @Nested
class TestProcess { class TestProcess {
@Nested private final String zufiSearchUri = LoremIpsum.getInstance().getUrl() + "?searchBy={searchBy}";
class OrganisationsEinheitenLinkRelation {
@Test @Test
void shouldExistsIfFeatureEnabled() { void shouldCheckUserRole() {
givenFeatureIsEnabled(); processModel();
verify(currentUserService).hasRole(UserRole.ADMIN_ADMIN);
}
var model = organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create())); @Nested
class TestOnWrongUserRole {
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATIONS_EINHEITEN)).isNotEmpty(); @BeforeEach
void givenHasWrongRole() {
when(currentUserService.hasRole(anyString())).thenReturn(false);
} }
@Test @Test
void shouldNotExistIfFeatureDisabled() { void shouldNotAddAnyLinks() {
givenFeatureIsDisabled(); var model = processModel();
assertThat(model.getLinks()).isEmpty();
}
}
var model = organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create())); @Nested
class TestOnAdminRole {
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATIONS_EINHEITEN)).isEmpty(); @BeforeEach
void givenHasAdminRole() {
when(currentUserService.hasRole(anyString())).thenReturn(true);
when(organisationsEinheitProperties.getZufiSearchUri()).thenReturn(zufiSearchUri);
} }
@Nested
class TestOrganisationsEinheitenLinkRelation {
@Test @Test
void shouldHaveHref() { void shouldExist() {
givenFeatureIsEnabled(); var model = processModel();
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATION_EINHEITEN)).isNotEmpty();
}
var model = organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create())); @Test
void shouldHaveHref() {
var model = processModel();
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATIONS_EINHEITEN)) assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_ORGANISATION_EINHEITEN))
.get() .get()
.extracting(Link::getHref) .extracting(Link::getHref)
.isEqualTo(OrganisationsEinheitController.PATH); .isEqualTo(OrganisationsEinheitController.PATH);
} }
}
@Nested
class TestSearchOrganisationsEinheitenLink {
private void givenFeatureIsEnabled() { @Test
when(featureToggleProperties.isOrganisationsEinheiten()).thenReturn(true); void shouldExistsIfFeatureEnabled() {
var model = processModel();
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_SEARCH_ORGANISATION_EINHEIT)).isNotEmpty();
} }
private void givenFeatureIsDisabled() { @Test
when(featureToggleProperties.isOrganisationsEinheiten()).thenReturn(false); void shouldGetZufiSearchUri() {
processModel();
verify(organisationsEinheitProperties).getZufiSearchUri();
} }
@Test
void shouldHaveHref() {
var model = processModel();
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_SEARCH_ORGANISATION_EINHEIT))
.get()
.extracting(Link::getHref)
.isEqualTo(zufiSearchUri);
} }
@Test
void shouldBeTemplated() {
var model = processModel();
assertThat(model.getLink(OrganisationsEinheitRootProcessor.REL_SEARCH_ORGANISATION_EINHEIT))
.get()
.extracting(Link::isTemplated)
.isEqualTo(true);
}
}
} }
private EntityModel<Root> processModel() {
return organisationsEinheitRootProcessor.process(EntityModel.of(RootTestFactory.create()));
}
}
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment