Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/main/java/com/augment/cbsa/web/delcus/DelcusController.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,21 @@ public ResponseEntity<?> delete(
// but DELCUS itself only consumes COMM-CUSTNO.
Objects.requireNonNull(requestDto, "requestDto must not be null");

DelcusResult result = delcusService.delete(new DelcusRequest(Long.parseLong(customerNumber)));
long pathCustomerNumber = Long.parseLong(customerNumber);
// Reject body/path mismatches up front. The body's CommCustno is
// optional (pattern allows ""); when supplied it must agree with the
// path so we never silently delete the path target on a misaddressed
// request.
String bodyCustno = requestDto.delCus().commCustno();
if (bodyCustno != null && !bodyCustno.isEmpty()
&& Long.parseLong(bodyCustno) != pathCustomerNumber) {
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
problemDetail.setTitle("Validation failed");
problemDetail.setDetail("Body CommCustno does not match path customerNumber.");
return ResponseEntity.badRequest().body(problemDetail);
}

DelcusResult result = delcusService.delete(new DelcusRequest(pathCustomerNumber));
if (!result.deleteSuccess()) {
return ResponseEntity.status(failureStatus(result)).body(failureBody(result));
}
Expand Down Expand Up @@ -99,7 +113,10 @@ private DelcusResponseDto toResponse(DelcusResult result) {
customer.creditScore(),
toCobolDate(customer.csReviewDate()),
"Y",
""
// CommDelFailCd is a fixed-width 1-char commarea slot;
// emit a single space on success to preserve the length-1
// contract for clients porting from COBOL.
" "
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,67 @@ void returnsSuccessfulResponseForHappyPath() throws Exception {
.andExpect(jsonPath("$.DelCus.CommEye").value("CUST"))
.andExpect(jsonPath("$.DelCus.CommScode").value("987654"))
.andExpect(jsonPath("$.DelCus.CommCustno").value("0000000001"))
.andExpect(jsonPath("$.DelCus.CommDelSuccess").value("Y"));
.andExpect(jsonPath("$.DelCus.CommDelSuccess").value("Y"))
.andExpect(jsonPath("$.DelCus.CommDelFailCd").value(" "));
}

@Test
void rejectsBodyCommCustnoThatMismatchesPath() throws Exception {
String body = """
{
"DelCus": {
"CommEye": "CUST",
"CommScode": "987654",
"CommCustno": "0000000002",
"CommName": "",
"CommAddr": "",
"CommDob": 0,
"CommCreditScore": 0,
"CommCsReviewDate": 0,
"CommDelSuccess": " ",
"CommDelFailCd": " "
}
}
""";

mockMvc.perform(delete("/api/v1/delcus/remove/1").contentType(APPLICATION_JSON).content(body))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.title").value("Validation failed"))
.andExpect(jsonPath("$.detail").value("Body CommCustno does not match path customerNumber."));
}

@Test
void acceptsMatchingBodyCommCustno() throws Exception {
when(delcusService.delete(new DelcusRequest(1L))).thenReturn(DelcusResult.success(new CustomerDetails(
"987654",
1L,
"Mr Alice Example",
"1 Main Street",
LocalDate.of(2000, 1, 10),
430,
LocalDate.of(2026, 5, 8)
)));

String body = """
{
"DelCus": {
"CommEye": "CUST",
"CommScode": "987654",
"CommCustno": "0000000001",
"CommName": "",
"CommAddr": "",
"CommDob": 0,
"CommCreditScore": 0,
"CommCsReviewDate": 0,
"CommDelSuccess": " ",
"CommDelFailCd": " "
}
}
""";

mockMvc.perform(delete("/api/v1/delcus/remove/1").contentType(APPLICATION_JSON).content(body))
.andExpect(status().isOk())
.andExpect(jsonPath("$.DelCus.CommCustno").value("0000000001"));
}

@Test
Expand Down
Loading