Skip to content

Commit

Permalink
Merge pull request #266 from bcgov/feature/activationValidation
Browse files Browse the repository at this point in the history
Moving validation to payload validator
  • Loading branch information
trev-dev authored Oct 26, 2023
2 parents 647f6c9 + 49f5c79 commit 92f6b6d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public EdxSagaController(EdxActivationCodeSagaDataPayloadValidator edxActivation

@Override
public ResponseEntity<String> edxSchoolUserActivationInvite(EdxUserSchoolActivationInviteSagaData edxUserActivationInviteSagaData) {
validatePayload(() -> getEdxActivationCodeSagaDataPayLoadValidator().validateEdxActivationCodeSagaDataPayload(edxUserActivationInviteSagaData));
validatePayload(() -> getEdxActivationCodeSagaDataPayLoadValidator().validateEdxSchoolUserActivationCodeSagaDataPayload(edxUserActivationInviteSagaData));
RequestUtil.setAuditColumnsForCreate(edxUserActivationInviteSagaData);
return this.processEdxSchoolUserActivationLinkSaga(EDX_SCHOOL_USER_ACTIVATION_INVITE_SAGA, edxUserActivationInviteSagaData);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Null;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;

import jakarta.validation.constraints.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -21,25 +23,19 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class EdxUserSchoolActivationInviteSagaData extends BaseRequest implements Serializable {
private static final long serialVersionUID = -7847063658732692951L;
@NotNull(message = "schoolID cannot be null")
UUID schoolID;

@NotNull(message = "School Name cannot be null")
String schoolName;

@NotEmpty(message = "Activation Roles cannot be null or empty")

private List<String> edxActivationRoleCodes;

@Size(max = 255)
@NotNull(message = "First Name cannot be null")
String firstName;

@Size(max = 255)
@NotNull(message = "Last Name cannot be null")
String lastName;

@Size(max = 255)
@NotNull(message = "Email cannot be null")
@Email(message = "Email address should be a valid email address")
String email;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,68 @@ public class EdxActivationCodeSagaDataPayloadValidator {
private static final String EDX_ACTIVATION_ROLE_CODE = "edxActivationRoleCode";
private final ApplicationProperties props;

public static final String DISTRICT_ID = "districtID";
public static final String DISTRICT_NAME = "districtName";

public static final String SCHOOL_ID = "schoolID";
public static final String SCHOOL_NAME = "schoolName";
public static final String FIRST_NAME = "firstName";
public static final String LAST_NAME = "lastName";
public static final String EMAIL = "email";

public EdxActivationCodeSagaDataPayloadValidator(EdxRoleRepository edxRoleRepository, ApplicationProperties props) {
this.edxRoleRepository = edxRoleRepository;
this.props = props;
}

public List<FieldError> validateEdxActivationCodeSagaDataPayload(EdxUserSchoolActivationInviteSagaData edxUserActivationInviteSagaData) {
return new ArrayList<>(validateEdxActivationCodes(edxUserActivationInviteSagaData.getEdxActivationRoleCodes()));
public List<FieldError> validateEdxSchoolUserActivationCodeSagaDataPayload(EdxUserSchoolActivationInviteSagaData edxUserActivationInviteSagaData) {
final List<FieldError> apiValidationErrors = new ArrayList<>();
apiValidationErrors.addAll(validatePayload(edxUserActivationInviteSagaData));
apiValidationErrors.addAll(validateEdxActivationCodes(edxUserActivationInviteSagaData.getEdxActivationRoleCodes()));
return apiValidationErrors;
}

public List<FieldError> validateDistrictUserEdxActivationCodeSagaDataPayload(EdxUserDistrictActivationInviteSagaData edxDistrictUserActivationInviteSagaData) {
return new ArrayList<>(validateEdxActivationCodes(edxDistrictUserActivationInviteSagaData.getEdxActivationRoleCodes()));
}

public List<FieldError> validatePayload(EdxUserSchoolActivationInviteSagaData edxUserSchoolActivationInviteSagaData) {
final List<FieldError> apiValidationErrors = new ArrayList<>();

if(edxUserSchoolActivationInviteSagaData.getSchoolID() == null) {
apiValidationErrors.add(createFieldError(SCHOOL_ID, edxUserSchoolActivationInviteSagaData.getSchoolID(), "School ID cannot be null"));
}

if(edxUserSchoolActivationInviteSagaData.getSchoolName() == null) {
apiValidationErrors.add(createFieldError(SCHOOL_NAME, edxUserSchoolActivationInviteSagaData.getSchoolName(), "School Name cannot be null"));
}

if(edxUserSchoolActivationInviteSagaData.getFirstName() == null) {
apiValidationErrors.add(createFieldError(FIRST_NAME, edxUserSchoolActivationInviteSagaData.getFirstName(), "First Name cannot be null"));
}

if(edxUserSchoolActivationInviteSagaData.getLastName() == null) {
apiValidationErrors.add(createFieldError(LAST_NAME, edxUserSchoolActivationInviteSagaData.getLastName(), "Last Name cannot be null"));
}

if(edxUserSchoolActivationInviteSagaData.getEmail() == null) {
apiValidationErrors.add(createFieldError(EMAIL, edxUserSchoolActivationInviteSagaData.getEmail(), "Email cannot be null"));
}

return apiValidationErrors;
}


private List<FieldError> validateEdxActivationCodes(List<String> roles) {
final List<FieldError> apiValidationErrors = new ArrayList<>();
for(var role: roles) {
if (!props.getAllowRolesList().contains(role)) {
apiValidationErrors.add(createFieldError(EDX_ACTIVATION_ROLE_CODE, role, "edxActivationRoleCode is not valid according to the allow list."));
break;
if(roles.isEmpty()){
apiValidationErrors.add(createFieldError(EDX_ACTIVATION_ROLE_CODE, null, "Roles list cannot be empty."));
}else {
for (var role : roles) {
if (!props.getAllowRolesList().contains(role)) {
apiValidationErrors.add(createFieldError(EDX_ACTIVATION_ROLE_CODE, role, "edxActivationRoleCode is not valid according to the allow list."));
break;
}
}
}
return apiValidationErrors;
Expand All @@ -51,7 +94,7 @@ public List<FieldError> validateEdxActivationCodeRelinkSchoolSagaDataPayload(Edx
if(StringUtils.isBlank(edxUserActivationRelinkSagaData.getEdxUserId())){
apiValidationErrors.add(createFieldError("edxUserID", edxUserActivationRelinkSagaData.getEdxUserId(), "EDX User ID must be provided for re-link"));
}
apiValidationErrors.addAll(validateEdxActivationCodeSagaDataPayload(edxUserActivationRelinkSagaData));
apiValidationErrors.addAll(validateEdxSchoolUserActivationCodeSagaDataPayload(edxUserActivationRelinkSagaData));
return apiValidationErrors;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void testEdxSchoolUserActivationInvite_GivenInputWithMissingLastNameRequiredFiel
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("Last Name cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -148,7 +148,7 @@ void testEdxSchoolUserActivationInvite_GivenInputWithMissingFirstNameRequiredFie
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("First Name cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -163,7 +163,7 @@ void testEdxSchoolUserActivationInvite_GivenInputWithMissingEmailRequiredField_S
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("Email cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -178,7 +178,7 @@ void testEdxSchoolUserActivationInvite_GivenInputWithMissingSchoolNameRequiredFi
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("School Name cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -193,8 +193,8 @@ void testEdxSchoolUserActivationInvite_GivenInputWithMissingSchoolIDRequiredFiel
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.subErrors[0].message", is("schoolID cannot be null")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("School ID cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}

Expand All @@ -208,8 +208,8 @@ void testEdxSchoolUserActivationInvite_GivenInputWithMissingRoleIdsRequiredField
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.subErrors[0].message", is("Activation Roles cannot be null or empty")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("Roles list cannot be empty.")))
.andDo(print()).andExpect(status().isBadRequest());
}

Expand Down Expand Up @@ -264,7 +264,7 @@ void testEdxSchoolUserActivationRelink_GivenInputWithMissingLastNameRequiredFiel
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("Last Name cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -279,7 +279,7 @@ void testEdxSchoolUserActivationRelink_GivenInputWithMissingFirstNameRequiredFie
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("First Name cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -294,7 +294,7 @@ void testEdxSchoolUserActivationRelink_GivenInputWithMissingEmailRequiredField_S
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("Email cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -309,7 +309,7 @@ void testEdxSchoolUserActivationRelink_GivenInputWithMissingSchoolNameRequiredFi
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("School Name cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}
Expand All @@ -324,8 +324,8 @@ void testEdxSchoolUserActivationRelink_GivenInputWithMissingSchoolIDRequiredFiel
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.subErrors[0].message", is("schoolID cannot be null")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("School ID cannot be null")))
.andDo(print()).andExpect(status().isBadRequest());
}

Expand All @@ -339,8 +339,8 @@ void testEdxSchoolUserActivationRelink_GivenInputWithMissingRoleIdsRequiredField
.content(jsonString)
.accept(MediaType.APPLICATION_JSON)
.with(jwt().jwt((jwt) -> jwt.claim("scope", "SCHOOL_USER_ACTIVATION_INVITE_SAGA"))))
.andExpect(jsonPath("$.message", is("Validation error")))
.andExpect(jsonPath("$.subErrors[0].message", is("Activation Roles cannot be null or empty")))
.andExpect(jsonPath("$.message", is("Payload contains invalid data.")))
.andExpect(jsonPath("$.subErrors[0].message", is("Roles list cannot be empty.")))
.andDo(print()).andExpect(status().isBadRequest());
}

Expand Down

0 comments on commit 92f6b6d

Please sign in to comment.