diff --git a/apps/web/composables/useJsonEditor/useJsonEditor.ts b/apps/web/composables/useJsonEditor/useJsonEditor.ts index 75c087f3d..6a666f8fc 100644 --- a/apps/web/composables/useJsonEditor/useJsonEditor.ts +++ b/apps/web/composables/useJsonEditor/useJsonEditor.ts @@ -18,7 +18,7 @@ export const useJsonEditor = (initialJson: string) => { const updateLineCount = () => { if (textarea.value) { const lineBreaks = (jsonText.value.match(/\n/g) || []).length; - lineCount.value = Array.from({ length: lineBreaks + 1 }, (_, i) => i + 1); + lineCount.value = Array.from({ length: lineBreaks + 1 }, (_, index) => index + 1); } }; diff --git a/apps/web/composables/useReadCookieBar/__tests__/useReadCookieBar.spec.ts b/apps/web/composables/useReadCookieBar/__tests__/useReadCookieBar.spec.ts new file mode 100644 index 000000000..9347d6050 --- /dev/null +++ b/apps/web/composables/useReadCookieBar/__tests__/useReadCookieBar.spec.ts @@ -0,0 +1,62 @@ +import { mockNuxtImport } from '@nuxt/test-utils/runtime'; +import { useReadCookieBar } from '../useReadCookieBar'; + +const { useCookie } = vi.hoisted(() => ({ + useCookie: vi.fn().mockReturnValue({}), +})); + +const { useRouter } = vi.hoisted(() => ({ + useRouter: vi.fn().mockReturnValue({ + go: vi.fn(), + }), +})); + +mockNuxtImport('useRouter', () => useRouter); +mockNuxtImport('useCookie', () => useCookie); + + +describe('useReadCookieBar', () => { + + describe('setConsent', () => { + beforeEach(() => { + useCookie.mockImplementation(() => ({ + value: { + 'CookieBar.functional.label': { + 'CookieBar.functional.cookies.payPal.name': true, + 'CookieBar.functional.cookies.scriptDemo.name': true, + } + }, + })); + }); + + it('should reload the page if a consent cookie is revoked', () => { + const { setConsent, initializeCookies, data } = useReadCookieBar(); + const RouterGoSpy = vi.fn(); + + useRouter.mockReturnValue({ + go: RouterGoSpy, + }); + + initializeCookies(); + + data.value.groups[2].cookies[1].accepted = false; + setConsent(); + + expect(RouterGoSpy).toHaveBeenCalledTimes(1); + }); + + it('should not reload the page if a consent cookie is accepted', () => { + const { setConsent, initializeCookies } = useReadCookieBar(); + const RouterGoSpy = vi.fn(); + + useRouter.mockReturnValue({ + go: RouterGoSpy, + }); + + initializeCookies(); + setConsent(); + + expect(RouterGoSpy).toHaveBeenCalledTimes(0); + }); + }); +}); \ No newline at end of file diff --git a/apps/web/composables/useReadCookieBar/useReadCookieBar.ts b/apps/web/composables/useReadCookieBar/useReadCookieBar.ts index 0b994db7c..c92f6dadc 100644 --- a/apps/web/composables/useReadCookieBar/useReadCookieBar.ts +++ b/apps/web/composables/useReadCookieBar/useReadCookieBar.ts @@ -1,5 +1,5 @@ import type { UseReadCookieBarState, UseReadCookieBarReturn } from './types'; -import type { Cookie, CookieGroup, CookieGroupFromNuxtConfig } from '~/configuration/cookie.config'; +import type { Cookie, CookieGroup, CookieGroupFromNuxtConfig, JsonCookie } from '~/configuration/cookie.config'; import type { ChangeVisibilityState, SetAllCookiesState, SetConsent, InitializeCookies } from './types'; import cookieScripts from '~/cookie-scripts.config'; @@ -18,7 +18,7 @@ const fetchScripts = (scripts: string[]) => { } else if (cookieScripts[script]) { cookieScripts[script](); } - } catch (error: any) { + } catch (error: unknown) { console.error(error); } }); @@ -75,11 +75,11 @@ export const useReadCookieBar: UseReadCookieBarReturn = () => { const initializeCookies: InitializeCookies = () => { const cookies = JSON.parse(JSON.stringify(initialCookies)); - const browserCookies = useCookie('consent-cookie'); + const browserCookies = useCookie('consent-cookie') as Ref; cookies.groups.slice(1).forEach((group: CookieGroup) => { group.cookies.forEach((cookie: Cookie) => { - cookie.accepted = !!browserCookies.value?.[group.name as any]?.[cookie.name as any] || false; + cookie.accepted = !!browserCookies.value?.[group.name]?.[cookie.name] || false; const { consent } = useCookieConsent(cookie.name); consent.value = cookie.accepted || false; @@ -108,13 +108,22 @@ export const useReadCookieBar: UseReadCookieBarReturn = () => { const setConsent: SetConsent = () => { const { getMinimumLifeSpan } = cookieBarHelper(); const router = useRouter(); + const browserCookies = useCookie('consent-cookie') as Ref; - const jsonCookie = state.value.data.groups.reduce((accumulator: any, group: CookieGroup) => { - accumulator[group.name] = group.cookies.reduce((childAccumulator: any, cookie: Cookie) => { - childAccumulator[cookie.name] = cookie.accepted; + let cookieRevoke = false; + const jsonCookie = state.value.data.groups.reduce((accumulator: JsonCookie, group: CookieGroup) => { + accumulator[group.name] = group.cookies.reduce((childAccumulator: { [key: string]: boolean }, cookie: Cookie) => { + const currentStatus = !!browserCookies.value?.[group.name]?.[cookie.name] || false; const { consent } = useCookieConsent(cookie.name); + + childAccumulator[cookie.name] = cookie.accepted || false; consent.value = cookie.accepted || false; + + if (currentStatus && !consent.value) { + cookieRevoke = true; + } + return childAccumulator; }, {}); @@ -126,15 +135,11 @@ export const useReadCookieBar: UseReadCookieBarReturn = () => { maxAge: getMinimumLifeSpan(state.value.data.groups), }); - const alreadySetCookie = Boolean(consentCookie.value); - - consentCookie.value = jsonCookie; - + consentCookie.value = JSON.stringify(jsonCookie); changeVisibilityState(); - loadThirdPartyScripts(); - if (alreadySetCookie) { + if (cookieRevoke) { router.go(0); } }; diff --git a/apps/web/configuration/cookie.config.ts b/apps/web/configuration/cookie.config.ts index 9413eec39..27817aed7 100644 --- a/apps/web/configuration/cookie.config.ts +++ b/apps/web/configuration/cookie.config.ts @@ -21,6 +21,12 @@ export interface CookieGroupFromNuxtConfig { barDescription: string; } +export type JsonCookie = { + [groupName: string]: { + [cookieName: string]: boolean; + }; +}; + export default { barTitle: 'CookieBar.about.label', barDescription: 'CookieBar.about.description', diff --git a/docs/changelog/changelog_en.md b/docs/changelog/changelog_en.md index 82cbb6352..bbb1a9ab3 100644 --- a/docs/changelog/changelog_en.md +++ b/docs/changelog/changelog_en.md @@ -20,6 +20,7 @@ - The default data for the homepage is now available for both English and German. - PayPal is now a functional cookie and has to be accepted by the user. Default behavior can be changed by changing accepted to true https://pwa-docs.plentymarkets.com/guide/how-to/cookie - PayPal shows a message if the cookie is not accepted. +- We only reload the page after a cookie gets revoked. #### GitHub Action: Upload