diff --git a/src/main/java/de/ozgcloud/admin/DocumentationProperties.java b/src/main/java/de/ozgcloud/admin/DocumentationProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..956faa74b200bc9cdb50968f9b26689be672cea8 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/DocumentationProperties.java @@ -0,0 +1,19 @@ +package de.ozgcloud.admin; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Configuration +@ConfigurationProperties(prefix = DocumentationProperties.DOCUMENTATION_PROPERTIES_PREFIX) +public class DocumentationProperties { + + static final String DOCUMENTATION_PROPERTIES_PREFIX = "ozgcloud.user-assistance.documentation"; + + private String url; + +} diff --git a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java index 3b564cf37f4483a8b793e1f5c845fdfce4c9ad69..09e8c615f2959334c2487d91d509b5e776361eab 100644 --- a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java +++ b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java @@ -23,8 +23,7 @@ */ package de.ozgcloud.admin; -import java.util.ArrayList; -import java.util.List; +import java.util.Objects; import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties; import org.springframework.hateoas.EntityModel; @@ -40,24 +39,19 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class RootModelAssembler implements RepresentationModelAssembler<Root, EntityModel<Root>> { static final String REL_CONFIGURATION = "configuration"; + static final String REL_DOCUMENTATIONS = "documentations"; private final RepositoryRestProperties restProperties; private final CurrentUserService currentUserService; + private final DocumentationProperties documentationProperties; @Override public EntityModel<Root> toModel(Root root) { - List<Link> links = buildRootModelLinks(); - return EntityModel.of(root, links); - } - - List<Link> buildRootModelLinks() { - List<Link> links = new ArrayList<>(); - var rootLinkBuilder = WebMvcLinkBuilder.linkTo(RootController.class); - links.add(rootLinkBuilder.withSelfRel()); - if (currentUserService.hasConfigurationPermission()) { - links.add(buildConfigLink()); - } - return links; + var rootModel = EntityModel.of(root); + rootModel.add(WebMvcLinkBuilder.linkTo(RootController.class).withSelfRel()); + rootModel.addIf(currentUserService.hasConfigurationPermission(), this::buildConfigLink); + rootModel.addIf(Objects.nonNull(documentationProperties.getUrl()), () -> Link.of(documentationProperties.getUrl(), REL_DOCUMENTATIONS)); + return rootModel; } private Link buildConfigLink() { diff --git a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java index d3933e7611bc6c2682d105a3bd92f022f14421a2..893389235ab0de4590d6463b8c5aaa224bdd4f19 100644 --- a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java +++ b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java @@ -27,8 +27,6 @@ import static de.ozgcloud.admin.RootModelAssembler.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import java.util.List; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -37,8 +35,11 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties; +import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; +import com.thedeanda.lorem.LoremIpsum; + import de.ozgcloud.admin.common.user.CurrentUserService; class RootModelAssemblerTest { @@ -53,82 +54,116 @@ class RootModelAssemblerTest { private RepositoryRestProperties restProperties; @Mock private CurrentUserService currentUserService; + @Mock + private DocumentationProperties documentationProperties; @DisplayName("Entity Model") @Nested - class TestEntityModel { - - private final List<Link> links = List.of(Link.of(RootController.PATH)); + class TestToModel { - @BeforeEach - void beforeEach() { - doReturn(links).when(modelAssembler).buildRootModelLinks(); - } + private final Root root = RootTestFactory.create(); @Test - void shouldHaveRoot() { - var givenRoot = RootTestFactory.create(); - - var resultRoot = modelAssembler.toModel(givenRoot).getContent(); + void shouldHaveRootContent() { + var resultRoot = modelAssembler.toModel(root).getContent(); - assertThat(resultRoot).isEqualTo(givenRoot); + assertThat(resultRoot).isEqualTo(root); } @Test - void shouldHaveLinks() { - var modelLinks = modelAssembler.toModel(RootTestFactory.create()).getLinks(); + void shouldHaveSelfLink() { + var model = modelAssembler.toModel(root); - assertThat(modelLinks).containsAll(links); + assertThat(model.getLink(IanaLinkRelations.SELF)).get().extracting(Link::getHref).isEqualTo(RootController.PATH); } - } - @DisplayName("Root Model Links") - @Nested - class TestBuildRootModelLinks { + @Nested + class TestConfigurationLink { - @Test - void shouldCheckConfigurationPermission() { - modelAssembler.buildRootModelLinks(); + @Test + void shouldCallHasConfigurationPermission() { + modelAssembler.toModel(root); - verify(currentUserService).hasConfigurationPermission(); - } + verify(currentUserService).hasConfigurationPermission(); + } - @Nested - class TestOnHasConfigurationPermission { + @Nested + class TestOnHasConfigurationPermission { + + @BeforeEach + void hasConfigurationPermission() { + when(currentUserService.hasConfigurationPermission()).thenReturn(true); + when(restProperties.getBasePath()).thenReturn(BASE_PATH); + } + + @Test + void shouldHaveHrefToConfiguration() { + var model = modelAssembler.toModel(root); - @BeforeEach - void hasConfigurationPermission() { - when(currentUserService.hasConfigurationPermission()).thenReturn(true); - when(restProperties.getBasePath()).thenReturn(BASE_PATH); + assertThat(model.getLink(REL_CONFIGURATION)).get().extracting(Link::getHref).isEqualTo(BASE_PATH); + } } - @Test - void shouldHaveHrefToConfiguration() { - var links = modelAssembler.buildRootModelLinks(); + @Nested + class TestOnHasNotConfigurationPermission { + + @BeforeEach + void hasNotConfigurationPermission() { + when(currentUserService.hasConfigurationPermission()).thenReturn(false); + } - assertThat(links).containsExactly( - Link.of(RootController.PATH), - Link.of(BASE_PATH, REL_CONFIGURATION)); + @Test + void shouldNotHaveConfigurationLink() { + var model = modelAssembler.toModel(root); + + assertThat(model.getLink(REL_CONFIGURATION)).isEmpty(); + } } } @Nested - class TestOnNotHasConfigurationPermission { + class TestDocumentationLink { + + @Test + void shouldGetDocumentationUrl() { + modelAssembler.toModel(root); - @BeforeEach - void hasNotConfigurationPermission() { - when(currentUserService.hasConfigurationPermission()).thenReturn(false); + verify(documentationProperties).getUrl(); } - @Test - void shouldHaveOnlySelfLink() { - var links = modelAssembler.buildRootModelLinks(); + @Nested + class TestOnDocumentationUrlGiven { + + private final String documentationUrl = LoremIpsum.getInstance().getUrl(); + + @BeforeEach + void mock() { + when(documentationProperties.getUrl()).thenReturn(documentationUrl); + } - assertThat(links).containsExactly( - Link.of(RootController.PATH)); + @Test + void shouldHaveDocumentationLink() { + var model = modelAssembler.toModel(root); + + assertThat(model.getLink(REL_DOCUMENTATIONS)).get().extracting(Link::getHref).isEqualTo(documentationUrl); + } } - } - } + @Nested + class TestOnDocumentationUrlNotGiven { + + @BeforeEach + void mock() { + when(documentationProperties.getUrl()).thenReturn(null); + } + @Test + void shouldNotHaveDocumentationLink() { + var model = modelAssembler.toModel(root); + + assertThat(model.getLink(REL_DOCUMENTATIONS)).isEmpty(); + } + } + } + } } \ No newline at end of file