Skip to content

Commit

Permalink
PO-559: Update DraftAccount POST endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
RustyHMCTS committed Sep 4, 2024
1 parent 7ca5d81 commit 339741d
Show file tree
Hide file tree
Showing 16 changed files with 386 additions and 51 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ dependencies {
implementation group: 'com.launchdarkly', name: 'launchdarkly-java-server-sdk', version: '7.5.0'

implementation(group: 'com.networknt', name: 'json-schema-validator', version: '1.5.1');
implementation(group: 'com.jayway.jsonpath', name: 'json-path', version: '2.9.0');

implementation group: 'io.rest-assured', name: 'rest-assured'
implementation 'org.flywaydb:flyway-core'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import uk.gov.hmcts.opal.dto.search.DraftAccountSearchDto;
import uk.gov.hmcts.opal.entity.BusinessUnitEntity;
import uk.gov.hmcts.opal.entity.DraftAccountEntity;
import uk.gov.hmcts.opal.entity.DraftAccountStatus;
import uk.gov.hmcts.opal.service.opal.DraftAccountService;
import uk.gov.hmcts.opal.service.opal.JsonSchemaValidationService;
import uk.gov.hmcts.opal.service.opal.UserStateService;
Expand Down Expand Up @@ -69,15 +70,15 @@ void testGetDraftAccountById() throws Exception {

when(draftAccountService.getDraftAccount(1L)).thenReturn(draftAccountEntity);

MvcResult result = mockMvc.perform(get("/api/draft-account/1")
MvcResult result = mockMvc.perform(get("/api/draft-accounts/1")
.header("authorization", "Bearer some_value"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.draft_account_id").value(1))
.andExpect(jsonPath("$.business_unit_id").value(7))
.andExpect(jsonPath("$.account_type").value("DRAFT"))
.andExpect(jsonPath("$.submitted_by").value("Tony"))
.andExpect(jsonPath("$.account_status").value("CREATED"))
.andExpect(jsonPath("$.account_status").value("Submitted"))
.andReturn();

String body = result.getResponse().getContentAsString();
Expand All @@ -92,7 +93,7 @@ void testGetDraftAccountById() throws Exception {
void testGetDraftAccountById_WhenDraftAccountDoesNotExist() throws Exception {
when(draftAccountService.getDraftAccount(2L)).thenReturn(null);

mockMvc.perform(get("/api/draft-account/2").header("authorization", "Bearer some_value"))
mockMvc.perform(get("/api/draft-accounts/2").header("authorization", "Bearer some_value"))
.andExpect(status().isNotFound());
}

Expand All @@ -103,7 +104,7 @@ void testPostDraftAccountsSearch() throws Exception {
when(draftAccountService.searchDraftAccounts(any(DraftAccountSearchDto.class)))
.thenReturn(singletonList(draftAccountEntity));

mockMvc.perform(post("/api/draft-account/search")
mockMvc.perform(post("/api/draft-accounts/search")
.header("authorization", "Bearer some_value")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"criteria\":\"value\"}"))
Expand All @@ -113,12 +114,12 @@ void testPostDraftAccountsSearch() throws Exception {
.andExpect(jsonPath("$[0].businessUnit.businessUnitId").value(7))
.andExpect(jsonPath("$[0].accountType").value("DRAFT"))
.andExpect(jsonPath("$[0].submittedBy").value("Tony"))
.andExpect(jsonPath("$[0].accountStatus").value("CREATED"));
.andExpect(jsonPath("$[0].accountStatus").value("SUBMITTED"));
}

@Test
void testPostDraftAccountsSearch_WhenDraftAccountDoesNotExist() throws Exception {
mockMvc.perform(post("/api/draft-account/search")
mockMvc.perform(post("/api/draft-accounts/search")
.header("authorization", "Bearer some_value")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"criteria\":\"2\"}"))
Expand Down Expand Up @@ -159,7 +160,7 @@ private DraftAccountEntity createDraftAccountEntity() {
.createdDate(LocalDate.of(2023, 1, 2).atStartOfDay())
.submittedBy("Tony")
.accountType("DRAFT")
.accountStatus("CREATED")
.accountStatus(DraftAccountStatus.SUBMITTED)
.account("{}")
.accountSnapshot("{}")
.timelineData("{}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import uk.gov.hmcts.opal.dto.GetDraftAccountResponseDto;
import uk.gov.hmcts.opal.authorisation.model.UserState;
import uk.gov.hmcts.opal.dto.AddDraftAccountRequestDto;
import uk.gov.hmcts.opal.dto.DraftAccountResponseDto;
import uk.gov.hmcts.opal.dto.search.DraftAccountSearchDto;
import uk.gov.hmcts.opal.entity.DraftAccountEntity;
import uk.gov.hmcts.opal.entity.DraftAccountStatus;
import uk.gov.hmcts.opal.service.opal.DraftAccountService;
import uk.gov.hmcts.opal.service.opal.JsonSchemaValidationService;
import uk.gov.hmcts.opal.service.opal.UserStateService;
Expand All @@ -23,15 +26,18 @@
import java.util.Optional;

import static uk.gov.hmcts.opal.util.DateTimeUtils.toOffsetDateTime;
import static uk.gov.hmcts.opal.util.HttpUtil.buildCreatedResponse;
import static uk.gov.hmcts.opal.util.HttpUtil.buildResponse;


@RestController
@RequestMapping("/api/draft-account")
@RequestMapping("/api/draft-accounts")
@Slf4j(topic = "DraftAccountController")
@Tag(name = "DraftAccount Controller")
public class DraftAccountController {

public static final String ADD_DRAFT_ACCOUNT_REQUEST_JSON = "addDraftAccountRequest.json";

private final DraftAccountService draftAccountService;

private final UserStateService userStateService;
Expand All @@ -47,7 +53,7 @@ public DraftAccountController(UserStateService userStateService, DraftAccountSer

@GetMapping(value = "/{draftAccountId}")
@Operation(summary = "Returns the Draft Account for the given draftAccountId.")
public ResponseEntity<GetDraftAccountResponseDto> getDraftAccountById(
public ResponseEntity<DraftAccountResponseDto> getDraftAccountById(
@PathVariable Long draftAccountId,
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

Expand All @@ -74,20 +80,22 @@ public ResponseEntity<List<DraftAccountEntity>> postDraftAccountsSearch(@Request
}

@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Creates a Draft Account entity in the DB based upon data in request body")
public ResponseEntity<DraftAccountEntity> postDraftAccount(@RequestBody DraftAccountEntity entity,
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
@Operation(summary = "Creates a Draft Account Entity in the DB based upon data in request body")
public ResponseEntity<DraftAccountResponseDto> postDraftAccount(@RequestBody AddDraftAccountRequestDto dto,
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:postDraftAccount: creating a new draft account entity.");

userStateService.checkForAuthorisedUser(authHeaderValue);
UserState user = userStateService.checkForAuthorisedUser(authHeaderValue);

DraftAccountEntity response = draftAccountService.saveDraftAccount(entity);
jsonSchemaValidationService.validateOrError(dto.toJson(), ADD_DRAFT_ACCOUNT_REQUEST_JSON);

return buildResponse(response);
DraftAccountEntity response = draftAccountService.submitDraftAccount(dto, user.getUserName());

return buildCreatedResponse(toGetResponseDto(response));
}

GetDraftAccountResponseDto toGetResponseDto(DraftAccountEntity entity) {
return GetDraftAccountResponseDto.builder()
DraftAccountResponseDto toGetResponseDto(DraftAccountEntity entity) {
return DraftAccountResponseDto.builder()
.draftAccountId(entity.getDraftAccountId())
.businessUnitId(entity.getBusinessUnit().getBusinessUnitId())
.createdDate(toOffsetDateTime(entity.getCreatedDate()))
Expand All @@ -97,10 +105,12 @@ GetDraftAccountResponseDto toGetResponseDto(DraftAccountEntity entity) {
.account(entity.getAccount())
.accountSnapshot(entity.getAccountSnapshot())
.accountType(entity.getAccountType())
.accountStatus(entity.getAccountStatus())
.accountStatus(Optional.ofNullable(entity.getAccountStatus())
.map(DraftAccountStatus::getLabel).orElse(null))
.timelineData(entity.getTimelineData())
.accountNumber(entity.getAccountNumber())
.accountId(entity.getAccountId())
.build();
}

}
63 changes: 63 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/dto/AddDraftAccountRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package uk.gov.hmcts.opal.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import uk.gov.hmcts.opal.util.KeepAsJsonDeserializer;

import java.time.OffsetDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AddDraftAccountRequestDto implements ToJsonString {

@JsonProperty("draft_account_id")
private Long draftAccountId;

@JsonProperty("created_at")
private OffsetDateTime createdDate;

@JsonProperty("validated_at")
private OffsetDateTime validatedDate;

@JsonProperty(value = "business_unit_id", required = true)
private Short businessUnitId;

@JsonProperty("validated_by")
private String validatedBy;

@JsonProperty(value = "account", required = true)
@JsonDeserialize(using = KeepAsJsonDeserializer.class)
@JsonRawValue
private String account;

@JsonProperty("account_snapshot")
@JsonDeserialize(using = KeepAsJsonDeserializer.class)
@JsonRawValue
private String accountSnapshot;

@JsonProperty(value = "account_type", required = true)
private String accountType;

@JsonProperty(value = "timeline_data", required = true)
@JsonDeserialize(using = KeepAsJsonDeserializer.class)
@JsonRawValue
private String timelineData;

@JsonProperty("account_number")
private String accountNumber;

@JsonProperty("account_id")
private Long accountId;

@JsonProperty(value = "submitted_by", required = true)
private String submittedBy;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@AllArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GetDraftAccountResponseDto implements ToJsonString {
public class DraftAccountResponseDto implements ToJsonString {

@JsonProperty("draft_account_id")
private Long draftAccountId;
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/dto/DraftAccountSnapshotsDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package uk.gov.hmcts.opal.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.OffsetDateTime;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DraftAccountSnapshotsDto implements ToJsonString {

@JsonProperty("AccountSnapshot")
private List<Snapshot> accountSnapshot;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Snapshot implements ToJsonString {
@JsonProperty("DefendantName")
private String defendantName;

@JsonProperty("DateOfBirth")
private String dateOfBirth;

@JsonProperty("CreatedDate")
private OffsetDateTime createdDate;

@JsonProperty("AccountType")
private String accountType;

@JsonProperty("SubmittedBy")
private String submittedBy;

@JsonProperty("ApprovedDate")
private OffsetDateTime approvedDate;

@JsonProperty("BusinessUnitName")
private String businessUnitName;
}
}
3 changes: 3 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/dto/ToJsonString.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS;

public interface ToJsonString {

ObjectMapper OBJECT_MAPPER = new ObjectMapper()
.disable(WRITE_DATES_AS_TIMESTAMPS)
.registerModule(new JavaTimeModule());

default String toJsonString() throws JsonProcessingException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
Expand Down Expand Up @@ -72,7 +74,8 @@ public class DraftAccountEntity {
private String accountSnapshot;

@Column(name = "account_status", length = 30, nullable = false)
private String accountStatus;
@Enumerated(EnumType.STRING)
private DraftAccountStatus accountStatus;

@Column(name = "timeline_data", columnDefinition = "json")
@JsonDeserialize(using = KeepAsJsonDeserializer.class)
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/entity/DraftAccountStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package uk.gov.hmcts.opal.entity;

public enum DraftAccountStatus {
SUBMITTED("Submitted");

private final String label;

DraftAccountStatus(String label) {
this.label = label;
}

public String getLabel() {
return label;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import uk.gov.hmcts.opal.entity.BusinessUnitEntity;
import uk.gov.hmcts.opal.entity.DraftAccountEntity;
import uk.gov.hmcts.opal.entity.DraftAccountEntity_;
import uk.gov.hmcts.opal.entity.DraftAccountStatus;

import java.util.Set;
import java.util.stream.Collectors;

import static uk.gov.hmcts.opal.repository.jpa.BusinessUnitSpecs.equalsBusinessUnitIdPredicate;

Expand All @@ -17,7 +21,7 @@ public Specification<DraftAccountEntity> findBySearchCriteria(DraftAccountSearch
numericLong(criteria.getDraftAccountId()).map(DraftAccountSpecs::equalsDraftAccountId),
numericShort(criteria.getBusinessUnitId()).map(DraftAccountSpecs::equalsBusinessUnitId),
notBlank(criteria.getAccountType()).map(DraftAccountSpecs::likeAccountType),
notBlank(criteria.getAccountStatus()).map(DraftAccountSpecs::likeAccountStatus)
notBlank(criteria.getAccountStatus()).map(DraftAccountSpecs::equalsAccountStatus)
));
}

Expand All @@ -35,9 +39,16 @@ public static Specification<DraftAccountEntity> likeAccountType(String accountTy
likeWildcardPredicate(root.get(DraftAccountEntity_.accountType), builder, accountType);
}

public static Specification<DraftAccountEntity> likeAccountStatus(String accountStatus) {
return (root, query, builder) ->
likeWildcardPredicate(root.get(DraftAccountEntity_.accountStatus), builder, accountStatus);
public static Specification<DraftAccountEntity> equalsAccountStatus(String accountStatus) {
DraftAccountStatus status = DraftAccountStatus.valueOf(accountStatus);
return (root, query, builder) -> builder.equal(root.get(DraftAccountEntity_.accountStatus), status);
}

public static Specification<DraftAccountEntity> equalsAccountStatuses(Set<String> accountStatuses) {
Set<DraftAccountStatus> statuses = accountStatuses.stream()
.map(DraftAccountStatus::valueOf)
.collect(Collectors.toSet());
return (root, query, builder) -> root.get(DraftAccountEntity_.accountStatus).in(statuses);
}

public static Join<DraftAccountEntity, BusinessUnitEntity> joinBusinessUnit(From<?, DraftAccountEntity> from) {
Expand Down
Loading

0 comments on commit 339741d

Please sign in to comment.