Skip to content

Commit

Permalink
Merge pull request #42 from bcgov/feature/AddRemoveAssessment
Browse files Browse the repository at this point in the history
Adds endpoints for update and delete assessments
  • Loading branch information
arcshiftsolutions authored Nov 5, 2024
2 parents 4432b86 + c0764ec commit 9157e90
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ private URL(){

public static final String BASE_URL= "/api/v1/eas";
public static final String PAGINATED="/paginated";

public static final String BASE_URL_STUDENT = BASE_URL + "/student";
public static final String SESSIONS_URL = BASE_URL + "/sessions";
public static final String ASSESSMENTS_URL = BASE_URL + "/assessments";


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ca.bc.gov.educ.eas.api.controller.v1;

import ca.bc.gov.educ.eas.api.endpoint.v1.AssessmentEndpoint;
import ca.bc.gov.educ.eas.api.mappers.v1.AssessmentMapper;
import ca.bc.gov.educ.eas.api.service.v1.AssessmentService;
import ca.bc.gov.educ.eas.api.struct.v1.Assessment;
import ca.bc.gov.educ.eas.api.util.RequestUtil;
import ca.bc.gov.educ.eas.api.util.ValidationUtil;
import ca.bc.gov.educ.eas.api.validator.AssessmentValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
public class AssessmentController implements AssessmentEndpoint {

private final AssessmentService assessmentService;
private final AssessmentValidator validator;
private static final AssessmentMapper mapper = AssessmentMapper.mapper;

@Autowired
public AssessmentController(AssessmentService assessmentService, AssessmentValidator assessmentValidator) {
this.assessmentService = assessmentService;
this.validator = assessmentValidator;
}

@Override
public Assessment updateAssessment(UUID assessmentID, Assessment assessment) {
ValidationUtil.validatePayload(() -> validator.validatePayload(assessment));
RequestUtil.setAuditColumnsForUpdate(assessment);
return mapper.toStructure(assessmentService.updateAssessment(mapper.toEntity(assessment)));
}

@Override
public ResponseEntity<Void> deleteAssessment(UUID assessmentID){
this.assessmentService.deleteAssessment(assessmentID);
return ResponseEntity.noContent().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ca.bc.gov.educ.eas.api.endpoint.v1;

import ca.bc.gov.educ.eas.api.constants.v1.URL;
import ca.bc.gov.educ.eas.api.struct.v1.Assessment;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.UUID;

import static org.springframework.http.HttpStatus.NO_CONTENT;

@RequestMapping(URL.ASSESSMENTS_URL)
public interface AssessmentEndpoint {
@PreAuthorize("hasAuthority('SCOPE_WRITE_EAS_SESSIONS')")
@PutMapping("/{assessmentID}")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "BAD REQUEST"), @ApiResponse(responseCode = "404", description = "NOT FOUND")})
@Tag(name = "Assessment Entity", description = "Endpoints for assessment entity.")
Assessment updateAssessment(@PathVariable UUID assessmentID, @Validated @RequestBody Assessment assessment);

@PreAuthorize("hasAuthority('SCOPE_WRITE_EAS_SESSIONS')")
@DeleteMapping("/{assessmentID}")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "NO CONTENT"), @ApiResponse(responseCode = "404", description = "NOT FOUND")})
@Tag(name = "Assessment Entity", description = "Endpoints for assessment entity.")
@Schema(name = "Assessment", implementation = Assessment.class)
@ResponseStatus(NO_CONTENT)
ResponseEntity<Void> deleteAssessment(@PathVariable UUID assessmentID);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;
import java.util.UUID;

@Repository
public interface AssessmentTypeCodeRepository extends JpaRepository<AssessmentTypeCodeEntity, UUID> {
Optional<AssessmentTypeCodeEntity> findByAssessmentTypeCode(String assessmentTypeCode);

}
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
package ca.bc.gov.educ.eas.api.service.v1;

import ca.bc.gov.educ.eas.api.exception.EntityNotFoundException;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentEntity;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentRepository;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentCriteriaRepository;
import lombok.AccessLevel;
import lombok.Getter;
import ca.bc.gov.educ.eas.api.util.TransformUtil;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;
import java.util.UUID;

@Service
@Slf4j
@RequiredArgsConstructor
public class AssessmentService {

@Getter(AccessLevel.PRIVATE)
private final AssessmentRepository assessmentRepository;

@Getter(AccessLevel.PRIVATE)
private final AssessmentCriteriaRepository assessmentCriteriaRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public AssessmentEntity updateAssessment(AssessmentEntity assessmentEntity){
AssessmentEntity currentAssessmentEntity = assessmentRepository.findById(assessmentEntity.getAssessmentID()).orElseThrow(() ->
new EntityNotFoundException(AssessmentEntity.class, "Assessment", assessmentEntity.getAssessmentID().toString())
);
BeanUtils.copyProperties(assessmentEntity, currentAssessmentEntity, "assessmentEntity", "createUser", "createDate", "assessmentStudentStatusCode");
TransformUtil.uppercaseFields(currentAssessmentEntity);
return assessmentRepository.save(assessmentEntity);

}

@Autowired
public AssessmentService(AssessmentRepository assessmentRepository, AssessmentCriteriaRepository assessmentCriteriaRepository) {
this.assessmentRepository = assessmentRepository;
this.assessmentCriteriaRepository = assessmentCriteriaRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void deleteAssessment(UUID assessmentID) {
Optional<AssessmentEntity> assessmentOptionalEntity = assessmentRepository.findById(assessmentID);
AssessmentEntity assessmentEntity = assessmentOptionalEntity.orElseThrow(() -> new EntityNotFoundException(AssessmentEntity.class, "assessmentID", assessmentID.toString()));
assessmentRepository.delete(assessmentEntity);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ca.bc.gov.educ.eas.api.validator;

import ca.bc.gov.educ.eas.api.model.v1.AssessmentEntity;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentTypeCodeEntity;
import ca.bc.gov.educ.eas.api.model.v1.SessionEntity;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentRepository;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentTypeCodeRepository;
import ca.bc.gov.educ.eas.api.repository.v1.SessionRepository;
import ca.bc.gov.educ.eas.api.struct.v1.Assessment;
import ca.bc.gov.educ.eas.api.util.ValidationUtil;
import lombok.AccessLevel;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.FieldError;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;


@Component
public class AssessmentValidator {

public static final String ASSESSMENT = "assessment";

@Getter(AccessLevel.PRIVATE)
private final AssessmentRepository assessmentRepository;

@Getter(AccessLevel.PRIVATE)
private final AssessmentTypeCodeRepository assessmentTypeCodeRepository;

@Getter(AccessLevel.PRIVATE)
private final SessionRepository sessionRepository;

private static final String ASSESSMENT_ID = "assessmentID";

@Autowired
AssessmentValidator(AssessmentRepository assessmentRepository, AssessmentTypeCodeRepository assessmentTypeCodeRepository, SessionRepository sessionRepository) {

this.assessmentRepository = assessmentRepository;
this.assessmentTypeCodeRepository = assessmentTypeCodeRepository;
this.sessionRepository = sessionRepository;
}

public List<FieldError> validatePayload(Assessment assessment) {
final List<FieldError> apiValidationErrors = new ArrayList<>();

Optional<SessionEntity> sessionEntity = sessionRepository.findById(UUID.fromString(assessment.getSessionID()));
if(sessionEntity.isEmpty()){
apiValidationErrors.add(ValidationUtil.createFieldError(ASSESSMENT, "sessionID", assessment.getSessionID(), "Invalid session ID."));
}

Optional<AssessmentTypeCodeEntity> assessmentTypeCodeEntity = assessmentTypeCodeRepository.findByAssessmentTypeCode(assessment.getAssessmentTypeCode());
if (assessmentTypeCodeEntity.isEmpty() || (sessionEntity.isPresent() && assessmentTypeCodeEntity.get().getExpiryDate().isBefore(sessionEntity.get().getActiveUntilDate())) || (sessionEntity.isPresent() && assessmentTypeCodeEntity.get().getEffectiveDate().isAfter(sessionEntity.get().getActiveUntilDate()))){
apiValidationErrors.add(ValidationUtil.createFieldError(ASSESSMENT, "assessmentTypeCode", assessment.getAssessmentTypeCode(), "Invalid assessment type code."));
}

if (StringUtils.isEmpty(assessment.getAssessmentID())) {
apiValidationErrors.add(ValidationUtil.createFieldError(ASSESSMENT, ASSESSMENT_ID, null, "Assessment ID cannot be null for put operation."));
}

Optional<AssessmentEntity> assessmentEntity = assessmentRepository.findById(UUID.fromString(assessment.getAssessmentID()));
if (assessmentEntity.isEmpty()) {
apiValidationErrors.add(ValidationUtil.createFieldError(ASSESSMENT, ASSESSMENT_ID, assessment.getAssessmentID(), "Invalid assessment ID."));
}

return apiValidationErrors;
}

}
16 changes: 14 additions & 2 deletions api/src/test/java/ca/bc/gov/educ/eas/api/BaseEasAPITest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package ca.bc.gov.educ.eas.api;

import ca.bc.gov.educ.eas.api.constants.v1.AssessmentStudentStatusCodes;
import ca.bc.gov.educ.eas.api.constants.v1.AssessmentTypeCodes;
import ca.bc.gov.educ.eas.api.model.v1.*;
import ca.bc.gov.educ.eas.api.properties.ApplicationProperties;
import ca.bc.gov.educ.eas.api.struct.external.institute.v1.*;
import ca.bc.gov.educ.eas.api.struct.v1.Assessment;
import ca.bc.gov.educ.eas.api.struct.v1.AssessmentStudent;
import ca.bc.gov.educ.eas.api.struct.v1.AssessmentStudentGet;
import ca.bc.gov.educ.eas.api.struct.v1.Session;
Expand Down Expand Up @@ -111,8 +113,8 @@ public AssessmentTypeCodeEntity createMockAssessmentTypeCodeEntity(String assess
.label(assessmentTypeCode)
.description("This is a test code for assessment type.")
.displayOrder(1)
.effectiveDate(LocalDateTime.now())
.expiryDate(LocalDateTime.now().plusYears(1))
.effectiveDate(LocalDateTime.now().minusYears(10))
.expiryDate(LocalDateTime.now().plusYears(10))
.language("EN")
.createUser("TEST-USER")
.createDate(LocalDateTime.now())
Expand Down Expand Up @@ -145,6 +147,16 @@ public Set<AssessmentCriteriaEntity> createMockAssessmentSessionTypeCodeCriteria
return typeCodeCriteriaEntities;
}

public Assessment createMockAssessment() {
return Assessment.builder()
.assessmentID(UUID.randomUUID().toString())
.sessionID(UUID.randomUUID().toString())
.assessmentTypeCode(AssessmentTypeCodes.LTF12.getCode())
.createUser(ApplicationProperties.EAS_API)
.updateUser(ApplicationProperties.EAS_API)
.build();
}

public AssessmentStudent createMockStudent() {
return AssessmentStudent.builder()
.assessmentStudentID(UUID.randomUUID().toString())
Expand Down
Loading

0 comments on commit 9157e90

Please sign in to comment.