• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / fx-private-relay / 884a4ed9-7ba0-4252-adb7-c15a0bd9c086

13 Oct 2025 08:41PM UTC coverage: 88.859% (-0.006%) from 88.865%
884a4ed9-7ba0-4252-adb7-c15a0bd9c086

Pull #5944

circleci

vpremamozilla
MPP-4229 - task(tests): consolidate and centralize test mocks
Pull Request #5944: MPP-4229 - Consolidate and Centralize Test Mocks

2916 of 3927 branches covered (74.26%)

Branch coverage included in aggregate %.

0 of 2 new or added lines in 1 file covered. (0.0%)

42 existing lines in 2 files now uncovered.

18076 of 19697 relevant lines covered (91.77%)

11.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/frontend/src/pages/_app.page.tsx
1
/* eslint-disable @typescript-eslint/no-explicit-any */
2
import "../styles/globals.scss";
×
3
import { createElement, useEffect, useRef, useState } from "react";
×
4
import type { AppProps } from "next/app";
5
import { useRouter } from "next/router";
×
6
import { LocalizationProvider, ReactLocalization } from "@fluent/react";
×
7
import { OverlayProvider } from "@react-aria/overlays";
×
8
import ReactGa from "react-ga";
×
9
import { getL10n } from "../functions/getL10n";
×
10
import { AddonDataContext, useAddonElementWatcher } from "../hooks/addon";
×
11
import { ReactAriaI18nProvider } from "../components/ReactAriaI18nProvider";
×
12
import { useIsLoggedIn } from "../hooks/session";
×
13
import { useMetrics } from "../hooks/metrics";
×
14
import {
15
  useGoogleAnalytics,
16
  initGoogleAnalytics,
17
} from "../hooks/googleAnalytics";
×
18
import "@stripe/stripe-js";
×
19

20
function MyApp({ Component, pageProps }: AppProps) {
21
  const router = useRouter();
×
22
  const isLoggedIn = useIsLoggedIn();
×
23
  const googleAnalytics = useGoogleAnalytics();
×
24
  const metricsEnabled = useMetrics();
×
25
  const addonDataElementRef = useRef<HTMLElement>(null);
×
26

27
  const addonData = useAddonElementWatcher(addonDataElementRef);
×
28
  const [l10n, setL10n] = useState<ReactLocalization>(
×
29
    getL10n({ deterministicLocales: true }),
30
  );
31

32
  useEffect(() => {
×
33
    // When pre-rendering and on the first render, we deterministically load the
34
    // `en` bundle.  After that, however, we want to load the bundles relevant
35
    // to the user's preferred locales. (See the `useL10n` hook for more detail
36
    // on why.) Unfortunately we can't load additional needed locales
37
    // asynchronously on the client-side yet using @fluent/react, see
38
    // https://github.com/projectfluent/fluent.js/wiki/ReactLocalization/43a959b35fbf9eea694367f948cfb1387914657c#flexibility
39
    setL10n(getL10n({ deterministicLocales: false }));
×
40
  }, []);
41

42
  useEffect(() => {
×
43
    if (metricsEnabled === "enabled" && !googleAnalytics) {
×
44
      initGoogleAnalytics();
×
45
    }
46
  }, [metricsEnabled, googleAnalytics]);
47

48
  useEffect(() => {
×
49
    if (!googleAnalytics) return;
×
50
    ReactGa.pageview(router.asPath);
×
51
  }, [router.asPath, googleAnalytics]);
52

53
  const [waitingForMsw, setIsWaitingForMsw] = useState(
×
54
    process.env.NEXT_PUBLIC_MOCK_API === "true",
55
  );
56
  useEffect(() => {
×
57
    if (process.env.NEXT_PUBLIC_MOCK_API !== "true") {
×
58
      return;
×
59
    }
60
    (async () => {
×
NEW
61
      const { initialiseApiMocks } = await import(
×
62
        "../../__mocks__/api/initialise"
63
      );
NEW
64
      const { mockIds } = await import("../../__mocks__/api/mockData");
×
65

66
      await initialiseApiMocks();
×
67

68
      if (
×
69
        typeof URLSearchParams !== "undefined" &&
×
70
        typeof document !== "undefined"
71
      ) {
72
        // When deploying the frontend with a mocked back-end,
73
        // this query parameter will allow us to automatically "sign in" with one
74
        // of the mock users. This is useful to be able to give testers a link
75
        // in which to see a particular feature:
76
        const searchParams = new URLSearchParams(document.location.search);
×
77
        const mockId = searchParams.get("mockId");
×
78
        const selectedMockId = mockIds.find((id) => id === mockId);
×
79
        if (typeof selectedMockId === "string") {
×
80
          // See `src/hooks/api/api.ts`; this localStorage entry is how we tell the
81
          // API mock what mock data we want to load:
82
          localStorage.setItem("authToken", selectedMockId);
×
83
        }
84
      }
85

86
      setIsWaitingForMsw(false);
×
87
    })();
88
  }, []);
89

90
  if (waitingForMsw) {
×
91
    // As soon as we start rendering the app, it will start sending requests.
92
    // If we're running the demo site, we want to hold off on doing that until
93
    // MSW is fully initialised. Usually, you'd run the initialisation before
94
    // rendering in the first place, but since Next.js handles the start of the
95
    // rendering (which it does to support server-side rendering), we're doing
96
    // it here instead. For more info, see
97
    // https://mswjs.io/docs/integrations/browser#conditionally-enable-mocking
98
    return <></>;
×
99
  }
100

101
  return (
102
    <LocalizationProvider l10n={l10n}>
103
      <ReactAriaI18nProvider>
104
        <AddonDataContext.Provider value={addonData}>
105
          {createElement("firefox-private-relay-addon", {
106
            // The following attributes are set by the add-on,
107
            // and read by the website (via the useAddonElementWatcher hook).
108
            "data-addon-installed": addonData.present,
109
            "data-local-labels": JSON.stringify(addonData.localLabels),
110
            // The following attributes are set by the website,
111
            // and read by the add-on.
112
            // Capitalised boolean for backwards compatibility;
113
            // this element was previously generated by Django:
114
            "data-user-logged-in":
115
              isLoggedIn === "logged-in" ? "True" : "False",
×
116
          })}
117
          <OverlayProvider id="overlayProvider">
118
            <Component {...pageProps} />
119
          </OverlayProvider>
120
        </AddonDataContext.Provider>
121
      </ReactAriaI18nProvider>
122
    </LocalizationProvider>
123
  );
124
}
125
export default MyApp;
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc