Skip to content

Commit

Permalink
feat(wip): Further tidy ups, tests all passing
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr committed Apr 5, 2024
1 parent fb37b31 commit 93fef31
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 182 deletions.
158 changes: 103 additions & 55 deletions editor.planx.uk/src/@planx/components/FileUploadAndLabel/Public.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
act,
findByRole,
fireEvent,
screen,
waitFor,
Expand Down Expand Up @@ -342,7 +343,15 @@ describe("Modal trigger", () => {
describe("Adding tags and syncing state", () => {
test("Can continue when all required file types are uploaded and tagged", async () => {
const handleSubmit = jest.fn();
const { user } = setup(
const {
getAllByRole,
getAllByTestId,
getByRole,
getByTestId,
getByText,
queryByRole,
user,
} = setup(
<FileUploadAndLabelComponent
title="Test title"
handleSubmit={handleSubmit}
Expand All @@ -351,7 +360,7 @@ describe("Adding tags and syncing state", () => {
);

// No file requirements have been satisfied yet
let incompleteIcons = screen.getAllByTestId("incomplete-icon");
let incompleteIcons = getAllByTestId("incomplete-icon");
expect(incompleteIcons).toHaveLength(2);

// Upload one file
Expand All @@ -363,49 +372,67 @@ describe("Adding tags and syncing state", () => {
});

const file1 = new File(["test1"], "test1.png", { type: "image/png" });
const input = screen.getByTestId("upload-input");
const input = getByTestId("upload-input");
await user.upload(input, [file1]);

// Modal opened automatically
const fileTaggingModal = await within(document.body).findByTestId(
"file-tagging-dialog",
);

// The number of selects in the modal matches the number of uploaded files
const selects = await within(document.body).findAllByTestId("select");
expect(selects).toHaveLength(1);
// The number of autocompletes in the modal matches the number of uploaded files
const autocompleteInputs = getAllByRole("combobox", {
name: /What does this file show/,
});
expect(autocompleteInputs).toHaveLength(1);

const submitModalButton = await within(fileTaggingModal).findByText("Done");
const submitModalButton = getByRole("button", { name: /Done/ });
expect(submitModalButton).toBeVisible();

// Apply multiple tags to this file
fireEvent.change(selects[0], { target: { value: "Roof plan" } });
// Autocomplete is close, option unavailable
let roofPlanOption = queryByRole("option", { name: /Roof plan/ });
expect(roofPlanOption).toBeNull();

// Close modal successfully
user.click(submitModalButton);
await waitFor(() => expect(fileTaggingModal).not.toBeVisible());
// Open dropdown
await user.click(autocompleteInputs[0]);
roofPlanOption = getByRole("option", { name: /Roof plan/ });
expect(roofPlanOption).toBeVisible();

// Apply tag to this file
await user.click(roofPlanOption);

// Close modal
await user.click(submitModalButton);
expect(fileTaggingModal).not.toBeVisible();

// Uploaded file displayed as card with chip tags
expect(screen.getByText("test1.png")).toBeVisible();
const chips = screen.getAllByTestId("uploaded-file-chip");
expect(getByText("test1.png")).toBeVisible();
const chips = getAllByTestId("uploaded-file-chip");
expect(chips).toHaveLength(1);
expect(chips[0]).toHaveTextContent("Roof plan");

// Requirements list reflects successfully tagged uploads
const completeIcons = screen.getAllByTestId("complete-icon");
const completeIcons = getAllByTestId("complete-icon");
expect(completeIcons).toHaveLength(1);
incompleteIcons = screen.getAllByTestId("incomplete-icon");
incompleteIcons = getAllByTestId("incomplete-icon");
expect(incompleteIcons).toHaveLength(1);

// "Continue" onto to the next node
expect(screen.getByText("Continue")).toBeEnabled();
await user.click(screen.getByText("Continue"));
expect(getByText("Continue")).toBeEnabled();
await user.click(getByText("Continue"));
expect(handleSubmit).toHaveBeenCalledTimes(1);
});

test("Cannot continue when only an optional file type is uploaded and tagged", async () => {
const handleSubmit = jest.fn();
const { user } = setup(
const {
getAllByRole,
getAllByTestId,
getByTestId,
getByRole,
getByText,
user,
} = setup(
<FileUploadAndLabelComponent
title="Test title"
handleSubmit={handleSubmit}
Expand All @@ -414,7 +441,7 @@ describe("Adding tags and syncing state", () => {
);

// No file requirements have been satisfied yet
let incompleteIcons = screen.getAllByTestId("incomplete-icon");
let incompleteIcons = getAllByTestId("incomplete-icon");
expect(incompleteIcons).toHaveLength(2);

// Upload one file
Expand All @@ -426,40 +453,50 @@ describe("Adding tags and syncing state", () => {
});

const file1 = new File(["test1"], "test1.png", { type: "image/png" });
const input = screen.getByTestId("upload-input");
const input = getByTestId("upload-input");
await user.upload(input, [file1]);

// Modal opened automatically
const fileTaggingModal = await within(document.body).findByTestId(
"file-tagging-dialog",
);

// The number of selects in the modal matches the number of uploaded files
const selects = await within(document.body).findAllByTestId("select");
expect(selects).toHaveLength(1);
// The number of autocompletes in the modal matches the number of uploaded files
const autocompleteInputs = getAllByRole("combobox", {
name: /What does this file show/,
});
expect(autocompleteInputs).toHaveLength(1);

// Apply multiple tags to this file
fireEvent.change(selects[0], { target: { value: "Heritage statement" } });
await user.click(autocompleteInputs[0]);
const heritageStatementOption = getByRole("option", {
name: /Heritage statement/,
});
expect(heritageStatementOption).toBeVisible();

// Apply tag to this file, and close autocomplete dropdown
await user.click(heritageStatementOption);
await user.keyboard("{Esc}");

// Close modal
await user.keyboard("{Esc}");
await waitFor(() => expect(fileTaggingModal).not.toBeVisible());

// Uploaded file displayed as card with chip tags
expect(screen.getByText("test1.png")).toBeVisible();
const chips = screen.getAllByTestId("uploaded-file-chip");
expect(getByText("test1.png")).toBeVisible();
const chips = getAllByTestId("uploaded-file-chip");
expect(chips).toHaveLength(1);
expect(chips[0]).toHaveTextContent("Heritage statement");

// Requirements list reflects successfully tagged uploads
const completeIcons = screen.getAllByTestId("complete-icon");
const completeIcons = getAllByTestId("complete-icon");
expect(completeIcons).toHaveLength(1);
incompleteIcons = screen.getAllByTestId("incomplete-icon");
incompleteIcons = getAllByTestId("incomplete-icon");
expect(incompleteIcons).toHaveLength(1);

// Show error when attempting to "Continue" onto to the next node
expect(screen.getByText("Continue")).toBeEnabled();
await user.click(screen.getByText("Continue"));
expect(getByText("Continue")).toBeEnabled();
await user.click(getByText("Continue"));
expect(handleSubmit).toHaveBeenCalledTimes(0);
const error = await within(document.body).findByText(
"Please upload and label all required files",
Expand Down Expand Up @@ -565,15 +602,11 @@ describe("Error handling", () => {
test("An error is thrown in the main component if a user does not tag all files", async () => {
const handleSubmit = jest.fn();

const { user } = setup(
const { getAllByRole, getByTestId, getByRole, findByText, user } = setup(
<FileUploadAndLabelComponent
handleSubmit={handleSubmit}
title="Test title"
fileTypes={[
mockFileTypes.AlwaysRequired,
mockFileTypes.AlwaysRecommended,
mockFileTypes.NotRequired,
]}
fileTypes={mockFileTypesUniqueKeys}
/>,
);

Expand All @@ -585,29 +618,38 @@ describe("Error handling", () => {
});

const file = new File(["test"], "test.jpg", { type: "image/jpg" });
const input = screen.getByTestId("upload-input");
const input = getByTestId("upload-input");
await user.upload(input, file);

// Exit modal without tagging
await user.keyboard("{Esc}");

// User cannot submit without uploading a file
await user.click(screen.getByTestId("continue-button"));
await user.click(getByTestId("continue-button"));
expect(handleSubmit).not.toHaveBeenCalled();
const fileListError = await screen.findByText(
/File test.jpg is not labeled/,
);
const fileListError = await findByText(/File test.jpg is not labeled/);
expect(fileListError).toBeVisible();

// Re-open modal and tag file
await user.click(screen.getByRole("button", { name: /Change/ }));
const select = within(document.body).getByTestId("select");
fireEvent.change(select, { target: { value: "Utility bill" } });
await user.click(screen.getByRole("button", { name: /Done/ }));
await user.click(getByRole("button", { name: /Change/ }));
const autocompleteInputs = getAllByRole("combobox", {
name: /What does this file show/,
});
expect(autocompleteInputs).toHaveLength(1);
await user.click(autocompleteInputs[0]);

const utilityBillOption = getByRole("option", { name: /Utility bill/ });
expect(utilityBillOption).toBeVisible();

// Apply tag to this file, and close autocomplete dropdown
await user.click(utilityBillOption);
await user.keyboard("{Esc}");

await user.click(getByRole("button", { name: /Done/ }));

// Error message is cleared, user can submit
expect(fileListError).toBeEmptyDOMElement();
await user.click(screen.getByTestId("continue-button"));
await user.click(getByTestId("continue-button"));
expect(handleSubmit).not.toHaveBeenCalled();
});
});
Expand All @@ -619,7 +661,7 @@ describe("Submitting data", () => {

it("records the user uploaded files", async () => {
const handleSubmit = jest.fn();
const { user } = setup(
const { getByText, user } = setup(
<FileUploadAndLabelComponent
title="Test title"
handleSubmit={handleSubmit}
Expand All @@ -629,7 +671,7 @@ describe("Submitting data", () => {

await uploadAndTagSingleFile(user);

await user.click(screen.getByText("Continue"));
await user.click(getByText("Continue"));
expect(handleSubmit).toHaveBeenCalledTimes(1);

const submitted = handleSubmit.mock.calls[0][0];
Expand All @@ -647,7 +689,7 @@ describe("Submitting data", () => {

it("records the full file type list presented to the user", async () => {
const handleSubmit = jest.fn();
const { user } = setup(
const { getByText, user } = setup(
<FileUploadAndLabelComponent
title="Test title"
handleSubmit={handleSubmit}
Expand All @@ -656,7 +698,7 @@ describe("Submitting data", () => {
);

await uploadAndTagSingleFile(user);
await user.click(screen.getByText("Continue"));
await user.click(getByText("Continue"));

const submitted = handleSubmit.mock.calls[0][0];
const requestedFiles = submitted?.data?._requestedFiles;
Expand Down Expand Up @@ -720,7 +762,7 @@ describe("Submitting data", () => {
act(() => setState({ flow, breadcrumbs }));

const handleSubmit = jest.fn();
const { user } = setup(
const { getByText, user } = setup(
<FileUploadAndLabelComponent
title="Test title"
handleSubmit={handleSubmit}
Expand All @@ -729,7 +771,7 @@ describe("Submitting data", () => {
);

await uploadAndTagSingleFile(user);
await user.click(screen.getByText("Continue"));
await user.click(getByText("Continue"));

const submitted = handleSubmit.mock.calls[0][0];
const requestedFiles = submitted?.data?._requestedFiles;
Expand Down Expand Up @@ -764,8 +806,14 @@ const uploadAndTagSingleFile = async (user: UserEvent) => {
"file-tagging-dialog",
);

const selects = await within(document.body).findAllByTestId("select");
fireEvent.change(selects[0], { target: { value: "Roof plan" } });
const autocompleteInputs = screen.getAllByRole("combobox", {
name: /What does this file show/,
});

await user.click(autocompleteInputs[0]);
const roofPlanOption = screen.getByRole("option", { name: /Roof plan/ });
expect(roofPlanOption).toBeVisible();
await user.click(roofPlanOption);

const submitModalButton = await within(fileTaggingModal).findByText("Done");
user.click(submitModalButton);
Expand Down
Loading

0 comments on commit 93fef31

Please sign in to comment.