From 42df2c6741fedf54366de0d64dbb8e40c856aa74 Mon Sep 17 00:00:00 2001 From: Jessica McInchak Date: Tue, 20 Feb 2024 13:37:21 +0100 Subject: [PATCH] better flattenFlow test coverage --- .../flows/flattenFlow/flattenFlow.test.ts | 118 +++++++++++++++++- .../tests/mocks/validateAndPublishMocks.ts | 113 +++++++++++++++++ 2 files changed, 225 insertions(+), 6 deletions(-) diff --git a/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts b/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts index 1d95a64179..1bb95949ec 100644 --- a/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts +++ b/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts @@ -2,7 +2,12 @@ import supertest from "supertest"; import app from "../../../server"; import { queryMock } from "../../../tests/graphqlQueryMock"; -import { mockFlowData } from "../../../tests/mocks/validateAndPublishMocks"; +import { + childFlow, + draftParentFlow, + flattenedParentFlow, + mockFlowData, +} from "../../../tests/mocks/validateAndPublishMocks"; beforeEach(() => { queryMock.mockQuery({ @@ -14,7 +19,7 @@ beforeEach(() => { data: { flow: { data: mockFlowData, - slug: "mock-flow-name", + slug: "mock-flow", team_id: 1, team: { slug: "testing", @@ -23,6 +28,25 @@ beforeEach(() => { }, }, }); + + queryMock.mockQuery({ + name: "GetFlowData", + matchOnVariables: true, + variables: { + id: "parent-flow-with-external-portal", + }, + data: { + flow: { + data: draftParentFlow, + slug: "parent-flow", + team_id: 1, + team: { + slug: "testing", + }, + publishedFlows: [{ data: flattenedParentFlow }], + }, + }, + }); }); it("is publicly accessible and does not require a user to be signed in", async () => { @@ -40,11 +64,93 @@ it("returns the expected result for a simple flow without external portals", asy }); }); -it.todo("throws an error for a flow with unpublished external portals"); +it("returns the expected result for a simple flow without external portals when the ?unpublished=true query param is set", async () => { + await supertest(app) + .get("/flows/basic-flow-no-external-portals/flatten-data?unpublished=true") + .expect(200) + .then((res) => { + expect(res.body).toEqual(mockFlowData); + }); +}); + +it("returns the expected result for a flow with published external portals", async () => { + queryMock.mockQuery({ + name: "GetFlowData", + matchOnVariables: true, + variables: { + id: "child-flow-id", + }, + data: { + flow: { + data: childFlow, + slug: "child-flow", + team_id: 1, + team: { + slug: "testing", + }, + publishedFlows: [{ data: childFlow }], + }, + }, + }); + + await supertest(app) + .get("/flows/parent-flow-with-external-portal/flatten-data") + .expect(200) + .then((res) => expect(res.body).toEqual(flattenedParentFlow)); +}); + +it("throws an error for a flow with unpublished external portals", async () => { + queryMock.mockQuery({ + name: "GetFlowData", + matchOnVariables: true, + variables: { + id: "child-flow-id", + }, + data: { + flow: { + data: childFlow, + slug: "child-flow", + team_id: 1, + team: { + slug: "testing", + }, + publishedFlows: [], + }, + }, + }); + + await supertest(app) + .get("/flows/parent-flow-with-external-portal/flatten-data") + .expect(500); +}); + +it("returns the expected draft result for a flow with unpublished external portals when ?unpublished=true query param is set", async () => { + queryMock.mockQuery({ + name: "GetFlowData", + matchOnVariables: true, + variables: { + id: "child-flow-id", + }, + data: { + flow: { + data: childFlow, + slug: "child-flow", + team_id: 1, + team: { + slug: "testing", + }, + publishedFlows: [], + }, + }, + }); -it.todo( - "returns the expected draft result for a flow with unpublished external portals if ?unpublished=true query param is set", -); + await supertest(app) + .get( + "/flows/parent-flow-with-external-portal/flatten-data?unpublished=true", + ) + .expect(200) + .then((res) => expect(res.body).toEqual(flattenedParentFlow)); +}); it("throws an error if no flow is found", async () => { await supertest(app).get("/flows/invalid-id/flatten-data").expect(500); diff --git a/api.planx.uk/tests/mocks/validateAndPublishMocks.ts b/api.planx.uk/tests/mocks/validateAndPublishMocks.ts index c137f6095d..a8bf58c1ec 100644 --- a/api.planx.uk/tests/mocks/validateAndPublishMocks.ts +++ b/api.planx.uk/tests/mocks/validateAndPublishMocks.ts @@ -109,3 +109,116 @@ export const mockFlowData: FlowGraph = { type: 650, }, }; + +export const draftParentFlow: FlowGraph = { + _root: { + edges: ["ContentNode", "ExternalPortalNode", "NoticeNode"], + }, + ContentNode: { + type: 250, + data: { + content: "

This is a test flow with external portal content

", + }, + }, + NoticeNode: { + type: 8, + data: { + title: "End of test", + color: "#EFEFEF", + resetButton: true, + }, + }, + ExternalPortalNode: { + type: 310, + data: { + flowId: "child-flow-id", + }, + }, +}; + +export const flattenedParentFlow: FlowGraph = { + _root: { + edges: ["ContentNode", "ExternalPortalNode", "NoticeNode"], + }, + ContentNode: { + data: { + content: "

This is a test flow with external portal content

", + }, + type: 250, + }, + NoticeNode: { + data: { + color: "#EFEFEF", + title: "End of test", + resetButton: true, + }, + type: 8, + }, + ExternalPortalNode: { + type: 300, + edges: ["child-flow-id"], + }, + "child-flow-id": { + edges: ["QuestionInsidePortal"], + type: 300, + data: { + text: "child-flow", + }, + }, + OptionB: { + data: { + text: "B", + }, + type: 200, + }, + OptionC: { + data: { + text: "C", + }, + type: 200, + }, + QuestionInsidePortal: { + data: { + text: "This is a question in a flow referenced as an external portal", + }, + type: 100, + edges: ["OptionA", "OptionB", "OptionC"], + }, + OptionA: { + data: { + text: "A", + }, + type: 200, + }, +}; + +export const childFlow: FlowGraph = { + _root: { + edges: ["QuestionInsidePortal"], + }, + OptionB: { + data: { + text: "B", + }, + type: 200, + }, + OptionC: { + data: { + text: "C", + }, + type: 200, + }, + QuestionInsidePortal: { + data: { + text: "This is a question in a flow referenced as an external portal", + }, + type: 100, + edges: ["OptionA", "OptionB", "OptionC"], + }, + OptionA: { + data: { + text: "A", + }, + type: 200, + }, +};