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

OZG-1523 Edit und Create auf Command Strecke umgestellt

parent b6c36d5c
No related branches found
No related tags found
No related merge requests found
Showing
with 191 additions and 33 deletions
......@@ -3,6 +3,7 @@ package de.itvsh.goofy.common.command;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import de.itvsh.goofy.kommentar.Kommentar;
import de.itvsh.goofy.postfach.PostfachMail;
import de.itvsh.goofy.vorgang.AssignUserCommandBody;
import de.itvsh.goofy.vorgang.RedirectRequest;
......@@ -12,7 +13,8 @@ import de.itvsh.goofy.wiedervorlage.Wiedervorlage;
@Type(value = PostfachMail.class, name = "SEND_POSTFACH_MAIL"),
@Type(value = AssignUserCommandBody.class, name = "ASSIGN_USER"),
@Type(value = RedirectRequest.class, name = "REDIRECT_VORGANG"),
@Type(value = Wiedervorlage.class, name = "WIEDERVORLAGE")
@Type(value = Wiedervorlage.class, name = "WIEDERVORLAGE"),
@Type(value = Kommentar.class, name = "KOMMENTAR")
})
public interface CommandBody {
......
......@@ -15,13 +15,13 @@ public enum CommandOrder {
VORGANG_ZURUECKSTELLEN(true, Type.VORGANG),
VORGANG_ABSCHLIESSEN(true, Type.VORGANG),
VORGANG_WIEDEREROEFFNEN(true, Type.VORGANG),
//
ASSIGN_USER(false, Type.VORGANG),
//
REDIRECT_VORGANG(false, Type.FORWARDING),
FORWARD_SUCCESSFULL(false, Type.FORWARDING),
FORWARD_FAILED(false, Type.FORWARDING),
//
CREATE_KOMMENTAR(false, Type.KOMMENTAR),
EDIT_KOMMENTAR(false, Type.KOMMENTAR),
......
......@@ -12,6 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonProperty.Access;
import de.itvsh.goofy.common.LinkedResource;
import de.itvsh.goofy.common.command.CommandBody;
import de.itvsh.goofy.common.user.UserProfileController;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
......@@ -25,11 +26,14 @@ import lombok.ToString;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@ToString
public class Kommentar {
public class Kommentar implements CommandBody {
@JsonIgnore
private String id;
@JsonIgnore
private String vorgangId;
@JsonProperty(access = Access.READ_ONLY)
@LinkedResource(controllerClass = UserProfileController.class)
private String createdBy;
......
......@@ -2,6 +2,8 @@ package de.itvsh.goofy.kommentar;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import java.time.ZonedDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
......@@ -10,26 +12,50 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import de.itvsh.goofy.common.command.Command;
import de.itvsh.goofy.common.command.CommandController;
import de.itvsh.goofy.common.command.CommandController.CommandByRelationController;
import de.itvsh.goofy.common.command.CommandOrder;
import de.itvsh.goofy.common.command.CreateCommand;
import de.itvsh.goofy.common.user.CurrentUserService;
@RestController
@RequestMapping(KommentarCommandController.KOMMENTAR_COMMANDS)
public class KommentarCommandController {
static final String KOMMENTAR_COMMANDS = "/api/kommentars/{kommentarId}/commands";
static final String NOT_SET = "-1";
@Autowired
private KommentarService service;
@Autowired
private CommandByRelationController commandByRelationController;
@PostMapping
public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand command, @PathVariable String kommentarId) {
return buildResponseLink(service.createCommand(kommentarId, command));
public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand kommentarCommand, @PathVariable String kommentarId) {
var command = commandByRelationController.createCommand(buildCommand(service.getById(kommentarId), kommentarCommand),
KommentarRemoteService.ITEM_NAME);
return buildResponseLink(command);
}
private ResponseEntity<Void> buildResponseLink(KommentarCommand createdKommentarCommand) {
private ResponseEntity<Void> buildResponseLink(Command createdKommentarCommand) {
return ResponseEntity.created(linkTo(CommandController.class).slash(createdKommentarCommand.getId()).toUri()).build();
}
CreateCommand buildCommand(Kommentar kommentar, KommentarCommand command) {
var commandBuilder = CreateCommand.builder()
.order(CommandOrder.UPDATE_ATTACHED_ITEM)
.relationId(NOT_SET)
.vorgangId(kommentar.getVorgangId());
return commandBuilder.body(updateKommandByCommand(kommentar, command)).build();
}
private Kommentar updateKommandByCommand(Kommentar kommentar, KommentarCommand command) {
return kommentar.toBuilder().text(command.getKommentar().getText()).build();
}
@RestController
@RequestMapping(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG)
public static class KommentarCommandByVorgangController {
......@@ -37,13 +63,33 @@ public class KommentarCommandController {
static final String KOMMENTAR_COMMANDS_BY_VORGANG = "/api/vorgangs/{vorgangId}/kommentarCommands";
@Autowired
private KommentarService service;
private CommandByRelationController commandByRelationController;
@Autowired
private CurrentUserService userService;
@PostMapping()
public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand command, @PathVariable String vorgangId) {
var created = service.createCommand(vorgangId, command);
var createdCommand = commandByRelationController.createCommand(buildCommand(vorgangId, command), KommentarRemoteService.ITEM_NAME);
return ResponseEntity.created(linkTo(CommandController.class).slash(createdCommand.getId()).toUri()).build();
}
CreateCommand buildCommand(String vorgangId, KommentarCommand command) {
return CreateCommand.builder()
.vorgangId(vorgangId)
.order(CommandOrder.CREATE_ATTACHED_ITEM)
.relationId(NOT_SET)
.body(buildBody(command.getKommentar()))
.build();
}
return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build();
Kommentar buildBody(Kommentar kommentar) {
return kommentar.toBuilder()
.createdAt(ZonedDateTime.now().withNano(0))
.createdBy(userService.getUserId().toString())
.build();
}
}
}
package de.itvsh.goofy.kommentar;
import java.time.ZonedDateTime;
import java.util.Map;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingConstants;
......@@ -14,14 +17,31 @@ import de.itvsh.ozg.pluto.kommentar.GrpcKommentar;
@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface KommentarMapper {
static final String ID = "id";
static final String TEXT = "text";
static final String CREATED_BY = "createdBy";
static final String CREATED_AT = "createdAt";
static final String VORGANG_ID = "vorgangId";
@Mapping(target = "textBytes", ignore = true)
@IgnoreGrpcFields
GrpcKommentar toGrpcKommentar(Kommentar kommentar);
@Mapping(target = "vorgangId", ignore = true)
Kommentar toKommentar(GrpcKommentar grpcKommentar);
@Mapping(target = "kommentar", ignore = true)
@ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL)
@ValueMapping(source = "UNDEFINED", target = MappingConstants.NULL)
KommentarCommand toKommentarCommand(GrpcCommand command);
default Kommentar fromItemMap(Map<String, Object> map) {
return Kommentar.builder()
.id((String) map.get(ID))
.createdAt(ZonedDateTime.parse((String) map.get(CREATED_AT)))
.createdBy((String) map.get(CREATED_BY))
.text((String) map.get(TEXT))
.vorgangId((String) map.get(VORGANG_ID))
.build();
}
}
......@@ -18,6 +18,7 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
@Service
class KommentarRemoteService {
public static final String ITEM_NAME = "Kommentar";
@GrpcClient("pluto")
private KommentarServiceBlockingStub serviceStub;
@Autowired
......@@ -46,6 +47,7 @@ class KommentarRemoteService {
return GrpcGetKommentarRequest.newBuilder().setId(kommentarId).build();
}
@Deprecated
public KommentarCommand sendKommentarCommand(String relationId, KommentarCommand command) {
var request = buildCreateCommandRequest(relationId, command);
var response = serviceStub.createCommand(request);
......
......@@ -23,6 +23,7 @@ class KommentarService {
return remoteService.getById(kommentarId);
}
@Deprecated
public KommentarCommand createCommand(String relationId, @Valid KommentarCommand command) {
return remoteService.sendKommentarCommand(relationId, command);
}
......
......@@ -2,6 +2,7 @@ package de.itvsh.goofy.kommentar;
import de.itvsh.ozg.pluto.kommentar.GrpcKommentar;
@Deprecated
public class GrpcKommentarTestFactory {
final static String ID = KommentarTestFactory.ID;
......
......@@ -7,6 +7,8 @@ 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.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
......@@ -19,14 +21,19 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import de.itvsh.goofy.common.command.CommandController.CommandByRelationController;
import de.itvsh.goofy.common.command.CommandOrder;
import de.itvsh.goofy.common.command.CommandTestFactory;
import de.itvsh.goofy.common.command.CreateCommand;
import de.itvsh.goofy.common.user.CurrentUserService;
import de.itvsh.goofy.common.user.UserId;
import de.itvsh.goofy.kommentar.KommentarCommandController.KommentarCommandByVorgangController;
import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory;
class KommentarCommandControllerTest {
@Captor
private ArgumentCaptor<KommentarCommand> commandCaptor;
private ArgumentCaptor<CreateCommand> commandCaptor;
@Nested
class TestCreateKommentarCommandByVorgang {
......@@ -35,13 +42,18 @@ class KommentarCommandControllerTest {
private KommentarCommandByVorgangController controller;
@Mock
private KommentarService service;
@Mock
private CommandByRelationController commandByRelationController;
@Mock
private CurrentUserService userService;
private MockMvc mockMvc;
@BeforeEach
void init() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
when(service.createCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.create());
when(userService.getUserId()).thenReturn(UserId.from(UUID.randomUUID()));
when(commandByRelationController.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create());
}
@Test
......@@ -53,19 +65,19 @@ class KommentarCommandControllerTest {
void shouldCallService() throws Exception {
doRequest();
verify(service).createCommand(eq(VorgangHeaderTestFactory.ID), notNull());
verify(commandByRelationController).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME));
}
@Test
void shouldGiveCommandToService() throws Exception {
doRequest();
verify(service).createCommand(eq(VorgangHeaderTestFactory.ID), commandCaptor.capture());
verify(commandByRelationController).createCommand(commandCaptor.capture(), anyString());
var command = commandCaptor.getValue();
assertThat(command).usingRecursiveComparison()
.ignoringFields("kommentar.id", "kommentar.createdBy", "kommentar.createdByName", "kommentar.createdAt")
.isEqualTo(KommentarCommandTestFactory.createBuilder().id(null).build());
.ignoringFields("body", "status")
.isEqualTo(CommandTestFactory.createBuilder().order(CommandOrder.CREATE_ATTACHED_ITEM).relationId("-1").id(null).build());
}
private ResultActions doRequest() throws Exception {
......@@ -83,6 +95,8 @@ class KommentarCommandControllerTest {
@InjectMocks
private KommentarCommandController controller;
@Mock
private CommandByRelationController commandByRelationController;
@Mock
private KommentarService service;
private MockMvc mockMvc;
......@@ -90,8 +104,8 @@ class KommentarCommandControllerTest {
@BeforeEach
void init() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
when(service.createCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.createBuilder()
.order(CommandOrder.EDIT_KOMMENTAR).build());
when(commandByRelationController.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create());
when(service.getById(any())).thenReturn(KommentarTestFactory.create());
}
@Test
......@@ -103,19 +117,19 @@ class KommentarCommandControllerTest {
void shouldCallService() throws Exception {
doRequest();
verify(service).createCommand(anyString(), notNull());
verify(service).getById(any());
}
@Test
void shouldGiveCommandToService() throws Exception {
doRequest();
verify(service).createCommand(anyString(), commandCaptor.capture());
verify(commandByRelationController).createCommand(commandCaptor.capture(), anyString());
var command = commandCaptor.getValue();
assertThat(command).usingRecursiveComparison()
.ignoringFields("kommentar.id", "kommentar.createdBy", "kommentar.createdByName", "kommentar.createdAt")
.isEqualTo(KommentarCommandTestFactory.createBuilder().id(null).build());
.ignoringFields("body", "status")
.isEqualTo(CommandTestFactory.createBuilder().order(CommandOrder.UPDATE_ATTACHED_ITEM).relationId("-1").id(null).build());
}
@Test
......
......@@ -22,6 +22,8 @@ import org.springframework.test.web.servlet.ResultActions;
import de.itvsh.goofy.common.ValidationMessageCodes;
import de.itvsh.goofy.common.command.CommandOrder;
import de.itvsh.goofy.common.command.CommandRemoteService;
import de.itvsh.goofy.common.command.CommandTestFactory;
import de.itvsh.goofy.kommentar.KommentarCommandController.KommentarCommandByVorgangController;
import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory;
......@@ -34,6 +36,8 @@ class KommentarCommandITCase {
private MockMvc mockMvc;
@MockBean
private KommentarRemoteService remoteService;
@MockBean
private CommandRemoteService commandRemoteService;
@WithMockUser
@Nested
......@@ -41,14 +45,15 @@ class KommentarCommandITCase {
@BeforeEach
void initTest() {
when(remoteService.sendKommentarCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.create());
when(remoteService.getById(any())).thenReturn(KommentarTestFactory.create());
when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create());
}
@Test
void shouldCreateCommand() throws Exception {
doRequestByKommentarId(createValidRequestContent()).andExpect(status().isCreated());
verify(remoteService).sendKommentarCommand(eq(KommentarTestFactory.ID), any());
verify(commandRemoteService).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME));
}
@WithMockUser
......@@ -63,7 +68,7 @@ class KommentarCommandITCase {
doRequestByKommentarId(content).andExpect(status().isUnprocessableEntity())
.andExpect(jsonPath("$.issues.length()").value(1))
.andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text"))
.andExpect(jsonPath("$.issues.[0].field").value("command.body.text"))
.andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY));
}
......@@ -73,7 +78,7 @@ class KommentarCommandITCase {
String content = buildContentWithText(StringUtils.EMPTY);
doRequestByKommentarId(content).andExpect(status().isUnprocessableEntity())
.andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text"));
.andExpect(jsonPath("$.issues.[0].field").value("command.body.text"));
}
......@@ -88,7 +93,7 @@ class KommentarCommandITCase {
private String buildContentWithText(String text) {
return createRequestContent(KommentarCommandTestFactory.createBuilder()
.order(CommandOrder.EDIT_KOMMENTAR)
.order(CommandOrder.CREATE_ATTACHED_ITEM)
.kommentar(KommentarTestFactory.createBuilder().text(text).build())
.build());
}
......@@ -107,14 +112,15 @@ class KommentarCommandITCase {
@BeforeEach
void initTest() {
when(remoteService.sendKommentarCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.create());
when(remoteService.getById(any())).thenReturn(KommentarTestFactory.create());
when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create());
}
@Test
void shouldCreateCommand() throws Exception {
doRequestByVorgangId(createValidRequestContent()).andExpect(status().isCreated());
verify(remoteService).sendKommentarCommand(eq(VorgangHeaderTestFactory.ID), any());
verify(commandRemoteService).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME));
}
@WithMockUser
......@@ -129,7 +135,7 @@ class KommentarCommandITCase {
doRequestByVorgangId(content).andExpect(status().isUnprocessableEntity())
.andExpect(jsonPath("$.issues.length()").value(1))
.andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text"))
.andExpect(jsonPath("$.issues.[0].field").value("command.body.text"))
.andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY));
}
......@@ -139,7 +145,7 @@ class KommentarCommandITCase {
String content = buildContentWithText(StringUtils.EMPTY);
doRequestByVorgangId(content).andExpect(status().isUnprocessableEntity())
.andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text"));
.andExpect(jsonPath("$.issues.[0].field").value("command.body.text"));
}
......
......@@ -2,6 +2,7 @@ package de.itvsh.goofy.kommentar;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers;
......@@ -11,6 +12,51 @@ class KommentarMapperTest {
private KommentarMapper mapper = Mappers.getMapper(KommentarMapper.class);
@Nested
class TestFromItemMap {
@Test
void shouldMapId() {
var kommentar = map();
assertThat(kommentar.getId()).isEqualTo(KommentarTestFactory.ID);
}
@Test
void shouldMapCreatedBy() {
var kommentar = map();
assertThat(kommentar.getCreatedBy()).isEqualTo(KommentarTestFactory.CREATED_BY);
}
@Test
void shouldMapCreatedAt() {
var kommentar = map();
assertThat(kommentar.getCreatedAt()).isEqualTo(KommentarTestFactory.CREATED_AT);
}
@Test
void shouldMapText() {
var kommentar = map();
assertThat(kommentar.getText()).isEqualTo(KommentarTestFactory.TEXT);
}
@Test
void shouldMapVorgangID() {
var kommentar = map();
assertThat(kommentar.getVorgangId()).isEqualTo(KommentarTestFactory.VORGANG_ID);
}
}
private Kommentar map() {
return mapper.fromItemMap(KommentarTestFactory.createAsMap());
}
@Nested
@Deprecated
@Disabled
class TestFromGrpc {
@Test
......@@ -29,6 +75,8 @@ class KommentarMapperTest {
}
@Nested
@Deprecated
@Disabled
class TestToGrpc {
@Test
......
package de.itvsh.goofy.kommentar;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.UUID;
import com.thedeanda.lorem.Lorem;
import com.thedeanda.lorem.LoremIpsum;
import de.itvsh.goofy.common.user.UserProfileTestFactory;
import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory;
public class KommentarTestFactory {
......@@ -21,6 +23,8 @@ public class KommentarTestFactory {
public static final String TEXT = lorem.getWords(15);
public static final String VORGANG_ID = VorgangHeaderTestFactory.ID;
public static Kommentar create() {
return createBuilder().build();
}
......@@ -31,6 +35,16 @@ public class KommentarTestFactory {
.text(TEXT)
.createdBy(CREATED_BY)
.createdByName(CREATED_BY_NAME)
.createdAt(CREATED_AT);
.createdAt(CREATED_AT)
.vorgangId(VORGANG_ID);
}
public static Map<String, Object> createAsMap() {
return Map.of(
KommentarMapper.ID, ID,
KommentarMapper.TEXT, TEXT,
KommentarMapper.CREATED_BY, CREATED_BY,
KommentarMapper.CREATED_AT, CREATED_AT_STR,
KommentarMapper.VORGANG_ID, VORGANG_ID);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment