Merge branch 'fix-typo-drive' into 'main'
[ProtonMail-WebClient.git] / packages / unleash / storage / UnleashCookiesProvider.test.ts
bloba52db8a03d43ed05768a8cab9cfaa2097022150d
1 import { addDays, endOfDay } from 'date-fns';
3 import * as cookiesModule from '@proton/shared/lib/helpers/cookies';
5 import { type FeatureFlagToggle } from '../interface';
6 import saveWhitelistedFlagInCookies, { UNLEASH_FLAG_COOKIE_NAME } from './UnleashCookiesProvider';
8 // ------------------------------
9 // Mocks
10 // ------------------------------
11 jest.mock('@proton/shared/lib/helpers/cookies', () => ({
12     getCookie: jest.fn(),
13     setCookie: jest.fn(),
14     deleteCookie: jest.fn(),
15 }));
17 // ------------------------------
18 // Spies
19 // ------------------------------
20 const getCookieSpys = () => {
21     return {
22         getCookie: jest.spyOn(cookiesModule, 'getCookie'),
23         setCookie: jest.spyOn(cookiesModule, 'setCookie'),
24         deleteCookie: jest.spyOn(cookiesModule, 'deleteCookie'),
25     };
28 // ------------------------------
29 // Helpers
30 // ------------------------------
31 const generateFlag = (name: string, variantName: string, flagEnabled?: boolean, variantEnabled?: boolean) => {
32     return {
33         enabled: flagEnabled ?? true,
34         name,
35         variant: {
36             name: variantName,
37             enabled: variantEnabled ?? true,
38         },
39     } satisfies FeatureFlagToggle;
42 // ------------------------------
43 // Test suite
44 // ------------------------------
45 describe('UnleashCookiesProvider', () => {
46     beforeAll(() => {
47         Object.defineProperty(globalThis, 'window', {
48             value: { location: { hostname: 'www.example.com' } },
49             writable: true,
50         });
51     });
53     beforeEach(() => {
54         jest.clearAllMocks();
55     });
57     describe('Whitelisted flag with variant', () => {
58         beforeEach(() => {
59             const whitelistedFlags = ['ValidFlag'];
60             const unleashFlagsList = [generateFlag('ValidFlag', 'VariantA'), generateFlag('InvalidFlag', 'VariantB')];
61             saveWhitelistedFlagInCookies(unleashFlagsList, whitelistedFlags);
62         });
64         it.each([
65             ['cookieName', UNLEASH_FLAG_COOKIE_NAME],
66             ['cookieValue', 'ValidFlag:VariantA'],
67             ['path', '/'],
68             ['secure', true],
69             ['expirationDate', endOfDay(addDays(new Date(), 30)).toUTCString()],
70             ['domain', 'www.example.com'],
71         ])('%s key should be set to %j', (key, value) => {
72             const { setCookie } = getCookieSpys();
73             expect(setCookie).toHaveBeenCalledWith(
74                 expect.objectContaining({
75                     [key]: value,
76                 })
77             );
78         });
79     });
81     it('Should not save non whitelisted flag with variant', () => {
82         const { setCookie } = getCookieSpys();
83         const whitelistedFlags = ['ValidFlag'];
84         const unleashFlagsList = [generateFlag('ValidFlag', 'VariantA'), generateFlag('InvalidFlag', 'VariantB')];
86         saveWhitelistedFlagInCookies(unleashFlagsList, whitelistedFlags);
87         expect(setCookie).toHaveBeenCalledWith(
88             expect.objectContaining({
89                 cookieValue: 'ValidFlag:VariantA',
90             })
91         );
92     });
94     it('Should not save disabled flags', () => {
95         const { setCookie } = getCookieSpys();
96         const whitelistedFlags = ['ValidFlag'];
97         const unleashFlagsList = [
98             generateFlag('ValidFlag', 'VariantA', false, true),
99             generateFlag('InvalidFlag', 'VariantB'),
100         ];
102         saveWhitelistedFlagInCookies(unleashFlagsList, whitelistedFlags);
103         expect(setCookie).not.toHaveBeenCalled();
104     });
106     it('Should not save enabled flag with disabled variant', () => {
107         const { setCookie } = getCookieSpys();
108         const whitelistedFlags = ['ValidFlag'];
109         const unleashFlagsList = [
110             generateFlag('ValidFlag', 'VariantA', true, false),
111             generateFlag('InvalidFlag', 'VariantB'),
112         ];
114         saveWhitelistedFlagInCookies(unleashFlagsList, whitelistedFlags);
115         expect(setCookie).not.toHaveBeenCalled();
116     });
118     describe('Should not save flag or variant with invalid characters', () => {
119         const cases = [
120             ['coma in flag name', 'Invalid,Flag', 'VariantA'],
121             ['colon in flag name', 'Invalid:Flag', 'VariantA'],
122             ['space in flag name', 'Invalid Flag', 'VariantA'],
123             ['coma in variantName', 'Flag', 'Invalid,Variant'],
124             ['colon in variantName', 'Flag', 'Invalid:Variant'],
125             ['space in variantName', 'Flag', 'Invalid Variant'],
126         ];
128         it.each(cases)('%s should not be saved', async (_, flagName, variantName) => {
129             const { setCookie } = getCookieSpys();
130             const whitelistedFlags = [flagName];
131             const unleashFlagsList = [generateFlag(flagName, variantName)];
133             saveWhitelistedFlagInCookies(unleashFlagsList, whitelistedFlags);
134             expect(setCookie).not.toHaveBeenCalled();
135         });
136     });