Skip to content

Commit

Permalink
feat: Capture _requestedFiles from DrawBoundary component
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr committed Feb 9, 2024
1 parent 62b947c commit 9197d74
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import { Breadcrumbs } from "@opensystemslab/planx-core/types";
import { PASSPORT_REQUESTED_FILES_KEY } from "@planx/components/FileUploadAndLabel/model";
import { screen } from "@testing-library/react";
import axios from "axios";
import { useStore, vanillaStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { act } from "react-dom/test-utils";
import { axe, setup } from "testUtils";

import {
DrawBoundaryUserAction,
PASSPORT_COMPONENT_ACTION_KEY,
PASSPORT_UPLOAD_KEY,
} from "../model";
import DrawBoundary from "./";

jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios>;
global.URL.createObjectURL = jest.fn();

const { getState, setState } = vanillaStore;

test("recovers previously submitted files when clicking the back button", async () => {
const handleSubmit = jest.fn();
const previouslySubmittedData = {
"locationPlan": [
locationPlan: [
{
file: {
path: "placeholder.png",
Expand Down Expand Up @@ -147,3 +163,212 @@ test("hides the upload option and allows user to continue without drawing if edi
await user.click(screen.getByTestId("continue-button"));
expect(handleSubmit).toHaveBeenCalledTimes(1);
});

test("captures output data in the correct format when uploading a file", async () => {
// Setup file mock
const mockFileName = "test.png";
const mockFileURL =
"https://api.editor.planx.dev/file/private/gws7l5d1/test.png";

const file = new File(["test"], mockFileName, { type: "image/png" });

const mockedPost = mockedAxios.post.mockResolvedValueOnce({
data: {
fileType: "image/png",
fileUrl: mockFileURL,
},
});

const handleSubmit = jest.fn();

const { user } = setup(
<DrawBoundary
dataFieldBoundary="property.boundary.site"
dataFieldArea="property.area.site"
description=""
descriptionForUploading=""
title="Draw a boundary"
titleForUploading="Upload a file"
handleSubmit={handleSubmit}
/>,
);

// Toggle to file upload mode
await user.click(screen.getByTestId("upload-file-button"));

// Upload file
const input = screen.getByTestId("upload-input");
await user.upload(input, file);
expect(mockedPost).toHaveBeenCalled();

await user.click(screen.getByTestId("continue-button"));
const submitted = handleSubmit.mock.calls[0][0];

// DrawBoundary passport variable set
expect(submitted.data).toHaveProperty(PASSPORT_UPLOAD_KEY);
expect(submitted.data.locationPlan).toHaveLength(1);
expect(submitted.data.locationPlan[0].url).toEqual(mockFileURL);
expect(submitted.data.locationPlan[0].file.path).toEqual(mockFileName);

// DrawBoundary action captured
expect(submitted.data[PASSPORT_COMPONENT_ACTION_KEY]).toEqual(
DrawBoundaryUserAction.Upload,
);

// File added to requested files
expect(submitted.data).toHaveProperty(PASSPORT_REQUESTED_FILES_KEY);
expect(submitted.data[PASSPORT_REQUESTED_FILES_KEY]).toMatchObject(
expect.objectContaining({
required: [PASSPORT_UPLOAD_KEY],
recommended: [],
optional: [],
}),
);
});

test("appends to existing '_requestedFiles' value", async () => {
// Setup file mock
const mockFileName = "test.png";
const mockFileURL =
"https://api.editor.planx.dev/file/private/gws7l5d1/test.png";

const file = new File(["test"], mockFileName, { type: "image/png" });

mockedAxios.post.mockResolvedValueOnce({
data: {
fileType: "image/png",
fileUrl: mockFileURL,
},
});

const handleSubmit = jest.fn();

// Mimic having passed file upload / file upload and label component
const breadcrumbs: Breadcrumbs = {
previousFileUploadComponent: {
auto: false,
data: {
floorPlan: [
{
url: "http://test.com/file1.jpg",
filename: "file1.jpg",
},
],
utilityBill: [
{
url: "http://test.com/file2.jpg",
filename: "file2.jpg",
},
],
"elevations.existing": [
{
url: "http://test.com/file3.jpg",
filename: "file3.jpg",
},
],
[PASSPORT_REQUESTED_FILES_KEY]: {
required: ["floorPlan", "utilityBill"],
recommended: ["elevations.existing"],
optional: [],
},
},
},
};

const flow = {
_root: {
edges: ["previousFileUploadComponent", "DrawBoundary"],
},
previousFileUploadComponent: {
type: 145,
data: {
title: "Upload and label",
fileTypes: [
{
name: "Floor Plan",
fn: "floorPlan",
rule: {
condition: "AlwaysRequired",
},
},
{
name: "Utility Bill",
fn: "utilityBill",
rule: {
condition: "AlwaysRequired",
},
},
{
name: "Existing elevations",
fn: "elevations.existing",
rule: {
condition: "AlwaysRecommended",
},
},
],
hideDropZone: false,
},
},
DrawBoundary: {
type: 10,
data: {
howMeasured: "",
policyRef: "",
info: "",
title: "Confirm your location plan",
description: "",
titleForUploading: "Upload a location plan",
descriptionForUploading: "",
hideFileUpload: false,
dataFieldBoundary: "property.boundary.site",
dataFieldArea: "property.boundary.area",
},
},
};

act(() => setState({ flow, breadcrumbs }));

const { user } = setup(
<DrawBoundary
dataFieldBoundary="property.boundary.site"
dataFieldArea="property.area.site"
description=""
descriptionForUploading=""
title="Draw a boundary"
titleForUploading="Upload a file"
handleSubmit={handleSubmit}
/>,
);

// Check current passport setup
const passport = getState().computePassport();
const existingRequestedFiles = passport.data?.[PASSPORT_REQUESTED_FILES_KEY];
expect(existingRequestedFiles).toBeDefined();
expect(existingRequestedFiles).toMatchObject({
required: ["floorPlan", "utilityBill"],
recommended: ["elevations.existing"],
optional: [],
});

// Toggle to file upload mode
await user.click(screen.getByTestId("upload-file-button"));

// Upload file and continue
const input = screen.getByTestId("upload-input");
await user.upload(input, file);
await user.click(screen.getByTestId("continue-button"));

const { required, recommended, optional } =
handleSubmit.mock.calls[0][0].data[PASSPORT_REQUESTED_FILES_KEY];

// Current file key has been added to required
expect(required).toContain(PASSPORT_UPLOAD_KEY);

// Previous file keys have not been overwritten
expect(required).toContain("floorPlan");
expect(required).toContain("utilityBill");

// Recommended and optional keys untouched
expect(recommended).toEqual(["elevations.existing"]);
expect(optional).toHaveLength(0);
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Link from "@mui/material/Link";
import Typography from "@mui/material/Typography";
import { visuallyHidden } from "@mui/utils";
import { FileUploadSlot } from "@planx/components/FileUpload/Public";
import { PASSPORT_REQUESTED_FILES_KEY } from "@planx/components/FileUploadAndLabel/model";
import Card from "@planx/components/shared/Preview/Card";
import {
MapContainer,
Expand Down Expand Up @@ -134,6 +135,17 @@ export default function Component(props: Props) {
newPassportData[PASSPORT_UPLOAD_KEY] = slots;
newPassportData[PASSPORT_COMPONENT_ACTION_KEY] =
DrawBoundaryUserAction.Upload;

// Track as requested file
const { required, recommended, optional } = passport.data?.[
PASSPORT_REQUESTED_FILES_KEY
] || { required: [], recommended: [], optional: [] };

newPassportData[PASSPORT_REQUESTED_FILES_KEY] = {
required: [...required, PASSPORT_UPLOAD_KEY],
recommended,
optional,
};
}

props.handleSubmit?.({ data: { ...newPassportData } });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {
import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup";
import axios from "axios";
import { vanillaStore } from "pages/FlowEditor/lib/store";
import { FullStore, useStore } from "pages/FlowEditor/lib/store";
import { FullStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { axe, setup } from "testUtils";
import { Breadcrumbs } from "types";

import { mockFileTypes, mockFileTypesUniqueKeys } from "./mocks";
import { Condition, PASSPORT_REQUESTED_FILES_KEY } from "./model";
import { PASSPORT_REQUESTED_FILES_KEY } from "./model";
import FileUploadAndLabelComponent from "./Public";

const { getState, setState } = vanillaStore;
Expand Down Expand Up @@ -717,9 +717,6 @@ describe("Submitting data", () => {

act(() => setState({ flow, breadcrumbs }));

const passport = useStore.getState().computePassport();
console.log({ passport });

const handleSubmit = jest.fn();
const { user } = setup(
<FileUploadAndLabelComponent
Expand Down

0 comments on commit 9197d74

Please sign in to comment.