Skip to content

Commit f3906b2

Browse files
Story(CCLS-2194) return checkpoint data from get assessment/assessments
Also includes: CCLS-2100 - delete checkpoint endpoint
1 parent 5e59ca2 commit f3906b2

File tree

14 files changed

+253
-5
lines changed

14 files changed

+253
-5
lines changed

assessment-api/open-api-specification.yml

+35
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,32 @@ paths:
137137
description: 'Not found'
138138
'500':
139139
description: 'Internal server error'
140+
/assessments/{assessment-id}/checkpoint:
141+
delete:
142+
tags:
143+
- assessments
144+
summary: 'delete checkpoint from assessment'
145+
operationId: 'deleteAssessmentCheckpoint'
146+
parameters:
147+
- name: 'assessment-id'
148+
in: 'path'
149+
required: true
150+
schema:
151+
type: 'integer'
152+
format: 'int64'
153+
example: '1234567890'
154+
- $ref: '#/components/parameters/requiredUserLoginId'
155+
responses:
156+
'204':
157+
description: 'Successful deletion'
158+
'400':
159+
description: 'Bad request'
160+
'401':
161+
description: 'Unauthorized'
162+
'404':
163+
description: 'Not found'
164+
'500':
165+
description: 'Internal server error'
140166

141167
components:
142168
parameters:
@@ -192,6 +218,8 @@ components:
192218
default: [ ]
193219
items:
194220
$ref: '#/components/schemas/assessmentEntityTypeDetail'
221+
checkpoint:
222+
$ref: '#/components/schemas/assessmentCheckpointDetail'
195223
audit_detail:
196224
$ref: '#/components/schemas/auditDetail'
197225
patchAssessmentDetail:
@@ -218,6 +246,13 @@ components:
218246
format: 'date'
219247
last_saved_by:
220248
type: 'string'
249+
assessmentCheckpointDetail:
250+
type: 'object'
251+
properties:
252+
username:
253+
type: 'string'
254+
interviewData:
255+
type: 'string'
221256
assessmentEntityTypeDetail:
222257
type: object
223258
properties:

assessment-service/src/integrationTest/resources/sql/assessment_tables_create_schema.sql

+7
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,11 @@ CREATE TABLE XXCCMS_OPA_RELSHIPTARGET (
5858
TARGET_ENTITY_ID VARCHAR2(255 CHAR) NOT NULL,
5959
FK_OPA_RELATIONSHIP NUMBER(19, 0),
6060
PRIMARY KEY (ID)
61+
);
62+
63+
CREATE TABLE XXCCMS_OPA_CHECKPOINT (
64+
RESUME_ID NUMBER(19,0) NOT NULL,
65+
USER_NAME VARCHAR2(255 CHAR),
66+
INTERVIEW_DATA BLOB,
67+
CONSTRAINT PK_OPA_CHECKPOINT PRIMARY KEY (RESUME_ID)
6168
);

assessment-service/src/integrationTest/resources/sql/assessment_tables_drop_schema.sql

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ DROP TABLE XXCCMS_OPA_RELATIONSHIP;
33
DROP TABLE XXCCMS_OPA_ATTRIBUTE;
44
DROP TABLE XXCCMS_OPA_ENTITY;
55
DROP TABLE XXCCMS_OPA_LISTENTITY;
6+
DROP TABLE XXCCMS_OPA_CHECKPOINT;
67
DROP TABLE XXCCMS_OPA_SESSION;

assessment-service/src/integrationTest/resources/sql/assessments_insert.sql

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ VALUES (30, 28, 'name1', 1);
1919

2020
-- Insert into XXCCMS_OPA_RELSHIPTARGET
2121
INSERT INTO XXCCMS_OPA_RELSHIPTARGET (ID, TARGET_ENTITY_ID)
22-
VALUES (31, 'entityId1');
22+
VALUES (31, 'entityId1');
23+
24+
INSERT INTO XXCCMS_OPA_CHECKPOINT (RESUME_ID, USER_NAME, INTERVIEW_DATA)
25+
VALUES (1, 'john.doe', hextoraw('48656c6c6f20776f726c64'));
26+
27+

assessment-service/src/integrationTest/resources/sql/delete_data.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ DELETE FROM XXCCMS_OPA_RELATIONSHIP;
33
DELETE FROM XXCCMS_OPA_ATTRIBUTE;
44
DELETE FROM XXCCMS_OPA_ENTITY;
55
DELETE FROM XXCCMS_OPA_LISTENTITY;
6-
DELETE FROM XXCCMS_OPA_SESSION;
6+
DELETE FROM XXCCMS_OPA_CHECKPOINT;
7+
DELETE FROM XXCCMS_OPA_SESSION;

assessment-service/src/main/java/uk/gov/laa/ccms/caab/assessment/controller/AssessmentController.java

+10
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ public ResponseEntity<AssessmentDetails> getAssessments(
5757
return ResponseEntity.ok(assessmentService.getAssessments(criteria, name));
5858
}
5959

60+
@Override
61+
public ResponseEntity<Void> deleteAssessmentCheckpoint(
62+
final Long assessmentId,
63+
final String caabUserLoginId) {
64+
65+
assessmentService.deleteCheckpoint(assessmentId);
66+
67+
return ResponseEntity.noContent().build();
68+
}
69+
6070
/**
6171
* Deletes assessments based on given criteria and a list of names.
6272
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package uk.gov.laa.ccms.caab.assessment.entity;
2+
3+
import jakarta.persistence.CascadeType;
4+
import jakarta.persistence.Column;
5+
import jakarta.persistence.Entity;
6+
import jakarta.persistence.Id;
7+
import jakarta.persistence.JoinColumn;
8+
import jakarta.persistence.Lob;
9+
import jakarta.persistence.MapsId;
10+
import jakarta.persistence.OneToOne;
11+
import jakarta.persistence.Table;
12+
import lombok.Data;
13+
14+
/**
15+
* Represents an Oracle Intelligence Advisor Checkpoint.
16+
*/
17+
@Entity
18+
@Table(name = "XXCCMS_OPA_CHECKPOINT")
19+
@Data
20+
public class OpaCheckpoint {
21+
22+
@Id
23+
@Column(name = "RESUME_ID")
24+
private long resumeId;
25+
26+
@Column(name = "USER_NAME")
27+
private String username;
28+
29+
@Column(name = "INTERVIEW_DATA")
30+
@Lob
31+
private byte[] interviewData;
32+
33+
@OneToOne(cascade = {
34+
CascadeType.PERSIST,
35+
CascadeType.MERGE
36+
})
37+
@MapsId
38+
@JoinColumn(name = "RESUME_ID")
39+
private OpaSession opaSession;
40+
41+
}

assessment-service/src/main/java/uk/gov/laa/ccms/caab/assessment/entity/OpaSession.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import jakarta.persistence.GeneratedValue;
99
import jakarta.persistence.Id;
1010
import jakarta.persistence.OneToMany;
11+
import jakarta.persistence.OneToOne;
1112
import jakarta.persistence.SequenceGenerator;
1213
import jakarta.persistence.Table;
1314
import java.util.List;
@@ -76,11 +77,13 @@ public class OpaSession {
7677
)
7778
private List<OpaListEntity> opaListEntities;
7879

80+
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "opaSession")
81+
private OpaCheckpoint checkpoint;
82+
7983
/**
8084
* audit trail info.
8185
*/
8286
@Embedded
8387
private AuditTrail auditTrail = new AuditTrail();
8488

85-
8689
}

assessment-service/src/main/java/uk/gov/laa/ccms/caab/assessment/mapper/AssessmentMapper.java

+3
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ public interface AssessmentMapper {
3030
@Mapping(target = "targetId", source = "caseReferenceNumber")
3131
@Mapping(target = "auditTrail", ignore = true)
3232
@Mapping(target = "opaListEntities", ignore = true)
33+
@Mapping(target = "checkpoint", ignore = true)
3334
OpaSession toOpaSession(AssessmentDetail assessmentDetail);
3435

3536
@InheritInverseConfiguration(name = "toOpaSession")
3637
@Mapping(target = "auditDetail", source = "auditTrail")
3738
@Mapping(target = "entityTypes", source = "opaListEntities")
39+
@Mapping(target = "checkpoint", source = "checkpoint")
3840
AssessmentDetail toAssessmentDetail(OpaSession opaSession);
3941

4042
@Mapping(target = "entities", source = "opaEntities")
@@ -55,6 +57,7 @@ public interface AssessmentMapper {
5557
@Mapping(target = "auditTrail", ignore = true)
5658
@Mapping(target = "opaListEntities", ignore = true)
5759
@Mapping(target = "id", ignore = true)
60+
@Mapping(target = "checkpoint", ignore = true)
5861
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
5962
void mapIntoOpaSession(
6063
@MappingTarget OpaSession opaSession,

assessment-service/src/main/java/uk/gov/laa/ccms/caab/assessment/mapper/CommonMapper.java

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package uk.gov.laa.ccms.caab.assessment.mapper;
22

3+
import java.util.Base64;
34
import org.mapstruct.Mapper;
45

56
/**
@@ -17,5 +18,14 @@ public interface CommonMapper {
1718
default Boolean toBoolean(Boolean flag) {
1819
return flag != null ? flag : Boolean.FALSE;
1920
}
21+
22+
23+
default String toBase64String(byte[] bytes) {
24+
return bytes != null ? Base64.getEncoder().encodeToString(bytes) : null;
25+
}
26+
27+
default byte[] toByteArrayFromBase64EncodedString(String base64EncodedString) {
28+
return Base64.getDecoder().decode(base64EncodedString);
29+
}
2030
}
2131

assessment-service/src/main/java/uk/gov/laa/ccms/caab/assessment/service/AssessmentService.java

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package uk.gov.laa.ccms.caab.assessment.service;
22

3-
import jakarta.persistence.criteria.Path;
43
import jakarta.persistence.criteria.Predicate;
54
import jakarta.transaction.Transactional;
65
import java.util.ArrayList;
@@ -78,6 +77,32 @@ public void deleteAssessments(
7877
opaSessionRepository.findAll(buildQuerySpecification(Example.of(example), names)));
7978
}
8079

80+
/**
81+
* Deletes a checkpoint from an assessment.
82+
*
83+
* @param assessmentId the ID of the assessment to delete the checkpoint from
84+
* @throws ApplicationException if the checkpoint with the specified ID
85+
* does not exist.
86+
*/
87+
public void deleteCheckpoint(
88+
final Long assessmentId) {
89+
90+
opaSessionRepository.findById(assessmentId)
91+
.ifPresentOrElse(
92+
assessment -> {
93+
assessment.getCheckpoint().setOpaSession(null);
94+
assessment.setCheckpoint(null);
95+
opaSessionRepository.save(assessment);
96+
}, () -> {
97+
throw new ApplicationException(
98+
String.format("Assessment checkpoint with id: %s not found", assessmentId),
99+
HttpStatus.NOT_FOUND);
100+
}
101+
);
102+
}
103+
104+
105+
81106
/**
82107
* Updates an assessment's details in the database.
83108
*
@@ -106,7 +131,7 @@ public void updateAssessment(
106131
* @param names a list of names to include in the query; may be null or empty.
107132
* @return the Specification object that constructs the predicate for querying.
108133
*/
109-
private Specification<OpaSession> buildQuerySpecification(
134+
protected Specification<OpaSession> buildQuerySpecification(
110135
final Example<OpaSession> assessment,
111136
final List<String> names) {
112137
return (root, query, builder) -> {

assessment-service/src/test/java/uk/gov/laa/ccms/caab/assessment/controller/AssessmentControllerTest.java

+14
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import static org.mockito.Mockito.when;
55
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
66
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
7+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
78
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
89
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
910

11+
import com.fasterxml.jackson.databind.ObjectMapper;
1012
import java.util.ArrayList;
1113
import java.util.List;
1214
import org.junit.jupiter.api.Test;
@@ -20,6 +22,7 @@
2022
import uk.gov.laa.ccms.caab.assessment.exception.ApplicationException;
2123
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetail;
2224
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetails;
25+
import uk.gov.laa.ccms.caab.assessment.model.PatchAssessmentDetail;
2326
import uk.gov.laa.ccms.caab.assessment.service.AssessmentService;
2427

2528
@WebMvcTest(AssessmentController.class)
@@ -138,4 +141,15 @@ public void deleteAssessments_returnsNoContentWhenNoMatchingAssessments() throws
138141
verify(assessmentService).deleteAssessments(criteria, names);
139142
}
140143

144+
@Test
145+
public void deleteAssessmentCheckpoint_returnsNoContent_whenCheckpointExists() throws Exception {
146+
Long assessmentId = 1L;
147+
148+
this.mockMvc.perform(delete("/assessments/{assessment-id}/checkpoint", assessmentId)
149+
.header("caab-User-Login-Id", "TestUser"))
150+
.andExpect(status().isNoContent());
151+
152+
verify(assessmentService).deleteCheckpoint(assessmentId);
153+
}
154+
141155
}

assessment-service/src/test/java/uk/gov/laa/ccms/caab/assessment/mapper/AssessmentMapperTest.java

+23
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import static org.junit.jupiter.api.Assertions.assertNotNull;
55
import static org.junit.jupiter.api.Assertions.assertNull;
66
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
import static org.mockito.Mockito.mock;
8+
import static org.mockito.Mockito.when;
79

810
import java.util.ArrayList;
911
import java.util.Arrays;
@@ -17,12 +19,14 @@
1719
import org.mockito.Mock;
1820
import org.mockito.junit.jupiter.MockitoExtension;
1921
import uk.gov.laa.ccms.caab.assessment.entity.OpaAttribute;
22+
import uk.gov.laa.ccms.caab.assessment.entity.OpaCheckpoint;
2023
import uk.gov.laa.ccms.caab.assessment.entity.OpaEntity;
2124
import uk.gov.laa.ccms.caab.assessment.entity.OpaListEntity;
2225
import uk.gov.laa.ccms.caab.assessment.entity.OpaRelationship;
2326
import uk.gov.laa.ccms.caab.assessment.entity.OpaRelationshipTarget;
2427
import uk.gov.laa.ccms.caab.assessment.entity.OpaSession;
2528
import uk.gov.laa.ccms.caab.assessment.model.AssessmentAttributeDetail;
29+
import uk.gov.laa.ccms.caab.assessment.model.AssessmentCheckpointDetail;
2630
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetail;
2731
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetails;
2832
import uk.gov.laa.ccms.caab.assessment.model.AssessmentEntityDetail;
@@ -357,6 +361,25 @@ void mapIntoOpaSession_WithPartialDetail_MapsNonNullFields() {
357361
assertNull(opaSession.getStatus());
358362
}
359363

364+
@Test
365+
void opaCheckpointToAssessmentCheckpointDetail_returnsNull_whenOpaCheckpointIsNull() {
366+
AssessmentCheckpointDetail result = assessmentMapper.opaCheckpointToAssessmentCheckpointDetail(null);
367+
assertNull(result);
368+
}
369+
370+
@Test
371+
void opaCheckpointToAssessmentCheckpointDetail_returnsAssessmentCheckpointDetail_whenOpaCheckpointIsNotNull() {
372+
OpaCheckpoint opaCheckpoint = mock(OpaCheckpoint.class);
373+
when(opaCheckpoint.getUsername()).thenReturn("testUser");
374+
when(opaCheckpoint.getInterviewData()).thenReturn(new byte[0]);
375+
376+
AssessmentCheckpointDetail result = assessmentMapper.opaCheckpointToAssessmentCheckpointDetail(opaCheckpoint);
377+
378+
assertNotNull(result);
379+
assertEquals("testUser", result.getUsername());
380+
assertEquals("", result.getInterviewData());
381+
}
382+
360383

361384

362385
}

0 commit comments

Comments
 (0)