Merge branch 'main' into 2589-may-19-zap-scan-fixes

Resolved conflicts by:
- Taking all backstop images from main branch
- Taking .ds.baseline from main (with updated line numbers)
- Keeping template literal security fixes in listEntry.js while incorporating main's styling changes
- Taking main's config.py updates (LOGO_CDN_DOMAIN and formatting)
This commit is contained in:
alexjanousekGSA
2025-07-31 16:08:12 -04:00
42 changed files with 342 additions and 107 deletions

View File

@@ -283,3 +283,58 @@ test('handleDropdownChange updates DOM for individual selection', () => {
window.fetchData.mockRestore();
});
test('handleDropdownChange shows empty message when user has no jobs', () => {
document.body.innerHTML = `
<div id="activityChartContainer">
<div class="chart-subtitle"></div>
</div>
<div id="aria-live-account"></div>
<div id="activityContainer" data-currentUserName="Test User" data-currentServiceId="12345"></div>
<div id="tableActivity">
<h2 id="table-heading"></h2>
<table id="activity-table">
<caption id="caption"></caption>
<tbody>
<tr><td class="sender-column">Other User</td></tr>
<tr><td class="sender-column">Another User</td></tr>
<tr><td class="sender-column">Different User</td></tr>
<tr class="table-row">
<td class="table-empty-message" colspan="10">No batched job messages found (messages are kept for 7 days).</td>
</tr>
</tbody>
</table>
</div>
<select id="options">
<option value="service">Service</option>
<option value="individual">Individual</option>
</select>
`;
window.currentUserName = "Test User";
jest.spyOn(window, 'fetchData').mockImplementation(() => {});
const selectElement = document.getElementById('options');
selectElement.value = 'individual';
const event = { target: selectElement };
window.handleDropdownChange(event);
expect(document.getElementById('table-heading').textContent).toBe('My activity');
expect(document.getElementById('caption').textContent).toContain('Test User');
document.querySelectorAll('.sender-column').forEach(col => {
expect(col.style.display).toBe('none');
});
const emptyMessageRow = document.querySelector('.table-empty-message').closest('tr');
expect(emptyMessageRow.style.display).toBe('');
const allRows = Array.from(document.querySelectorAll('#activity-table tbody tr'));
const visibleRows = allRows.filter(row => row.style.display !== 'none');
expect(visibleRows.length).toBe(1);
expect(visibleRows[0].querySelector('.table-empty-message')).not.toBeNull();
window.fetchData.mockRestore();
});

View File

@@ -48,10 +48,10 @@ describe("List entry", () => {
result += `
<div class="list-entry">
<div class="usa-form-group">
<label for="domains-${idx + 1}" class="usa-radio__label govuk-input--numbered__label">
<label for="domains-${idx + 1}" class="usa-label">
<span class="usa-sr-only">domain number </span>${idx + 1}.
</label>
<input type="text" name="domains-${idx + 1}" id="domains-${idx + 1}" class="govuk-input govuk-input--numbered " autocomplete="off">
<input type="text" name="domains-${idx + 1}" id="domains-${idx + 1}" class="usa-input" autocomplete="off">
</div>
</div>`;
}
@@ -247,7 +247,7 @@ describe("List entry", () => {
triggerEvent(inputList.querySelectorAll('.input-list__button--remove')[0], 'click');
const newNums = Array.from(
inputList.querySelectorAll('.govuk-input--numbered__label')
inputList.querySelectorAll('.usa-label')
)
.map((itemNum, idx) => {
return parseInt(itemNum.lastChild.nodeValue, 10);
@@ -350,4 +350,72 @@ describe("List entry", () => {
});
});
describe("getOriginalClasses functionality", () => {
test("Should handle inputs without any classes", () => {
// Create input without classes
document.body.innerHTML = `
<div class="input-list" data-module="list-entry" data-list-item-name="domain" id="list-entry-domains">
<div class="list-entry">
<input type="text" name="domains-1" id="domains-1">
</div>
</div>`;
inputList = document.querySelector('.input-list');
// start module
window.GOVUK.modules.start();
// Check that it handles missing classes gracefully
const newInput = inputList.querySelector('.list-entry input');
expect(newInput).not.toBeNull();
});
test("Should handle empty input list", () => {
// Create div without any inputs
document.body.innerHTML = `
<div class="input-list" data-module="list-entry" data-list-item-name="domain" id="list-entry-domains">
</div>`;
inputList = document.querySelector('.input-list');
// This should not throw an error
expect(() => {
window.GOVUK.modules.start();
}).not.toThrow();
});
});
describe("getId functionality", () => {
test("Should generate IDs correctly with and without number parameter", () => {
// Set up a simpler structure to test ID generation
document.body.innerHTML = `
<div class="input-list" data-module="list-entry" data-list-item-name="test-item" id="list-entry-test">
<div class="list-entry">
<input type="text" name="test-1" id="test-1" class="usa-input">
</div>
<div class="list-entry">
<input type="text" name="test-2" id="test-2" class="usa-input">
</div>
</div>`;
inputList = document.querySelector('.input-list');
// start module
window.GOVUK.modules.start();
// After module starts, check that IDs are generated correctly
// The module will have regenerated the DOM
const inputs = inputList.querySelectorAll('input');
// Check that inputs have proper IDs with numbers
expect(inputs[0].id).toEqual("test-1");
expect(inputs[1].id).toEqual("test-2");
// The getId function is called internally during render
// We can verify it worked by checking the generated HTML structure
expect(inputList.innerHTML).toContain('id="test-1"');
expect(inputList.innerHTML).toContain('id="test-2"');
});
});
});