From f9d88c5aede7555d51a7cf65db88ad7404369902 Mon Sep 17 00:00:00 2001 From: Kayla Firestack Date: Tue, 20 Aug 2024 09:33:29 -0400 Subject: [PATCH] feat: add detour button to list page (#2739) * feat: add detour button to list page * feat: add detour machine input to original route type * feat: show modal when add button is clicked --- assets/src/components/detourListPage.tsx | 21 +++++- assets/src/models/createDetourMachine.ts | 6 +- assets/src/models/detour.ts | 9 +-- .../detours/detoursPage.addDetour.test.tsx | 68 +++++++++++++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 assets/tests/components/detours/detoursPage.addDetour.test.tsx diff --git a/assets/src/components/detourListPage.tsx b/assets/src/components/detourListPage.tsx index e62d6e17c..6f1bcf83a 100644 --- a/assets/src/components/detourListPage.tsx +++ b/assets/src/components/detourListPage.tsx @@ -1,5 +1,9 @@ -import React from "react" +import React, { useState } from "react" import { DetoursTable } from "./detoursTable" +import userInTestGroup, { TestGroups } from "../userInTestGroup" +import { Button } from "react-bootstrap" +import { PlusSquare } from "../helpers/bsIcons" +import { DetourModal } from "./detours/detourModal" export interface Detour { route: string @@ -76,9 +80,24 @@ export const DetourListPage = () => { }, ] + const [showDetourModal, setShowDetourModal] = useState(false) + return (
+ {userInTestGroup(TestGroups.DetoursPilot) && ( + + )} + {showDetourModal && ( + setShowDetourModal(false)} + show + originalRoute={{}} + /> + )}
) } diff --git a/assets/src/models/createDetourMachine.ts b/assets/src/models/createDetourMachine.ts index f0530830c..da49e9353 100644 --- a/assets/src/models/createDetourMachine.ts +++ b/assets/src/models/createDetourMachine.ts @@ -36,12 +36,12 @@ export const createDetourMachine = setup({ | { // Caller has target route route: Route - routePattern: undefined + routePattern?: undefined } | { // Caller has no prior selection - route: undefined - routePattern: undefined + route?: undefined + routePattern?: undefined }, events: {} as diff --git a/assets/src/models/detour.ts b/assets/src/models/detour.ts index cddd0d81e..79e84e207 100644 --- a/assets/src/models/detour.ts +++ b/assets/src/models/detour.ts @@ -1,5 +1,6 @@ import { LatLngLiteral } from "leaflet" -import { Route, RoutePattern, ShapePoint, Stop } from "../schedule" +import { ShapePoint, Stop } from "../schedule" +import { CreateDetourMachineInput } from "./createDetourMachine" export interface DetourShape { coordinates: ShapePoint[] @@ -10,13 +11,13 @@ export type DetourDirection = { instruction: string } -export interface OriginalRoute { - route: Route - routePattern?: RoutePattern +export interface MapLocation { center?: LatLngLiteral zoom?: number } +export type OriginalRoute = CreateDetourMachineInput & MapLocation + export interface UnfinishedRouteSegments { beforeStartPoint: ShapePoint[] afterStartPoint: ShapePoint[] diff --git a/assets/tests/components/detours/detoursPage.addDetour.test.tsx b/assets/tests/components/detours/detoursPage.addDetour.test.tsx new file mode 100644 index 000000000..db6568528 --- /dev/null +++ b/assets/tests/components/detours/detoursPage.addDetour.test.tsx @@ -0,0 +1,68 @@ +import { describe, expect, jest, test } from "@jest/globals" + +import React from "react" + +import { screen } from "@testing-library/dom" +import "@testing-library/jest-dom/jest-globals" +import { render } from "@testing-library/react" +import userEvent from "@testing-library/user-event" + +import { DetourListPage } from "../../../src/components/detourListPage" +import { TestGroups } from "../../../src/userInTestGroup" +import getTestGroups from "../../../src/userTestGroups" + +jest.mock("../../../src/userTestGroups") + +const renderDetourListPage = () => { + return render() +} + +describe("Detours Page: Create Detour", () => { + test("Shows the add detour button when in test group", () => { + jest.mocked(getTestGroups).mockReturnValue([TestGroups.DetoursPilot]) + + renderDetourListPage() + + expect(screen.getByRole("button", { name: "Add detour" })).toBeVisible() + }) + + test("Does not show add detour button when not in test group", () => { + jest.mocked(getTestGroups).mockReturnValue([]) + + renderDetourListPage() + + expect( + screen.queryByRole("button", { name: "Add detour" }) + ).not.toBeInTheDocument() + }) + + test("Opens Detour Modal when clicked", async () => { + jest.mocked(getTestGroups).mockReturnValue([TestGroups.DetoursPilot]) + + renderDetourListPage() + + await userEvent.click(screen.getByRole("button", { name: "Add detour" })) + + expect( + await screen.findByRole("heading", { name: "Create Detour" }) + ).toBeVisible() + }) + + test("Returns to page when modal is closed", async () => { + jest.mocked(getTestGroups).mockReturnValue([TestGroups.DetoursPilot]) + + renderDetourListPage() + + await userEvent.click(screen.getByRole("button", { name: "Add detour" })) + + const createDetourHeading = await screen.findByRole("heading", { + name: "Create Detour", + }) + expect(createDetourHeading).toBeVisible() + + await userEvent.click(screen.getByRole("button", { name: "Close" })) + await userEvent.click(screen.getByRole("button", { name: "Yes, I'm sure" })) + + expect(createDetourHeading).not.toBeInTheDocument() + }) +})