Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ozg-cloud/app/alfa
1 result
Show changes
Commits on Source (5)
......@@ -25,6 +25,7 @@ package de.ozgcloud.alfa.common.command;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
......@@ -41,10 +42,11 @@ import de.ozgcloud.alfa.bescheid.DocumentController;
import de.ozgcloud.alfa.collaboration.CollaborationController.CollaborationByVorgangController;
import de.ozgcloud.alfa.forwarding.ForwardingController;
import de.ozgcloud.alfa.kommentar.KommentarController;
import de.ozgcloud.alfa.postfach.PostfachMailController;
import de.ozgcloud.alfa.vorgang.VorgangController;
import de.ozgcloud.alfa.wiedervorlage.WiedervorlageController;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Component
class CommandModelAssembler implements RepresentationModelAssembler<Command, EntityModel<Command>> {
......@@ -57,14 +59,29 @@ class CommandModelAssembler implements RepresentationModelAssembler<Command, Ent
static final Predicate<Command> HAS_KNOWN_COMMAND_ORDER = command -> command.getCommandOrder() != CommandOrder.UNBEKANNT;
private static final List<CommandOrder> ORDER_PROCESSED_SEPERATELY = List.of(
CommandOrder.RECEIVE_POSTFACH_NACHRICHT,
CommandOrder.RESEND_POSTFACH_MAIL,
CommandOrder.SEND_POSTFACH_MAIL,
CommandOrder.SEND_POSTFACH_NACHRICHT);
static final Predicate<Command> IS_PROCESSABLE_ORDER = command -> !ORDER_PROCESSED_SEPERATELY.contains(command.getCommandOrder());
private final List<CommandProcessor> processors;
@Override
public EntityModel<Command> toModel(Command command) {
return EntityModel.of(command)
var entityModel = EntityModel.of(command)
.add(linkTo(CommandController.class).slash(command.getId()).withSelfRel())
.addIf(CommandHelper.IS_DONE.and(HAS_KNOWN_COMMAND_ORDER).test(command), () -> effectedResourceLinkByOrderType(command))
.addIf(CommandHelper.IS_DONE.and(HAS_KNOWN_COMMAND_ORDER).and(IS_PROCESSABLE_ORDER).test(command),
() -> effectedResourceLinkByOrderType(command))
.addIf(CommandHelper.IS_PENDING.test(command), () -> linkTo(CommandController.class).slash(command.getId()).withRel(REL_UPDATE))
.addIf(IS_NOT_LOESCH_ANFORDERUNG_AND_REVOKEABLE.test(command),
() -> linkTo(methodOn(CommandController.class).revoke(command.getId(), null)).withRel(REL_REVOKE));
processors.forEach(processor -> processor.process(entityModel));
return entityModel;
}
Link effectedResourceLinkByOrderType(Command entity) {
......@@ -73,14 +90,13 @@ class CommandModelAssembler implements RepresentationModelAssembler<Command, Ent
WebMvcLinkBuilder linkBuilder = switch (type) {
case FORWARDING -> linkTo(methodOn(ForwardingController.class).findByVorgangId(entity.getVorgangId()));
case KOMMENTAR -> linkTo(KommentarController.class).slash(entity.getRelationId());
case POSTFACH -> linkTo(methodOn(PostfachMailController.class).getAll(entity.getVorgangId()));
case VORGANG -> linkTo(VorgangController.class).slash(entity.getRelationId());
case VORGANG_LIST -> linkTo(VorgangController.class);
case WIEDERVORLAGE -> linkTo(WiedervorlageController.class).slash(entity.getRelationId());
case BESCHEID -> linkTo(methodOn(BescheidController.class).getDraft(entity.getVorgangId()));
case DOCUMENT -> linkTo(DocumentController.class).slash(entity.getCreatedResource());
case COLLABORATION -> linkTo(methodOn(CollaborationByVorgangController.class).getAllByVorgangId(entity.getVorgangId()));
case NONE -> throw new IllegalArgumentException("Unknown CommandOrder: " + entity.getOrder());
default -> throw new IllegalArgumentException("Unknown CommandOrder: " + entity.getOrder());
};
return linkBuilder.withRel(REL_EFFECTED_RESOURCE);
......
package de.ozgcloud.alfa.common.command;
import java.util.Objects;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.LinkRelation;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
public abstract class CommandProcessor {
static final LinkRelation REL_EFFECTED_RESOURCE = LinkRelation.of("effected_resource");
static final LinkRelation REL_RELATED_RESOURCE = LinkRelation.of("related_resource");
public void process(EntityModel<Command> model) {
var command = model.getContent();
if (Objects.isNull(command)) {
return;
}
model.addIf(CommandHelper.IS_DONE.test(command) && isResponsibleForEffectedResource(command.getCommandOrder()),
() -> createEffectedResourceLinkBuilder(command).withRel(REL_EFFECTED_RESOURCE));
model.addIf(isResponsibleForRelatedResource(command.getCommandOrder()),
() -> createRelatedResourceLinkBuilder(command).withRel(REL_RELATED_RESOURCE));
}
public abstract boolean isResponsibleForEffectedResource(CommandOrder order);
public abstract WebMvcLinkBuilder createEffectedResourceLinkBuilder(Command command);
public abstract boolean isResponsibleForRelatedResource(CommandOrder order);
public abstract WebMvcLinkBuilder createRelatedResourceLinkBuilder(Command command);
}
\ No newline at end of file
package de.ozgcloud.alfa.postfach;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import java.util.List;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.stereotype.Component;
import de.ozgcloud.alfa.common.command.Command;
import de.ozgcloud.alfa.common.command.CommandOrder;
import de.ozgcloud.alfa.common.command.CommandProcessor;
@Component
public class PostfachNachrichtCommandProcessor extends CommandProcessor {
private static final List<CommandOrder> RESPONSIBLE_ORDER = List.of(
CommandOrder.RECEIVE_POSTFACH_NACHRICHT,
CommandOrder.RESEND_POSTFACH_MAIL);
private static final List<CommandOrder> RESPONSIBLE_EFFECTED_RESOURCE_ORDER = List.of(
CommandOrder.SEND_POSTFACH_MAIL,
CommandOrder.SEND_POSTFACH_NACHRICHT,
CommandOrder.RESEND_POSTFACH_MAIL,
CommandOrder.RECEIVE_POSTFACH_NACHRICHT);
@Override
public boolean isResponsibleForRelatedResource(CommandOrder order) {
return RESPONSIBLE_ORDER.contains(order);
}
@Override
public WebMvcLinkBuilder createRelatedResourceLinkBuilder(Command command) {
return linkTo(PostfachMailController.class).slash(command.getRelationId());
}
@Override
public boolean isResponsibleForEffectedResource(CommandOrder order) {
return RESPONSIBLE_EFFECTED_RESOURCE_ORDER.contains(order);
}
@Override
public WebMvcLinkBuilder createEffectedResourceLinkBuilder(Command command) {
return linkTo(methodOn(PostfachMailController.class).getAll(command.getVorgangId()));
}
}
\ No newline at end of file
......@@ -27,7 +27,12 @@ import static de.ozgcloud.alfa.common.command.CommandModelAssembler.*;
import static de.ozgcloud.alfa.common.command.CommandTestFactory.*;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
......@@ -35,7 +40,11 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.EnumSource.Mode;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link;
......@@ -49,6 +58,19 @@ class CommandModelAssemblerTest {
@InjectMocks
private CommandModelAssembler modelAssembler;
@Spy
private List<CommandProcessor> processors = new ArrayList<>();
@Mock
private CommandProcessor processor;
@Captor
private ArgumentCaptor<EntityModel<Command>> commandEntityModelCaptor;
@BeforeEach
void setProcessorMocks() {
processors.add(processor);
}
@Test
void shouldHaveSelfLink() {
var model = modelAssembler.toModel(CommandTestFactory.create());
......@@ -56,6 +78,16 @@ class CommandModelAssemblerTest {
assertThat(model.getLink(IanaLinkRelations.SELF)).isPresent().get().extracting(Link::getHref).isEqualTo(COMMAND_SINGLE_PATH);
}
@Test
void shouldCallProcessor() {
var command = CommandTestFactory.create();
modelAssembler.toModel(command);
verify(processor).process(commandEntityModelCaptor.capture());
assertThat(commandEntityModelCaptor.getValue().getContent()).isEqualTo(command);
}
@Nested
@DisplayName("Link to effected Resource")
class TestEffectedResourceLink {
......@@ -103,22 +135,6 @@ class CommandModelAssemblerTest {
}
}
@DisplayName("on postfach")
@Nested
class TestOnPostfach {
private static final String POSTFACH_URL = "/api/postfachMails?vorgangId=" + VorgangHeaderTestFactory.ID;
@ParameterizedTest
@ValueSource(strings = { "SEND_POSTFACH_MAIL" })
void shouldHaveLinkToPostfach(String order) {
var model = toModelWithOrder(order);
assertThat(model.getLink(CommandModelAssembler.REL_EFFECTED_RESOURCE)).isPresent().get()
.extracting(Link::getHref).isEqualTo(POSTFACH_URL);
}
}
@DisplayName("on bescheid")
@Nested
class TestOnBescheid {
......@@ -196,7 +212,8 @@ class CommandModelAssemblerTest {
}
@ParameterizedTest
@EnumSource(mode = Mode.EXCLUDE, names = { "UNBEKANNT" })
@EnumSource(mode = Mode.EXCLUDE, names = { "UNBEKANNT", "SEND_POSTFACH_MAIL", "SEND_POSTFACH_NACHRICHT", "RESEND_POSTFACH_MAIL",
"RECEIVE_POSTFACH_NACHRICHT" })
void shouldBeAbleToBuildLinkForEveryOrder(CommandOrder order) {
var link = modelAssembler.effectedResourceLinkByOrderType(CommandTestFactory.createBuilder().order(order.name()).build());
......
package de.ozgcloud.alfa.common.command;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
class CommandProcessorTest {
@Spy
private CommandProcessor processor;
@DisplayName("Process")
@Nested
class TestProcess {
private final Command command = CommandTestFactory.create();
private final EntityModel<Command> model = EntityModel.of(command);
private final WebMvcLinkBuilder linkBuilder = WebMvcLinkBuilder.linkTo(CommandController.class).slash("id");
@Test
void shouldNotThrowExceptionsOnNullContent() {
EntityModel<Command> entityModel = when(mock(EntityModel.class).getContent()).thenReturn(null).getMock();
assertDoesNotThrow(() -> processor.process(entityModel));
}
@DisplayName("effected resource")
@Nested
class TestEffectedResource {
@DisplayName("should verify if responsibility is related to the order")
@Test
void shouldCallIsResponsibleForEffectedResource() {
processor.process(model);
verify(processor).isResponsibleForEffectedResource(CommandOrder.fromOrder(CommandTestFactory.ORDER));
}
@DisplayName("should NOT create link builder for related resource if the responsibility matches")
@Test
void shouldNOTCallCreateEffectedResourceLinkBuilder() {
when(processor.isResponsibleForEffectedResource(any())).thenReturn(false);
processor.process(model);
verify(processor, never()).createEffectedResourceLinkBuilder(command);
}
@DisplayName("should create link builder for effected resource if the responsibility matches")
@Test
void shouldCallCreateEffectedResourceLinkBuilder() {
when(processor.isResponsibleForEffectedResource(any())).thenReturn(true);
doReturn(linkBuilder).when(processor).createEffectedResourceLinkBuilder(any());
processor.process(model);
verify(processor).createEffectedResourceLinkBuilder(command);
}
@DisplayName("link")
@Nested
class TestEffectedResourceLink {
@Test
void shouldBeAddedIfResponsible() {
doReturn(true).when(processor).isResponsibleForEffectedResource(any());
doReturn(linkBuilder).when(processor).createEffectedResourceLinkBuilder(any());
var finishedCommand = CommandTestFactory.createBuilder().status(CommandStatus.FINISHED).build();
var entityModel = EntityModel.of(finishedCommand);
processor.process(entityModel);
assertThat(entityModel.getLink(CommandProcessor.REL_EFFECTED_RESOURCE).get().getHref()).isEqualTo("/api/commands/id");
}
@Test
void shouldNotBeAddedIfCommandNotDone() {
var pendingCommand = CommandTestFactory.createBuilder().status(CommandStatus.PENDING).build();
var entityModel = EntityModel.of(pendingCommand);
processor.process(entityModel);
assertThat(entityModel.getLink(CommandProcessor.REL_EFFECTED_RESOURCE)).isNotPresent();
}
}
}
@DisplayName("related resource")
@Nested
class TestRelatedResource {
@DisplayName("should verify if responsibility is related to the order")
@Test
void shouldCallIsResponsibleForRelatedResource() {
processor.process(model);
verify(processor).isResponsibleForRelatedResource(CommandOrder.fromOrder(CommandTestFactory.ORDER));
}
@DisplayName("should create link builder for related resource if the responsibility matches")
@Test
void shouldCallCreateRelatedResourceLinkBuilder() {
when(processor.isResponsibleForRelatedResource(any())).thenReturn(true);
doReturn(linkBuilder).when(processor).createRelatedResourceLinkBuilder(any());
processor.process(model);
verify(processor).createRelatedResourceLinkBuilder(command);
}
@DisplayName("should NOT create link builder for related resource if the responsibility matches")
@Test
void shouldNOTCallCreateRelatedResourceLinkBuilder() {
when(processor.isResponsibleForRelatedResource(any())).thenReturn(false);
processor.process(model);
verify(processor, never()).createRelatedResourceLinkBuilder(command);
}
@DisplayName("link")
@Nested
class TestRelatedResourceLink {
@Test
void shouldBeAddedIfResponsible() {
doReturn(true).when(processor).isResponsibleForRelatedResource(any());
doReturn(linkBuilder).when(processor).createRelatedResourceLinkBuilder(any());
processor.process(model);
assertThat(model.getLink(CommandProcessor.REL_RELATED_RESOURCE).get().getHref()).isEqualTo("/api/commands/id");
}
}
}
}
}
\ No newline at end of file
package de.ozgcloud.alfa.postfach;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.EnumSource.Mode;
import org.mockito.Spy;
import de.ozgcloud.alfa.common.command.CommandOrder;
import de.ozgcloud.alfa.common.command.CommandTestFactory;
class PostfachNachrichtCommandProcessorTest {
@Spy
private PostfachNachrichtCommandProcessor processor;
@DisplayName("Related resource")
@Nested
class TestRelatedResource {
@DisplayName("is responsible")
@Nested
class TestIsResponsible {
@EnumSource(mode = Mode.INCLUDE, names = { "RECEIVE_POSTFACH_NACHRICHT", "RESEND_POSTFACH_MAIL" })
@ParameterizedTest(name = "{0}")
void shouldReturnTrueOnOrder(CommandOrder order) {
var isResponsible = processor.isResponsibleForRelatedResource(order);
assertThat(isResponsible).isTrue();
}
@EnumSource(mode = Mode.EXCLUDE, names = { "RECEIVE_POSTFACH_NACHRICHT", "RESEND_POSTFACH_MAIL" })
@ParameterizedTest(name = "{0}")
void shouldReturnFalseOnOrder(CommandOrder order) {
var isResponsible = processor.isResponsibleForRelatedResource(order);
assertThat(isResponsible).isFalse();
}
}
@Test
void shouldCreateLinkBuilder() {
var linkBuilder = processor.createRelatedResourceLinkBuilder(CommandTestFactory.create());
assertThat(linkBuilder).hasToString(PostfachMailController.PATH + "/" + CommandTestFactory.RELATION_ID);
}
}
@DisplayName("Effected resource")
@Nested
class TestEffectedResource {
@DisplayName("is responsible")
@Nested
class TestIsResponsible {
@EnumSource(mode = Mode.INCLUDE, names = { "SEND_POSTFACH_MAIL", "SEND_POSTFACH_NACHRICHT", "RESEND_POSTFACH_MAIL",
"RECEIVE_POSTFACH_NACHRICHT" })
@ParameterizedTest(name = "{0}")
void shouldReturnTrueOnOrder(CommandOrder order) {
var isResponsible = processor.isResponsibleForEffectedResource(order);
assertThat(isResponsible).isTrue();
}
@EnumSource(mode = Mode.EXCLUDE, names = { "SEND_POSTFACH_MAIL", "SEND_POSTFACH_NACHRICHT", "RESEND_POSTFACH_MAIL",
"RECEIVE_POSTFACH_NACHRICHT" })
@ParameterizedTest(name = "{0}")
void shouldReturnFalseOnOrder(CommandOrder order) {
var isResponsible = processor.isResponsibleForEffectedResource(order);
assertThat(isResponsible).isFalse();
}
}
@Test
void shouldCreateLinkBuilder() {
var linkBuilder = processor.createEffectedResourceLinkBuilder(CommandTestFactory.create());
assertThat(linkBuilder).hasToString(PostfachMailController.PATH + "?vorgangId=" + CommandTestFactory.VORGANG_ID);
}
}
}
\ No newline at end of file