diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResource.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResource.java new file mode 100644 index 0000000000000000000000000000000000000000..3a5d37676d95578418ebba3385ddb8f5f7287e99 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResource.java @@ -0,0 +1,8 @@ +package de.ozgcloud.alfa.resource; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class OzgcloudResource { + +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java new file mode 100644 index 0000000000000000000000000000000000000000..a0ccfcd416ac66767589bc373197b2238d4e99c5 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java @@ -0,0 +1,47 @@ +package de.ozgcloud.alfa.resource; + +import java.util.Collection; +import java.util.Optional; + +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.RepresentationModel; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import de.ozgcloud.alfa.common.errorhandling.ResourceNotFoundException; +import de.ozgcloud.common.errorhandling.TechnicalException; +import jakarta.validation.constraints.NotBlank; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping(OzgcloudResourceController.PATH) +@RequiredArgsConstructor +public class OzgcloudResourceController { + + static final String PATH = "/api/resources"; + static final String PARAM_URI = "uri"; + + private final Collection<OzgcloudResourceURIResolver> resolvers; + private final OzgcloudResourceModelAssembler assembler; + + @GetMapping(params = PARAM_URI) + public RepresentationModel<EntityModel<OzgcloudResource>> getOzgcloudResource(@RequestParam @NotBlank String uri) { + var resourceLink = resolveUri(uri); + if (resourceLink.isEmpty()) { + throw new ResourceNotFoundException(OzgcloudResource.class, uri); + } + return assembler.toModel(new OzgcloudResourceURIResolveResult(uri, resourceLink.get())); + } + + private Optional<Link> resolveUri(String uri) { + return resolvers.stream() + .map(resolver -> resolver.resolve(uri)) + .flatMap(Optional::stream) + .reduce((r1, r2) -> { + throw new TechnicalException("Multiple resolvers accepted uri " + uri); + }); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java new file mode 100644 index 0000000000000000000000000000000000000000..e3e83cf3a97ba6615974c72667fb32b976b6a733 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java @@ -0,0 +1,24 @@ +package de.ozgcloud.alfa.resource; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.server.RepresentationModelAssembler; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +class OzgcloudResourceModelAssembler implements RepresentationModelAssembler<OzgcloudResourceURIResolveResult, EntityModel<OzgcloudResource>> { + + @Override + public EntityModel<OzgcloudResource> toModel(OzgcloudResourceURIResolveResult uriResolveResult) { + return EntityModel.of(new OzgcloudResource()).add(getSelfLink(uriResolveResult.getResourceURI())).add(uriResolveResult.getResourceLink()); + } + + private Link getSelfLink(String uri) { + return linkTo(methodOn(OzgcloudResourceController.class).getOzgcloudResource(uri)).withSelfRel(); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..ebe46beb467ae69720dafe31da6121fcd4b4a956 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java @@ -0,0 +1,20 @@ +package de.ozgcloud.alfa.resource; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.server.RepresentationModelProcessor; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.Root; + +@Component +class OzgcloudResourceRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> { + + static final String REL_RESOURCE = "resource"; + + @Override + public EntityModel<Root> process(EntityModel<Root> model) { + return model.add(linkTo(methodOn(OzgcloudResourceController.class).getOzgcloudResource(null)).withRel(REL_RESOURCE)); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java new file mode 100644 index 0000000000000000000000000000000000000000..edcbd9ef072905e7a30930396e1afa0d68a90aa3 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java @@ -0,0 +1,15 @@ +package de.ozgcloud.alfa.resource; + +import org.springframework.hateoas.Link; + +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Builder +@Getter +@ToString +public class OzgcloudResourceURIResolveResult { + private final String resourceURI; + private final Link resourceLink; +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolver.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..de38d882ecb8d41c198915eafc20b830798f4fbc --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolver.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.resource; + +import java.util.Optional; + +import org.springframework.hateoas.Link; + +public interface OzgcloudResourceURIResolver { + + Optional<Link> resolve(String uri); +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangURIResolver.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangURIResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..c3b6a185dce5c3e3189fabe78e6301c23ccce5a0 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangURIResolver.java @@ -0,0 +1,29 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import java.util.Optional; +import java.util.regex.Pattern; + +import org.springframework.hateoas.Link; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.resource.OzgcloudResourceURIResolver; + +@Component +class VorgangURIResolver implements OzgcloudResourceURIResolver { + + static final String REL_NAME = "vorgang"; + + private final Pattern pattern = Pattern.compile("ozgcloud://[^/]+/vorgangs/([0-9a-fA-F]+)"); + + @Override + public Optional<Link> resolve(String uri) { + var matcher = pattern.matcher(uri); + if (!matcher.matches()) { + return Optional.empty(); + } + var vorgangId = matcher.group(1); + return Optional.of(linkTo(VorgangController.class).slash(vorgangId).withRel(REL_NAME)); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..c4bc47bb1aba700a268c32f282fb569ecb3f909e --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java @@ -0,0 +1,52 @@ +package de.ozgcloud.alfa; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.hamcrest.core.StringEndsWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +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.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import de.ozgcloud.alfa.common.user.CurrentUserService; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; + +@AutoConfigureMockMvc +@SpringBootTest +@WithMockUser +class RootControllerITCase { + + @MockBean + private CurrentUserService currentUserService; + + @Autowired + private MockMvc mockMvc; + + @BeforeEach + void init() { + when(currentUserService.getUser()).thenReturn(UserProfileTestFactory.create()); + } + + @Nested + class TestProcess { + + @Test + void shouldAddResourceLink() throws Exception { + var response = doRequest(); + + response.andExpect(jsonPath("$._links.resource.href").value(StringEndsWith.endsWith("/api/resources?uri={uri}"))); + } + } + + private ResultActions doRequest() throws Exception { + return mockMvc.perform(get(RootController.PATH)).andExpect(status().isOk()); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..a545d2ee05325037544e883b529b7c39d4d9c991 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java @@ -0,0 +1,90 @@ +package de.ozgcloud.alfa.resource; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import org.hamcrest.core.StringEndsWith; +import org.junit.jupiter.api.Nested; +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.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import de.ozgcloud.alfa.common.AlfaTestUtils; +import lombok.SneakyThrows; + +@AutoConfigureMockMvc +@SpringBootTest +@WithMockUser +class OzgcloudResourceControllerITCase { + + @Autowired + private MockMvc mockMvc; + + @Nested + class TestGetOzgcloudResource { + + private static final String VORGANG_ID = AlfaTestUtils.createMongoDbObjectId(); + + @Test + void shouldReturnStatusOk() throws Exception { + var response = doRequest("ozgcloud://test.de/vorgangs/" + VORGANG_ID); + + response.andExpect(status().isOk()); + } + + @Test + void shouldHaveVorgangLink() throws Exception { + var response = doRequest("ozgcloud://test.de/vorgangs/" + VORGANG_ID); + + response.andExpect(jsonPath("$._links.vorgang.href").value(StringEndsWith.endsWith("/api/vorgangs/" + VORGANG_ID))); + } + + @Test + void shouldHaveSelfLink() throws Exception { + var uri = "ozgcloud://test.de/vorgangs/" + VORGANG_ID; + var encodedUri = URLEncoder.encode(uri, StandardCharsets.UTF_8); + + var response = doRequest(uri); + + response.andExpect(jsonPath("$._links.self.href").value(StringEndsWith.endsWith(OzgcloudResourceController.PATH + "?uri=" + encodedUri))); + } + + @Test + void shouldReturnStatusNotFound() throws Exception { + var response = doRequest("dummy://test.de"); + + response.andExpect(status().isNotFound()); + } + + @Test + void shouldReturnBadRequestOnNoRequestParam() throws Exception { + var response = doRequestWithQueryString(""); + + response.andExpect(status().isBadRequest()); + } + + @Test + void shouldReturnBadRequestOnEmptyUri() throws Exception { + var response = doRequestWithQueryString("?uri="); + + response.andExpect(status().isBadRequest()); + } + + @SneakyThrows + private ResultActions doRequest(String uri) { + return doRequestWithQueryString("?uri=" + uri); + } + + @SneakyThrows + private ResultActions doRequestWithQueryString(String queryString) { + return mockMvc.perform(get(OzgcloudResourceController.PATH + queryString)); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9ea5e3d62933188bc4a839a69b7b3cb4d2c63cb1 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java @@ -0,0 +1,130 @@ +package de.ozgcloud.alfa.resource; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.RepresentationModel; + +import de.ozgcloud.alfa.common.errorhandling.ResourceNotFoundException; +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.SneakyThrows; + +class OzgcloudResourceControllerTest { + + @Mock + private OzgcloudResourceURIResolver resourceAResolver; + @Mock + private OzgcloudResourceURIResolver resourceBResolver; + @Spy + private Collection<OzgcloudResourceURIResolver> resourceResolvers = new ArrayList<>(); + @Mock + private OzgcloudResourceModelAssembler assembler; + @InjectMocks + private OzgcloudResourceController controller; + + @BeforeEach + void init() { + resourceResolvers.add(resourceAResolver); + resourceResolvers.add(resourceBResolver); + } + + @Nested + class TestGetOzgcloudResource { + + @Nested + class OnUriCouldBeResolved { + + private final ArgumentMatcher<OzgcloudResourceURIResolveResult> HAS_MATCHING_RESOURCE_URI = mapping -> mapping.getResourceURI().equals( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI); + private final ArgumentMatcher<OzgcloudResourceURIResolveResult> HAS_MATCHING_RESOURCE_LINK = mapping -> mapping.getResourceLink().equals( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK); + + @BeforeEach + void init() { + when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK)); + } + + @Test + void shouldCallResolver() { + callController(); + + verify(resourceBResolver).resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI); + } + + @Test + void shouldCallAssemblerWithUri() { + callController(); + + verify(assembler).toModel(argThat(HAS_MATCHING_RESOURCE_URI)); + } + + @Test + void shouldCallAssemblerWithResourceLink() { + callController(); + + verify(assembler).toModel(argThat(HAS_MATCHING_RESOURCE_LINK)); + } + + @Test + void shouldReturnModelFromAssembler() { + EntityModel<OzgcloudResource> modelFromAssembler = EntityModel.of(new OzgcloudResource()); + when(assembler.toModel(argThat(mapping -> HAS_MATCHING_RESOURCE_URI.matches(mapping) && HAS_MATCHING_RESOURCE_LINK.matches(mapping)))) + .thenReturn(modelFromAssembler); + + var model = callController(); + + assertThat(model).isEqualTo(modelFromAssembler); + } + } + + @Nested + class OnUriCouldNotBeResolved { + + @BeforeEach + void init() { + when(resourceAResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.empty()); + when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.empty()); + } + + @Test + void shouldThrowResourceNotFoundException() { + assertThatThrownBy(TestGetOzgcloudResource.this::callController).isInstanceOf(ResourceNotFoundException.class); + } + } + + @Nested + class OnMultipleResolveResults { + + @BeforeEach + void init() { + when(resourceAResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK)); + when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK)); + } + + @Test + void shouldThrowTechnicalException() { + assertThatThrownBy(TestGetOzgcloudResource.this::callController).isInstanceOf(TechnicalException.class); + } + } + + @SneakyThrows + private RepresentationModel<EntityModel<OzgcloudResource>> callController() { + return controller.getOzgcloudResource(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ed144040a39978e418d2248ca496007c4c4f05ac --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java @@ -0,0 +1,43 @@ +package de.ozgcloud.alfa.resource; + +import static de.ozgcloud.alfa.resource.OzgcloudResourceController.*; +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.IanaLinkRelations; +import org.springframework.hateoas.Link; + +class OzgcloudResourceModelAssemblerTest { + + @InjectMocks + private OzgcloudResourceModelAssembler assembler; + + @Nested + class TestToModel { + + private final OzgcloudResourceURIResolveResult uriResolveResult = OzgcloudResourceURIResolveResultTestFactory.create(); + + @Test + void shouldHaveSelfLink() { + var model = callAssembler(); + + assertThat(model.getLink(IanaLinkRelations.SELF_VALUE)).isPresent().get().extracting(Link::getHref) + .isEqualTo(OzgcloudResourceController.PATH + "?" + PARAM_URI + "=" + OzgcloudResourceURIResolveResultTestFactory.ENCODED_RESOURCE_URI); + } + + @Test + void shouldHaveResourceLink() { + var model = callAssembler(); + + assertThat(model.getLink(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK.getRel())).isPresent().get().isEqualTo( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK); + } + + private EntityModel<OzgcloudResource> callAssembler() { + return assembler.toModel(uriResolveResult); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..71d60de1e746dd5f801b5d0a4f87b0d93493bcc7 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java @@ -0,0 +1,39 @@ +package de.ozgcloud.alfa.resource; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; + +import de.ozgcloud.alfa.Root; +import de.ozgcloud.alfa.RootTestFactory; + +class OzgcloudResourceRootProcessorTest { + + private final OzgcloudResourceRootProcessor processor = new OzgcloudResourceRootProcessor(); + + @Nested + class TestProcess { + + private final EntityModel<Root> model = EntityModel.of(RootTestFactory.create()); + + @Test + void shouldReturnOriginalModel() { + var result = processor.process(model); + + assertThat(result).isEqualTo(model); + } + + @Test + void shouldAddResourceLink() { + processor.process(model); + + assertThat(model.getLink(OzgcloudResourceRootProcessor.REL_RESOURCE)).isPresent().get().extracting(Link::getHref) + .isEqualTo(OzgcloudResourceController.PATH + "?uri={uri}"); + } + } +} + + diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..dd0ea565f584133ece1265c2c2a9782135a65a74 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.resource; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import org.springframework.hateoas.Link; + +import com.thedeanda.lorem.LoremIpsum; + +class OzgcloudResourceURIResolveResultTestFactory { + + public static final String RESOURCE_URI = String.format("%s://%s.%s/%s", (Object[]) LoremIpsum.getInstance().getWords(4).split("\\s")); + public static final String ENCODED_RESOURCE_URI = URLEncoder.encode(RESOURCE_URI, StandardCharsets.UTF_8); + public static final Link RESOURCE_LINK = Link.of(LoremIpsum.getInstance().getUrl()).withRel(LoremIpsum.getInstance().getWords(1)); + + public static OzgcloudResourceURIResolveResult create() { + return createBuilder().build(); + } + + public static OzgcloudResourceURIResolveResult.OzgcloudResourceURIResolveResultBuilder createBuilder() { + return OzgcloudResourceURIResolveResult.builder().resourceURI(RESOURCE_URI).resourceLink(RESOURCE_LINK); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangURIResolverTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangURIResolverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1d691c621cc7e42d207861ccb6503bd04026a74c --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangURIResolverTest.java @@ -0,0 +1,61 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.LinkRelation; + +import de.ozgcloud.alfa.common.AlfaTestUtils; + +class VorgangURIResolverTest { + + private VorgangURIResolver resolver = new VorgangURIResolver(); + + @Nested + class TestResolve { + + private final String VORGANG_ID = AlfaTestUtils.createMongoDbObjectId(); + private final String VORGANG_URI = "ozgcloud://dummy.de/vorgangs/" + VORGANG_ID; + + @ParameterizedTest + @ValueSource(strings = { + "http://dummy.de/vorgangs/123", + "ozgcloud://dummy.de/res-a/123", + "ozgcloud://dummy.de/xyz/vorgangs/123", + "ozgcloud://dummy.de/vorgangs/xyz/123" }) + void shouldReturnEmptyIfUriIsNotRecognized(String uri) { + var result = resolver.resolve(uri); + + assertThat(result).isEmpty(); + } + + @Test + void shouldReturnLink() { + var result = resolver.resolve(VORGANG_URI); + + assertThat(result).isPresent(); + } + + @Nested + class TestVorgangLink { + + @Test + void shouldHaveCorrectRelValue() { + var result = resolver.resolve(VORGANG_URI); + + assertThat(result).get().extracting(Link::getRel).extracting(LinkRelation::value).isEqualTo(VorgangURIResolver.REL_NAME); + } + + @Test + void shouldHaveHrefOfVorgang() { + var result = resolver.resolve(VORGANG_URI); + + assertThat(result).get().extracting(Link::getHref).isEqualTo("/api/vorgangs/" + VORGANG_ID); + } + } + } +}