Skip to content

Commit

Permalink
feat(FSADT1-1384): Submit data to create client by staff user (#1050)
Browse files Browse the repository at this point in the history
* fix: removing clientNumber from submitted

* chore: reworked the app startup to consider route init

wrapped the app to the router initialization, to make sure the router is ready before the application starts

* chore: refactored stubs

* chore: removed unsuded param from wiremock

* feat(FSADT1-1384): simplified confirmation data

* chore: removing unnecessary constants

* feat(FSADT1-1384): added processing info on review page

* chore: updating stubs

* fix(FSADT1-1384): update be to send submission id

* feat(FSADT1-1384): added staff processing route

* feat(FSADT1-1384): added loading overlay

* feat(FSADT1-1384): updating processing page

* test: fixex test due to constant removed

* test(FSADT1-1384): tests added to new components and pages

* feat(FSADT1-1384): updated form staff for submission

* Update SubmissionReviewPage.vue

* test(FSADT1-1384): test review page with refresh for staff

* test(FSADT1-1384): added tests to staff submission

* chore: set label class for readonly input text

* fix: fixed other id layout

* test: updated tests

* test: fixing data

* text: fixing test

* test: updating cypress tests for frontend

* chore: removing tests for now

* chore: updated files

* test: adding delay before check

* chore: ignoring report path for vite

---------

Co-authored-by: Maria Martinez <[email protected]>
  • Loading branch information
paulushcgcj and mamartinezmejia committed Aug 16, 2024
1 parent d878946 commit 16cac23
Show file tree
Hide file tree
Showing 63 changed files with 1,902 additions and 4,653 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private Mono<ServerResponse> renderErrorResponse(
}

if (exception instanceof DataMatchException matchException) {
log.error("Found matches: {}",matchException.getMatches());
log.error("Found matches: {}", matchException.getMatches());
return ServerResponse
.status(matchException.getStatusCode())
.contentType(MediaType.APPLICATION_JSON)
Expand All @@ -124,10 +124,14 @@ private Mono<ServerResponse> renderErrorResponse(
if (exception instanceof IllegalStateException e) {

if (e.getCause() instanceof SubmissionNotCompletedException notCompletedException) {
log.error("Submission is still ongoing: {}",notCompletedException.getReason());
log.error("Submission is still ongoing: {}", notCompletedException.getReason());
return ServerResponse.status(notCompletedException.getStatusCode())
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(Objects.requireNonNull(notCompletedException.getReason())));
.header("x-sub-id", notCompletedException.getSubmissionId().toString())
.header("Location",
"/api/clients/submissions/" + notCompletedException.getSubmissionId())
.body(
BodyInserters.fromValue(Objects.requireNonNull(notCompletedException.getReason())));
}
log.error("Request encountered an illegal state", exception);
return ServerResponse.status(HttpStatus.REQUEST_TIMEOUT)
Expand All @@ -151,7 +155,7 @@ private Mono<ServerResponse> renderErrorResponse(
BooleanUtils.toString(StringUtils.isBlank(errorMessage), StringUtils.EMPTY, errorMessage);

// Log the error status and message
log.error("{} - {}", errorStatus, errorMessage,exception);
log.error("{} - {}", errorStatus, errorMessage, exception);

// Return a response with the status code and error message
return ServerResponse.status(errorStatus)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package ca.bc.gov.app.exception;

import lombok.Getter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.server.ResponseStatusException;

@Getter
@ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
public class SubmissionNotCompletedException extends ResponseStatusException {

private final Integer submissionId;

public SubmissionNotCompletedException(Integer submissionId) {
super(
HttpStatus.REQUEST_TIMEOUT,
String.format("Submission %d is still being processed", submissionId)
);
this.submissionId = submissionId;
}
}
1 change: 1 addition & 0 deletions frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ declare module 'vue' {
DateInputPart: typeof import('./src/components/forms/DateInputComponent/DateInputPart.vue')['default']
DropdownInputComponent: typeof import('./src/components/forms/DropdownInputComponent.vue')['default']
ErrorNotificationGroupingComponent: typeof import('./src/components/grouping/ErrorNotificationGroupingComponent.vue')['default']
LoadingOverlayComponent: typeof import('./src/components/LoadingOverlayComponent.vue')['default']
MainHeaderComponent: typeof import('./src/components/MainHeaderComponent.vue')['default']
MultiselectInputComponent: typeof import('./src/components/forms/MultiselectInputComponent.vue')['default']
RadioInputComponent: typeof import('./src/components/forms/RadioInputComponent.vue')['default']
Expand Down
226 changes: 226 additions & 0 deletions frontend/cypress/e2e/FormStaffPage.Submission.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/* eslint-disable no-undef */
describe("Staff Form Submission", () => {

/* Test variables and functions */
const API_BASE = "http://localhost:8080/api";

const fillIndividual = (extraData : any = {}) => {

cy.fixture("testdata/individualBaseData").then((fixtureData: any) => {

const data = {...fixtureData, ...extraData};

cy.get("#clientType").should("be.visible").and("have.value", "");
cy.selectFormEntry("#clientType", "Individual", false);
cy.fillFormEntry("#firstName", data.firstName);
cy.fillFormEntry("#middleName", data.middleName);
cy.fillFormEntry("#lastName", data.lastName);
cy.selectFormEntry("#identificationType", data.identificationTypeValue,false);
cy.wait(200);

if (data.identificationProvinceValue) {
cy.selectFormEntry("#identificationProvince", data.identificationProvinceValue,false);
cy.wait(200);
}

cy.fillFormEntry("#clientIdentification", data.clientIdentification);
cy.fillFormEntry("#birthdateYear", data.birthdateYear);
cy.fillFormEntry("#birthdateMonth", data.birthdateMonth);
cy.fillFormEntry("#birthdateDay", data.birthdateDay);
});


};

const fillLocation = (extraData : any = {}) => {
cy.fixture("testdata/locationBaseData").then((fixtureData: any) => {
const data = {...fixtureData, ...extraData};

cy.fillFormEntry("#name_0", data.name_0, 0);
cy.selectAutocompleteEntry("#addr_0", data.addr_0,data.postal_0);
cy.wait("@getAddressValue");
});
};

const fillContact = (extraData : any = {}) => {
cy.fixture("testdata/contactBaseData").then((fixtureData: any) => {
const data = {...fixtureData, ...extraData};
cy.fillFormEntry("#emailAddress_0", data.mail);
cy.fillFormEntry("#businessPhoneNumber_0", data.phone1);
cy.fillFormEntry("#secondaryPhoneNumber_0", data.phone2);
cy.fillFormEntry("#faxNumber_0", data.fax);
cy.wait("@getRoles");
cy.selectFormEntry("#role_0", data.role, false);
cy.selectFormEntry("#addressname_0", data.address, true);
});
};

const clickNext = () => {
cy.get("[data-test='wizard-next-button']")
.shadow()
.find("button")
.should("be.enabled");
cy.get("[data-test='wizard-next-button']").click();
};

beforeEach(function() {
cy.viewport(1920, 1080);

cy.intercept("GET", `${API_BASE}/clients/submissions?page=0&size=10`,{
fixture: "submissions.json",
headers:{
"x-total-count": "1",
"content-type": "application/json;charset=UTF-8",
"Access-Control-Expose-Headers": "x-total-count"
}
}).as("getSubmissions");

cy.intercept("GET", `${API_BASE}/codes/identification-types`,{
fixture: "identificationTypes.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getIdentificationTypes");

cy.intercept("GET", `${API_BASE}/codes/countries?page=0&size=250`,{
fixture: "countries.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getCountries");

cy.intercept("GET", `${API_BASE}/codes/countries/CA/provinces?page=0&size=250`,{
fixture: "provinces.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getProvinces");

cy.intercept("GET", `${API_BASE}/addresses?country=CA&maxSuggestions=10&searchTerm=297`,{
fixture: "addressSearch.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getAddressAutoComplete");

cy.intercept("GET", `${API_BASE}/addresses?country=CA&maxSuggestions=10&searchTerm=2975%20Jutland%20Rd%20Victoria,%20BC,%20V8T%205J9`,{
fixture: "addressSearch.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getAddressAutoCompleteSelect1");

cy.intercept("GET", `${API_BASE}/addresses?country=CA&maxSuggestions=10&searchTerm=2975%20Jutland%20Rd`,{
fixture: "addressSearch.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getAddressAutoCompleteSelect2");

cy.intercept("GET", `${API_BASE}/addresses/V8T5J9`,{
fixture: "address.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getAddressValue");

cy.intercept("GET", `${API_BASE}/codes/contact-types?page=0&size=250`,{
fixture: "roles.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getRoles");

cy.intercept("GET", `${API_BASE}/codes/client-types/I`,{
fixture: "clientTypeIndividual.json",
headers:{
"content-type": "application/json;charset=UTF-8"
}
}).as("getClientType");

const testSubmissionFixture = this.currentTest.title.replace("should be ", "").replaceAll(" ", "-");

cy.fixture(`staffSubmit/${testSubmissionFixture}`).then((fixtureData: any) => {
cy.intercept("POST", "/api/clients/submissions/staff", fixtureData).as("submitForm");
});

cy.visit("/");

cy.get("#landing-title").should(
"contain",
"Forests Client Management System"
);

cy.get("#landing-subtitle").should(
"contain",
"Create and manage client accounts"
);

cy.login("[email protected]", "Uat Test", "idir", {
given_name: "James",
family_name: "Baxter",
"cognito:groups": ["CLIENT_ADMIN"],
});

cy.wait("@getSubmissions");

// Check if the Create client button is visible
cy.get("#menu-list-staff-form").should("be.visible").click();

cy.get("h1").should("be.visible").should("contain", " Create client ");

});

it("should be success message", () => {
fillIndividual();
clickNext();
fillLocation();
clickNext();
fillContact();
clickNext();

cy.get("[data-test='wizard-submit-button']").click();
cy.get("h1").should("contain", "New client 00123456 has been created!");
});

it("should be timeout message", () => {
fillIndividual();
clickNext();
fillLocation();
clickNext();
fillContact();
clickNext();

cy.fillFormEntry("cds-textarea","error",10,true);

cy.get("[data-test='wizard-submit-button']").click();
cy.wait("@submitForm").then((interception) => {
cy.wait(5000);
cy.get("h1").should("contain", "Submission still being processed!");
cy.get("cds-button[href='/submissions/4444']").should("exist");
});

});

it("should be validation error message", () => {
fillIndividual({
identificationTypeValue: "Canadian passport",
identificationProvinceValue: undefined,
clientIdentification: "AB345678",
});
clickNext();
fillLocation();
clickNext();
fillContact();
clickNext();

cy.get("[data-test='wizard-submit-button']").click();
cy.get("cds-actionable-notification")
.should("be.visible")
.and("have.attr", "kind", "error")
.shadow()
.find("div.cds--actionable-notification__details div.cds--actionable-notification__text-wrapper div.cds--actionable-notification__content div.cds--actionable-notification__title")
.should("contain", "Your application could not be submitted:");
});

});
32 changes: 31 additions & 1 deletion frontend/cypress/e2e/FormStaffPage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,12 @@ describe("Staff Form", () => {
.click()
.and("have.value", "Individual");

fillIndividual();
fillIndividual({
...individualBaseData,
identificationTypeValue: "Canadian driver's licence",
identificationProvinceValue: "Nova Scotia",
clientIdentification: "12345678"
});
cy.get("[data-test='wizard-next-button']").click();

fillLocation();
Expand All @@ -537,6 +542,31 @@ describe("Staff Form", () => {
it("displays the Review section", () => {
cy.contains("h2", "Review");
});

it("should allow notes to be added", () => {
cy.get("cds-textarea")
.shadow()
.find("textarea")
.type("This is a note!");

cy.get("cds-textarea")
.shadow()
.find(".cds--text-area__label-wrapper")
.should("contain", "15/4000");

// Even if I try to add more than 4k characters, it will stop at 4k
cy.get("cds-textarea")
.shadow()
.find("textarea")
.type("A".repeat(4010));

cy.get("cds-textarea")
.shadow()
.find(".cds--text-area__label-wrapper")
.should("contain", "4000/4000");

});

});

});
Expand Down
Loading

0 comments on commit 16cac23

Please sign in to comment.