Skip to content

Commit

Permalink
Update notification button attributes from API
Browse files Browse the repository at this point in the history
No longer replace the entire single page notification button HTML from the personalisation API response. Instead, check the boolean "active" in the response: if active is true, user has subscribed to notifications. Update the tracking attribute on the button HTML according to the value of active in the API response. Append the value of data-button-location, if it is provided in the markup, to the tracking attribute value. Update the button text if both data-button-text-unsubscribe and data-button-text-subscribe are provided in the markup attributes

Add a new wrapper class .gem-c-single-page-notication-button__text to more reliably target the button text.

Add tests to check whether the tracking attribute, including optional location, and the custom button text are updated correctly upon receiving the API response. Remove some no longer relevant test classes (.old-button-for-test and .new-button-for-test) since the whole button is no longer being replaced. Add an additional test for checking that the button is rendered visible when the API call completes (the button is initially hidden when JS runs)
  • Loading branch information
hannalaakso committed Nov 17, 2022
1 parent 98df79e commit dd0a733
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,31 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var responseText = xhr.responseText
// if response text exists and is JSON parse-able, parse the response and get the button html
// if response text exists and is JSON parse-able, parse the response and update the button html
if (responseText && this.responseIsJSON(responseText)) {
var newButton = JSON.parse(responseText).button_html
var html = document.createElement('div')
html.innerHTML = newButton
// test that the html returned contains the button component; if yes, swap the button for the updated version
var responseButtonContainer = html.querySelector('form.gem-c-single-page-notification-button')
if (responseButtonContainer) {
this.$module.parentNode.replaceChild(responseButtonContainer, this.$module)
var active = JSON.parse(responseText).active

var customSubscribeText = this.$module.getAttribute('data-button-text-subscribe')
var customUnsubscribeText = this.$module.getAttribute('data-button-text-unsubscribe')
// Only set custom button text if both text items are provided
var customText = customSubscribeText && customUnsubscribeText

// Append '-[button-location]' to the tracking data attribute value if data-button-location is set
var optionalButtonLocation = this.$module.getAttribute('data-button-location') ? '-' + this.$module.getAttribute('data-button-location') : ''

// If response returns active, user has subscribed to notifications
if (active === true) {
this.$module.setAttribute('data-track-action', 'Unsubscribe-button' + optionalButtonLocation)

if (customText) {
this.$module.querySelector('.gem-c-single-page-notication-button__text').innerHTML = customUnsubscribeText
}
} else {
this.$module.setAttribute('data-track-action', 'Subscribe-button' + optionalButtonLocation)

if (customText) {
this.$module.querySelector('.gem-c-single-page-notication-button__text').innerHTML = customSubscribeText
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
wrapper_classes << shared_helper.get_margin_bottom
%>
<% button_text = capture do %>
<svg class="gem-c-single-page-notification-button__icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" height="18" width="18" viewBox="0 0 459.334 459.334"><path fill="currentColor" d="M177.216 404.514c-.001.12-.009.239-.009.359 0 30.078 24.383 54.461 54.461 54.461s54.461-24.383 54.461-54.461c0-.12-.008-.239-.009-.359H175.216zM403.549 336.438l-49.015-72.002v-89.83c0-60.581-43.144-111.079-100.381-122.459V24.485C254.152 10.963 243.19 0 229.667 0s-24.485 10.963-24.485 24.485v27.663c-57.237 11.381-100.381 61.879-100.381 122.459v89.83l-49.015 72.002a24.76 24.76 0 0 0 20.468 38.693H383.08a24.761 24.761 0 0 0 20.469-38.694z"/></svg><%= component_helper.button_text %>
<svg class="gem-c-single-page-notification-button__icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" height="18" width="18" viewBox="0 0 459.334 459.334"><path fill="currentColor" d="M177.216 404.514c-.001.12-.009.239-.009.359 0 30.078 24.383 54.461 54.461 54.461s54.461-24.383 54.461-54.461c0-.12-.008-.239-.009-.359H175.216zM403.549 336.438l-49.015-72.002v-89.83c0-60.581-43.144-111.079-100.381-122.459V24.485C254.152 10.963 243.19 0 229.667 0s-24.485 10.963-24.485 24.485v27.663c-57.237 11.381-100.381 61.879-100.381 122.459v89.83l-49.015 72.002a24.76 24.76 0 0 0 20.468 38.693H383.08a24.761 24.761 0 0 0 20.469-38.694z"/></svg><span class="gem-c-single-page-notication-button__text"><%= component_helper.button_text %></span>
<% end %>
<%= tag.div class: wrapper_classes, data: { module: "gem-track-click"} do %>
<%= tag.form class: component_helper.classes, action: "/email/subscriptions/single-page/new", method: "POST", data: component_helper.data do %>
Expand Down
108 changes: 97 additions & 11 deletions spec/javascripts/components/single-page-notification-button-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ describe('Single page notification component', function () {

beforeEach(function () {
FIXTURE =
'<form class="gem-c-single-page-notification-button old-button-for-test js-personalisation-enhancement" action="/email/subscriptions/single-page/new" method="POST" data-module="single-page-notification-button">' +
'<form class="gem-c-single-page-notification-button js-personalisation-enhancement" action="/email/subscriptions/single-page/new" method="POST" data-module="single-page-notification-button">' +
'<input type="hidden" name="base_path" value="/current-page-path">' +
'<button class="gem-c-single-page-notification-button__submit" type="submit">Get emails about this page</button>' +
'<button class="gem-c-single-page-notification-button__submit" type="submit"><span class="gem-c-single-page-notication-button__text">Get emails about this page</span></button>' +
'</form>'
window.setFixtures(FIXTURE)
jasmine.Ajax.install()
Expand All @@ -27,7 +27,7 @@ describe('Single page notification component', function () {

it('includes button_location in the call to the personalisation API when button_location is specified', function () {
FIXTURE =
'<form class="gem-c-single-page-notification-button old-button-for-test js-personalisation-enhancement" action="/email/subscriptions/single-page/new" method="POST" data-module="single-page-notification-button" data-button-location="top">' +
'<form class="gem-c-single-page-notification-button js-personalisation-enhancement" action="/email/subscriptions/single-page/new" method="POST" data-module="single-page-notification-button" data-button-location="top">' +
'<input type="hidden" name="base_path" value="/current-page-path">' +
'<button class="gem-c-single-page-notification-button__submit" type="submit">Get emails about this page</button>' +
'</form>'
Expand All @@ -39,17 +39,103 @@ describe('Single page notification component', function () {
expect(request.method).toBe('GET')
})

it('replaces the button when the API returns button html', function () {
it('renders the button visible when API response is received', function () {
initButton()

jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{\n "base_path": "/current-page-path",\n "active": false\n }'
})

var button = document.querySelector('form.gem-c-single-page-notification-button')
expect(button).toHaveClass('gem-c-single-page-notification-button--visible')
})

it('renders "Subscribe-button" tracking attribute value if "active" in the API response is false', function () {
initButton()

jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{\n "base_path": "/current-page-path",\n "active": false\n }'
})

var buttonTrackingAttribute = document.querySelector('form.gem-c-single-page-notification-button').getAttribute('data-track-action')
expect(buttonTrackingAttribute).toBe('Subscribe-button')
})

it('renders "Unsubscribe-button" tracking attribute value if "active" in the API response is true', function () {
initButton()

jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{\n "base_path": "/current-page-path",\n "active": true\n }'
})

var buttonTrackingAttribute = document.querySelector('form.gem-c-single-page-notification-button').getAttribute('data-track-action')
expect(buttonTrackingAttribute).toBe('Unsubscribe-button')
})

it('renders button location as part of the tracking attribute value when API response is received if "data-button-location" is set', function () {
FIXTURE =
'<form class="gem-c-single-page-notification-button js-personalisation-enhancement" action="/email/subscriptions/ single-page/new" method="POST" data-module="single-page-notification-button" data-button-location="top">' +
'<input type="hidden" name="base_path" value="/current-page-path">' +
'<button class="gem-c-single-page-notification-button__submit" type="submit"><span class="gem-c-single-page-notication-button__text">Get emails about this page</span></button>' +
'</form>'
window.setFixtures(FIXTURE)

initButton()

jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{\n "base_path": "/current-page-path",\n "active": false\n }'
})

var buttonTrackingAttribute = document.querySelector('form.gem-c-single-page-notification-button').getAttribute('data-track-action')
expect(buttonTrackingAttribute).toBe('Subscribe-button-top')
})

it('renders custom subscribe button text when API response is received if "data-button-text-subscribe" and "data-button-text-unsubscribe" are set', function () {
FIXTURE =
'<form class="gem-c-single-page-notification-button js-personalisation-enhancement" action="/email/subscriptions/ single-page/new" method="POST" data-module="single-page-notification-button" data-button-text-subscribe="Start getting emails about this stuff" data-button-text-unsubscribe="Stop getting emails about this stuff">' +
'<input type="hidden" name="base_path" value="/current-page-path">' +
'<button class="gem-c-single-page-notification-button__submit" type="submit"><span class="gem-c-single-page-notication-button__text">Get emails about this page</span></button>' +
'</form>'
window.setFixtures(FIXTURE)

initButton()

jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{\n "base_path": "/current-page-path",\n "active": false\n }'
})

var button = document.querySelector('form.gem-c-single-page-notification-button')
expect(button).toHaveText('Start getting emails about this stuff')
})

it('renders custom unsubscribe button text when API response is received if "data-button-text-subscribe" and "data-button-text-unsubscribe" are set', function () {
FIXTURE =
'<form class="gem-c-single-page-notification-button js-personalisation-enhancement" action="/email/subscriptions/ single-page/new" method="POST" data-module="single-page-notification-button" data-button-text-subscribe="Start getting emails about this stuff" data-button-text-unsubscribe="Stop getting emails about this stuff">' +
'<input type="hidden" name="base_path" value="/current-page-path">' +
'<button class="gem-c-single-page-notification-button__submit" type="submit"><span class="gem-c-single-page-notication-button__text">Get emails about this page</span></button>' +
'</form>'
window.setFixtures(FIXTURE)

initButton()

jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{\n "base_path": "/current-page-path",\n "active": true,\n "button_html": "<form class=\\"gem-c-single-page-notification-button new-button-for-test\\" action=\\"/email/subscriptions/single-page/new\\" method=\\"POST\\">\\n <input type=\\"hidden\\" name=\\"base_path\\" value=\\"/current-page-path\\">\\n <button class=\\"gem-c-single-page-notification-button__submit\\" type=\\"submit\\">Stop getting emails about this page\\n</button>\\n</form>"\n}'
responseText: '{\n "base_path": "/current-page-path",\n "active": true\n }'
})

var button = document.querySelector('form.gem-c-single-page-notification-button.new-button-for-test button')
expect(button).toHaveText('Stop getting emails about this page')
var button = document.querySelector('form.gem-c-single-page-notification-button')
expect(button).toHaveText('Stop getting emails about this stuff')
})

it('should remain unchanged if the response is not JSON', function () {
Expand All @@ -62,7 +148,7 @@ describe('Single page notification component', function () {
responseText: responseText
})

var button = document.querySelector('form.gem-c-single-page-notification-button.old-button-for-test.gem-c-single-page-notification-button--visible button')
var button = document.querySelector('form.gem-c-single-page-notification-button.gem-c-single-page-notification-button--visible button')
expect(button).toHaveText('Get emails about this page')
expect(GOVUK.Modules.SinglePageNotificationButton.prototype.responseIsJSON(responseText)).toBe(false)
})
Expand All @@ -77,7 +163,7 @@ describe('Single page notification component', function () {
responseText: responseText
})

var button = document.querySelector('form.gem-c-single-page-notification-button.old-button-for-test.gem-c-single-page-notification-button--visible button')
var button = document.querySelector('form.gem-c-single-page-notification-button.gem-c-single-page-notification-button--visible button')
expect(button).toHaveText('Get emails about this page')
expect(GOVUK.Modules.SinglePageNotificationButton.prototype.responseIsJSON(responseText)).toBe(false)
})
Expand All @@ -91,7 +177,7 @@ describe('Single page notification component', function () {
responseText: ''
})

var button = document.querySelector('form.gem-c-single-page-notification-button.old-button-for-test.gem-c-single-page-notification-button--visible button')
var button = document.querySelector('form.gem-c-single-page-notification-button.gem-c-single-page-notification-button--visible button')
expect(button).toHaveText('Get emails about this page')
})

Expand All @@ -100,7 +186,7 @@ describe('Single page notification component', function () {
initButton()
jasmine.Ajax.requests.mostRecent().responseTimeout()

var button = document.querySelector('form.gem-c-single-page-notification-button.old-button-for-test.gem-c-single-page-notification-button--visible button')
var button = document.querySelector('form.gem-c-single-page-notification-button.gem-c-single-page-notification-button--visible button')
expect(button).toHaveText('Get emails about this page')
jasmine.clock().uninstall()
})
Expand Down

0 comments on commit dd0a733

Please sign in to comment.