Skip to content

Commit

Permalink
Add single consent library
Browse files Browse the repository at this point in the history
  • Loading branch information
andysellick committed Feb 6, 2024
1 parent 738e1e3 commit 8040e72
Show file tree
Hide file tree
Showing 2 changed files with 275 additions and 0 deletions.
@@ -0,0 +1,65 @@
/* 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 (!this.shouldUseConsentApi()) {
if (callback) {
callback()
}
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 && environment.name === 'production') {
this.url = 'production'
}
}
// create the consent API object
window.GOVUK.singleConsent.consentApiObj = new GovSingleConsent(callback, this.url)
},

shouldUseConsentApi: function () {
return window.GOVUK.useSingleConsentApi
},

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')
}
}
},

setPreferences: function (type, options) {
try {
if (!window.GOVUK.singleConsent.consentApiObj) {
this.init()
}
switch (type) {
case 'accept':
window.GOVUK.singleConsent.consentApiObj.setConsents(GovSingleConsent.ACCEPT_ALL)
break
case 'reject':
window.GOVUK.singleConsent.consentApiObj.setConsents(GovSingleConsent.REJECT_ALL)
break
default:
window.GOVUK.singleConsent.consentApiObj.setConsents(options)
}
} catch (e) {
console.error('Single consent ' + type + ' error: ' + e.message, window.location)
}
}
}
}(window))
@@ -0,0 +1,210 @@
/* 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 () {
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('does nothing', function () {
window.GOVUK.singleConsent.init()
expect(window.GOVUK.singleConsent.consentApiObj).not.toBeDefined()
})

it('immediately calls anything passed as a callback', function () {
var test = {
testFunction: function () {}
}
spyOn(test, 'testFunction')
window.GOVUK.singleConsent.init(test.testFunction)
expect(window.GOVUK.singleConsent.consentApiObj).not.toBeDefined()
expect(test.testFunction).toHaveBeenCalled()
})
})

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)
expect(window.GOVUK.triggerEvent).not.toHaveBeenCalled()
})

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 () {
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).toHaveBeenCalled()
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.triggerEvent).not.toHaveBeenCalled()
expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}')
})

it('allows individual cookies to be set', 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.triggerEvent).not.toHaveBeenCalled()
expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":true,"settings":true}')
})
})

describe('when there is a problem', function () {
beforeEach(function () {
jasmine.clock().install()
window.GOVUK.cookie('gov_singleconsent_uid', '1234')
})

afterEach(function () {
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 not as expected', function () {
window.GOVUK.singleConsent.init()
window.GOVUK.singleConsent.setPreferences('accept')
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'text/plain',
responseText: 'surprise!'
})
expect(window.GOVUK.singleConsent.consentApiObj).toBeDefined()
expect(window.GOVUK.cookie('cookies_policy')).toEqual('{"essential":true,"usage":false,"campaigns":false,"settings":false}')
})
})
})
})

0 comments on commit 8040e72

Please sign in to comment.