-
0
+ beforeEach(() => {
+
+ // store HTML in string to allow use in AJAX responses
+ HTMLString = `
+
`;
+
+
+ initialHTMLString = `
+ ${HTMLString}
+
`;
+
+ document.body.innerHTML = initialHTMLString;
+
+ // default the response to match the content inside div[data-module]
+ responseObj[updateKey] = HTMLString;
+
+ });
+
+ test("It should make requests to the URL specified in the data-resource attribute", () => {
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ expect($.ajax.mock.calls[0][0]).toEqual(resourceURL);
+
+ });
+
+ test("If the response contains no changes, the DOM should stay the same", () => {
+
+ // send the done callback a response with updates included
+ responseObj[updateKey] = HTMLString;
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ // check a sample DOM node is unchanged
+ expect(document.querySelectorAll('.big-number-number')[0].textContent.trim()).toEqual("0");
+
+ });
+
+ test("If the response contains changes, it should update the DOM with them", () => {
+
+ // send the done callback a response with updates included
+ responseObj[updateKey] = HTMLString.replace(/
0<\/div>{1}/, '
1
');
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ // check the right DOM node is updated
+ expect(document.querySelectorAll('.big-number-number')[0].textContent.trim()).toEqual("1");
+
+ });
+
+ describe("By default", () => {
+
+ beforeEach(() => {
+
+ // start the module
+ window.GOVUK.modules.start();
+
+ });
+
+ test("It should use the GET HTTP method", () => {
+
+ jest.advanceTimersByTime(2000);
+ expect($.ajax.mock.calls[0][1].method).toEqual('get');
+
+ });
+
+ test("It shouldn't send any data as part of the requests", () => {
+
+ jest.advanceTimersByTime(2000);
+ expect($.ajax.mock.calls[0][1].data).toEqual({});
+
+ });
+
+ test("It should request updates with a dynamic interval", () => {
+
+ // First call doesn’t happen in the first 2000ms
+ jest.advanceTimersByTime(1999);
+ expect($.ajax).toHaveBeenCalledTimes(0);
+
+ // But it happens after 2000ms by default
+ jest.advanceTimersByTime(1);
+ expect($.ajax).toHaveBeenCalledTimes(1);
+
+ // It took the server 1000ms to respond to the first call so we
+ // will back off – the next call shouldn’t happen in the next 6904ms
+ jest.advanceTimersByTime(6904);
+ expect($.ajax).toHaveBeenCalledTimes(1);
+
+ // But it should happen after 6905ms
+ jest.advanceTimersByTime(1);
+ expect($.ajax).toHaveBeenCalledTimes(2);
+
+ });
+
+ each([
+ [1000, 0],
+ [1500, 100],
+ [4590, 500],
+ [6905, 1000],
+ [24000, 10000],
+ ]).test('It calculates a delay of %dms if the API responds in %dms', (waitTime, responseTime) => {
+ expect(
+ window.GOVUK.Modules.UpdateContent.calculateBackoff(responseTime)
+ ).toBe(
+ waitTime
+ );
+ });
+
+ });
+
+ describe("If a form is used as a source for data, referenced in the data-form attribute", () => {
+
+ beforeEach(() => {
+
+ document.body.innerHTML += `
+
`;
+
+ document.querySelector('[data-module=update-content]').setAttribute('data-form', 'service');
+
+ // start the module
+ window.GOVUK.modules.start();
+
+ });
+
+ test("requests should use the same HTTP method as the form", () => {
+
+ jest.advanceTimersByTime(2000);
+ expect($.ajax.mock.calls[0][1].method).toEqual('post');
+
+ })
+
+ test("requests should use the data from the form", () => {
+
+ jest.advanceTimersByTime(2000);
+ expect($.ajax.mock.calls[0][1].data).toEqual(helpers.getFormDataFromPairs([
+ ['serviceName', 'Buckhurst surgery'],
+ ['serviceNumber', serviceNumber]
+ ]));
+
+ })
+
+ });
+
+ });
+
+ describe("When adding or removing DOM nodes", () => {
+ var getItemHTMLString = content => {
+ var areas = '';
+
+ content.areas.forEach(area =>
+ areas += "\n" + `
${area}`
+ );
+
+ return `
+
+
`;
+ };
+ var getHTMLString = items => {
- initialHTMLString = `
- ${HTMLString}
-
`;
+ var itemsHTMLString = '';
- document.body.innerHTML = initialHTMLString;
+ items.forEach(item => itemsHTMLString += "\n" + getItemHTMLString(item));
- // default the response to match the content inside div[data-module]
- responseObj[updateKey] = HTMLString;
+ return `
+ ${itemsHTMLString};
+
+
`;
+
+ };
+
+ test("If the response contains no changes, the DOM should stay the same", () => {
+
+ // store HTML in string to allow use in AJAX responses
+ HTMLString = getHTMLString([
+ {
+ title: "Gas leak",
+ hint: "There's a gas leak in the local area. Residents should vacate until further notice.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi B",
+ "Santa Claus Village, Rovaniemi C"
+ ]
+ }
+ ]);
+
+ initialHTMLString = `
+ ${HTMLString}
+
`;
+
+ document.body.innerHTML = initialHTMLString;
+
+ // make the response have an extra item
+ responseObj[updateKey] = HTMLString;
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ // check it has the same number of items
+ expect(document.querySelectorAll('.file-list').length).toEqual(1);
+ expect(document.querySelectorAll('.file-list h2 a')[0].textContent.trim()).toEqual("Gas leak");
+
+ });
+
+ test("If the response adds a node, the DOM should contain that node", () => {
+
+ // store HTML in string to allow use in AJAX responses
+ HTMLString = getHTMLString([
+ {
+ title: "Gas leak",
+ hint: "There's a gas leak in the local area. Residents should vacate until further notice.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi B",
+ "Santa Claus Village, Rovaniemi C"
+ ]
+ }
+ ]);
+
+ initialHTMLString = `
+ ${HTMLString}
+
`;
+
+ document.body.innerHTML = initialHTMLString;
+
+ var updatedHTMLString = getHTMLString([
+ {
+ title: "Gas leak",
+ hint: "There's a gas leak in the local area. Residents should vacate until further notice.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi B",
+ "Santa Claus Village, Rovaniemi C"
+ ]
+ },
+ {
+ title: "Reservoir flooding template",
+ hint: "The local reservoir has flooded. All people within 5 miles should move to a safer location.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi A",
+ "Santa Claus Village, Rovaniemi D"
+ ]
+ }
+ ]);
+
+ // make the response have an extra item
+ responseObj[updateKey] = updatedHTMLString;
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ // check the node has been added
+ expect(document.querySelectorAll('.file-list').length).toEqual(2);
+ expect(document.querySelectorAll('.file-list h2 a')[0].textContent.trim()).toEqual("Gas leak");
+ expect(document.querySelectorAll('.file-list h2 a')[1].textContent.trim()).toEqual("Reservoir flooding template");
+
+ });
+
+ test("If the response removes a node, the DOM should not contain that node", () => {
+
+ // store HTML in string to allow use in AJAX responses
+ HTMLString = getHTMLString([
+ {
+ title: "Gas leak",
+ hint: "There's a gas leak in the local area. Residents should vacate until further notice.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi B",
+ "Santa Claus Village, Rovaniemi C"
+ ]
+ },
+ {
+ title: "Reservoir flooding template",
+ hint: "The local reservoir has flooded. All people within 5 miles should move to a safer location.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi A",
+ "Santa Claus Village, Rovaniemi D"
+ ]
+ }
+ ]);
+
+ initialHTMLString = `
+ ${HTMLString}
+
`;
+
+ document.body.innerHTML = initialHTMLString;
+
+ var updatedHTMLString = getHTMLString([
+ {
+ title: "Gas leak",
+ hint: "There's a gas leak in the local area. Residents should vacate until further notice.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi B",
+ "Santa Claus Village, Rovaniemi C"
+ ]
+ }
+ ]);
+
+ // default the response to match the content inside div[data-module]
+ responseObj[updateKey] = updatedHTMLString;
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ // check the node has been removed
+ expect(document.querySelectorAll('.file-list').length).toEqual(1);
+ expect(document.querySelectorAll('.file-list h2 a')[0].textContent.trim()).toEqual("Gas leak");
+
+ });
+
+ test("If other scripts have added classes to the DOM, they should persist through updates", () => {
+
+ // store HTML in string to allow use in AJAX responses
+ HTMLString = getHTMLString([
+ {
+ title: "Gas leak",
+ hint: "There's a gas leak in the local area. Residents should vacate until further notice.",
+ status: "Waiting for approval",
+ areas: [
+ "Santa Claus Village, Rovaniemi B",
+ "Santa Claus Village, Rovaniemi C"
+ ]
+ }
+ ]);
+
+ initialHTMLString = `
+ ${HTMLString}
+
`;
+
+ document.body.innerHTML = initialHTMLString;
+
+ // mark classes to persist on the partial
+ document.querySelector('.ajax-block-container').setAttribute('data-classes-to-persist', 'js-child-has-focus');
+
+ // Add class to indicate focus state of link on parent heading
+ document.querySelectorAll('.file-list h2')[0].classList.add('js-child-has-focus');
+
+ // make the response match the initial HTML to emulate a response with no changes
+ responseObj[updateKey] = HTMLString;
+
+ // start the module
+ window.GOVUK.modules.start();
+ jest.advanceTimersByTime(2000);
+
+ // check the class is still there
+ expect(document.querySelectorAll('.file-list h2')[0].classList.contains('js-child-has-focus')).toBe(true);
+
+ });
});
@@ -115,138 +485,4 @@ describe('Update content', () => {
});
- test("It should make requests to the URL specified in the data-resource attribute", () => {
-
- // start the module
- window.GOVUK.modules.start();
- jest.advanceTimersByTime(2000);
-
- expect($.ajax.mock.calls[0][0]).toEqual(resourceURL);
-
- });
-
- test("If the response contains no changes, the DOM should stay the same", () => {
-
- // send the done callback a response with updates included
- responseObj[updateKey] = HTMLString;
-
- // start the module
- window.GOVUK.modules.start();
- jest.advanceTimersByTime(2000);
-
- // check the right DOM node is updated
- expect(document.querySelectorAll('.big-number-number')[0].textContent.trim()).toEqual("0");
-
- });
-
- test("If the response contains changes, it should update the DOM with them", () => {
-
- // send the done callback a response with updates included
- responseObj[updateKey] = HTMLString.replace(/
0<\/div>{1}/, '
1
');
-
- // start the module
- window.GOVUK.modules.start();
- jest.advanceTimersByTime(2000);
-
- // check the right DOM node is updated
- expect(document.querySelectorAll('.big-number-number')[0].textContent.trim()).toEqual("1");
-
- });
-
- describe("By default", () => {
-
- beforeEach(() => {
-
- // start the module
- window.GOVUK.modules.start();
-
- });
-
- test("It should use the GET HTTP method", () => {
-
- jest.advanceTimersByTime(2000);
- expect($.ajax.mock.calls[0][1].method).toEqual('get');
-
- });
-
- test("It shouldn't send any data as part of the requests", () => {
-
- jest.advanceTimersByTime(2000);
- expect($.ajax.mock.calls[0][1].data).toEqual({});
-
- });
-
- test("It should request updates with a dynamic interval", () => {
-
- // First call doesn’t happen in the first 2000ms
- jest.advanceTimersByTime(1999);
- expect($.ajax).toHaveBeenCalledTimes(0);
-
- // But it happens after 2000ms by default
- jest.advanceTimersByTime(1);
- expect($.ajax).toHaveBeenCalledTimes(1);
-
- // It took the server 1000ms to respond to the first call so we
- // will back off – the next call shouldn’t happen in the next 6904ms
- jest.advanceTimersByTime(6904);
- expect($.ajax).toHaveBeenCalledTimes(1);
-
- // But it should happen after 6905ms
- jest.advanceTimersByTime(1);
- expect($.ajax).toHaveBeenCalledTimes(2);
-
- });
-
- each([
- [1000, 0],
- [1500, 100],
- [4590, 500],
- [6905, 1000],
- [24000, 10000],
- ]).test('It calculates a delay of %dms if the API responds in %dms', (waitTime, responseTime) => {
- expect(
- window.GOVUK.Modules.UpdateContent.calculateBackoff(responseTime)
- ).toBe(
- waitTime
- );
- });
-
- });
-
- describe("If a form is used as a source for data, referenced in the data-form attribute", () => {
-
- beforeEach(() => {
-
- document.body.innerHTML += `
-
`;
-
- document.querySelector('[data-module=update-content]').setAttribute('data-form', 'service');
-
- // start the module
- window.GOVUK.modules.start();
-
- });
-
- test("requests should use the same HTTP method as the form", () => {
-
- jest.advanceTimersByTime(2000);
- expect($.ajax.mock.calls[0][1].method).toEqual('post');
-
- })
-
- test("requests should use the data from the form", () => {
-
- jest.advanceTimersByTime(2000);
- expect($.ajax.mock.calls[0][1].data).toEqual(helpers.getFormDataFromPairs([
- ['serviceName', 'Buckhurst surgery'],
- ['serviceNumber', serviceNumber]
- ]));
-
- })
-
- });
-
});