diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/View.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/View.tsx index 85b993aa70d..d3c6fd06a32 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/View.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/View.tsx @@ -178,7 +178,6 @@ export const View = (props: Props) => { arraySortedByDate.filter((exposure: Exposure) => { const exposureStatus = getExposureStatus( exposure, - isDataBrokerUnderMaintenance(exposure), props.enabledFeatureFlags, ); @@ -598,13 +597,3 @@ export const View = (props: Props) => { ); }; - -export function isDataBrokerUnderMaintenance( - exposure: Exposure | OnerepScanResultDataBrokerRow, -): boolean { - return ( - isScanResult(exposure) && - exposure.broker_status === "removal_under_maintenance" && - exposure.status !== "removed" - ); -} diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/FixView.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/FixView.tsx index a29aa882ac1..e807600c97b 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/FixView.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/FixView.tsx @@ -18,14 +18,13 @@ import { StepLink, } from "../../../../../../../functions/server/getRelevantGuidedSteps"; import { useTelemetry } from "../../../../../../../hooks/useTelemetry"; -import { TelemetryButton } from "../../../../../../../components/client/TelemetryButton"; import { FeatureFlagName } from "../../../../../../../../db/tables/featureFlags"; export type FixViewProps = { children: ReactNode; subscriberEmails: string[]; data: StepDeterminationData; - nextStep: StepLink | (() => void); + nextStep: StepLink; currentSection: | "data-broker-profiles" | "high-risk-data-breach" @@ -93,47 +92,22 @@ export const FixView = (props: FixViewProps) => { {!props.hideNavClose && navigationClose()}
{props.children}
- {!props.hideNextNavigationRightArrow && - (isNextStepALink(props.nextStep) ? ( - { - recordTelemetry("button", "click", { - button_id: "next_arrow", - }); - }} - > - - - ) : ( - - - - ))} + {!props.hideNextNavigationRightArrow && ( + { + recordTelemetry("button", "click", { + button_id: "next_arrow", + }); + }} + > + + + )}
); }; - -function isNextStepALink( - nextStep: StepLink | (() => void), -): nextStep is StepLink { - return "href" in nextStep; -} diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenance.module.scss b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenance.module.scss deleted file mode 100644 index db7720d7c7b..00000000000 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenance.module.scss +++ /dev/null @@ -1,118 +0,0 @@ -@use "../../../../../../../../../tokens"; - -.dataBrokerInformationWrapper { - .exposureCardWrapper { - margin-top: tokens.$spacing-md; - padding-bottom: tokens.$spacing-lg; - - .exposureCard { - display: flex; - flex-direction: column; - background-color: tokens.$color-white; - border: 2px solid rgba(tokens.$color-purple-70, 0.2); - border-radius: tokens.$border-radius-lg; - padding: tokens.$layout-sm tokens.$layout-sm tokens.$layout-xs - tokens.$layout-sm; - - .dataClassesList { - justify-content: space-between; - margin-left: 0; - display: grid; - grid-template-columns: 1fr; - row-gap: tokens.$spacing-sm; - transition: opacity 0.35s ease-in-out; - opacity: 1; - - &.fadeOut { - opacity: 0; - } - - @media screen and (min-width: tokens.$screen-md) { - grid-template-columns: 1fr 1fr 1fr; - gap: tokens.$spacing-sm; - } - - @media screen and (min-width: tokens.$screen-lg) { - display: flex; - flex-direction: row; - align-items: flex-start; - gap: tokens.$layout-xs; - flex-wrap: wrap; - justify-content: flex-start; - } - } - - .buttonsWrapper { - margin-top: tokens.$spacing-lg; - border-top: 2px solid tokens.$color-grey-10; - padding-top: tokens.$spacing-lg; - display: flex; - gap: tokens.$spacing-sm; - } - - .estimatedTime { - @include tokens.estimated-time; - padding-top: tokens.$spacing-sm; - } - } - } - - .header { - font: tokens.$text-body-lg; - font-weight: 700; - transition: opacity 0.35s ease-in-out; - opacity: 1; - - &.fadeOut { - opacity: 0; - } - } -} - -.removalGuideInstructionsWrapper { - .backArrow { - all: unset; - cursor: pointer; - } - .headerRemovalGuide { - padding-top: tokens.$spacing-lg; - font: tokens.$text-body-xl; - font-weight: 700; - } - - .buttonWrapper { - display: flex; - justify-content: center; - padding-top: tokens.$spacing-lg; - } -} - -.removalContentSection { - margin-top: tokens.$layout-md; - - dt { - font: tokens.$text-body-lg; - font-weight: 600; - - &.removalGuideInstructions { - font: tokens.$text-body-md; - font-weight: 700; - } - } - - dd { - padding-top: tokens.$spacing-sm; - } - - ol { - padding-top: tokens.$spacing-sm; - - li { - margin-bottom: tokens.$spacing-xs; - } - } - - button { - margin-top: tokens.$spacing-lg; - } -} diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.stories.tsx deleted file mode 100644 index c32066880d2..00000000000 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.stories.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -import type { Meta, StoryObj } from "@storybook/nextjs"; -import { OnerepScanRow } from "knex/types/tables"; -import { - createRandomAnnouncement, - createRandomBreach, - createRandomScanResult, - createUserWithPremiumSubscription, -} from "../../../../../../../../../../apiMocks/mockData"; -import { Shell } from "../../../../../../../Shell/Shell"; -import { getL10n } from "../../../../../../../../../functions/l10n/storybookAndJest"; -import { LatestOnerepScanData } from "../../../../../../../../../../db/tables/onerep_scans"; -import { RemovalUnderMaintenanceView } from "./RemovalUnderMaintenanceView"; -import { defaultExperimentData } from "../../../../../../../../../../telemetry/generated/nimbus/experiments"; -import { UserAnnouncementWithDetails } from "../../../../../../../../../../db/tables/user_announcements"; - -const meta: Meta = { - title: "Pages/Logged in/Guided resolution/1d. Removal Under Maintenance", - component: RemovalUnderMaintenanceView, -}; -export default meta; -type Story = StoryObj; - -const user = createUserWithPremiumSubscription(); - -const mockedSession = { - expires: new Date().toISOString(), - user: user, -}; -const mockedScan: OnerepScanRow = { - created_at: new Date(1998, 2, 31), - updated_at: new Date(1998, 2, 31), - id: 0, - onerep_profile_id: 0, - onerep_scan_id: 0, - onerep_scan_reason: "initial", - onerep_scan_status: "finished", -}; - -const mockedScanData: LatestOnerepScanData = { - scan: mockedScan, - results: [...Array(5)].map(() => - createRandomScanResult({ status: "new", manually_resolved: false }), - ), -}; -const mockedBreaches = [...Array(5)].map(() => createRandomBreach()); - -const mockedAnnouncements: UserAnnouncementWithDetails[] = [ - createRandomAnnouncement({ audience: "premium_users" }), - createRandomAnnouncement({ audience: "premium_users" }), - createRandomAnnouncement({ audience: "premium_users" }), -]; - -export const RemovalUnderMaintenanceViewStory: Story = { - render: () => { - return ( - - - - ); - }, -}; diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.test.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.test.tsx deleted file mode 100644 index a2aa12db021..00000000000 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.test.tsx +++ /dev/null @@ -1,149 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -import { it, expect } from "@jest/globals"; -import { render, screen } from "@testing-library/react"; -import { userEvent } from "@testing-library/user-event"; -import { composeStory } from "@storybook/react"; -import { axe } from "jest-axe"; -import Meta, { - RemovalUnderMaintenanceViewStory, -} from "./RemovalUnderMaintenanceView.stories"; -const mockedRouterPush = jest.fn(); - -jest.mock("next/navigation", () => ({ - useRouter: () => ({ - push: mockedRouterPush, - }), - usePathname: jest.fn(), - useSearchParams: () => ({ - get: jest.fn(), - }), -})); -const mockedRecordTelemetry = jest.fn(); - -jest.mock("../../../../../../../../../hooks/useTelemetry", () => { - return { - useTelemetry: () => mockedRecordTelemetry, - }; -}); - -describe("Removal under maintenance", () => { - it("passes the axe accessibility test suite", async () => { - const RemovalUnderMaintenanceView = composeStory( - RemovalUnderMaintenanceViewStory, - Meta, - ); - const { container } = render(); - expect(await axe(container)).toHaveNoViolations(); - }, 10_000); - - it("shows removal instructions", async () => { - const user = userEvent.setup(); - const RemovalUnderMaintenanceView = composeStory( - RemovalUnderMaintenanceViewStory, - Meta, - ); - render(); - const viewRemovalInstructionsButton = screen.getByRole("button", { - name: "View removal instructions", - }); - await user.click(viewRemovalInstructionsButton); - - const headerRemovalGuide = screen.getByText( - "Removal guide for data broker websites", - ); - expect(headerRemovalGuide).toBeInTheDocument(); - }); - - it("closes removal instructions using the “back arrow”", async () => { - const user = userEvent.setup(); - const RemovalUnderMaintenanceView = composeStory( - RemovalUnderMaintenanceViewStory, - Meta, - ); - render(); - const viewRemovalInstructionsButton = screen.getByRole("button", { - name: "View removal instructions", - }); - await user.click(viewRemovalInstructionsButton); - - const headerRemovalGuideOne = screen.getByText( - "Removal guide for data broker websites", - ); - expect(headerRemovalGuideOne).toBeInTheDocument(); - const arrowBackButton = screen.getAllByRole("button", { - name: "Back to exposures", - })[0]; - await user.click(arrowBackButton); - const headerRemovalGuideTwo = screen.queryByText( - "Removal guide for data broker websites", - ); - expect(headerRemovalGuideTwo).not.toBeInTheDocument(); - }); - - it("closes removal instructions using the “Back to exposures” button", async () => { - const user = userEvent.setup(); - const RemovalUnderMaintenanceView = composeStory( - RemovalUnderMaintenanceViewStory, - Meta, - ); - render(); - const viewRemovalInstructionsButton = screen.getByRole("button", { - name: "View removal instructions", - }); - await user.click(viewRemovalInstructionsButton); - - const headerRemovalGuideOne = screen.getByText( - "Removal guide for data broker websites", - ); - expect(headerRemovalGuideOne).toBeInTheDocument(); - const closeButton = screen.getAllByRole("button", { - name: "Back to exposures", - })[1]; - await user.click(closeButton); - const headerRemovalGuideTwo = screen.queryByText( - "Removal guide for data broker websites", - ); - expect(headerRemovalGuideTwo).not.toBeInTheDocument(); - }); - - it("clicks the “Marks exposure resolved” button and shows a loader while resolving the exposure", async () => { - global.fetch = jest.fn().mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve(), - }); - const user = userEvent.setup(); - const RemovalUnderMaintenanceView = composeStory( - RemovalUnderMaintenanceViewStory, - Meta, - ); - render(); - const resolveButton = screen.getByRole("button", { - name: "Mark exposure resolved", - }); - await user.click(resolveButton); - expect(resolveButton).toHaveTextContent("Loading"); - }); -}); - -it("clicks the right arrow button to show the next step", async () => { - const user = userEvent.setup(); - const RemovalUnderMaintenanceView = composeStory( - RemovalUnderMaintenanceViewStory, - Meta, - ); - render(); - const rightArrowBtn = screen.getByRole("button", { - name: "Go to next result", - }); - await user.click(rightArrowBtn); - expect(mockedRecordTelemetry).toHaveBeenCalledWith( - "button", - "click", - expect.objectContaining({ - button_id: "go_to_next_result", - }), - ); -}); diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.tsx deleted file mode 100644 index 28467157828..00000000000 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/RemovalUnderMaintenanceView.tsx +++ /dev/null @@ -1,431 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use client"; - -import { - StepDeterminationData, - getNextGuidedStep, -} from "../../../../../../../../../functions/server/getRelevantGuidedSteps"; -import { FixView } from "../../FixView"; -import styles from "./RemovalUnderMaintenance.module.scss"; -import { useL10n } from "../../../../../../../../../hooks/l10n"; -import { TelemetryLink } from "../../../../../../../../../components/client/TelemetryLink"; -import { TelemetryButton } from "../../../../../../../../../components/client/TelemetryButton"; -import { CONST_URL_SUMO_MANUAL_REMOVAL } from "../../../../../../../../../../constants"; -import React, { useState } from "react"; -import { - BackArrow, - ClockIcon, - OpenInNew, -} from "../../../../../../../../../components/server/Icons"; -import { LatestOnerepScanData } from "../../../../../../../../../../db/tables/onerep_scans"; -import { ExposureCardDataClassLayout } from "../../../../../../../../../components/client/exposure_card/ExposureCardDataClass"; -import confetti from "canvas-confetti"; -import { toast } from "react-toastify"; -import fetchWithDelay from "../../../../../../../../../../utils/fetchWithDelay"; -import { useRouter } from "next/navigation"; -import { FeatureFlagName } from "../../../../../../../../../../db/tables/featureFlags"; - -export type Props = { - data: LatestOnerepScanData; - stepDeterminationData: StepDeterminationData; - subscriberEmails: string[]; - enabledFeatureFlags: FeatureFlagName[]; -}; - -export const RemovalUnderMaintenanceView = (props: Props) => { - const l10n = useL10n(); - const router = useRouter(); - const [detailedRemovalGuide, setDetailedRemovalGuide] = useState(false); - const [firstScanResultNotResolved, setFirstScanResultNotResolved] = useState( - props.data.results[0], - ); - const [isLoadingNextDataBroker, setIsLoadingNextDataBroker] = useState(false); - - const nextGuidedStep = getNextGuidedStep( - props.stepDeterminationData, - props.enabledFeatureFlags, - "DataBrokerManualRemoval", - ); - - // Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy - /* c8 ignore start */ - - function moveToNextAvailableStep() { - const currentResultIndex = props.data.results.findIndex( - (result) => - result.onerep_scan_result_id === - firstScanResultNotResolved.onerep_scan_result_id, - ); - - if (currentResultIndex < props.data.results.length - 1) { - // Move to the next unresolved result - const nextUnresolvedResult = props.data.results[currentResultIndex + 1]; - setFirstScanResultNotResolved(nextUnresolvedResult); - } else { - // Redirect if no unresolved scan result remains - router.push(nextGuidedStep.href); - router.refresh(); - } - } - - async function handleManualRemovalChange() { - setIsLoadingNextDataBroker(true); - try { - const response = await fetchWithDelay( - `/api/v1/user/scan-result/${firstScanResultNotResolved.onerep_scan_result_id}/resolution`, - { - method: "POST", - credentials: "same-origin", - delay: 750, - }, - ); - - if (!response.ok) { - toast.error("Could not resolve data broker."); - console.error( - "Could not update next data broker with removal under maintenance status.", - ); - return; - } - void confetti(); - - // Mark the current scan result as manually resolved - moveToNextAvailableStep(); - } catch (error) { - console.error("Error occurred in handleManualRemovalChange:", error); - } finally { - setIsLoadingNextDataBroker(false); - } - } - /* c8 ignore stop */ - - const exposureCategoriesArray: React.ReactElement[] = []; - if (firstScanResultNotResolved.relatives.length > 0) { - exposureCategoriesArray.push( - , - ); - } - if (firstScanResultNotResolved.phones.length > 0) { - exposureCategoriesArray.push( - , - ); - } - if (firstScanResultNotResolved.emails.length > 0) { - exposureCategoriesArray.push( - , - ); - } - if (firstScanResultNotResolved.addresses.length > 0) { - exposureCategoriesArray.push( - , - ); - } - - const dataBrokerCard = ( -
-
- {exposureCategoriesArray.map((item) => ( - {item} - ))} -
-
- - {l10n.getString( - "data-broker-removal-maintenance-cta-go-to-data-broker", - )} - - - void handleManualRemovalChange()} - event={{ - module: "ctaButton", - name: "click", - data: { - button_id: `data_broker_removal_mark_as_resolved`, - }, - }} - > - {l10n.getString( - "data-broker-removal-maintenance-cta-mark-as-resolved", - )} - -
-
- - {l10n.getString("data-broker-removal-maintenance-estimated-time", { - range: "5 - 10", - })} -
-
- ); - - const dataBrokerInformation = ( -
-

- {l10n.getFragment("data-broker-removal-maintenance-header", { - elems: { - link_to_data_broker: ( - - ), - }, - vars: { - data_broker_name: firstScanResultNotResolved.data_broker, - }, - })} -

-
- {dataBrokerCard} -
-
-
- {l10n.getString( - "data-broker-removal-maintenance-steps-to-remove-header", - )} -
-
-
    -
  1. - {l10n.getString( - "data-broker-removal-maintenance-steps-to-remove-header-step-one", - )} -
  2. -
  3. - {l10n.getString( - "data-broker-removal-maintenance-steps-to-remove-header-step-two", - )} -
  4. -
-
-
- setDetailedRemovalGuide(true)} - event={{ - module: "button", - name: "click", - data: { - button_id: "view_removal_instructions", - }, - }} - > - {l10n.getString( - "data-broker-removal-maintenance-steps-to-remove-view-more-link", - )} - -
- -
-
-
- {l10n.getString( - "data-broker-removal-maintenance-steps-to-remove-header", - )} -
-
- {l10n.getFragment( - "data-broker-removal-maintenance-rationale-answer", - { - elems: { - learn_about_data_exposure_link: ( - - ), - }, - }, - )} -
-
-
-
-
- ); - - const removalGuideInstructions = ( -
- -

- {l10n.getString("data-broker-removal-guide-header")} -

-

{l10n.getString("data-broker-removal-guide-top-section-para-1")}

-
-

{l10n.getString("data-broker-removal-guide-top-section-para-2")}

- -
-
-
- {l10n.getString("data-broker-removal-guide-step-1-header")} -
-
- {l10n.getString("data-broker-removal-guide-step-1-body")} - -
    -
  • - {l10n.getString("data-broker-removal-guide-step-1-list-item-1")} -
  • -
  • - {l10n.getString("data-broker-removal-guide-step-1-list-item-2")} -
  • -
  • - {l10n.getString("data-broker-removal-guide-step-1-list-item-3")} -
  • -
  • - {l10n.getString("data-broker-removal-guide-step-1-list-item-4")} -
  • -
-
-
-
- -
-
-
- {l10n.getString("data-broker-removal-guide-step-2-header")} -
-
- {l10n.getString("data-broker-removal-guide-step-2-body-para-1")} -
-
- {l10n.getString("data-broker-removal-guide-step-2-body-para-2")} -
-
-
- -
-
-
- {l10n.getString("data-broker-removal-guide-step-3-header")} -
-
- {l10n.getString("data-broker-removal-guide-step-3-body-para-1")} -
-
- {l10n.getString("data-broker-removal-guide-step-3-body-para-2")} -
-
-
- -
-
-
- {l10n.getString("data-broker-removal-guide-step-4-header")} -
-
{l10n.getString("data-broker-removal-guide-step-4-body")}
-
-
- -
- setDetailedRemovalGuide(!detailedRemovalGuide)} - variant="primary" - event={{ - module: "button", - name: "click", - data: { - button_id: "return_to_data_broker", - }, - }} - > - {l10n.getString("data-broker-removal-guide-button-back-to-exposures")} - -
-
- ); - - return ( - moveToNextAvailableStep()} - currentSection="data-broker-profiles" - data={props.stepDeterminationData} - hideProgressIndicator={detailedRemovalGuide} - hideNavClose={detailedRemovalGuide} - hideNextNavigationRightArrow={detailedRemovalGuide} - enabledFeatureFlags={props.enabledFeatureFlags} - > - {!detailedRemovalGuide ? dataBrokerInformation : removalGuideInstructions} - - ); -}; diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/page.tsx deleted file mode 100644 index 462cb39bad2..00000000000 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/removal-under-maintenance/page.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -import { redirect } from "next/navigation"; -import { getServerSession } from "../../../../../../../../../functions/server/getServerSession"; -import { - getNextGuidedStep, - StepDeterminationData, -} from "../../../../../../../../../functions/server/getRelevantGuidedSteps"; -import { getCountryCode } from "../../../../../../../../../functions/server/getCountryCode"; -import { headers } from "next/headers"; -import { - getMockedScanResults, - getMockedScanResultsWithBrokerUnderMaintenance, - getScanResultsWithBroker, - getScanResultsWithBrokerUnderMaintenance, -} from "../../../../../../../../../../db/tables/onerep_scans"; -import { getOnerepProfileId } from "../../../../../../../../../../db/tables/subscribers"; -import { getSubscriberBreaches } from "../../../../../../../../../functions/server/getSubscriberBreaches"; -import { getSubscriberEmails } from "../../../../../../../../../functions/server/getSubscriberEmails"; -import { RemovalUnderMaintenanceView } from "./RemovalUnderMaintenanceView"; -import { hasPremium } from "../../../../../../../../../functions/universal/user"; -import { getEnabledFeatureFlags } from "../../../../../../../../../../db/tables/featureFlags"; - -export default async function RemovalUnderMaintenance() { - const session = await getServerSession(); - const countryCode = getCountryCode(await headers()); - - if (!session?.user?.subscriber?.id) { - return redirect("/"); - } - - const enabledFeatureFlags = await getEnabledFeatureFlags({ - email: session.user.email, - }); - - if ( - !hasPremium(session.user) || - !enabledFeatureFlags.includes("EnableRemovalUnderMaintenanceStep") - ) { - redirect("/user/dashboard"); - } - - const profileId = await getOnerepProfileId(session.user.subscriber.id); - const useMockedScans = - enabledFeatureFlags.includes("CustomDataBrokers") && - process.env.APP_ENV !== "production"; - - const scanResultsWithRemovalUnderMaintenance = useMockedScans - ? await getMockedScanResultsWithBrokerUnderMaintenance(profileId) - : await getScanResultsWithBrokerUnderMaintenance(profileId); - - const scanResults = useMockedScans - ? await getMockedScanResults(profileId) - : // MNTOR-4893: Implement removal under maintenance? - await getScanResultsWithBroker(profileId, hasPremium(session.user)); - - const data: StepDeterminationData = { - countryCode, - user: session.user, - latestScanData: scanResults ?? null, - subscriberBreaches: await getSubscriberBreaches({ - fxaUid: session.user.subscriber.fxa_uid, - countryCode, - }), - }; - - const getNextStep = getNextGuidedStep( - data, - enabledFeatureFlags, - "DataBrokerManualRemoval", - ); - - if ( - scanResultsWithRemovalUnderMaintenance?.results.length === 0 || - !scanResultsWithRemovalUnderMaintenance - ) { - redirect(getNextStep.href); - } - - const subscriberEmails = await getSubscriberEmails(session.user); - - return ( - - ); -} diff --git a/src/app/components/client/FixNavigation.tsx b/src/app/components/client/FixNavigation.tsx index d69945525d1..f3d8d38342f 100644 --- a/src/app/components/client/FixNavigation.tsx +++ b/src/app/components/client/FixNavigation.tsx @@ -83,12 +83,8 @@ export const Steps = (props: { {label} {count > 0 && `(${count})`} ); - const dataBrokerStepCompleted = - hasCompletedStepSection(props.data, "Scan") && - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - /* c8 ignore next */ - (!props.enabledFeatureFlags.includes("EnableRemovalUnderMaintenanceStep") || - hasCompletedStepSection(props.data, "DataBrokerManualRemoval")); + + const dataBrokerStepCompleted = hasCompletedStepSection(props.data, "Scan"); return (
    diff --git a/src/app/components/client/exposure_card/ExposureCard.stories.tsx b/src/app/components/client/exposure_card/ExposureCard.stories.tsx index 11e5fd895f1..cf8e6171f15 100644 --- a/src/app/components/client/exposure_card/ExposureCard.stories.tsx +++ b/src/app/components/client/exposure_card/ExposureCard.stories.tsx @@ -52,11 +52,6 @@ const ScanMockItemInProgress = createRandomScanResult({ manually_resolved: false, }); -const ScanMockItemRemovalUnderMaintenance = createRandomScanResult({ - status: "optout_in_progress", - manually_resolved: false, - broker_status: "removal_under_maintenance", -}); const ScanMockItemNoExposureData: OnerepScanResultDataBrokerRow = { id: 0, onerep_scan_result_id: 123, @@ -82,21 +77,6 @@ const ScanMockItemNoExposureData: OnerepScanResultDataBrokerRow = { addresses: [], }; -const ScanMockItemRemovalUnderMaintenanceManuallyFixed = createRandomScanResult( - { - status: "optout_in_progress", - manually_resolved: true, - broker_status: "removal_under_maintenance", - }, -); - -const ScanMockItemRemovalUnderMaintenanceAutomaticallyRemoved = - createRandomScanResult({ - status: "removed", - manually_resolved: false, - broker_status: "removal_under_maintenance", - }); - const BreachMockItemRemoved = createRandomBreach({ isResolved: true, dataClassesEffected: [ @@ -161,33 +141,6 @@ export const DataBreachActionNeeded: Story = { }, }; -export const DataBrokerRemovalUnderMaintenance: Story = { - args: { - exposureImg: FamilyTreeImage, - exposureData: ScanMockItemRemovalUnderMaintenance, - isPremiumUser: true, - enabledFeatureFlags: ["EnableRemovalUnderMaintenanceStep"], - }, -}; - -export const DataBrokerRemovalUnderMaintenanceFixed: Story = { - args: { - exposureImg: FamilyTreeImage, - exposureData: ScanMockItemRemovalUnderMaintenanceManuallyFixed, - isPremiumUser: true, - enabledFeatureFlags: ["EnableRemovalUnderMaintenanceStep"], - }, -}; - -export const DataBrokerRemovalUnderMaintenanceAutomaticallyRemoved: Story = { - args: { - exposureImg: FamilyTreeImage, - exposureData: ScanMockItemRemovalUnderMaintenanceAutomaticallyRemoved, - isPremiumUser: true, - enabledFeatureFlags: ["EnableRemovalUnderMaintenanceStep"], - }, -}; - export const DataBreachFixed: Story = { args: { exposureImg: TwitterImage, diff --git a/src/app/components/client/exposure_card/ExposureCard.test.tsx b/src/app/components/client/exposure_card/ExposureCard.test.tsx index 40bb40a3b0c..0601d015ecd 100644 --- a/src/app/components/client/exposure_card/ExposureCard.test.tsx +++ b/src/app/components/client/exposure_card/ExposureCard.test.tsx @@ -15,12 +15,8 @@ import Meta, { DataBrokerManualRemoved, DataBrokerRemoved, DataBrokerRequestedRemoval, - DataBrokerRemovalUnderMaintenance, - DataBrokerRemovalUnderMaintenanceFixed, - DataBrokerRemovalUnderMaintenanceAutomaticallyRemoved, DataBrokerActionNeededNoExposureResults, } from "./ExposureCard.stories"; -import { isDataBrokerUnderMaintenance } from "../../../(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/View"; import { createRandomScanResult } from "../../../../apiMocks/mockData"; jest.mock("../../../hooks/useTelemetry"); @@ -115,52 +111,6 @@ describe("ScanResultCard", () => { expect(innerDescription).toBeInTheDocument(); }); - // Data broker removal under maintenance unresolved - it("shows the right description for a scan result card with removal under maintenance status", () => { - const ComposedProgressCard = composeStory( - DataBrokerRemovalUnderMaintenance, - Meta, - ); - render(); - const innerDescription = screen.getByText( - "We’ve asked this data broker to remove your profile but they haven’t done it.", - { exact: false }, - ); - - expect(innerDescription).toBeInTheDocument(); - }); - - // Data broker removal under maintenance manually removed - it("shows the right description for a scan result card with removal under maintenance status that's been manually resolved", () => { - const ComposedProgressCard = composeStory( - DataBrokerRemovalUnderMaintenanceFixed, - Meta, - ); - render(); - const innerDescription = screen.getByText( - "You could be added back in the future, so ⁨Monitor⁩ will continue to scan data broker sites for new exposures.", - { exact: false }, - ); - - expect(innerDescription).toBeInTheDocument(); - }); - - // Data broker removal under maintenance automatically removed - it("shows the right description for a scan result card with removal under maintenance status that's been automatically resolved", () => { - const ComposedProgressCard = composeStory( - DataBrokerRemovalUnderMaintenanceAutomaticallyRemoved, - Meta, - ); - - render(); - const innerDescription = screen.getByText( - "will continually monitor to make sure they don’t add you back", - { exact: false }, - ); - - expect(innerDescription).toBeInTheDocument(); - }); - // Data broker removal in progress it("shows the right description for a scan result card where removal is in progress", () => { const ComposedProgressCard = composeStory(DataBrokerInProgress, Meta); @@ -173,20 +123,6 @@ describe("ScanResultCard", () => { expect(innerDescription).toBeInTheDocument(); }); - it("shows the right description for a scan result card where removal is under maintenance", () => { - const ComposedProgressCard = composeStory( - DataBrokerRemovalUnderMaintenance, - Meta, - ); - render(); - const innerDescription = screen.getByText( - "We’ve asked this data broker to remove your profile but they haven’t done it.", - { exact: false }, - ); - - expect(innerDescription).toBeInTheDocument(); - }); - it("shows an additional note for “requested removal” status label if the feature flag `DataBrokerRemovalAttempts` is enabled", () => { const ComposedProgressCard = composeStory(DataBrokerRequestedRemoval, Meta); render(); @@ -373,25 +309,3 @@ describe("DataBreachCard", () => { expect(removalTimeLabel).toBeInTheDocument(); }); }); - -it("returns false for brokers not under maintenance", () => { - const result = isDataBrokerUnderMaintenance( - createRandomScanResult({ - broker_status: "active", - status: "optout_in_progress", - }), - ); - - expect(result).toBe(false); -}); - -it("returns false for brokers under maintenance that are removed", () => { - const result = isDataBrokerUnderMaintenance( - createRandomScanResult({ - broker_status: "removal_under_maintenance", - status: "removed", - }), - ); - - expect(result).toBe(false); -}); diff --git a/src/app/components/client/exposure_card/ScanResultCard.tsx b/src/app/components/client/exposure_card/ScanResultCard.tsx index a51ba47371d..53f1f5e7aa3 100644 --- a/src/app/components/client/exposure_card/ScanResultCard.tsx +++ b/src/app/components/client/exposure_card/ScanResultCard.tsx @@ -17,7 +17,6 @@ import { TelemetryLink } from "../TelemetryLink"; import { FeatureFlagName } from "../../../../db/tables/featureFlags"; import { ExperimentData } from "../../../../telemetry/generated/nimbus/experiments"; import SparkleImage from "../assets/sparkle.png"; -import { isDataBrokerUnderMaintenance } from "../../../(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/View"; import { UpsellLinkButton } from "../toolbar/UpsellBadge"; import { parseIso8601Datetime } from "../../../../utils/parse"; @@ -112,27 +111,6 @@ export const ScanResultCard = (props: ScanResultCardProps) => { // Data broker cards manually resolved do not change their status to "removed"; // instead, we track them using the "manually_resolved" property. - if ( - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - props.enabledFeatureFlags.includes("EnableRemovalUnderMaintenanceStep") && - isDataBrokerUnderMaintenance(props.scanResult) - ) { - if (scanResult.manually_resolved) { - return l10n.getFragment( - "exposure-card-description-info-for-sale-fixed-removal-under-maintenance-manually-fixed", - { elems: { data_broker_profile: dataBrokerProfileLink } }, - ); - } - return l10n.getFragment( - "exposure-card-description-info-for-sale-manual-removal-needed", - { - elems: { - b: , - }, - }, - ); - } - if (scanResult.manually_resolved) { return l10n.getFragment( "exposure-card-description-info-for-sale-fixed-manually-fixed", @@ -260,14 +238,6 @@ export const ScanResultCard = (props: ScanResultCardProps) => { ); } - if ( - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - props.enabledFeatureFlags.includes("EnableRemovalUnderMaintenanceStep") && - isDataBrokerUnderMaintenance(props.scanResult) - ) { - return {props.resolutionCta}; - } - switch (props.scanResult.status) { case "new": return {props.resolutionCta}; @@ -346,9 +316,6 @@ export const ScanResultCard = (props: ScanResultCardProps) => {
    { const pillType = hasDirectType(props) ? props.type - : getExposureStatus( - props.exposure, - props.isRemovalUnderMaintenance || false, - props.enabledFeatureFlags ?? [], - ); + : getExposureStatus(props.exposure, props.enabledFeatureFlags ?? []); return (
    @@ -53,12 +48,6 @@ export const StatusPill = (props: Props) => { exposure: props.exposure, pillType, l10n, - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - isDataBrokerUnderMaintenance: props.enabledFeatureFlags?.includes( - "EnableRemovalUnderMaintenanceStep", - ) - ? props.isRemovalUnderMaintenance - : undefined, }) : getStatusLabel({ pillType, @@ -78,7 +67,6 @@ type StatusLabelProps = { exposure?: Exposure; pillType: string; l10n: ExtendedReactLocalization; - isDataBrokerUnderMaintenance?: boolean; }; const getStatusLabel = (props: StatusLabelProps): string => { @@ -91,10 +79,6 @@ const getStatusLabel = (props: StatusLabelProps): string => { return props.l10n.getString("status-pill-removed"); } - if (props.isDataBrokerUnderMaintenance) { - return props.l10n.getString("status-pill-action-needed"); - } - switch (props.pillType) { case StatusPillTypeMap.RequestedRemoval: return props.l10n.getString("status-pill-requested-removal"); @@ -112,26 +96,17 @@ const getStatusLabel = (props: StatusLabelProps): string => { export const getExposureStatus = ( exposure: Exposure, - isRemovalUnderMaintenance: boolean, enabledFeatureFlags: FeatureFlagName[], ): StatusPillType => { if (isScanResult(exposure)) { const additionalRemovalStatusesEnabled = enabledFeatureFlags.includes( "AdditionalRemovalStatuses", ); - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - const manualRemovalEnabled = enabledFeatureFlags.includes( - "EnableRemovalUnderMaintenanceStep", - ); if (exposure.manually_resolved) { return "fixed"; } - if (manualRemovalEnabled && isRemovalUnderMaintenance) { - return "actionNeeded"; - } - switch (exposure.status) { case "removed": return "removed"; diff --git a/src/app/functions/server/dashboard.ts b/src/app/functions/server/dashboard.ts index d34dfac306e..62b27424e5a 100644 --- a/src/app/functions/server/dashboard.ts +++ b/src/app/functions/server/dashboard.ts @@ -6,7 +6,6 @@ import { OnerepScanResultDataBrokerRow } from "knex/types/tables"; import { BreachDataTypes } from "../universal/breach"; import { RemovalStatusMap } from "../universal/scanResult"; import { SubscriberBreach } from "../../../utils/subscriberBreaches"; -import { DataBrokerRemovalStatusMap } from "../universal/dataBroker"; import { FeatureFlagName } from "../../../db/tables/featureFlags"; export type DataPoints = { @@ -98,7 +97,7 @@ export const dataClassKeyMap: Record = { export function getDashboardSummary( scannedResults: OnerepScanResultDataBrokerRow[], subscriberBreaches: SubscriberBreach[], - enabledFeatureFlags?: FeatureFlagName[], + _enabledFeatureFlags?: FeatureFlagName[], ): DashboardSummary { const summary: DashboardSummary = { dataBreachTotalNum: 0, @@ -207,22 +206,8 @@ export function getDashboardSummary( r.status === RemovalStatusMap.WaitingForVerification) && !isManuallyResolved; - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - // If the flag is disabled, include the data. - // If the flag is enabled, include the data only if the broker status is not - const isRemovalUnderMaintenance = - r.broker_status === DataBrokerRemovalStatusMap.RemovalUnderMaintenance; - - // The condition ensures that removal under maintenance is only considered when the flag is enabled. - /* c8 ignore next 3 */ - const countRemovalUnderMaintenanceData = - !enabledFeatureFlags?.includes("EnableRemovalUnderMaintenanceStep") || - !isRemovalUnderMaintenance; - if (isInProgress) { - if (countRemovalUnderMaintenanceData) { - summary.dataBrokerInProgressNum++; - } + summary.dataBrokerInProgressNum++; } else if (isAutoFixed) { summary.dataBrokerAutoFixedNum++; } else if (isManuallyResolved) { @@ -244,13 +229,11 @@ export function getDashboardSummary( summary.allDataPoints.familyMembers += r.relatives.length; if (isInProgress) { - if (countRemovalUnderMaintenanceData) { - summary.inProgressDataPoints.emailAddresses += r.emails.length; - summary.inProgressDataPoints.phoneNumbers += r.phones.length; - summary.inProgressDataPoints.addresses += r.addresses.length; - summary.inProgressDataPoints.familyMembers += r.relatives.length; - summary.dataBrokerInProgressDataPointsNum += dataPointsIncrement; - } + summary.inProgressDataPoints.emailAddresses += r.emails.length; + summary.inProgressDataPoints.phoneNumbers += r.phones.length; + summary.inProgressDataPoints.addresses += r.addresses.length; + summary.inProgressDataPoints.familyMembers += r.relatives.length; + summary.dataBrokerInProgressDataPointsNum += dataPointsIncrement; } // for fixed data points: email, phones, addresses, relatives, full name (1) diff --git a/src/app/functions/server/getRelevantGuidedSteps.test.ts b/src/app/functions/server/getRelevantGuidedSteps.test.ts index 79ab5870af5..60a6120c64a 100644 --- a/src/app/functions/server/getRelevantGuidedSteps.test.ts +++ b/src/app/functions/server/getRelevantGuidedSteps.test.ts @@ -3,11 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { describe, expect, it } from "@jest/globals"; -import { - getNextGuidedStep, - hasCompletedStep, - isEligibleForStep, -} from "./getRelevantGuidedSteps"; +import { getNextGuidedStep, hasCompletedStep } from "./getRelevantGuidedSteps"; import { createRandomBreach, createRandomScanResult, @@ -650,42 +646,7 @@ describe("getNextGuidedStep", () => { ).toBe("Done"); }); - it("links to the removal under maintenance step if a user has scan results with a data broker that has a removal under maintenance status", () => { - expect( - getNextGuidedStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - status: "optout_in_progress", - manually_resolved: false, - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { - email: "arbitrary@example.com", - }, - }, - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toStrictEqual({ - href: "/user/dashboard/fix/data-broker-profiles/removal-under-maintenance", - id: "DataBrokerManualRemoval", - completed: false, - eligible: true, - }); - }); - - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - it("does not link to the removal under maintenance step if the feature flag is off", () => { + it("does not link to the removal under maintenance step", () => { expect( getNextGuidedStep( { @@ -713,92 +674,7 @@ describe("getNextGuidedStep", () => { ).toBe("Done"); }); - it("returns true when all data brokers that are removal under maintenance are resolved", () => { - expect( - hasCompletedStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: true, - status: "optout_in_progress", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(true); - }); - - it("returns false when data brokers that are removal under maintenance are not resolved", () => { - expect( - hasCompletedStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: false, - status: "optout_in_progress", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(false); - }); - - it("returns true when data brokers that are removal under maintenance are automatically resolved", () => { - expect( - hasCompletedStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: false, - status: "removed", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(true); - }); - - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - it("returns false when data brokers that are removal under maintenance are resolved, but the flag is off", () => { + it("returns false when data brokers that are removal under maintenance are resolved", () => { expect( hasCompletedStep( { @@ -825,127 +701,6 @@ describe("getNextGuidedStep", () => { ).toBe(false); }); - it("is not eligible for step if the data brokers under maintenance is already removed", () => { - expect( - isEligibleForStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: false, - status: "removed", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(false); - }); - - it("is not eligible for step if the data brokers under maintenance is already manually resolved", () => { - expect( - isEligibleForStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: true, - status: "optout_in_progress", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(false); - }); - - it("is not eligible for step if the data brokers under maintenance is already automatically resolved", () => { - expect( - isEligibleForStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: false, - status: "removed", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(false); - }); - - it("is eligible for step if there are valid data brokers under maintenance", () => { - expect( - isEligibleForStep( - { - countryCode: "us", - latestScanData: { - scan: { - ...completedScan.scan!, - onerep_scan_status: "finished", - }, - results: [ - createRandomScanResult({ - manually_resolved: true, - status: "optout_in_progress", - broker_status: "removal_under_maintenance", - }), - createRandomScanResult({ - manually_resolved: false, - status: "removed", - broker_status: "removal_under_maintenance", - }), - createRandomScanResult({ - manually_resolved: false, - status: "optout_in_progress", - broker_status: "removal_under_maintenance", - }), - ], - }, - subscriberBreaches: [], - user: { email: "arbitrary@example.com" }, - }, - "DataBrokerManualRemoval", - ["EnableRemovalUnderMaintenanceStep"], - ), - ).toBe(true); - }); - it("links to the Credit Card step if the user's credit card has been breached", () => { expect( getNextGuidedStep( diff --git a/src/app/functions/server/getRelevantGuidedSteps.ts b/src/app/functions/server/getRelevantGuidedSteps.ts index 8909a43c162..f283cf8f029 100644 --- a/src/app/functions/server/getRelevantGuidedSteps.ts +++ b/src/app/functions/server/getRelevantGuidedSteps.ts @@ -144,26 +144,6 @@ export function isEligibleForStep( enabledFeatureFlags?: FeatureFlagName[], ): boolean { // Only premium users can see the manual data broker removal flow, once they have run a scan - /* c8 ignore start */ - if ( - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - enabledFeatureFlags?.includes("EnableRemovalUnderMaintenanceStep") && - stepId === "DataBrokerManualRemoval" - ) { - return ( - data.latestScanData?.results?.some((result) => { - return ( - result.broker_status === "removal_under_maintenance" && - result.status !== "removed" && - !result.manually_resolved - ); - // MNTOR-3892 - // Already covered by unit test - }) ?? false - ); - } - /* c8 ignore stop */ - if (stepId === "Scan") { return ( data.countryCode === "us" && @@ -220,17 +200,8 @@ export function hasCompletedStepSection( | "LeakedPasswords" | "SecurityTips" | "DataBrokerManualRemoval", - enabledFeatureFlags?: FeatureFlagName[], + _enabledFeatureFlags?: FeatureFlagName[], ): boolean { - /* c8 ignore next 8 */ - // Already covered by unit tests - if ( - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - enabledFeatureFlags?.includes("EnableRemovalUnderMaintenanceStep") && - section === "DataBrokerManualRemoval" - ) { - return hasCompletedStep(data, "DataBrokerManualRemoval"); - } if (section === "Scan") { return hasCompletedStep(data, "Scan"); } @@ -265,26 +236,8 @@ export function hasCompletedStepSection( export function hasCompletedStep( data: StepDeterminationData, stepId: StepLink["id"], - enabledFeatureFlags?: FeatureFlagName[], + _enabledFeatureFlags?: FeatureFlagName[], ): boolean { - /* c8 ignore start */ - if ( - // TODO: MNTOR-3886 - Remove EnableRemovalUnderMaintenanceStep feature flag - enabledFeatureFlags?.includes("EnableRemovalUnderMaintenanceStep") && - stepId === "DataBrokerManualRemoval" - ) { - return ( - data.latestScanData?.results?.every( - (result) => - result.broker_status !== "removal_under_maintenance" || - result.status === "removed" || - result.manually_resolved, - // MNTOR-3892 - // Already covered by unit tests - ) ?? false - ); - } - /* c8 ignore stop */ if (stepId === "Scan") { const hasRunScan = typeof data.latestScanData?.scan === "object" && diff --git a/src/db/tables/featureFlags.ts b/src/db/tables/featureFlags.ts index c135b6fab4d..1690414be28 100644 --- a/src/db/tables/featureFlags.ts +++ b/src/db/tables/featureFlags.ts @@ -61,7 +61,6 @@ export const featureFlagNames = [ "DataBrokerRemovalTimeEstimateLabel", "DataBrokerRemovalTimeEstimateCsat", "LandingPageRedesign", - "EnableRemovalUnderMaintenanceStep", "CirrusV2", "DataBrokerRemovalAttempts", "CustomDataBrokers", diff --git a/src/db/tables/onerep_scans.ts b/src/db/tables/onerep_scans.ts index 2a9f93d2639..232f75cfc18 100644 --- a/src/db/tables/onerep_scans.ts +++ b/src/db/tables/onerep_scans.ts @@ -17,7 +17,6 @@ import { OnerepScanResultDataBrokerRow, } from "knex/types/tables"; import { RemovalStatus } from "../../app/functions/universal/scanResult.js"; -import { CONST_DAY_MILLISECONDS } from "../../constants.ts"; import { getAllMockedScanResults } from "./qa_customs.ts"; const knex = createDbConnection(); @@ -431,45 +430,6 @@ async function getEmailForProfile(onerepProfileId: number) { } /* c8 ignore stop */ -// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy -/* c8 ignore start */ -// MNTOR-4893: Re-implement ? -async function getScanResultsWithBrokerUnderMaintenance( - onerepProfileId: number | null, -): Promise { - if (onerepProfileId === null) { - return { results: [], scan: null }; - } - - let scanResults: OnerepScanResultDataBrokerRow[] = await knex( - "onerep_scan_results as sr", - ) - .select( - "sr.*", - "s.*", - "sr.status as scan_result_status", // rename to avoid collision - "db.status as broker_status", // rename to avoid collision - ) - .distinctOn("link") - .innerJoin("onerep_scans as s", "sr.onerep_scan_id", "s.onerep_scan_id") - .where("s.onerep_profile_id", onerepProfileId) - .andWhere("sr.manually_resolved", "false") - .andWhereNot("sr.status", "removed") - .join("onerep_data_brokers as db", "sr.data_broker", "db.data_broker") - .orderBy("link") - .orderBy("sr.onerep_scan_result_id"); - - scanResults = scanResults.filter( - (result) => - result.broker_status === "removal_under_maintenance" || - new Date().getTime() - new Date(result.updated_at).getTime() > - CONST_DAY_MILLISECONDS * 200, - ); - - return { results: scanResults } as LatestOnerepScanData; -} -/* c8 ignore stop */ - // Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy /* c8 ignore start */ /** @deprecated */ @@ -531,36 +491,6 @@ async function getMockedScanResults( } /* c8 ignore stop */ -// Not covered by tests; mostly side-effects. See test-coverage.md#mock-heavy -/* c8 ignore start */ -/** @deprecated */ -async function getMockedScanResultsWithBrokerUnderMaintenance( - onerepProfileId: number | null, -): Promise { - if (onerepProfileId === null) { - return { - scan: null, - results: [], - } as LatestOnerepScanData; - } - - let scanResults = (await knex("qa_custom_brokers") - .where("broker_status", "removal_under_maintenance") - .where("manually_resolved", false) - .where("onerep_scan_id", onerepProfileId) - .select("*")) as OnerepScanResultDataBrokerRow[]; - - scanResults = scanResults.filter( - (result) => - result.broker_status === "removal_under_maintenance" || - new Date().getTime() - new Date(result.updated_at).getTime() > - CONST_DAY_MILLISECONDS * 200, - ); - - return { results: scanResults } as LatestOnerepScanData; -} -/* c8 ignore stop */ - export { getAllScansForProfile, getLatestScanForProfileByReason, @@ -576,10 +506,8 @@ export { deleteScanResultsForProfile, deleteSomeScansForProfile, getEmailForProfile, - getScanResultsWithBrokerUnderMaintenance, getScanResultsWithBroker, getMockedScanResults, - getMockedScanResultsWithBrokerUnderMaintenance, /** @deprecated This has been replaced by getScanResultsWithBroker */ getLatestOnerepScanResults, };