Skip to content

Commit 39467b6

Browse files
HDPI-6415 Retrieving defendant claim list (#1913)
1 parent 72844a9 commit 39467b6

6 files changed

Lines changed: 334 additions & 0 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package uk.gov.hmcts.reform.pcs.ccd.domain.respondpossessionclaim;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
@Builder
9+
@Data
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
public class ClaimSummary {
13+
14+
private String caseReference;
15+
16+
private String claimantName;
17+
18+
private String propertyPostcode;
19+
}

src/main/java/uk/gov/hmcts/reform/pcs/ccd/repository/PartyRepository.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
import org.springframework.data.jpa.repository.Query;
55
import org.springframework.data.repository.query.Param;
66
import org.springframework.stereotype.Repository;
7+
import uk.gov.hmcts.reform.pcs.ccd.entity.ClaimEntity;
78
import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyEntity;
9+
import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyRole;
810

11+
import java.util.List;
912
import java.util.Optional;
1013
import java.util.UUID;
1114

@@ -18,6 +21,9 @@ public interface PartyRepository extends JpaRepository<PartyEntity, UUID> {
1821
@Query("SELECT p FROM PartyEntity p WHERE p.idamId = :idamId AND p.pcsCase.caseReference = :caseReference")
1922
Optional<PartyEntity> queryPartyByIdamId(@Param("idamId") UUID idamId, @Param("caseReference") long caseReference);
2023

24+
@Query("SELECT cp.claim FROM ClaimPartyEntity cp WHERE cp.party.idamId = :idamId AND cp.role = :role")
25+
List<ClaimEntity> findClaimsByIdamIdAndRole(@Param("idamId") UUID idamId, @Param("role") PartyRole role);
26+
2127
Optional<PartyEntity> findByIdAndPcsCaseCaseReference(UUID id, long caseReference);
2228

2329
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package uk.gov.hmcts.reform.pcs.ccd.service.respondpossessionclaim;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.stereotype.Service;
5+
import org.springframework.transaction.annotation.Transactional;
6+
import uk.gov.hmcts.reform.pcs.ccd.domain.respondpossessionclaim.ClaimSummary;
7+
import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity;
8+
import uk.gov.hmcts.reform.pcs.ccd.entity.ClaimEntity;
9+
import uk.gov.hmcts.reform.pcs.ccd.entity.party.ClaimPartyEntity;
10+
import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyRole;
11+
import uk.gov.hmcts.reform.pcs.ccd.repository.PartyRepository;
12+
13+
import java.util.List;
14+
import java.util.Optional;
15+
import java.util.UUID;
16+
17+
@Service
18+
@RequiredArgsConstructor
19+
@Transactional(readOnly = true)
20+
public class CitizenClaimListService {
21+
22+
private final PartyRepository partyRepository;
23+
24+
public List<ClaimSummary> getClaimsAgainst(UUID idamId) {
25+
return partyRepository.findClaimsByIdamIdAndRole(idamId, PartyRole.DEFENDANT).stream()
26+
.map(claim -> ClaimSummary.builder()
27+
.caseReference(String.valueOf(claim.getPcsCase().getCaseReference()))
28+
.claimantName(extractClaimantName(claim))
29+
.propertyPostcode(extractPostcode(claim))
30+
.build())
31+
.toList();
32+
}
33+
34+
private String extractClaimantName(ClaimEntity claim) {
35+
return claim.getClaimParties().stream()
36+
.filter(cp -> cp.getRole() == PartyRole.CLAIMANT)
37+
.map(ClaimPartyEntity::getParty)
38+
.map(claimant -> (claimant.getOrgName() != null
39+
? claimant.getOrgName()
40+
: String.format("%s %s", claimant.getFirstName(), claimant.getLastName())))
41+
.findFirst()
42+
.orElse(null);
43+
}
44+
45+
private String extractPostcode(ClaimEntity claim) {
46+
return Optional.ofNullable(claim.getPcsCase().getPropertyAddress())
47+
.map(AddressEntity::getPostcode)
48+
.orElse(null);
49+
}
50+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package uk.gov.hmcts.reform.pcs.controllers;
2+
3+
import io.swagger.v3.oas.annotations.Operation;
4+
import io.swagger.v3.oas.annotations.Parameter;
5+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
6+
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
7+
import io.swagger.v3.oas.annotations.tags.Tag;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.http.MediaType;
10+
import org.springframework.http.ResponseEntity;
11+
import org.springframework.web.bind.annotation.GetMapping;
12+
import org.springframework.web.bind.annotation.RequestHeader;
13+
import org.springframework.web.bind.annotation.RequestMapping;
14+
import org.springframework.web.bind.annotation.RestController;
15+
import uk.gov.hmcts.reform.pcs.ccd.domain.respondpossessionclaim.ClaimSummary;
16+
import uk.gov.hmcts.reform.pcs.ccd.service.respondpossessionclaim.CitizenClaimListService;
17+
import uk.gov.hmcts.reform.pcs.idam.IdamAuthenticator;
18+
19+
import java.util.List;
20+
import java.util.UUID;
21+
22+
@RestController
23+
@RequestMapping("/cases")
24+
@RequiredArgsConstructor
25+
@Tag(name = "Citizen Claim List", description = "Retrieve claims associated with the authenticated citizen")
26+
public class CitizenClaimListController {
27+
28+
private final IdamAuthenticator idamAuthenticator;
29+
private final CitizenClaimListService citizenClaimListService;
30+
31+
@GetMapping(value = "/citizen-claims", produces = MediaType.APPLICATION_JSON_VALUE)
32+
@Operation(
33+
summary = "Get all claims against the authenticated citizen",
34+
description = "Returns all possession claims where the authenticated user is linked as a defendant",
35+
security = {
36+
@SecurityRequirement(name = "AuthorizationToken"),
37+
@SecurityRequirement(name = "ServiceAuthorization")
38+
}
39+
)
40+
@ApiResponse(responseCode = "200", description = "Claims retrieved successfully")
41+
@ApiResponse(responseCode = "401", description = "Invalid access token")
42+
@ApiResponse(responseCode = "403", description = "Invalid Service Authorization")
43+
public ResponseEntity<List<ClaimSummary>> getDefendantClaims(
44+
@Parameter(description = "Bearer token for user authentication", required = true)
45+
@RequestHeader("Authorization") String authorization,
46+
@Parameter(description = "Service-to-Service (S2S) authorization token", required = true)
47+
@RequestHeader("ServiceAuthorization") String s2sToken
48+
) {
49+
UUID idamId = UUID.fromString(idamAuthenticator.validateAuthToken(authorization).getUserDetails().getUid());
50+
return ResponseEntity.ok(citizenClaimListService.getClaimsAgainst(idamId));
51+
}
52+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package uk.gov.hmcts.reform.pcs.ccd.service.respondpossessionclaim;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.ExtendWith;
5+
import org.mockito.InjectMocks;
6+
import org.mockito.Mock;
7+
import org.mockito.junit.jupiter.MockitoExtension;
8+
import uk.gov.hmcts.reform.pcs.ccd.domain.respondpossessionclaim.ClaimSummary;
9+
import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity;
10+
import uk.gov.hmcts.reform.pcs.ccd.entity.ClaimEntity;
11+
import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity;
12+
import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyEntity;
13+
import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyRole;
14+
import uk.gov.hmcts.reform.pcs.ccd.repository.PartyRepository;
15+
16+
import java.util.List;
17+
import java.util.UUID;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.mockito.Mockito.when;
21+
22+
@ExtendWith(MockitoExtension.class)
23+
class CitizenClaimListServiceTest {
24+
25+
@Mock
26+
private PartyRepository partyRepository;
27+
28+
@InjectMocks
29+
private CitizenClaimListService underTest;
30+
31+
private static final UUID IDAM_ID = UUID.randomUUID();
32+
33+
@Test
34+
void shouldReturnMappedClaimSummariesWhenClaimsExist() {
35+
// Given
36+
PartyEntity claimant = PartyEntity.builder().orgName("Smith & Co").build();
37+
38+
PcsCaseEntity pcsCase = PcsCaseEntity.builder()
39+
.caseReference(1234567890L)
40+
.propertyAddress(AddressEntity.builder().postcode("SW1A 1AA").build())
41+
.build();
42+
43+
ClaimEntity claim = ClaimEntity.builder().pcsCase(pcsCase).build();
44+
claim.addParty(claimant, PartyRole.CLAIMANT);
45+
when(partyRepository.findClaimsByIdamIdAndRole(IDAM_ID, PartyRole.DEFENDANT))
46+
.thenReturn(List.of(claim));
47+
48+
// When
49+
List<ClaimSummary> result = underTest.getClaimsAgainst(IDAM_ID);
50+
51+
// Then
52+
assertThat(result).hasSize(1);
53+
assertThat(result.get(0).getCaseReference()).isEqualTo("1234567890");
54+
assertThat(result.get(0).getClaimantName()).isEqualTo("Smith & Co");
55+
assertThat(result.get(0).getPropertyPostcode()).isEqualTo("SW1A 1AA");
56+
}
57+
58+
@Test
59+
void shouldReturnEmptyListWhenNoClaimsExist() {
60+
// Given
61+
when(partyRepository.findClaimsByIdamIdAndRole(IDAM_ID, PartyRole.DEFENDANT))
62+
.thenReturn(List.of());
63+
// When
64+
List<ClaimSummary> result = underTest.getClaimsAgainst(IDAM_ID);
65+
// Then
66+
assertThat(result).isEmpty();
67+
}
68+
69+
@Test
70+
void shouldIgnoreDefendantPartyWhenExtractingClaimantName() {
71+
// Given
72+
PartyEntity defendant = PartyEntity.builder().orgName("Defendant Org").build();
73+
PcsCaseEntity pcsCase = PcsCaseEntity.builder()
74+
.caseReference(1234567890L)
75+
.propertyAddress(AddressEntity.builder().postcode("SW1A 1AA").build())
76+
.build();
77+
78+
ClaimEntity claim = ClaimEntity.builder().pcsCase(pcsCase).build();
79+
claim.addParty(defendant, PartyRole.DEFENDANT);
80+
when(partyRepository.findClaimsByIdamIdAndRole(IDAM_ID, PartyRole.DEFENDANT))
81+
.thenReturn(List.of(claim));
82+
83+
// When
84+
List<ClaimSummary> result = underTest.getClaimsAgainst(IDAM_ID);
85+
86+
// Then
87+
assertThat(result.get(0).getClaimantName()).isNull();
88+
}
89+
90+
@Test
91+
void shouldReturnNullClaimantNameWhenNoClaimantPartyExists() {
92+
// Given
93+
PcsCaseEntity pcsCase = PcsCaseEntity.builder()
94+
.caseReference(1234567890L)
95+
.propertyAddress(AddressEntity.builder().postcode("SW1A 1AA").build())
96+
.build();
97+
98+
ClaimEntity claim = ClaimEntity.builder().pcsCase(pcsCase).build();
99+
when(partyRepository.findClaimsByIdamIdAndRole(IDAM_ID, PartyRole.DEFENDANT))
100+
.thenReturn(List.of(claim));
101+
102+
// When
103+
List<ClaimSummary> result = underTest.getClaimsAgainst(IDAM_ID);
104+
105+
// Then
106+
assertThat(result.get(0).getClaimantName()).isNull();
107+
}
108+
109+
@Test
110+
void shouldReturnNullPostcodeWhenPropertyAddressIsAbsent() {
111+
// Given
112+
PartyEntity claimant = PartyEntity.builder().orgName("Smith & Co").build();
113+
PcsCaseEntity pcsCase = PcsCaseEntity.builder()
114+
.caseReference(1234567890L)
115+
.build();
116+
117+
ClaimEntity claim = ClaimEntity.builder().pcsCase(pcsCase).build();
118+
claim.addParty(claimant, PartyRole.CLAIMANT);
119+
when(partyRepository.findClaimsByIdamIdAndRole(IDAM_ID, PartyRole.DEFENDANT))
120+
.thenReturn(List.of(claim));
121+
122+
// When
123+
List<ClaimSummary> result = underTest.getClaimsAgainst(IDAM_ID);
124+
125+
// Then
126+
assertThat(result.get(0).getPropertyPostcode()).isNull();
127+
}
128+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package uk.gov.hmcts.reform.pcs.controllers;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.ExtendWith;
5+
import org.mockito.InjectMocks;
6+
import org.mockito.Mock;
7+
import org.mockito.junit.jupiter.MockitoExtension;
8+
import org.springframework.http.HttpStatus;
9+
import org.springframework.http.ResponseEntity;
10+
import uk.gov.hmcts.reform.pcs.ccd.domain.respondpossessionclaim.ClaimSummary;
11+
import uk.gov.hmcts.reform.pcs.ccd.service.respondpossessionclaim.CitizenClaimListService;
12+
import uk.gov.hmcts.reform.pcs.idam.IdamAuthenticator;
13+
import uk.gov.hmcts.reform.pcs.idam.User;
14+
import uk.gov.hmcts.reform.pcs.idam.UserInfo;
15+
16+
import java.util.List;
17+
import java.util.UUID;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.mockito.Mockito.mock;
21+
import static org.mockito.Mockito.when;
22+
23+
@ExtendWith(MockitoExtension.class)
24+
class CitizenClaimListControllerTest {
25+
26+
private static final String AUTH_HEADER = "Bearer user-token";
27+
private static final String S2S_TOKEN = "service-token";
28+
private static final UUID IDAM_ID = UUID.randomUUID();
29+
30+
@Mock
31+
private IdamAuthenticator idamAuthenticator;
32+
33+
@Mock
34+
private CitizenClaimListService citizenClaimListService;
35+
36+
@InjectMocks
37+
private CitizenClaimListController underTest;
38+
39+
@Test
40+
void shouldReturn200WithClaims_WhenClaimsExist() {
41+
// Given
42+
UserInfo userDetails = mock(UserInfo.class);
43+
when(userDetails.getUid()).thenReturn(IDAM_ID.toString());
44+
User user = mock(User.class);
45+
when(user.getUserDetails()).thenReturn(userDetails);
46+
when(idamAuthenticator.validateAuthToken(AUTH_HEADER)).thenReturn(user);
47+
48+
List<ClaimSummary> claims = List.of(
49+
ClaimSummary.builder().caseReference("123").claimantName("Smith & Co").propertyPostcode("SW1A 1AA").build()
50+
);
51+
when(citizenClaimListService.getClaimsAgainst(IDAM_ID)).thenReturn(claims);
52+
53+
// When
54+
ResponseEntity<List<ClaimSummary>> response = underTest.getDefendantClaims(AUTH_HEADER, S2S_TOKEN);
55+
56+
// Then
57+
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
58+
assertThat(response.getBody()).isEqualTo(claims);
59+
}
60+
61+
@Test
62+
void shouldReturn200WithEmptyList_WhenNoClaimsExist() {
63+
// Given
64+
UserInfo userDetails = mock(UserInfo.class);
65+
when(userDetails.getUid()).thenReturn(IDAM_ID.toString());
66+
User user = mock(User.class);
67+
when(user.getUserDetails()).thenReturn(userDetails);
68+
when(idamAuthenticator.validateAuthToken(AUTH_HEADER)).thenReturn(user);
69+
70+
when(citizenClaimListService.getClaimsAgainst(IDAM_ID)).thenReturn(List.of());
71+
72+
// When
73+
ResponseEntity<List<ClaimSummary>> response = underTest.getDefendantClaims(AUTH_HEADER, S2S_TOKEN);
74+
75+
// Then
76+
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
77+
assertThat(response.getBody()).isEmpty();
78+
}
79+
}

0 commit comments

Comments
 (0)