Skip to content

Commit

Permalink
Story(CCLS-2194) return checkpoint data from get assessment/assessments
Browse files Browse the repository at this point in the history
Also includes:

CCLS-2100 - delete checkpoint endpoint
  • Loading branch information
PhilDigitalJustice committed May 10, 2024
1 parent 5e59ca2 commit 3b06642
Show file tree
Hide file tree
Showing 15 changed files with 270 additions and 5 deletions.
35 changes: 35 additions & 0 deletions assessment-api/open-api-specification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,32 @@ paths:
description: 'Not found'
'500':
description: 'Internal server error'
/assessments/{assessment-id}/checkpoint:
delete:
tags:
- assessments
summary: 'delete checkpoint from assessment'
operationId: 'deleteAssessmentCheckpoint'
parameters:
- name: 'assessment-id'
in: 'path'
required: true
schema:
type: 'integer'
format: 'int64'
example: '1234567890'
- $ref: '#/components/parameters/requiredUserLoginId'
responses:
'204':
description: 'Successful deletion'
'400':
description: 'Bad request'
'401':
description: 'Unauthorized'
'404':
description: 'Not found'
'500':
description: 'Internal server error'

components:
parameters:
Expand Down Expand Up @@ -192,6 +218,8 @@ components:
default: [ ]
items:
$ref: '#/components/schemas/assessmentEntityTypeDetail'
checkpoint:
$ref: '#/components/schemas/assessmentCheckpointDetail'
audit_detail:
$ref: '#/components/schemas/auditDetail'
patchAssessmentDetail:
Expand All @@ -218,6 +246,13 @@ components:
format: 'date'
last_saved_by:
type: 'string'
assessmentCheckpointDetail:
type: 'object'
properties:
username:
type: 'string'
interviewData:
type: 'string'
assessmentEntityTypeDetail:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;

Expand Down Expand Up @@ -32,6 +34,8 @@ public void testGetAssessment_expect200() {
final Long id = 26L;
ResponseEntity<AssessmentDetail> response = assessmentController.getAssessment(id);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
assertNotNull(response.getBody().getCheckpoint());
}

private static Stream<Arguments> getAssessmentsArguments() {
Expand Down Expand Up @@ -151,6 +155,19 @@ public void testPatchAssessments_expect200_empty() {
assertEquals(beforeProviderId, afterProviderId);
assertEquals(beforeEntityTypes, afterEntityTypes);
}
@Test
@Sql(scripts = "/sql/assessments_insert.sql")
public void testDeleteCheckpoint_returns204() {
final Long id = 26L;
ResponseEntity<Void> response = assessmentController.deleteAssessmentCheckpoint(id, "testUser");
assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());

ResponseEntity<AssessmentDetail> assessmentResponse = assessmentController.getAssessment(id);
assertNotNull(assessmentResponse.getBody());
assertNull(assessmentResponse.getBody().getCheckpoint());
}





Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,11 @@ CREATE TABLE XXCCMS_OPA_RELSHIPTARGET (
TARGET_ENTITY_ID VARCHAR2(255 CHAR) NOT NULL,
FK_OPA_RELATIONSHIP NUMBER(19, 0),
PRIMARY KEY (ID)
);

CREATE TABLE XXCCMS_OPA_CHECKPOINT (
RESUME_ID NUMBER(19,0) NOT NULL,
USER_NAME VARCHAR2(255 CHAR),
INTERVIEW_DATA BLOB,
CONSTRAINT PK_OPA_CHECKPOINT PRIMARY KEY (RESUME_ID)
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ DROP TABLE XXCCMS_OPA_RELATIONSHIP;
DROP TABLE XXCCMS_OPA_ATTRIBUTE;
DROP TABLE XXCCMS_OPA_ENTITY;
DROP TABLE XXCCMS_OPA_LISTENTITY;
DROP TABLE XXCCMS_OPA_CHECKPOINT;
DROP TABLE XXCCMS_OPA_SESSION;
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ VALUES (30, 28, 'name1', 1);

-- Insert into XXCCMS_OPA_RELSHIPTARGET
INSERT INTO XXCCMS_OPA_RELSHIPTARGET (ID, TARGET_ENTITY_ID)
VALUES (31, 'entityId1');
VALUES (31, 'entityId1');

INSERT INTO XXCCMS_OPA_CHECKPOINT (RESUME_ID, USER_NAME, INTERVIEW_DATA)
VALUES (26, 'john.doe', hextoraw('48656c6c6f20776f726c64'));


Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ DELETE FROM XXCCMS_OPA_RELATIONSHIP;
DELETE FROM XXCCMS_OPA_ATTRIBUTE;
DELETE FROM XXCCMS_OPA_ENTITY;
DELETE FROM XXCCMS_OPA_LISTENTITY;
DELETE FROM XXCCMS_OPA_SESSION;
DELETE FROM XXCCMS_OPA_CHECKPOINT;
DELETE FROM XXCCMS_OPA_SESSION;
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ public ResponseEntity<AssessmentDetails> getAssessments(
return ResponseEntity.ok(assessmentService.getAssessments(criteria, name));
}

@Override
public ResponseEntity<Void> deleteAssessmentCheckpoint(
final Long assessmentId,
final String caabUserLoginId) {

assessmentService.deleteCheckpoint(assessmentId);

return ResponseEntity.noContent().build();
}

/**
* Deletes assessments based on given criteria and a list of names.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package uk.gov.laa.ccms.caab.assessment.entity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.MapsId;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Data;

/**
* Represents an Oracle Intelligence Advisor Checkpoint.
*/
@Entity
@Table(name = "XXCCMS_OPA_CHECKPOINT")
@Data
public class OpaCheckpoint {

@Id
@Column(name = "RESUME_ID")
private long resumeId;

@Column(name = "USER_NAME")
private String username;

@Column(name = "INTERVIEW_DATA")
@Lob
private byte[] interviewData;

@OneToOne(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@MapsId
@JoinColumn(name = "RESUME_ID")
private OpaSession opaSession;

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import java.util.List;
Expand Down Expand Up @@ -76,11 +77,13 @@ public class OpaSession {
)
private List<OpaListEntity> opaListEntities;

@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "opaSession")
private OpaCheckpoint checkpoint;

/**
* audit trail info.
*/
@Embedded
private AuditTrail auditTrail = new AuditTrail();


}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ public interface AssessmentMapper {
@Mapping(target = "targetId", source = "caseReferenceNumber")
@Mapping(target = "auditTrail", ignore = true)
@Mapping(target = "opaListEntities", ignore = true)
@Mapping(target = "checkpoint", ignore = true)
OpaSession toOpaSession(AssessmentDetail assessmentDetail);

@InheritInverseConfiguration(name = "toOpaSession")
@Mapping(target = "auditDetail", source = "auditTrail")
@Mapping(target = "entityTypes", source = "opaListEntities")
@Mapping(target = "checkpoint", source = "checkpoint")
AssessmentDetail toAssessmentDetail(OpaSession opaSession);

@Mapping(target = "entities", source = "opaEntities")
Expand All @@ -55,6 +57,7 @@ public interface AssessmentMapper {
@Mapping(target = "auditTrail", ignore = true)
@Mapping(target = "opaListEntities", ignore = true)
@Mapping(target = "id", ignore = true)
@Mapping(target = "checkpoint", ignore = true)
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void mapIntoOpaSession(
@MappingTarget OpaSession opaSession,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.laa.ccms.caab.assessment.mapper;

import java.util.Base64;
import org.mapstruct.Mapper;

/**
Expand All @@ -17,5 +18,14 @@ public interface CommonMapper {
default Boolean toBoolean(Boolean flag) {
return flag != null ? flag : Boolean.FALSE;
}


default String toBase64String(byte[] bytes) {
return bytes != null ? Base64.getEncoder().encodeToString(bytes) : null;
}

default byte[] toByteArrayFromBase64EncodedString(String base64EncodedString) {
return Base64.getDecoder().decode(base64EncodedString);
}
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package uk.gov.laa.ccms.caab.assessment.service;

import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.transaction.Transactional;
import java.util.ArrayList;
Expand Down Expand Up @@ -78,6 +77,32 @@ public void deleteAssessments(
opaSessionRepository.findAll(buildQuerySpecification(Example.of(example), names)));
}

/**
* Deletes a checkpoint from an assessment.
*
* @param assessmentId the ID of the assessment to delete the checkpoint from
* @throws ApplicationException if the checkpoint with the specified ID
* does not exist.
*/
public void deleteCheckpoint(
final Long assessmentId) {

opaSessionRepository.findById(assessmentId)
.ifPresentOrElse(
assessment -> {
assessment.getCheckpoint().setOpaSession(null);
assessment.setCheckpoint(null);
opaSessionRepository.save(assessment);
}, () -> {
throw new ApplicationException(
String.format("Assessment checkpoint with id: %s not found", assessmentId),
HttpStatus.NOT_FOUND);
}
);
}



/**
* Updates an assessment's details in the database.
*
Expand Down Expand Up @@ -106,7 +131,7 @@ public void updateAssessment(
* @param names a list of names to include in the query; may be null or empty.
* @return the Specification object that constructs the predicate for querying.
*/
private Specification<OpaSession> buildQuerySpecification(
protected Specification<OpaSession> buildQuerySpecification(
final Example<OpaSession> assessment,
final List<String> names) {
return (root, query, builder) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
Expand All @@ -20,6 +22,7 @@
import uk.gov.laa.ccms.caab.assessment.exception.ApplicationException;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetail;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetails;
import uk.gov.laa.ccms.caab.assessment.model.PatchAssessmentDetail;
import uk.gov.laa.ccms.caab.assessment.service.AssessmentService;

@WebMvcTest(AssessmentController.class)
Expand Down Expand Up @@ -138,4 +141,15 @@ public void deleteAssessments_returnsNoContentWhenNoMatchingAssessments() throws
verify(assessmentService).deleteAssessments(criteria, names);
}

@Test
public void deleteAssessmentCheckpoint_returnsNoContent_whenCheckpointExists() throws Exception {
Long assessmentId = 1L;

this.mockMvc.perform(delete("/assessments/{assessment-id}/checkpoint", assessmentId)
.header("caab-User-Login-Id", "TestUser"))
.andExpect(status().isNoContent());

verify(assessmentService).deleteCheckpoint(assessmentId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -17,12 +19,14 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import uk.gov.laa.ccms.caab.assessment.entity.OpaAttribute;
import uk.gov.laa.ccms.caab.assessment.entity.OpaCheckpoint;
import uk.gov.laa.ccms.caab.assessment.entity.OpaEntity;
import uk.gov.laa.ccms.caab.assessment.entity.OpaListEntity;
import uk.gov.laa.ccms.caab.assessment.entity.OpaRelationship;
import uk.gov.laa.ccms.caab.assessment.entity.OpaRelationshipTarget;
import uk.gov.laa.ccms.caab.assessment.entity.OpaSession;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentAttributeDetail;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentCheckpointDetail;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetail;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentDetails;
import uk.gov.laa.ccms.caab.assessment.model.AssessmentEntityDetail;
Expand Down Expand Up @@ -357,6 +361,25 @@ void mapIntoOpaSession_WithPartialDetail_MapsNonNullFields() {
assertNull(opaSession.getStatus());
}

@Test
void opaCheckpointToAssessmentCheckpointDetail_returnsNull_whenOpaCheckpointIsNull() {
AssessmentCheckpointDetail result = assessmentMapper.opaCheckpointToAssessmentCheckpointDetail(null);
assertNull(result);
}

@Test
void opaCheckpointToAssessmentCheckpointDetail_returnsAssessmentCheckpointDetail_whenOpaCheckpointIsNotNull() {
OpaCheckpoint opaCheckpoint = mock(OpaCheckpoint.class);
when(opaCheckpoint.getUsername()).thenReturn("testUser");
when(opaCheckpoint.getInterviewData()).thenReturn(new byte[0]);

AssessmentCheckpointDetail result = assessmentMapper.opaCheckpointToAssessmentCheckpointDetail(opaCheckpoint);

assertNotNull(result);
assertEquals("testUser", result.getUsername());
assertEquals("", result.getInterviewData());
}



}
Loading

0 comments on commit 3b06642

Please sign in to comment.