diff --git a/tests/javascripts/analytics/analytics.test.js b/tests/javascripts/analytics/analytics.test.js new file mode 100644 index 000000000..6b357a1e8 --- /dev/null +++ b/tests/javascripts/analytics/analytics.test.js @@ -0,0 +1,97 @@ +const helpers = require('../support/helpers'); + +beforeAll(() => { + + // add the script GA looks for in the document + document.body.appendChild(document.createElement('script')); + + require('../../../app/assets/javascripts/govuk/cookie-functions.js'); + require('../../../app/assets/javascripts/analytics/analytics.js'); + require('../../../app/assets/javascripts/analytics/init.js'); + +}); + +afterAll(() => { + + require('../support/teardown.js'); + +}); + +describe("Analytics", () => { + + let analytics; + + beforeEach(() => { + + window.ga = jest.fn(); + + analytics = new GOVUK.Analytics({ + trackingId: 'UA-75215134-1', + cookieDomain: 'auto', + anonymizeIp: true, + displayFeaturesTask: null, + transport: 'beacon' + }); + + }); + + afterEach(() => { + + window.ga.mockReset(); + + }); + + describe("When created", () => { + + test("It configures a tracker", () => { + + setUpArguments = window.ga.mock.calls; + + expect(setUpArguments[0]).toEqual(['create', 'UA-75215134-1', 'auto']); + expect(setUpArguments[1]).toEqual(['set', 'anonymizeIp', true]); + expect(setUpArguments[2]).toEqual(['set', 'displayFeaturesTask', null]); + expect(setUpArguments[3]).toEqual(['set', 'transport', 'beacon']); + + }); + + }); + + describe("When tracking pageviews", () => { + + test("It sends the right URL for the page if no arguments", () => { + + window.ga.mockClear(); + + jest.spyOn(window, 'location', 'get').mockImplementation(() => { + return { + 'pathname': '/privacy', + 'search': '' + }; + }); + + analytics.trackPageview(); + + expect(window.ga.mock.calls[0]).toEqual(['send', 'pageview', '/privacy']); + + }); + + test("It strips the UUIDs from URLs", () => { + + window.ga.mockClear(); + + jest.spyOn(window, 'location', 'get').mockImplementation(() => { + return { + 'pathname': '/services/6658542f-0cad-491f-bec8-ab8457700ead', + 'search': '' + }; + }); + + analytics.trackPageview(); + + expect(window.ga.mock.calls[0]).toEqual(['send', 'pageview', '/services/…']); + + }); + + }); + +}); diff --git a/tests/javascripts/analytics/init.test.js b/tests/javascripts/analytics/init.test.js new file mode 100644 index 000000000..3f3563b5c --- /dev/null +++ b/tests/javascripts/analytics/init.test.js @@ -0,0 +1,123 @@ +const helpers = require('../support/helpers'); + +beforeAll(() => { + + // add the script GA looks for in the document + document.body.appendChild(document.createElement('script')); + + require('../../../app/assets/javascripts/govuk/cookie-functions.js'); + require('../../../app/assets/javascripts/analytics/analytics.js'); + require('../../../app/assets/javascripts/analytics/init.js'); + +}); + +afterAll(() => { + + require('../support/teardown.js'); + +}); + +describe("Analytics init", () => { + + beforeAll(() => { + + window.ga = jest.fn(); + jest.spyOn(window.GOVUK.Analytics, 'load'); + + // pretend we're on the /privacy page + jest.spyOn(window, 'location', 'get').mockImplementation(() => { + return { + 'pathname': '/privacy', + 'search': '' + }; + }); + + }); + + afterEach(() => { + + window.GOVUK.Analytics.load.mockClear(); + window.ga.mockClear(); + + }); + + test("After the init.js script has been loaded, Google Analytics will be disabled", () => { + + expect(window['ga-disable-UA-26179049-1']).toBe(true); + + }); + + describe("If initAnalytics has already been called", () => { + + beforeAll(() => { + + // Fake a tracker instance + window.GOVUK.analytics = {}; + + }); + + beforeEach(() => { + + window.GOVUK.initAnalytics(); + + }); + + afterAll(() => { + + delete window.GOVUK.analytics; + + }); + + test("The Google Analytics libraries will not be loaded", () => { + + expect(window.GOVUK.Analytics.load).not.toHaveBeenCalled(); + + }); + + }); + + describe("If initAnalytics has not been called", () => { + + beforeEach(() => { + + window.GOVUK.initAnalytics(); + + }); + + afterEach(() => { + + // window.GOVUK.initAnalytics sets up a new window.GOVUK.analytics which needs clearing + delete window.GOVUK.analytics; + + }); + + test("Google Analytics will not be disabled", () => { + + expect(window['ga-disable-UA-26179049-1']).toBe(false); + + }); + + test("The Google Analytics libraries will have been loaded", () => { + + expect(window.GOVUK.Analytics.load).toHaveBeenCalled(); + + }); + + test("There will be an interface with the Google Analytics API", () => { + + expect(window.GOVUK.analytics).toBeDefined(); + + }); + + test("A pageview will be registered", () => { + + expect(window.ga.mock.calls.length).toEqual(5); + + // The first 4 calls configure the analytics tracker. All subsequent calls send data + expect(window.ga.mock.calls[4]).toEqual(['send', 'pageview', '/privacy']); + + }); + + }); + +}); diff --git a/tests/javascripts/consent.test.js b/tests/javascripts/consent.test.js new file mode 100644 index 000000000..9217bd81c --- /dev/null +++ b/tests/javascripts/consent.test.js @@ -0,0 +1,55 @@ +const helpers = require('./support/helpers'); + +beforeAll(() => { + + require('../../app/assets/javascripts/govuk/cookie-functions.js'); + require('../../app/assets/javascripts/consent.js'); + +}); + +afterAll(() => { + + require('./support/teardown.js'); + +}); + +describe("Cookie consent", () => { + + describe("hasConsentFor", () => { + + afterEach(() => { + + // remove cookie set by tests + helpers.deleteCookie('cookies_policy'); + + }); + + test("If there is no consent cookie, return false", () => { + + expect(window.GOVUK.hasConsentFor('analytics')).toBe(false); + + }); + + describe("If a consent cookie is set", () => { + + test("If the category is not saved in the cookie, return false", () => { + + window.GOVUK.setConsentCookie({ 'usage': true }); + + expect(window.GOVUK.hasConsentFor('analytics')).toBe(false); + + }); + + test("If the category is saved in the cookie, return its value", () => { + + window.GOVUK.setConsentCookie({ 'analytics': true }); + + expect(window.GOVUK.hasConsentFor('analytics')).toBe(true); + + }); + + }); + + }); + +}); diff --git a/tests/javascripts/cookieMessage.test.js b/tests/javascripts/cookieMessage.test.js new file mode 100644 index 000000000..37e5f3bdf --- /dev/null +++ b/tests/javascripts/cookieMessage.test.js @@ -0,0 +1,230 @@ +const helpers = require('./support/helpers'); + +beforeAll(() => { + + require('../../app/assets/javascripts/govuk/cookie-functions.js'); + require('../../app/assets/javascripts/analytics/analytics.js'); + require('../../app/assets/javascripts/analytics/init.js'); + require('../../app/assets/javascripts/cookieMessage.js'); + +}); + +afterAll(() => { + + require('./support/teardown.js'); + +}); + +describe("Cookie message", () => { + + let cookieMessage; + + beforeAll(() => { + + helpers.deleteCookie('cookies-policy'); + + }); + + beforeEach(() => { + + // add the script GA looks for in the document + document.body.appendChild(document.createElement('script')); + + jest.spyOn(window.GOVUK, 'initAnalytics'); + + cookieMessage = ` +
`; + + document.body.innerHTML += cookieMessage; + + }); + + afterEach(() => { + + document.body.innerHTML = ''; + + // remove cookie set by tests + helpers.deleteCookie('cookies_policy'); + + // reset spies + window.GOVUK.initAnalytics.mockClear(); + + // remove analytics tracker + delete window.GOVUK.analytics; + + // reset global variable to state when init.js loaded + window['ga-disable-UA-26179049-1'] = true; + + }); + + /* + Note: If no JS, the cookie banner shows a button to take you to the cookies page for more information. + + This works through CSS, based on the presence of the `js-enabled` class on the so is not tested here. + */ + + test("If the cookies set by the old banner still exist, they can be cleared with the `clearOldCookies` method", () => { + + helpers.setCookie('seen_cookie_message', 'true', { 'days': 365 }); + helpers.setCookie('_ga', 'GA1.1.123.123', { 'days': 365 }); + helpers.setCookie('_gid', 'GA1.1.456.456', { 'days': 1 }); + + window.GOVUK.Modules.CookieBanner.clearOldCookies(); + + expect(window.GOVUK.cookie('seen_cookie_message')).toBeNull(); + expect(window.GOVUK.cookie('_ga')).toBeNull(); + expect(window.GOVUK.cookie('_gid')).toBeNull(); + + }); + + test("If user has made a choice to give their consent or not, the cookie banner should be hidden", () => { + + window.GOVUK.setConsentCookie({ 'analytics': false }); + + window.GOVUK.modules.start() + + expect(helpers.element(document.querySelector('.notify-cookie-banner')).is('hidden')).toBe(true); + + }); + + describe("If user hasn't made a choice to give their consent or not", () => { + + beforeEach(() => { + + window.GOVUK.modules.start(); + + }); + + test("The cookie banner should show", () => { + + const banner = helpers.element(document.querySelector('.notify-cookie-banner')); + + expect(banner.is('hidden')).toBe(false); + + }); + + test("No analytics should run", () => { + + expect(window.GOVUK.initAnalytics).not.toHaveBeenCalled(); + + }); + + describe("If the user clicks the button to accept analytics", () => { + + beforeEach(() => { + + const acceptButton = document.querySelector('.notify-cookie-banner__button-accept button'); + + helpers.triggerEvent(acceptButton, 'click'); + + }); + + test("the banner should confirm your choice and link to the cookies page as a way to change your mind", () => { + + confirmation = helpers.element(document.querySelector('.notify-cookie-banner__confirmation')); + + expect(confirmation.is('hidden')).toBe(false); + expect(confirmation.el.textContent.trim()).toEqual(expect.stringMatching(/^You’ve accepted analytics cookies/)); + + }); + + test("If the user clicks the 'hide' button, the banner should be hidden", () => { + + const hideButton = document.querySelector('.notify-cookie-banner__hide-button'); + const banner = helpers.element(document.querySelector('.notify-cookie-banner')); + + helpers.triggerEvent(hideButton, 'click'); + + expect(banner.is('hidden')).toBe(true); + + }); + + test("The consent cookie should be set, with analytics set to 'true'", () => { + + expect(window.GOVUK.getConsentCookie()).toEqual({ 'analytics': true }); + + }); + + test("The analytics should be set up", () => { + + expect(window.GOVUK.analytics).toBeDefined(); + + }); + + }); + + describe("If the user clicks the button to reject analytics", () => { + + beforeEach(() => { + + const rejectButton = document.querySelector('.notify-cookie-banner__button-reject button'); + + helpers.triggerEvent(rejectButton, 'click'); + + }); + + test("the banner should confirm your choice and link to the cookies page as a way to change your mind", () => { + + confirmation = helpers.element(document.querySelector('.notify-cookie-banner__confirmation')); + + expect(confirmation.is('hidden')).toBe(false); + expect(confirmation.el.textContent.trim()).toEqual(expect.stringMatching(/^You told us not to use analytics cookies/)); + + }); + + test("If the user clicks the 'hide' button, the banner should be hidden", () => { + + const hideButton = document.querySelector('.notify-cookie-banner__hide-button'); + const banner = helpers.element(document.querySelector('.notify-cookie-banner')); + + helpers.triggerEvent(hideButton, 'click'); + + expect(banner.is('hidden')).toBe(true); + + }); + + test("The consent cookie should be set, with analytics set to 'true'", () => { + + expect(window.GOVUK.getConsentCookie()).toEqual({ 'analytics': false }); + + }); + + test("The analytics should not be set up", () => { + + expect(window.GOVUK.analytics).not.toBeDefined(); + + }); + + }); + + }); + +}); diff --git a/tests/javascripts/cookieSettings.test.js b/tests/javascripts/cookieSettings.test.js new file mode 100644 index 000000000..a6c6f1344 --- /dev/null +++ b/tests/javascripts/cookieSettings.test.js @@ -0,0 +1,255 @@ +const helpers = require('./support/helpers'); + +beforeAll(() => { + + require('../../app/assets/javascripts/govuk/cookie-functions.js'); + require('../../app/assets/javascripts/consent.js'); + require('../../app/assets/javascripts/analytics/analytics.js'); + require('../../app/assets/javascripts/analytics/init.js'); + require('../../app/assets/javascripts/cookieSettings.js'); + +}); + +afterAll(() => { + + require('./support/teardown.js'); + +}); + +describe("Cookie settings", () => { + + let cookiesPageContent; + let yesRadio; + let noRadio; + let saveButton; + + beforeEach(() => { + + // add the script GA looks for in the document + document.body.appendChild(document.createElement('script')); + + window.ga = jest.fn(); + jest.spyOn(window.GOVUK, 'initAnalytics'); + + cookiesPageContent = ` + ++ Cookies are small files saved on your phone, tablet or computer when you visit a website. +
+We use cookies to make GOV.UK Notify work and collect information about how you use our service.
+ +