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

OZG-5822 validate nachricht text and subject

parent 0f196a8f
Branches
Tags
No related merge requests found
......@@ -16,3 +16,4 @@ target/
.attach**
.factorypath
.vscode*
.nx
\ No newline at end of file
18.18.2
20.14.0
package de.ozgcloud.alfa.bescheid;
import static de.ozgcloud.alfa.common.ValidationMessageCodes.*;
import java.util.List;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonIgnore;
......@@ -53,7 +56,9 @@ public class Bescheid implements CommandBody {
@LinkedResource(controllerClass = BinaryFileController.class)
private List<FileId> attachments;
@NotEmpty(message = FIELD_IS_EMPTY, groups = BescheidNachrichtValidation.class)
private String nachrichtText;
@NotEmpty(message = FIELD_IS_EMPTY, groups = BescheidNachrichtValidation.class)
private String nachrichtSubject;
private SendBy sendBy;
private BescheidStatus status;
......
......@@ -61,6 +61,9 @@ public class BescheidModelAssembler implements RepresentationModelAssembler<Besc
var attachmentsLink = linkTo(methodOn(BescheidController.class).getAttachments(bescheid.getId(), bescheid.getVorgangId()));
var createCommandLink = buildCreateCommandLink(bescheid);
var vorgangWithEingang = vorgangController.getVorgang(bescheid.getVorgangId());
var bescheidenUndSendenLink = linkTo(
methodOn(BescheidSendenCommandController.class).createCommand(vorgangWithEingang.getId(), bescheid.getId(), bescheid.getVersion(),
null));
return ModelBuilder.fromEntity(bescheid)
.addLink(selfLink.withSelfRel())
......@@ -75,7 +78,7 @@ public class BescheidModelAssembler implements RepresentationModelAssembler<Besc
.addLink(createCommandLink.withRel(REL_CREATE_DOCUMENT))
.addLink(createCommandLink.withRel(REL_CREATE_DOCUMENT_FROM_FILE))
.ifMatch(() -> canSendMessageToAntragsteller(vorgangWithEingang))
.addLink(createCommandLink.withRel(REL_BESCHEIDEN_UND_SENDEN))
.addLink(bescheidenUndSendenLink.withRel(REL_BESCHEIDEN_UND_SENDEN))
.addLink(createCommandLink.withRel(REL_BESCHEIDEN))
.buildModel();
}
......
package de.ozgcloud.alfa.bescheid;
interface BescheidNachrichtValidation {
}
package de.ozgcloud.alfa.bescheid;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import de.ozgcloud.alfa.common.command.Command;
import de.ozgcloud.alfa.common.command.CommandController;
import de.ozgcloud.alfa.common.command.CommandService;
import de.ozgcloud.alfa.common.command.CreateCommand;
import de.ozgcloud.common.errorhandling.TechnicalException;
import lombok.RequiredArgsConstructor;
@RestController
@RequestMapping(BescheidSendenCommandController.PATH)
@RequiredArgsConstructor
class BescheidSendenCommandController {
static final String PATH = "/api/vorgangs/{vorgangId}/bescheids/relations/{relationId}/{relationVersion}/commands"; // NOSONAR
private final BescheidService bescheidService;
private final CommandService commandService;
private final BescheidSendenCommandValidator bescheidSendenCommandValidator;
@PostMapping
public ResponseEntity<EntityModel<Command>> createCommand(@PathVariable String vorgangId, @PathVariable String relationId,
@PathVariable long relationVersion, @RequestBody CreateCommand command) {
command = command.toBuilder().vorgangId(vorgangId).relationId(relationId).build();
validate(vorgangId, command);
var created = commandService.createCommand(command, relationVersion);
return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build();
}
void validate(String vorgangId, CreateCommand command) {
var bescheid = bescheidService.getBescheidDraft(vorgangId)
.orElseThrow(() -> new TechnicalException("Bescheid not found for vorgang id: " + vorgangId));
bescheidSendenCommandValidator.validate(command.toBuilder().body(bescheid).build());
}
}
package de.ozgcloud.alfa.bescheid;
import jakarta.validation.Valid;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import de.ozgcloud.alfa.common.command.CreateCommand;
@Validated(BescheidNachrichtValidation.class)
@Component
class BescheidSendenCommandValidator {
public void validate(@Valid CreateCommand command) {
// noop
}
}
......@@ -177,7 +177,7 @@ class BescheidModelAssemblerTest {
assertThat(model.getLink(REL_BESCHEIDEN_UND_SENDEN))
.isPresent().get()
.extracting(Link::getHref).isEqualTo(createCommandLink());
.extracting(Link::getHref).isEqualTo(bescheidenUndSendenLink());
}
@Test
......@@ -225,6 +225,11 @@ class BescheidModelAssemblerTest {
.expand(VorgangHeaderTestFactory.ID, BescheidTestFactory.ID, BescheidTestFactory.VERSION).toString();
}
private String bescheidenUndSendenLink() {
return new UriTemplate(BescheidSendenCommandController.PATH)
.expand(VorgangHeaderTestFactory.ID, BescheidTestFactory.ID, BescheidTestFactory.VERSION).toString();
}
private EntityModel<Bescheid> callToModel() {
return callToModel(bescheid);
}
......@@ -240,6 +245,8 @@ class BescheidModelAssemblerTest {
@Test
void shouldCallToModel() {
when(vorgangController.getVorgang(VorgangHeaderTestFactory.ID)).thenReturn(VorgangWithEingangTestFactory.create());
callMethod();
verify(assembler).toCollectionModel(List.of(bescheid));
......@@ -257,6 +264,8 @@ class BescheidModelAssemblerTest {
@Test
void shouldHaveSelfLink() {
when(vorgangController.getVorgang(VorgangHeaderTestFactory.ID)).thenReturn(VorgangWithEingangTestFactory.create());
var collectionModel = callMethod();
assertThat(collectionModel.getLinks())
......
package de.ozgcloud.alfa.bescheid;
import static de.ozgcloud.alfa.common.command.CommandController.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
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.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import de.ozgcloud.alfa.common.command.Command;
import de.ozgcloud.alfa.common.command.CommandOrder;
import de.ozgcloud.alfa.common.command.CommandService;
import de.ozgcloud.alfa.common.command.CommandTestFactory;
import de.ozgcloud.alfa.common.command.CreateCommand;
import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory;
import de.ozgcloud.common.errorhandling.TechnicalException;
import de.ozgcloud.common.test.TestUtils;
class BescheidSendenCommandControllerTest {
@Spy
@InjectMocks
private BescheidSendenCommandController controller;
@Mock
private BescheidService bescheidService;
@Mock
private CommandService commandService;
@Mock
private BescheidSendenCommandValidator bescheidSendenCommandValidator;
private MockMvc mockMvc;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Nested
class TestCreateCommand {
private final Command command = CommandTestFactory.create();
@Captor
private ArgumentCaptor<CreateCommand> createCommandArgumentCaptor;
@BeforeEach
void setUp() {
doNothing().when(controller).validate(eq(VorgangHeaderTestFactory.ID), any(CreateCommand.class));
when(commandService.createCommand(any(CreateCommand.class), eq(BescheidTestFactory.VERSION))).thenReturn(command);
}
@Test
void shouldValidate() throws Exception {
doRequest();
verify(controller).validate(eq(VorgangHeaderTestFactory.ID), any(CreateCommand.class));
}
@Test
void shouldSetVorgangIdOnCreateCommand() throws Exception {
doRequest();
verify(controller).validate(eq(VorgangHeaderTestFactory.ID), createCommandArgumentCaptor.capture());
assertThat(createCommandArgumentCaptor.getValue().getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID);
}
@Test
void shouldSetRelationIdOnCreateCommand() throws Exception {
doRequest();
verify(controller).validate(eq(VorgangHeaderTestFactory.ID), createCommandArgumentCaptor.capture());
assertThat(createCommandArgumentCaptor.getValue().getRelationId()).isEqualTo(BescheidTestFactory.ID);
}
@Test
void shouldCallCommandService() throws Exception {
doRequest();
verify(commandService).createCommand(any(CreateCommand.class), eq(BescheidTestFactory.VERSION));
}
@Test
void shouldReturnCreated() throws Exception {
doRequest().andExpect(status().isCreated());
}
@Test
void shouldReturnCommand() throws Exception {
doRequest()
.andExpect(header().stringValues("location", "http://localhost" + COMMANDS_PATH + "/" + CommandTestFactory.ID));
}
private ResultActions doRequest() throws Exception {
return mockMvc.perform(
post(BescheidSendenCommandController.PATH,
VorgangHeaderTestFactory.ID,
BescheidTestFactory.ID,
BescheidTestFactory.VERSION)
.content(createContent())
.contentType(MediaType.APPLICATION_JSON));
}
private String createContent() {
return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithBody.json.tmpl",
CommandOrder.SEND_BESCHEID.name(),
null);
}
}
@Nested
class TestValidate {
private final CreateCommand createCommand = CommandTestFactory.createCreateCommand();
private final Bescheid bescheid = BescheidTestFactory.create();
@Captor
private ArgumentCaptor<CreateCommand> commandArgumentCaptor;
@Nested
class WhenBescheidExists {
@BeforeEach
void setUp() {
when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.of(bescheid));
doNothing().when(bescheidSendenCommandValidator).validate(any(CreateCommand.class));
}
@Test
void shouldGetBescheidDraft() {
controller.validate(VorgangHeaderTestFactory.ID, createCommand);
verify(bescheidService).getBescheidDraft(VorgangHeaderTestFactory.ID);
}
@Test
void shouldValidate() {
controller.validate(VorgangHeaderTestFactory.ID, createCommand);
verify(bescheidSendenCommandValidator).validate(any(CreateCommand.class));
}
@Test
void shouldAddBescheidToCommand() {
controller.validate(VorgangHeaderTestFactory.ID, createCommand);
verify(bescheidSendenCommandValidator).validate(commandArgumentCaptor.capture());
assertThat(commandArgumentCaptor.getValue()).usingRecursiveComparison().isEqualTo(createCommand.toBuilder().body(bescheid).build());
}
}
@Nested
class WhenBescheidNotExists {
@Test
void shouldThrowTechnicalException() {
when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.empty());
assertThatThrownBy(() -> controller.validate(VorgangHeaderTestFactory.ID, createCommand)).isInstanceOf(TechnicalException.class);
}
}
}
}
\ 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