Merge branch 'main' of https://github.com/GSA/notifications-admin into 2515-remove-autofocus-js

This commit is contained in:
Jonathan Bobel
2025-04-29 11:56:49 -04:00
50 changed files with 1170 additions and 701 deletions

View File

@@ -18,6 +18,12 @@ Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
});
// beforeAll hook to set up the DOM and load D3.js script
beforeAll(() => {
jest.spyOn(Intl, 'DateTimeFormat').mockImplementation(() => ({
resolvedOptions: () => ({ timeZone: 'UTC' })
}));
});
beforeAll(done => {
// Set up the DOM with the D3 script included
document.body.innerHTML = `

View File

@@ -0,0 +1,26 @@
// This will use the real function and listener
const {
initUploadStatusAnnouncer
} = require('../../app/assets/javascripts/fileUpload.js');
jest.useFakeTimers();
test('writes upload message to the live region on DOMContentLoaded', () => {
// Setup the DOM
document.body.innerHTML = `
<div id="upload-status-live" aria-live="assertive" role="status" class="usa-sr-only">Old message</div>
<span id="upload-success" class="usa-sr-only">File upload successful</span>
`;
// Register the listener (same as page load does)
initUploadStatusAnnouncer();
// Simulate the page load event
document.dispatchEvent(new Event('DOMContentLoaded'));
// Live region will be cleared first, then updated
jest.advanceTimersByTime(300);
const srRegion = document.getElementById('upload-status-live');
expect(srRegion.textContent).toBe('File upload successful\u00A0');
});

View File

@@ -1,13 +1,12 @@
const helpers = require('./support/helpers.js');
beforeAll(() => {
require('../../app/assets/javascripts/fileUpload.js');
});
const { announceUploadStatusFromElement } = require('../../app/assets/javascripts/fileUpload.js');
afterAll(() => {
require('./support/teardown.js');
});
describe('File upload', () => {
let form;
@@ -72,12 +71,116 @@ describe('File upload', () => {
});
test("It should add a link to cancel the upload by reloading the page", () => {
expect(form.querySelector("a[href='']")).not.toBeNull();
test("It should display a disabled Uploading button", () => {
const uploadingButton = form.querySelector("button.uploading-button");
expect(uploadingButton).not.toBeNull();
expect(uploadingButton.textContent).toMatch(/Uploading/);
expect(uploadingButton.getAttribute('aria-disabled')).toBe("true");
});
});
});
describe('File upload "upload-trigger" click handler', () => {
let form;
beforeEach(() => {
document.body.innerHTML = `
<form method="post" enctype="multipart/form-data" data-module="file-upload">
<button type="button" data-module="upload-trigger" data-file-input-id="test-file-input">Upload your file</button>
<input type="file" id="test-file-input" style="display:none;">
</form>
`;
form = document.querySelector('form');
// Register the module
window.GOVUK.modules.start();
});
afterEach(() => {
document.body.innerHTML = '';
});
test('clicking upload trigger simulates file input click', () => {
const uploadButton = form.querySelector('[data-module="upload-trigger"]');
const fileInput = document.getElementById('test-file-input');
// Spy on fileInput.click
const clickSpy = jest.spyOn(fileInput, 'click').mockImplementation(() => {});
// Trigger the click
helpers.triggerEvent(uploadButton, 'click');
expect(clickSpy).toHaveBeenCalled();
clickSpy.mockRestore();
});
});
describe('announceUploadStatusFromElement', () => {
beforeEach(() => {
jest.useFakeTimers();
document.body.innerHTML = `
<div id="upload-status-live" aria-live="assertive" role="status" class="usa-sr-only"></div>
`;
});
afterEach(() => {
jest.useRealTimers();
document.body.innerHTML = '';
});
test('announces error message from #upload-error', () => {
document.body.innerHTML += `
<span id="upload-error" class="usa-sr-only">File upload failed</span>
`;
const srRegion = document.getElementById('upload-status-live');
// Call the function
announceUploadStatusFromElement();
// Confirm it clears first
expect(srRegion.textContent).toBe('');
// Fast-forward the timer
jest.advanceTimersByTime(300);
// Confirm it updates after delay
expect(srRegion.textContent).toBe('File upload failed\u00A0');
});
test('announces success message from #upload-success if no error is present', () => {
document.body.innerHTML += `
<span id="upload-success" class="usa-sr-only">File upload successful</span>
`;
const srRegion = document.getElementById('upload-status-live');
announceUploadStatusFromElement();
expect(srRegion.textContent).toBe('');
jest.advanceTimersByTime(301);
expect(srRegion.textContent).toBe('File upload successful\u00A0');
});
test('does nothing if neither success nor error is present', () => {
const srRegion = document.getElementById('upload-status-live');
srRegion.textContent = 'Old message';
announceUploadStatusFromElement();
// Should not clear or update if no message element is found
expect(srRegion.textContent).toBe('Old message');
jest.advanceTimersByTime(300);
// Still unchanged
expect(srRegion.textContent).toBe('Old message');
});
});

View File

@@ -347,24 +347,4 @@ describe('FullscreenTable', () => {
});
describe("when the table is focused", () => {
beforeEach(() => {
// start module
window.GOVUK.modules.start();
tableFrame = document.querySelector('.fullscreen-scrollable-table');
tableFrame.focus();
});
test("it should make the parent frame a focus style", () => {
expect(container.classList.contains('js-focus-style')).toBe(true);
});
});
});