From 88c9f3426ac733d17afee5983110e51f8f9d113d Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Tue, 20 Feb 2024 09:16:55 +0000 Subject: [PATCH 1/7] Add the single consent API package --- package.json | 6 +++++- yarn.lock | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 87bd8613ed..0c88c1f985 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,10 @@ } }, "stylelint": { - "extends": ["stylelint-config-gds/scss", "stylelint-stylistic/config"], + "extends": [ + "stylelint-config-gds/scss", + "stylelint-stylistic/config" + ], "rules": { "stylistic/number-leading-zero": null, "stylistic/max-line-length": 160, @@ -34,6 +37,7 @@ "dependencies": { "axe-core": "^4.8.4", "govuk-frontend": "^4.8.0", + "govuk-single-consent": "^3.0.9", "sortablejs": "^1.15.2" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 71317d2e01..eda47c0e82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1343,6 +1343,11 @@ govuk-frontend@^4.8.0: resolved "https://registry.yarnpkg.com/govuk-frontend/-/govuk-frontend-4.8.0.tgz#df4e56c762e93aae74fed214bb6be08e13783772" integrity sha512-NOmPJxL8IYq1HSNHYKx9XY2LLTxuwb+IFASiGQO4sgJ8K7AG66SlSeqARrcetevV8zOf+i1z+MbJJ2O7//OxAw== +govuk-single-consent@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/govuk-single-consent/-/govuk-single-consent-3.0.9.tgz#e197bba4011c11c613807fd3635a8e0a007d914b" + integrity sha512-QtWIck/1gnR6eY6J3jw6+LwLsQN6U5upjRH/xyHjy5elrZZ7LDCVmMju4yzDDHMgOTn+TwRBRS/0V3Lqn3c2ew== + graceful-fs@^4.1.15, graceful-fs@^4.1.2: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" From fe5418e245ec68e2fe0b99da0d529092e4bdb8ae Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Mon, 5 Feb 2024 09:41:52 +0000 Subject: [PATCH 2/7] Add single consent library - adds code to include and manage our use of the single consent API code - init is called by the cookie banner code on every page, which determines which API endpoint to use (staging or prod) and creates the GovSingleConsent object - useConsentApi is called across the code to check whether or not to use the consent API, this will be set in static - the default callback for the consent object checks the returned response and if the user has consented, triggers the cookie-consent event, which will initialise analytics and hide the cookie banner - setPreferences allows user consent to be set through the API - use load analytics environment list for consent API URL --- .../lib/single-consent-functions.js | 59 +++++ .../load-analytics.js | 15 +- .../lib/single-consent-functions-spec.js | 227 ++++++++++++++++++ 3 files changed, 296 insertions(+), 5 deletions(-) create mode 100644 app/assets/javascripts/govuk_publishing_components/lib/single-consent-functions.js create mode 100644 spec/javascripts/govuk_publishing_components/lib/single-consent-functions-spec.js diff --git a/app/assets/javascripts/govuk_publishing_components/lib/single-consent-functions.js b/app/assets/javascripts/govuk_publishing_components/lib/single-consent-functions.js new file mode 100644 index 0000000000..9f42ed6de5 --- /dev/null +++ b/app/assets/javascripts/govuk_publishing_components/lib/single-consent-functions.js @@ -0,0 +1,59 @@ +/* global GovSingleConsent */ +// = require govuk-single-consent/dist/singleconsent.iife.js + +(function (root) { + 'use strict' + window.GOVUK = window.GOVUK || {} + + window.GOVUK.singleConsent = { + init: function (callback) { + if (!window.GOVUK.useSingleConsentApi) { + return + } + callback = callback || this.apiCallback + // determine where we are and set the consent api URL accordingly + if (!this.url) { + this.url = 'staging' + var environment = window.GOVUK.loadAnalytics.getEnvironment(window.GOVUK.analyticsGa4.core.trackFunctions.getHostname()) + if (environment) { + this.url = environment.consentApiUrl + } + } + // create the consent API object + this.consentApiObj = new GovSingleConsent(callback, this.url) + }, + + apiCallback: function (consents, consentsPreferencesSet, error) { + if (error) { + console.error('Single consent error: ', error, window.location) + return + } + if (consentsPreferencesSet) { + if (consents && consents.usage) { + window.GOVUK.triggerEvent(window, 'cookie-consent') + } + } else { + window.GOVUK.triggerEvent(window, 'show-cookie-banner') + } + }, + + setPreferences: function (type, options) { + if (window.GOVUK.useSingleConsentApi) { + try { + switch (type) { + case 'accept': + this.consentApiObj.setConsents(GovSingleConsent.ACCEPT_ALL) + break + case 'reject': + this.consentApiObj.setConsents(GovSingleConsent.REJECT_ALL) + break + default: + this.consentApiObj.setConsents(options) + } + } catch (e) { + console.error('Single consent ' + type + ' error: ', e, window.location) + } + } + } + } +}(window)) diff --git a/app/assets/javascripts/govuk_publishing_components/load-analytics.js b/app/assets/javascripts/govuk_publishing_components/load-analytics.js index b58c872adf..fd90159474 100644 --- a/app/assets/javascripts/govuk_publishing_components/load-analytics.js +++ b/app/assets/javascripts/govuk_publishing_components/load-analytics.js @@ -18,7 +18,8 @@ window.GOVUK.loadAnalytics = { auth: 'bRiZ-jiEHtw6hHpGd6dF9w', preview: 'env-3', gaProperty: 'UA-UNSET', - gaPropertyCrossDomain: 'UA-UNSET' + gaPropertyCrossDomain: 'UA-UNSET', + consentApiUrl: 'staging' }, { name: 'production', @@ -30,7 +31,8 @@ window.GOVUK.loadAnalytics = { initialiseGA4: true, id: 'GTM-MG7HG5W', gaProperty: 'UA-26179049-1', - gaPropertyCrossDomain: 'UA-145652997-1' + gaPropertyCrossDomain: 'UA-145652997-1', + consentApiUrl: 'production' }, { name: 'staging', @@ -44,7 +46,8 @@ window.GOVUK.loadAnalytics = { auth: 'oJWs562CxSIjZKn_GlB5Bw', preview: 'env-5', gaProperty: 'UA-26179049-20', - gaPropertyCrossDomain: 'UA-145652997-1' + gaPropertyCrossDomain: 'UA-145652997-1', + consentApiUrl: 'staging' }, { name: 'integration', @@ -58,7 +61,8 @@ window.GOVUK.loadAnalytics = { auth: 'C7iYdcsOlYgGmiUJjZKrHQ', preview: 'env-4', gaProperty: 'UA-26179049-22', - gaPropertyCrossDomain: 'UA-145652997-1' + gaPropertyCrossDomain: 'UA-145652997-1', + consentApiUrl: 'staging' }, { name: 'devdocs', @@ -66,7 +70,8 @@ window.GOVUK.loadAnalytics = { 'docs.publishing.service.gov.uk' ], initialiseGA4: true, - id: 'GTM-TNKCK97' + id: 'GTM-TNKCK97', + consentApiUrl: 'production' } ], diff --git a/spec/javascripts/govuk_publishing_components/lib/single-consent-functions-spec.js b/spec/javascripts/govuk_publishing_components/lib/single-consent-functions-spec.js new file mode 100644 index 0000000000..a34dfd3fe3 --- /dev/null +++ b/spec/javascripts/govuk_publishing_components/lib/single-consent-functions-spec.js @@ -0,0 +1,227 @@ +/* eslint-env jasmine */ + +describe('The single consent cookie code', function () { + var acceptAll = { + essential: true, + usage: true, + campaigns: true, + settings: true + } + var rejectAll = { + essential: true, + usage: false, + campaigns: false, + settings: false + } + var mix = { + essential: true, + usage: false, + campaigns: true, + settings: true + } + + beforeEach(function () { + delete window.GOVUK.singleConsent.consentApiObj + delete window.GOVUK.singleConsent.url + delete window.GOVUK.useSingleConsentApi + spyOn(window.GOVUK, 'triggerEvent').and.callThrough() + spyOn(window.GOVUK.singleConsent, 'apiCallback').and.callThrough() + jasmine.Ajax.install() + }) + + afterEach(function () { + jasmine.Ajax.uninstall() + delete window.GOVUK.singleConsent.consentApiObj + delete window.GOVUK.singleConsent.url + delete window.GOVUK.useSingleConsentApi + }) + + describe('if the single consent API should not be used', function () { + beforeEach(function () { + delete window.GOVUK.useSingleConsentApi + }) + + it('will not initialise', function () { + window.GOVUK.singleConsent.init() + expect(window.GOVUK.singleConsent.consentApiObj).not.toBeDefined() + }) + }) + + describe('if the single consent API should be used', function () { + beforeEach(function () { + window.GOVUK.useSingleConsentApi = true + }) + + afterEach(function () { + delete window.GOVUK.useSingleConsentApi + }) + + it('does nothing if there is no unique user id', function () { + window.GOVUK.singleConsent.init() + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(jasmine.Ajax.requests.count()).toEqual(0) + expect(window.GOVUK.singleConsent.apiCallback).toHaveBeenCalledWith(null, false, null) + }) + + it('accepts a function for the callback', function () { + var test = { + testFunction: function () {} + } + spyOn(test, 'testFunction') + window.GOVUK.singleConsent.init(test.testFunction) + expect(test.testFunction).toHaveBeenCalled() + }) + + describe('when determining the environment', function () { + it('starts without a URL for the consent API', function () { + expect(window.GOVUK.singleConsent.url).toBeFalsy() + }) + + it('defaults to staging if the environment is not recognised', function () { + spyOn(window.GOVUK.analyticsGa4.core.trackFunctions, 'getHostname').and.returnValue('moo') + window.GOVUK.singleConsent.init() + expect(window.GOVUK.singleConsent.url).toEqual('staging') + }) + + it('switches to production when on production', function () { + spyOn(window.GOVUK.analyticsGa4.core.trackFunctions, 'getHostname').and.returnValue('www.gov.uk') + window.GOVUK.singleConsent.init() + expect(window.GOVUK.singleConsent.url).toEqual('production') + }) + }) + + describe('when there is a user id', function () { + beforeEach(function () { + spyOn(window.GOVUK, 'checkConsentCookie').and.returnValue(true) + window.GOVUK.cookie('gov_singleconsent_uid', '1234') + window.GOVUK.singleConsent.init() + }) + + afterEach(function () { + window.GOVUK.cookie('gov_singleconsent_uid', null) + }) + + it('does everything expected when full consent is given', function () { + window.GOVUK.singleConsent.setPreferences('accept') + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(acceptAll) + '}' + }) + + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.singleConsent.apiCallback).toHaveBeenCalledWith(acceptAll, true, null) + expect(window.GOVUK.triggerEvent).toHaveBeenCalledWith(window, 'cookie-consent') + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":true,"campaigns":true,"settings":true}') + }) + + it('does everything expected when consent is rejected', function () { + window.GOVUK.singleConsent.setPreferences('reject') + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(rejectAll) + '}' + }) + + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.singleConsent.apiCallback).toHaveBeenCalledWith(rejectAll, true, null) + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}') + }) + + it('does everything expected when partial consent is given', function () { + window.GOVUK.singleConsent.setPreferences(false, mix) + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(mix) + '}' + }) + + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.singleConsent.apiCallback).toHaveBeenCalledWith(mix, true, null) + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":true,"settings":true}') + }) + }) + }) + + describe('when there is a problem with the consent api', function () { + beforeEach(function () { + spyOn(window.GOVUK, 'checkConsentCookie').and.returnValue(true) + window.GOVUK.cookie('gov_singleconsent_uid', '1234') + window.GOVUK.useSingleConsentApi = true + jasmine.clock().install() + }) + + afterEach(function () { + delete window.GOVUK.useSingleConsentApi + jasmine.clock().uninstall() + window.GOVUK.cookie('gov_singleconsent_uid', null) + }) + + it('handles a timeout gracefully', function () { + window.GOVUK.singleConsent.init() + window.GOVUK.singleConsent.setPreferences('accept') + jasmine.Ajax.requests.mostRecent().responseTimeout() + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}') + }) + + it('fails gracefully if pointed at an incorrect endpoint URL', function () { + window.GOVUK.singleConsent.init() + window.GOVUK.singleConsent.setPreferences('accept') + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 404, + contentType: 'text/plain', + responseText: 'error not found' + }) + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}') + }) + + it('fails gracefully when the server errors', function () { + window.GOVUK.singleConsent.init() + window.GOVUK.singleConsent.setPreferences('accept') + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 500, + contentType: 'text/plain', + responseText: 'error not found' + }) + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}') + }) + + it('fails gracefully when the response is invalid', function () { + window.GOVUK.singleConsent.init() + window.GOVUK.singleConsent.setPreferences('accept') + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: 'not valid json' + }) + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}') + }) + + it('fails gracefully when the response is not as expected', function () { + window.GOVUK.singleConsent.init() + window.GOVUK.singleConsent.setPreferences('accept') + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{"valid json but not":"what should be returned by the api"}' + }) + expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined() + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}') + }) + + it('restores correct cookie consent', function () { + window.GOVUK.cookie('cookies_policy', '{"essential":true,"usage":false,"campaigns":false,"settings":false}') + window.GOVUK.singleConsent.init() + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(acceptAll) + '}' + }) + expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":true,"campaigns":true,"settings":true}') + }) + }) +}) From 661980b43f8e7a357d6b6c0305b20f4d1ba3f811 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Wed, 7 Feb 2024 09:55:51 +0000 Subject: [PATCH 3/7] Cookie banner use single consent API - update the cookie banner component JS to use the single consent API code - stores an internal variable to check whether or not to use the consent API - if false, behaviour should be as normal - if true, should yield setting of consent cookies entirely to the consent API code - update cookie banner tests accordingly --- .../components/cookie-banner.js | 43 +- .../components/cookie-banner-spec.js | 425 +++++++++++------- 2 files changed, 304 insertions(+), 164 deletions(-) diff --git a/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js b/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js index f24a5164db..f982eee389 100644 --- a/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js +++ b/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js @@ -10,10 +10,17 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; CookieBanner.prototype.init = function () { this.$module.hideCookieMessage = this.hideCookieMessage.bind(this) + this.$module.showCookieMessage = this.showCookieMessage.bind(this) this.$module.showConfirmationMessage = this.showConfirmationMessage.bind(this) this.$module.setCookieConsent = this.setCookieConsent.bind(this) this.$module.rejectCookieConsent = this.rejectCookieConsent.bind(this) this.setupCookieMessage() + + if (window.GOVUK.useSingleConsentApi) { + window.addEventListener('hide-cookie-banner', this.$module.hideCookieMessage) + window.addEventListener('show-cookie-banner', this.$module.showCookieMessage) + window.GOVUK.singleConsent.init() + } } CookieBanner.prototype.setupCookieMessage = function () { @@ -34,10 +41,13 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; this.$rejectCookiesButton.addEventListener('click', this.$module.rejectCookieConsent) } - this.showCookieMessage() + if (!window.GOVUK.useSingleConsentApi) { + this.showCookieMessage() + } } CookieBanner.prototype.showCookieMessage = function () { + window.removeEventListener('show-cookie-banner', this.$module.showCookieMessage) // Show the cookie banner if not in the cookie settings page or in an iframe if (!this.isInCookiesPage() && !this.isInIframe()) { var shouldHaveCookieMessage = (this.$module && window.GOVUK.cookie('cookies_preferences_set') !== 'true') @@ -47,7 +57,9 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; // Set the default consent cookie if it isn't already present if (!window.GOVUK.cookie('cookies_policy')) { - window.GOVUK.setDefaultConsentCookie() + if (!window.GOVUK.useSingleConsentApi) { + window.GOVUK.setDefaultConsentCookie() + } } window.GOVUK.deleteUnconsentedCookies() @@ -56,9 +68,12 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; } CookieBanner.prototype.hideCookieMessage = function (event) { + window.removeEventListener('hide-cookie-banner', this.$module.hideCookieMessage) if (this.$module) { this.$module.hidden = true - window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + if (!window.GOVUK.useSingleConsentApi) { + window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + } } if (event.target) { @@ -70,25 +85,37 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; if (this.$acceptCookiesButton.getAttribute('data-cookie-types') === 'all') { this.$module.querySelector('.gem-c-cookie-banner__confirmation-message--accepted').hidden = false } - window.GOVUK.approveAllCookieTypes() + if (window.GOVUK.useSingleConsentApi) { + window.GOVUK.singleConsent.setPreferences('accept') + } else { + window.GOVUK.approveAllCookieTypes() + window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + } + this.$module.showConfirmationMessage() this.$module.cookieBannerConfirmationMessage.focus() - window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + if (window.GOVUK.analyticsInit) { window.GOVUK.analyticsInit() } if (window.GOVUK.globalBarInit) { window.GOVUK.globalBarInit.init() } - window.GOVUK.triggerEvent(window, 'cookie-consent') + if (!window.GOVUK.useSingleConsentApi) { + window.GOVUK.triggerEvent(window, 'cookie-consent') + } } CookieBanner.prototype.rejectCookieConsent = function () { this.$module.querySelector('.gem-c-cookie-banner__confirmation-message--rejected').hidden = false this.$module.showConfirmationMessage() this.$module.cookieBannerConfirmationMessage.focus() - window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) - window.GOVUK.setDefaultConsentCookie() + if (window.GOVUK.useSingleConsentApi) { + window.GOVUK.singleConsent.setPreferences('reject') + } else { + window.GOVUK.setDefaultConsentCookie() + window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + } } CookieBanner.prototype.showConfirmationMessage = function () { diff --git a/spec/javascripts/components/cookie-banner-spec.js b/spec/javascripts/components/cookie-banner-spec.js index c5c6e8e799..ef5e5fd3a0 100644 --- a/spec/javascripts/components/cookie-banner-spec.js +++ b/spec/javascripts/components/cookie-banner-spec.js @@ -40,230 +40,343 @@ describe('Cookie banner', function () { '' + '' + '' - document.body.appendChild(container) - // set and store consent for all as a basis of comparison - window.GOVUK.setCookie('cookies_policy', '{"essential":true,"settings":true,"usage":true,"campaigns":true}') - ALL_COOKIE_CONSENT = GOVUK.getCookie('cookies_policy') - - // set and store default cookie consent to use as basis of comparison - window.GOVUK.setDefaultConsentCookie() - DEFAULT_COOKIE_CONSENT = GOVUK.getCookie('cookies_policy') }) afterEach(function () { + delete window.GOVUK.useSingleConsentApi document.body.removeChild(container) }) - it('should show the cookie banner', function () { - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + describe('when the single consent api is not enabled', function () { + beforeEach(function () { + // set and store consent for all as a basis of comparison + window.GOVUK.setCookie('cookies_policy', '{"essential":true,"settings":true,"usage":true,"campaigns":true}') + ALL_COOKIE_CONSENT = GOVUK.getCookie('cookies_policy') - var cookieBannerMain = document.querySelector('.js-banner-wrapper') - var cookieBannerConfirmationAccept = document.querySelector('.gem-c-cookie-banner__confirmation-message--accepted') - var cookieBannerConfirmationReject = document.querySelector('.gem-c-cookie-banner__confirmation-message--rejected') + // set and store default cookie consent to use as basis of comparison + window.GOVUK.setDefaultConsentCookie() + DEFAULT_COOKIE_CONSENT = GOVUK.getCookie('cookies_policy') + }) - expect(element).toBeVisible() - expect(cookieBannerMain).toBeVisible() - expect(cookieBannerConfirmationAccept).toBeHidden() - expect(cookieBannerConfirmationReject).toBeHidden() - }) + it('should show the cookie banner', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - it('should show the cookie banner when preferences have not been actively set', function () { - GOVUK.setDefaultConsentCookie() // Set default cookies, which are set whether there is any interaction or not. + var cookieBannerMain = document.querySelector('.js-banner-wrapper') + var cookieBannerConfirmationAccept = document.querySelector('.gem-c-cookie-banner__confirmation-message--accepted') + var cookieBannerConfirmationReject = document.querySelector('.gem-c-cookie-banner__confirmation-message--rejected') - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + expect(element).toBeVisible() + expect(cookieBannerMain).toBeVisible() + expect(cookieBannerConfirmationAccept).toBeHidden() + expect(cookieBannerConfirmationReject).toBeHidden() + }) - var cookieBannerMain = document.querySelector('.js-banner-wrapper') - var cookieBannerConfirmationAccept = document.querySelector('.gem-c-cookie-banner__confirmation-message--accepted') - var cookieBannerConfirmationReject = document.querySelector('.gem-c-cookie-banner__confirmation-message--rejected') + it('should show the cookie banner when preferences have not been actively set', function () { + GOVUK.setDefaultConsentCookie() // Set default cookies, which are set whether there is any interaction or not. - expect(element).toBeVisible() - expect(cookieBannerMain).toBeVisible() - expect(cookieBannerConfirmationAccept).toBeHidden() - expect(cookieBannerConfirmationReject).toBeHidden() - }) + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - it('should hide the cookie banner when preferences have been actively set', function () { - GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + var cookieBannerMain = document.querySelector('.js-banner-wrapper') + var cookieBannerConfirmationAccept = document.querySelector('.gem-c-cookie-banner__confirmation-message--accepted') + var cookieBannerConfirmationReject = document.querySelector('.gem-c-cookie-banner__confirmation-message--rejected') - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + expect(element).toBeVisible() + expect(cookieBannerMain).toBeVisible() + expect(cookieBannerConfirmationAccept).toBeHidden() + expect(cookieBannerConfirmationReject).toBeHidden() + }) - expect(element).toBeHidden() - }) + it('should hide the cookie banner when preferences have been actively set', function () { + GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) - it('should have the hidden attribute by default, and remove it once the JS loads when cookies are not set', function () { - var element = document.querySelector('[data-module="cookie-banner"]') - expect(element.hasAttribute('hidden')).toEqual(true) - expect(element.offsetParent).toEqual(null) - new GOVUK.Modules.CookieBanner(element).init() - expect(element.hasAttribute('hidden')).toEqual(false) - expect(!!element.offsetParent).toEqual(true) - }) + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - it('should have the hidden attribute by default, and leave it when cookies are set', function () { - GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) - var element = document.querySelector('[data-module="cookie-banner"]') - expect(element.offsetParent).toEqual(null) - expect(element.hasAttribute('hidden')).toEqual(true) - new GOVUK.Modules.CookieBanner(element).init() - expect(element.offsetParent).toEqual(null) - expect(element.hasAttribute('hidden')).toEqual(true) - }) + expect(element).toBeHidden() + }) + + it('should have the hidden attribute by default, and remove it once the JS loads when cookies are not set', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + expect(element.hasAttribute('hidden')).toEqual(true) + expect(element.offsetParent).toEqual(null) + new GOVUK.Modules.CookieBanner(element).init() + expect(element.hasAttribute('hidden')).toEqual(false) + expect(!!element.offsetParent).toEqual(true) + }) + + it('should have the hidden attribute by default, and leave it when cookies are set', function () { + GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 }) + var element = document.querySelector('[data-module="cookie-banner"]') + expect(element.offsetParent).toEqual(null) + expect(element.hasAttribute('hidden')).toEqual(true) + new GOVUK.Modules.CookieBanner(element).init() + expect(element.offsetParent).toEqual(null) + expect(element.hasAttribute('hidden')).toEqual(true) + }) - it('sets a default consent cookie', function () { - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + it('sets a default consent cookie', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - expect(GOVUK.getCookie('cookies_preferences_set')).toEqual(null) - expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) - }) + expect(GOVUK.getCookie('cookies_preferences_set')).toEqual(null) + expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) + }) - it('deletes unconsented cookies if cookie preferences not explicitly set', function () { - window.GOVUK.setCookie('_ga', 'this is not allowed!') - spyOn(GOVUK, 'deleteUnconsentedCookies').and.callThrough() + it('deletes unconsented cookies if cookie preferences not explicitly set', function () { + window.GOVUK.setCookie('_ga', 'this is not allowed!') + spyOn(GOVUK, 'deleteUnconsentedCookies').and.callThrough() - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) - expect(GOVUK.deleteUnconsentedCookies).toHaveBeenCalled() - expect(GOVUK.getCookie('_ga', null)) - }) + expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) + expect(GOVUK.deleteUnconsentedCookies).toHaveBeenCalled() + expect(GOVUK.getCookie('_ga', null)) + }) - it('sets consent cookie when accepting cookies', function () { - spyOn(GOVUK, 'analyticsInit') - spyOn(GOVUK, 'setCookie').and.callThrough() + it('sets consent cookie when accepting cookies', function () { + spyOn(GOVUK, 'analyticsInit') + spyOn(GOVUK, 'setCookie').and.callThrough() - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - // Manually reset the consent cookie so we can check the accept button works as intended - expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) - GOVUK.cookie('cookies_policy', null) + // Manually reset the consent cookie so we can check the accept button works as intended + expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) + GOVUK.cookie('cookies_policy', null) - var acceptCookiesButton = document.querySelector('[data-accept-cookies]') - acceptCookiesButton.click() + var acceptCookiesButton = document.querySelector('[data-accept-cookies]') + acceptCookiesButton.click() - expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', 'true', { days: 365 }) - expect(GOVUK.getCookie('cookies_preferences_set')).toEqual('true') - expect(GOVUK.getCookie('cookies_policy')).toEqual(ALL_COOKIE_CONSENT) - expect(GOVUK.analyticsInit).toHaveBeenCalled() - }) + expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', 'true', { days: 365 }) + expect(GOVUK.getCookie('cookies_preferences_set')).toEqual('true') + expect(GOVUK.getCookie('cookies_policy')).toEqual(ALL_COOKIE_CONSENT) + expect(GOVUK.analyticsInit).toHaveBeenCalled() + }) - it('sets global_bar_seen cookie when accepting cookies', function () { - if (typeof GOVUK.globalBarInit === 'undefined') { - GOVUK.globalBarInit = { - init: function () {} + it('sets global_bar_seen cookie when accepting cookies', function () { + if (typeof GOVUK.globalBarInit === 'undefined') { + GOVUK.globalBarInit = { + init: function () {} + } } - } - spyOn(GOVUK.globalBarInit, 'init') - spyOn(GOVUK, 'setCookie').and.callThrough() + spyOn(GOVUK.globalBarInit, 'init') + spyOn(GOVUK, 'setCookie').and.callThrough() - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - // Manually reset the consent cookie so we can check the accept button works as intended - expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) - GOVUK.cookie('cookies_policy', null) + // Manually reset the consent cookie so we can check the accept button works as intended + expect(GOVUK.getCookie('cookies_policy')).toEqual(DEFAULT_COOKIE_CONSENT) + GOVUK.cookie('cookies_policy', null) - var acceptCookiesButton = document.querySelector('[data-accept-cookies]') - acceptCookiesButton.click() + var acceptCookiesButton = document.querySelector('[data-accept-cookies]') + acceptCookiesButton.click() - expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', 'true', { days: 365 }) - expect(GOVUK.getCookie('cookies_preferences_set')).toEqual('true') - expect(GOVUK.getCookie('cookies_policy')).toEqual(ALL_COOKIE_CONSENT) - expect(GOVUK.globalBarInit.init).toHaveBeenCalled() - }) + expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', 'true', { days: 365 }) + expect(GOVUK.getCookie('cookies_preferences_set')).toEqual('true') + expect(GOVUK.getCookie('cookies_policy')).toEqual(ALL_COOKIE_CONSENT) + expect(GOVUK.globalBarInit.init).toHaveBeenCalled() + }) - it('shows a confirmation message when cookies have been accepted', function () { - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + it('shows a confirmation message when cookies have been accepted', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - var acceptCookiesButton = document.querySelector('[data-accept-cookies]') - var confirmationMessageAccepted = document.querySelector('.gem-c-cookie-banner__confirmation-message--accepted') + var acceptCookiesButton = document.querySelector('[data-accept-cookies]') + var confirmationMessageAccepted = document.querySelector('.gem-c-cookie-banner__confirmation-message--accepted') - expect(confirmationMessageAccepted).toBeHidden() + expect(confirmationMessageAccepted).toBeHidden() - acceptCookiesButton.click() + acceptCookiesButton.click() - expect(confirmationMessageAccepted).toBeVisible() - expect(confirmationMessageAccepted.innerText).toContain('You have accepted additional cookies. You can change your cookie settings at any time.') - }) + expect(confirmationMessageAccepted).toBeVisible() + expect(confirmationMessageAccepted.innerText).toContain('You have accepted additional cookies. You can change your cookie settings at any time.') + }) - it('shows a confirmation message when cookies have been rejected', function () { - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + it('shows a confirmation message when cookies have been rejected', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - var rejectCookiesButton = document.querySelector('[data-reject-cookies]') - var confirmationMessageRejected = document.querySelector('.gem-c-cookie-banner__confirmation-message--rejected') + var rejectCookiesButton = document.querySelector('[data-reject-cookies]') + var confirmationMessageRejected = document.querySelector('.gem-c-cookie-banner__confirmation-message--rejected') - expect(confirmationMessageRejected).toBeHidden() + expect(confirmationMessageRejected).toBeHidden() - rejectCookiesButton.click() + rejectCookiesButton.click() - expect(confirmationMessageRejected).toBeVisible() - expect(confirmationMessageRejected.innerText).toContain('You have rejected additional cookies. You can change your cookie settings at any time.') - }) + expect(confirmationMessageRejected).toBeVisible() + expect(confirmationMessageRejected.innerText).toContain('You have rejected additional cookies. You can change your cookie settings at any time.') + }) - it('set focus to the confirmation message after clicking button', function () { - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + it('set focus to the confirmation message after clicking button', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - var rejectCookiesButton = document.querySelector('[data-reject-cookies]') - var confirmationMessage = document.querySelector('.gem-c-cookie-banner__confirmation') + var rejectCookiesButton = document.querySelector('[data-reject-cookies]') + var confirmationMessage = document.querySelector('.gem-c-cookie-banner__confirmation') - rejectCookiesButton.click() + rejectCookiesButton.click() - var focusedElement = document.activeElement + var focusedElement = document.activeElement - expect(focusedElement.className).toBe(confirmationMessage.className) - }) + expect(focusedElement.className).toBe(confirmationMessage.className) + }) - it('set cookies_preferences_set cookie, and re-set cookies_policy expiration date when rejecting cookies', function () { - spyOn(GOVUK, 'setCookie').and.callThrough() - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + it('set cookies_preferences_set cookie, and re-set cookies_policy expiration date when rejecting cookies', function () { + spyOn(GOVUK, 'setCookie').and.callThrough() + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() - var rejectCookiesButton = document.querySelector('[data-reject-cookies]') + var rejectCookiesButton = document.querySelector('[data-reject-cookies]') - rejectCookiesButton.click() + rejectCookiesButton.click() - expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_policy', DEFAULT_COOKIE_CONSENT, { days: 365 }) - expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', 'true', { days: 365 }) - }) + expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_policy', DEFAULT_COOKIE_CONSENT, { days: 365 }) + expect(GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', 'true', { days: 365 }) + }) - it('should hide when pressing the "hide" link', function () { - spyOn(GOVUK, 'setCookie').and.callThrough() + it('should hide when pressing the "hide" link', function () { + spyOn(GOVUK, 'setCookie').and.callThrough() - var element = document.querySelector('[data-module="cookie-banner"]') - new GOVUK.Modules.CookieBanner(element).init() + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() + + var link = document.querySelector('button[data-hide-cookie-banner="true"]') + link.dispatchEvent(new window.Event('click')) + + expect(element).toBeHidden() + expect(GOVUK.getCookie('cookies_preferences_set')).toBeTruthy() + }) + + describe('when rendered inside an iframe', function () { + var windowParent = window.parent + var mockWindowParent = {} // window.parent would be different than window when used inside an iframe + + beforeEach(function () { + window.parent = mockWindowParent + }) - var link = document.querySelector('button[data-hide-cookie-banner="true"]') - link.dispatchEvent(new window.Event('click')) + afterEach(function () { + window.parent = windowParent + }) - expect(element).toBeHidden() - expect(GOVUK.getCookie('cookies_preferences_set')).toBeTruthy() + it('should hide the cookie banner', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() + expect(element).toBeHidden() + }) + }) }) - describe('when rendered inside an iframe', function () { - var windowParent = window.parent - var mockWindowParent = {} // window.parent would be different than window when used inside an iframe + describe('when the single consent api is enabled', function () { + var acceptAll = { + essential: true, + usage: true, + campaigns: true, + settings: true + } + var rejectAll = { + essential: true, + usage: false, + campaigns: false, + settings: false + } + var mix = { + essential: true, + usage: false, + campaigns: true, + settings: true + } beforeEach(function () { - window.parent = mockWindowParent + window.GOVUK.useSingleConsentApi = true + // delete consent cookies + window.GOVUK.cookie('cookies_policy') + window.GOVUK.cookie('cookies_preferences_set') + spyOn(window.GOVUK, 'setCookie') + spyOn(window.GOVUK.singleConsent, 'init').and.callThrough() + spyOn(window.GOVUK.singleConsent, 'apiCallback').and.callThrough() }) afterEach(function () { - window.parent = windowParent + // delete consent cookies + window.GOVUK.cookie('cookies_policy') + window.GOVUK.cookie('cookies_preferences_set') }) - it('should hide the cookie banner', function () { + it('initialises the single consent api on init', function () { var element = document.querySelector('[data-module="cookie-banner"]') new GOVUK.Modules.CookieBanner(element).init() - expect(element).toBeHidden() + expect(window.GOVUK.singleConsent.init).toHaveBeenCalled() + expect(window.GOVUK.singleConsent.apiCallback).toHaveBeenCalled() + expect(window.GOVUK.setCookie).not.toHaveBeenCalled() + }) + + it('should show the cookie banner', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() + expect(element).toBeVisible() + }) + + describe('when a consent api UUID is passed in the URL', function () { + var existingUrl + + beforeEach(function () { + jasmine.Ajax.install() + existingUrl = window.location.pathname + window.location.search + window.history.replaceState(null, null, '?gov_singleconsent_uid=1234') + }) + + afterEach(function () { + jasmine.Ajax.uninstall() + window.history.replaceState(null, null, existingUrl) + }) + + it('should hide the cookie banner and set cookies for consent', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(acceptAll) + '}' + }) + expect(element).not.toBeVisible() + expect(window.GOVUK.cookie('cookies_preferences_set')).toEqual('true') + expect(window.GOVUK.cookie('cookies_policy')).toEqual(JSON.stringify(acceptAll)) + expect(window.GOVUK.setCookie).not.toHaveBeenCalled() + }) + + it('should hide the cookie banner and set cookies for reject', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(rejectAll) + '}' + }) + expect(element).not.toBeVisible() + expect(window.GOVUK.cookie('cookies_preferences_set')).toEqual('true') + expect(window.GOVUK.cookie('cookies_policy')).toEqual(JSON.stringify(rejectAll)) + expect(window.GOVUK.setCookie).not.toHaveBeenCalled() + }) + + it('should hide the cookie banner and set cookies for a varied cookie consent', function () { + var element = document.querySelector('[data-module="cookie-banner"]') + new GOVUK.Modules.CookieBanner(element).init() + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '{ "uid": "1234", "status": ' + JSON.stringify(mix) + '}' + }) + expect(element).not.toBeVisible() + expect(window.GOVUK.cookie('cookies_preferences_set')).toEqual('true') + expect(window.GOVUK.cookie('cookies_policy')).toEqual(JSON.stringify(mix)) + expect(window.GOVUK.setCookie).not.toHaveBeenCalled() + }) }) }) }) From b34a892dad0057418a1e1bb5301b4145929e2c1e Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Wed, 7 Feb 2024 11:22:52 +0000 Subject: [PATCH 4/7] Cookie settings use single consent API - updates the JavaScript for the cookie settings page to use the single consent API code - stores an internal variable to check whether or not to use the consent API - if false, behaviour should be as normal - if true, should yield setting of consent cookies entirely to the consent API code - note that this code sends its own callback function for the consent API, which sets the initial form values on page load, this means that any delay in the API call will result in these fields being unfilled until it responds --- .../lib/cookie-settings.js | 46 ++-- .../lib/cookie-settings-spec.js | 229 ++++++++++-------- 2 files changed, 160 insertions(+), 115 deletions(-) diff --git a/app/assets/javascripts/govuk_publishing_components/lib/cookie-settings.js b/app/assets/javascripts/govuk_publishing_components/lib/cookie-settings.js index ed3d5facf5..45c01eb8ab 100644 --- a/app/assets/javascripts/govuk_publishing_components/lib/cookie-settings.js +++ b/app/assets/javascripts/govuk_publishing_components/lib/cookie-settings.js @@ -12,31 +12,39 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; document.querySelector('form[data-module=cookie-settings]') .addEventListener('submit', this.$module.submitSettingsForm) - this.setInitialFormValues() + if (window.GOVUK.useSingleConsentApi) { + window.GOVUK.singleConsent.init(this.setInitialFormValues.bind(this)) + } else { + this.setInitialFormValues() + } } CookieSettings.prototype.setInitialFormValues = function () { if (!window.GOVUK.cookie('cookies_policy')) { - window.GOVUK.setDefaultConsentCookie() + if (!window.GOVUK.useSingleConsentApi) { + window.GOVUK.setDefaultConsentCookie() + } } var currentConsentCookie = window.GOVUK.cookie('cookies_policy') - var currentConsentCookieJSON = JSON.parse(currentConsentCookie) + if (currentConsentCookie) { + var currentConsentCookieJSON = JSON.parse(currentConsentCookie) - // We don't need the essential value as this cannot be changed by the user - delete currentConsentCookieJSON.essential + // We don't need the essential value as this cannot be changed by the user + delete currentConsentCookieJSON.essential - for (var cookieType in currentConsentCookieJSON) { - var radioButton + for (var cookieType in currentConsentCookieJSON) { + var radioButton - if (currentConsentCookieJSON[cookieType]) { - radioButton = document.querySelector('input[name=cookies-' + cookieType + '][value=on]') - } else { - radioButton = document.querySelector('input[name=cookies-' + cookieType + '][value=off]') - } + if (currentConsentCookieJSON[cookieType]) { + radioButton = document.querySelector('input[name=cookies-' + cookieType + '][value=on]') + } else { + radioButton = document.querySelector('input[name=cookies-' + cookieType + '][value=off]') + } - if (radioButton) { - radioButton.checked = true + if (radioButton) { + radioButton.checked = true + } } } } @@ -62,13 +70,15 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; } } - window.GOVUK.setConsentCookie(options) - window.GOVUK.setCookie('cookies_preferences_set', true, { days: 365 }) + if (window.GOVUK.useSingleConsentApi) { + window.GOVUK.singleConsent.setPreferences(null, options) + } else { + window.GOVUK.setConsentCookie(options) + window.GOVUK.setCookie('cookies_preferences_set', true, { days: 365 }) + } this.fireAnalyticsEvent(options) - this.showConfirmationMessage() - return false } diff --git a/spec/javascripts/govuk_publishing_components/lib/cookie-settings-spec.js b/spec/javascripts/govuk_publishing_components/lib/cookie-settings-spec.js index 54abc8fd8a..60f0943f79 100644 --- a/spec/javascripts/govuk_publishing_components/lib/cookie-settings-spec.js +++ b/spec/javascripts/govuk_publishing_components/lib/cookie-settings-spec.js @@ -8,6 +8,7 @@ describe('cookieSettings', function () { fakePreviousURL beforeEach(function () { + delete window.GOVUK.useSingleConsentApi GOVUK.Modules.CookieSettings.prototype.getReferrerLink = function () { return fakePreviousURL } @@ -42,160 +43,194 @@ describe('cookieSettings', function () { document.body.removeChild(confirmationContainer) }) - describe('setInitialFormValues', function () { - it('sets a consent cookie by default', function () { - GOVUK.cookie('cookies_policy', null) - spyOn(window.GOVUK, 'setDefaultConsentCookie').and.callThrough() + describe('when the single consent api is not enabled', function () { + describe('setInitialFormValues', function () { + it('sets a consent cookie by default', function () { + GOVUK.cookie('cookies_policy', null) + spyOn(window.GOVUK, 'setDefaultConsentCookie').and.callThrough() - new GOVUK.Modules.CookieSettings(element).init() + new GOVUK.Modules.CookieSettings(element).init() - expect(window.GOVUK.setDefaultConsentCookie).toHaveBeenCalled() - }) + expect(window.GOVUK.setDefaultConsentCookie).toHaveBeenCalled() + }) - it('sets all radio buttons to the default values', function () { - new GOVUK.Modules.CookieSettings(element).init() + it('sets all radio buttons to the default values', function () { + new GOVUK.Modules.CookieSettings(element).init() - var radioButtons = element.querySelectorAll('input[value=on]') - var consentCookieJSON = JSON.parse(window.GOVUK.cookie('cookies_policy')) + var radioButtons = element.querySelectorAll('input[value=on]') + var consentCookieJSON = JSON.parse(window.GOVUK.cookie('cookies_policy')) - for (var i = 0; i < radioButtons.length; i++) { - var name = radioButtons[i].name.replace('cookies-', '') + for (var i = 0; i < radioButtons.length; i++) { + var name = radioButtons[i].name.replace('cookies-', '') - if (consentCookieJSON[name]) { - expect(radioButtons[i].checked).toBeTruthy() - } else { - expect(radioButtons[i].checked).not.toBeTruthy() + if (consentCookieJSON[name]) { + expect(radioButtons[i].checked).toBeTruthy() + } else { + expect(radioButtons[i].checked).not.toBeTruthy() + } } - } - }) + }) - it('does not error if not all options are present', function () { - element.innerHTML = - '
' + - '' + - '' + - '' + - '
' + it('does not error if not all options are present', function () { + element.innerHTML = + '
' + + '' + + '' + + '' + + '
' - new GOVUK.Modules.CookieSettings(element).init() + new GOVUK.Modules.CookieSettings(element).init() - var radioButtons = element.querySelectorAll('input[value=on]') - var consentCookieJSON = JSON.parse(window.GOVUK.cookie('cookies_policy')) + var radioButtons = element.querySelectorAll('input[value=on]') + var consentCookieJSON = JSON.parse(window.GOVUK.cookie('cookies_policy')) - for (var i = 0; i < radioButtons.length; i++) { - var name = radioButtons[i].name.replace('cookies-', '') + for (var i = 0; i < radioButtons.length; i++) { + var name = radioButtons[i].name.replace('cookies-', '') - if (consentCookieJSON[name]) { - expect(radioButtons[i].checked).toBeTruthy() - } else { - expect(radioButtons[i].checked).not.toBeTruthy() + if (consentCookieJSON[name]) { + expect(radioButtons[i].checked).toBeTruthy() + } else { + expect(radioButtons[i].checked).not.toBeTruthy() + } } - } + }) }) - }) - describe('submitSettingsForm', function () { - it('updates consent cookie with any changes', function () { - spyOn(window.GOVUK, 'setConsentCookie').and.callThrough() + describe('submitSettingsForm', function () { + it('updates consent cookie with any changes', function () { + spyOn(window.GOVUK, 'setConsentCookie').and.callThrough() - new GOVUK.Modules.CookieSettings(element).init() + new GOVUK.Modules.CookieSettings(element).init() - element.querySelector('#settings-on').checked = false - element.querySelector('#settings-off').checked = true + element.querySelector('#settings-on').checked = false + element.querySelector('#settings-off').checked = true - var button = element.querySelector('#submit-button') - button.click() + var button = element.querySelector('#submit-button') + button.click() - var cookie = JSON.parse(GOVUK.cookie('cookies_policy')) + var cookie = JSON.parse(GOVUK.cookie('cookies_policy')) - expect(window.GOVUK.setConsentCookie).toHaveBeenCalledWith({ settings: false, usage: false, campaigns: false }) - expect(cookie.settings).toBeFalsy() - }) + expect(window.GOVUK.setConsentCookie).toHaveBeenCalledWith({ settings: false, usage: false, campaigns: false }) + expect(cookie.settings).toBeFalsy() + }) - it('sets cookies_preferences_set cookie on form submit', function () { - spyOn(window.GOVUK, 'setCookie').and.callThrough() + it('sets cookies_preferences_set cookie on form submit', function () { + spyOn(window.GOVUK, 'setCookie').and.callThrough() - new GOVUK.Modules.CookieSettings(element).init() + new GOVUK.Modules.CookieSettings(element).init() - GOVUK.cookie('cookies_preferences_set', null) + GOVUK.cookie('cookies_preferences_set', null) - expect(GOVUK.cookie('cookies_preferences_set')).toEqual(null) + expect(GOVUK.cookie('cookies_preferences_set')).toEqual(null) - var button = element.querySelector('#submit-button') - button.click() + var button = element.querySelector('#submit-button') + button.click() - expect(window.GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', true, { days: 365 }) - expect(GOVUK.cookie('cookies_preferences_set')).toBeTruthy() + expect(window.GOVUK.setCookie).toHaveBeenCalledWith('cookies_preferences_set', true, { days: 365 }) + expect(GOVUK.cookie('cookies_preferences_set')).toBeTruthy() + }) + + it('fires a Google Analytics event', function () { + spyOn(GOVUK.analytics, 'trackEvent').and.callThrough() + + new GOVUK.Modules.CookieSettings(element).init() + + element.querySelector('#settings-on').checked = false + element.querySelector('#settings-off').checked = true + + var button = element.querySelector('#submit-button') + button.click() + + expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith('cookieSettings', 'Save changes', { label: 'settings-no usage-no campaigns-no ' }) + }) }) - it('fires a Google Analytics event', function () { - spyOn(GOVUK.analytics, 'trackEvent').and.callThrough() + describe('showConfirmationMessage', function () { + it('sets the previous referrer link if one is present', function () { + fakePreviousURL = '/student-finance' - new GOVUK.Modules.CookieSettings(element).init() + new GOVUK.Modules.CookieSettings(element).init() - element.querySelector('#settings-on').checked = false - element.querySelector('#settings-off').checked = true + var button = element.querySelector('#submit-button') + button.click() - element.querySelector('#usage-on').checked = true - element.querySelector('#usage-off').checked = false + var previousLink = document.querySelector('.cookie-settings__prev-page') - var button = element.querySelector('#submit-button') - button.click() + expect(previousLink.style.display).toEqual('inline') + expect(previousLink.href).toContain('/student-finance') + }) - expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith('cookieSettings', 'Save changes', { label: 'settings-no usage-yes campaigns-no ' }) - }) - }) + it('does not set a referrer if one is not present', function () { + fakePreviousURL = null - describe('showConfirmationMessage', function () { - it('sets the previous referrer link if one is present', function () { - fakePreviousURL = '/student-finance' + new GOVUK.Modules.CookieSettings(element).init() - new GOVUK.Modules.CookieSettings(element).init() + var button = element.querySelector('#submit-button') + button.click() - var button = element.querySelector('#submit-button') - button.click() + var previousLink = document.querySelector('.cookie-settings__prev-page') - var previousLink = document.querySelector('.cookie-settings__prev-page') + expect(previousLink.style.display).toEqual('none') + }) - expect(previousLink.style.display).toEqual('inline') - expect(previousLink.href).toContain('/student-finance') - }) + it('does not set a referrer if URL is the same as current page (cookies page)', function () { + fakePreviousURL = document.location.pathname - it('does not set a referrer if one is not present', function () { - fakePreviousURL = null + new GOVUK.Modules.CookieSettings(element).init() - new GOVUK.Modules.CookieSettings(element).init() + var button = element.querySelector('#submit-button') + button.click() - var button = element.querySelector('#submit-button') - button.click() + var previousLink = document.querySelector('.cookie-settings__prev-page') + + expect(previousLink.style.display).toEqual('none') + }) - var previousLink = document.querySelector('.cookie-settings__prev-page') + it('shows a confirmation message', function () { + var confirmationMessage = document.querySelector('[data-cookie-confirmation]') - expect(previousLink.style.display).toEqual('none') + new GOVUK.Modules.CookieSettings(element).init() + + var button = element.querySelector('#submit-button') + button.click() + + expect(confirmationMessage.style.display).toEqual('block') + }) }) + }) - it('does not set a referrer if URL is the same as current page (cookies page)', function () { - fakePreviousURL = document.location.pathname + describe('when the single consent api is enabled', function () { + beforeEach(function () { + window.GOVUK.useSingleConsentApi = true + }) - new GOVUK.Modules.CookieSettings(element).init() + afterEach(function () { + delete window.GOVUK.useSingleConsentApi + }) - var button = element.querySelector('#submit-button') - button.click() + it('setInitialFormValues does not set a consent cookie by default', function () { + GOVUK.cookie('cookies_policy', null) + spyOn(window.GOVUK, 'setDefaultConsentCookie').and.callThrough() - var previousLink = document.querySelector('.cookie-settings__prev-page') + new GOVUK.Modules.CookieSettings(element).init() - expect(previousLink.style.display).toEqual('none') + expect(window.GOVUK.setDefaultConsentCookie).not.toHaveBeenCalled() }) - it('shows a confirmation message', function () { - var confirmationMessage = document.querySelector('[data-cookie-confirmation]') + it('submitSettingsForm passes responsibility for handling consent to the single consent api', function () { + spyOn(window.GOVUK, 'setConsentCookie') + spyOn(window.GOVUK.singleConsent, 'init') new GOVUK.Modules.CookieSettings(element).init() + element.querySelector('#settings-on').checked = false + element.querySelector('#settings-off').checked = true + var button = element.querySelector('#submit-button') button.click() - expect(confirmationMessage.style.display).toEqual('block') + expect(window.GOVUK.setConsentCookie).not.toHaveBeenCalled() + expect(window.GOVUK.singleConsent.init).toHaveBeenCalled() }) }) From d21cc1e2a4b086d8ea6e750f71d10489658f8bc1 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Wed, 28 Feb 2024 15:15:11 +0000 Subject: [PATCH 5/7] Default Youtube videos to off - previously the consent cookie was always set (to reject all cookies) prior to user choice - now that we're not doing that, the code that turns links to Youtube videos in govspeak content into embedded videos was checking for the consent cookie, not finding it, and defaulting to... true. - this meant that videos were appearing on a page before users had consented to cookies - setting the default value to false seems to be the simplest way to fix this. Videos still initialise automatically as before once cookies are consented to --- .../lib/govspeak/youtube-link-enhancement.js | 2 +- spec/javascripts/components/govspeak-spec.js | 8 ++++++++ .../lib/govspeak/youtube-link-enhancement-spec.js | 8 ++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js b/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js index 9c5522b253..96ddd21ed8 100644 --- a/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js +++ b/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js @@ -163,7 +163,7 @@ YoutubeLinkEnhancement.prototype.campaignCookiesAllowed = function () { var cookiePolicy = window.GOVUK.getConsentCookie() - return cookiePolicy !== null ? cookiePolicy.campaigns : true + return cookiePolicy !== null ? cookiePolicy.campaigns : false } YoutubeLinkEnhancement.nextId = function () { diff --git a/spec/javascripts/components/govspeak-spec.js b/spec/javascripts/components/govspeak-spec.js index 5de65f4f27..cb33a36cd1 100644 --- a/spec/javascripts/components/govspeak-spec.js +++ b/spec/javascripts/components/govspeak-spec.js @@ -9,6 +9,14 @@ describe('Govspeak', function () { }) describe('youtube enhancement', function () { + beforeEach(function () { + window.GOVUK.cookie('cookies_policy', '{"essential":true,"settings":true,"usage":true,"campaigns":true}') + }) + + afterEach(function () { + window.GOVUK.cookie('cookies_policy', null) + }) + it('embeds youtube videos', function () { container = document.createElement('div') container.innerHTML = diff --git a/spec/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement-spec.js b/spec/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement-spec.js index 1e80ce0671..d0ae3980b8 100644 --- a/spec/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement-spec.js +++ b/spec/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement-spec.js @@ -6,14 +6,16 @@ describe('Youtube link enhancement', function () { var container beforeEach(function () { + window.GOVUK.cookie('cookies_policy', '{"essential":true,"settings":true,"usage":true,"campaigns":true}') container = document.createElement('div') }) afterEach(function () { + window.GOVUK.cookie('cookies_policy', null) document.body.removeChild(container) }) - it('replaces a link and it\'s container with a media-player embed', function () { + it('replaces a link and its container with a media-player embed', function () { container.innerHTML = '
' + '

Agile at GDS

' + @@ -124,14 +126,16 @@ describe('Youtube link enhancement', function () { var container beforeEach(function () { + window.GOVUK.cookie('cookies_policy', '{"essential":true,"settings":true,"usage":true,"campaigns":true}') container = document.createElement('div') }) afterEach(function () { + window.GOVUK.cookie('cookies_policy', null) document.body.removeChild(container) }) - it('replaces a livestream link and it\'s container with a media-player embed', function () { + it('replaces a livestream link and its container with a media-player embed', function () { container.innerHTML = '
' + '

Livestream

' + From 743b2988cf90a6ad58a32ff18a2cce3430832a5b Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Thu, 29 Feb 2024 15:08:01 +0000 Subject: [PATCH 6/7] Refactor domain configuration for load-analytics - now that the domain config contains information about more than just analytics, it feels like it should be separated out for clarity - updated docs and tests accordingly --- .../domain-config.js | 73 +++++++++++++++ .../load-analytics.js | 89 ++----------------- docs/load-analytics.md | 6 +- .../load-analytics.spec.js | 35 ++++---- 4 files changed, 105 insertions(+), 98 deletions(-) create mode 100644 app/assets/javascripts/govuk_publishing_components/domain-config.js diff --git a/app/assets/javascripts/govuk_publishing_components/domain-config.js b/app/assets/javascripts/govuk_publishing_components/domain-config.js new file mode 100644 index 0000000000..eb419b710f --- /dev/null +++ b/app/assets/javascripts/govuk_publishing_components/domain-config.js @@ -0,0 +1,73 @@ +window.GOVUK = window.GOVUK || {} +window.GOVUK.vars = window.GOVUK.vars || {} +window.GOVUK.vars.domains = [ + { + // need to have this one at the start, see loadGa4 function + name: 'development', + domains: [ + 'localhost', + '127.0.0.1', + '0.0.0.0', + 'dev.gov.uk' + ], + initialiseGA4: true, + id: 'GTM-MG7HG5W', + auth: 'bRiZ-jiEHtw6hHpGd6dF9w', + preview: 'env-3', + gaProperty: 'UA-UNSET', + gaPropertyCrossDomain: 'UA-UNSET', + consentApiUrl: 'staging' + }, + { + name: 'production', + domains: [ + 'www.gov.uk', + 'www-origin.publishing.service.gov.uk', + 'assets.publishing.service.gov.uk' + ], + initialiseGA4: true, + id: 'GTM-MG7HG5W', + gaProperty: 'UA-26179049-1', + gaPropertyCrossDomain: 'UA-145652997-1', + consentApiUrl: 'production' + }, + { + name: 'staging', + domains: [ + 'www.staging.publishing.service.gov.uk', + 'www-origin.staging.publishing.service.gov.uk', + 'assets.staging.publishing.service.gov.uk' + ], + initialiseGA4: true, + id: 'GTM-MG7HG5W', + auth: 'oJWs562CxSIjZKn_GlB5Bw', + preview: 'env-5', + gaProperty: 'UA-26179049-20', + gaPropertyCrossDomain: 'UA-145652997-1', + consentApiUrl: 'staging' + }, + { + name: 'integration', + domains: [ + 'www.integration.publishing.service.gov.uk', + 'www-origin.integration.publishing.service.gov.uk', + 'assets.integration.publishing.service.gov.uk' + ], + initialiseGA4: true, + id: 'GTM-MG7HG5W', + auth: 'C7iYdcsOlYgGmiUJjZKrHQ', + preview: 'env-4', + gaProperty: 'UA-26179049-22', + gaPropertyCrossDomain: 'UA-145652997-1', + consentApiUrl: 'staging' + }, + { + name: 'devdocs', + domains: [ + 'docs.publishing.service.gov.uk' + ], + initialiseGA4: true, + id: 'GTM-TNKCK97', + consentApiUrl: 'production' + } +] diff --git a/app/assets/javascripts/govuk_publishing_components/load-analytics.js b/app/assets/javascripts/govuk_publishing_components/load-analytics.js index fd90159474..f958f16814 100644 --- a/app/assets/javascripts/govuk_publishing_components/load-analytics.js +++ b/app/assets/javascripts/govuk_publishing_components/load-analytics.js @@ -1,83 +1,12 @@ //= require govuk_publishing_components/analytics //= require govuk_publishing_components/analytics-ga4 //= require govuk_publishing_components/analytics/linked-domains +//= require govuk_publishing_components/domain-config window.GOVUK.loadAnalytics = { - domains: [ - { - // need to have this one at the start, see loadGa4 function - name: 'development', - domains: [ - 'localhost', - '127.0.0.1', - '0.0.0.0', - 'dev.gov.uk' - ], - initialiseGA4: true, - id: 'GTM-MG7HG5W', - auth: 'bRiZ-jiEHtw6hHpGd6dF9w', - preview: 'env-3', - gaProperty: 'UA-UNSET', - gaPropertyCrossDomain: 'UA-UNSET', - consentApiUrl: 'staging' - }, - { - name: 'production', - domains: [ - 'www.gov.uk', - 'www-origin.publishing.service.gov.uk', - 'assets.publishing.service.gov.uk' - ], - initialiseGA4: true, - id: 'GTM-MG7HG5W', - gaProperty: 'UA-26179049-1', - gaPropertyCrossDomain: 'UA-145652997-1', - consentApiUrl: 'production' - }, - { - name: 'staging', - domains: [ - 'www.staging.publishing.service.gov.uk', - 'www-origin.staging.publishing.service.gov.uk', - 'assets.staging.publishing.service.gov.uk' - ], - initialiseGA4: true, - id: 'GTM-MG7HG5W', - auth: 'oJWs562CxSIjZKn_GlB5Bw', - preview: 'env-5', - gaProperty: 'UA-26179049-20', - gaPropertyCrossDomain: 'UA-145652997-1', - consentApiUrl: 'staging' - }, - { - name: 'integration', - domains: [ - 'www.integration.publishing.service.gov.uk', - 'www-origin.integration.publishing.service.gov.uk', - 'assets.integration.publishing.service.gov.uk' - ], - initialiseGA4: true, - id: 'GTM-MG7HG5W', - auth: 'C7iYdcsOlYgGmiUJjZKrHQ', - preview: 'env-4', - gaProperty: 'UA-26179049-22', - gaPropertyCrossDomain: 'UA-145652997-1', - consentApiUrl: 'staging' - }, - { - name: 'devdocs', - domains: [ - 'docs.publishing.service.gov.uk' - ], - initialiseGA4: true, - id: 'GTM-TNKCK97', - consentApiUrl: 'production' - } - ], - loadExtraDomains: function () { - if (Array.isArray(window.GOVUK.analyticsGa4Domains)) { - this.domains = this.domains.concat(window.GOVUK.analyticsGa4Domains) + if (Array.isArray(window.GOVUK.vars.extraDomains)) { + window.GOVUK.vars.domains = window.GOVUK.vars.domains.concat(window.GOVUK.vars.extraDomains) } }, @@ -94,8 +23,8 @@ window.GOVUK.loadAnalytics = { window.GOVUK.analyticsVars.gaProperty = 'UA-UNSET' window.GOVUK.analyticsVars.gaPropertyCrossDomain = 'UA-UNSET' - for (var i = 0; i < this.domains.length; i++) { - var current = this.domains[i] + for (var i = 0; i < window.GOVUK.vars.domains.length; i++) { + var current = window.GOVUK.vars.domains[i] if (this.arrayContains(currentDomain, current.domains)) { window.GOVUK.analyticsVars.gaProperty = current.gaProperty window.GOVUK.analyticsVars.gaPropertyCrossDomain = current.gaPropertyCrossDomain @@ -140,11 +69,11 @@ window.GOVUK.loadAnalytics = { getEnvironment: function (currentDomain) { // lots of dev domains, so simplify the matching process if (currentDomain.match(/[a-zA-Z0-9.-]+dev\.gov\.uk/)) { - return this.domains[0] + return window.GOVUK.vars.domains[0] } else { - for (var i = 0; i < this.domains.length; i++) { - if (this.arrayContains(currentDomain, this.domains[i].domains)) { - return this.domains[i] + for (var i = 0; i < window.GOVUK.vars.domains.length; i++) { + if (this.arrayContains(currentDomain, window.GOVUK.vars.domains[i].domains)) { + return window.GOVUK.vars.domains[i] } } } diff --git a/docs/load-analytics.md b/docs/load-analytics.md index 9bbfa17f52..66fe418c63 100644 --- a/docs/load-analytics.md +++ b/docs/load-analytics.md @@ -18,11 +18,12 @@ The Google Analytics 4 environment variables are: ## Passing extra options -If you wish to initialise the GA4 code on a new domain with different attributes, the code has been written to accept an array of additional values. Extra domains can be added before loading `dependencies.js` as below. +If you wish to initialise the GA4 code on a new domain with different attributes, the code has been written to accept an array of additional values. Extra domains can be added at the end of your code as shown. ```JavaScript window.GOVUK = window.GOVUK || {} -window.GOVUK.analyticsGa4Domains = [ +window.GOVUK.vars = window.GOVUK.vars || {} +window.GOVUK.vars.extraDomains = [ { name: 'my-domain', domains: ['not-a-real-domain.co.org.uk'], @@ -34,6 +35,5 @@ window.GOVUK.analyticsGa4Domains = [ gaProperty: 'gaProperty', // for UA gaPropertyCrossDomain: 'gaPropertyCrossDomain' // for UA (optional) } - // add further into the array as required ] ``` diff --git a/spec/javascripts/govuk_publishing_components/load-analytics.spec.js b/spec/javascripts/govuk_publishing_components/load-analytics.spec.js index 5cbad97be8..fe588377fc 100644 --- a/spec/javascripts/govuk_publishing_components/load-analytics.spec.js +++ b/spec/javascripts/govuk_publishing_components/load-analytics.spec.js @@ -133,41 +133,46 @@ describe('Analytics loading', function () { }) it('doesnt load GA4 variables if initialiseGA4 is set to false', function () { - window.GOVUK.loadAnalytics.domains[0].initialiseGA4 = false + window.GOVUK.vars.domains[0].initialiseGA4 = false window.GOVUK.loadAnalytics.loadGa4('localhost') expect(window.GOVUK.analyticsGa4.vars).toEqual(null) - window.GOVUK.loadAnalytics.domains[0].initialiseGA4 = true + window.GOVUK.vars.domains[0].initialiseGA4 = true }) describe('when additional domain details are needed', function () { + var saveDomains + + beforeEach(function () { + // use slice to clone the array, otherwise this 'saving' doesn't work + saveDomains = window.GOVUK.vars.domains.slice() + }) + afterEach(function () { - delete window.GOVUK.analyticsGa4Domains + delete window.GOVUK.vars.extraDomains + window.GOVUK.vars.domains = saveDomains.slice() }) it('defaults to the normal list when no extras are passed', function () { - var domains = window.GOVUK.loadAnalytics.domains + var expected = window.GOVUK.vars.domains.slice() window.GOVUK.loadAnalytics.loadExtraDomains() window.GOVUK.loadAnalytics.loadGa4() - expect(window.GOVUK.loadAnalytics.domains).toEqual(domains) + expect(window.GOVUK.vars.domains).toEqual(expected) }) it('allows extra domains to be passed and appended to the existing list', function () { - var newDomain = { + var extra = { name: 'test-domain', domains: ['not-a-real-domain'], initialiseGA4: true, id: 'GTM-001' } - window.GOVUK.analyticsGa4Domains = [newDomain] + window.GOVUK.vars.extraDomains = [extra] + expected = window.GOVUK.vars.domains.slice() + expected.push(extra) + window.GOVUK.loadAnalytics.loadExtraDomains() - expected = { - name: 'test-domain', - domains: ['not-a-real-domain'], - initialiseGA4: true, - id: 'GTM-001' - } - // the new domain gets appended to the end of the array - expect(window.GOVUK.loadAnalytics.domains[5]).toEqual(expected) + // the new domain should be appended to the end of the array + expect(window.GOVUK.vars.domains).toEqual(expected) window.GOVUK.loadAnalytics.loadGa4('not-a-real-domain') expect(window.GOVUK.analyticsGa4.vars.id).toEqual('GTM-001') From 7b5f7515423d1eb2042d8126ee712419f4de23ac Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Tue, 5 Mar 2024 14:48:13 +0000 Subject: [PATCH 7/7] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aee1f36b41..b91f57494d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ of the commit log. ## Unreleased + +* Add single cookie consent API ([PR #3854](https://github.com/alphagov/govuk_publishing_components/pull/3854)) * Update popular links in super navigation header ([PR #3904](https://github.com/alphagov/govuk_publishing_components/pull/3904)) * Allow custom text for GA4 scroll tracker ([PR #3896](https://github.com/alphagov/govuk_publishing_components/pull/3896)) * Ensure analytics stops firing if a user disables usage cookies on our cookie settings page ([PR #3893](https://github.com/alphagov/govuk_publishing_components/pull/3893))