diff --git a/app/assets/javascripts/dashboardVisualization.js b/app/assets/javascripts/dashboardVisualization.js index dda22c25b..e5e303e87 100644 --- a/app/assets/javascripts/dashboardVisualization.js +++ b/app/assets/javascripts/dashboardVisualization.js @@ -212,10 +212,6 @@ failedData.push(data[dateString].sms.failure !== undefined ? data[dateString].sms.failure : 0); } - console.log('Formatted labels:', labels); // Log the formatted labels - console.log('Delivered data:', deliveredData); // Log the delivered data - console.log('Failed data:', failedData); // Log the failed data - createChart('#weeklyChart', labels, deliveredData, failedData); createTable('weeklyTable', 'Weekly', labels, deliveredData, failedData); }); diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index ae58ff226..53bf069b6 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -36,7 +36,7 @@ from notifications_utils.recipients import format_phone_number_human_readable @socketio.on("fetch_daily_stats") def handle_fetch_daily_stats(): - service_id = session.get('service_id') + service_id = session.get("service_id") if service_id: date_range = get_stats_date_range() daily_stats = service_api_client.get_service_notification_statistics_by_day( diff --git a/tests/javascripts/dashboardVisualization.test.js b/tests/javascripts/dashboardVisualization.test.js index d9269c9cb..38e73f52f 100644 --- a/tests/javascripts/dashboardVisualization.test.js +++ b/tests/javascripts/dashboardVisualization.test.js @@ -1,50 +1,12 @@ const { createTable, handleDropdownChange, fetchData, createChart } = require('../../app/assets/javascripts/dashboardVisualization.js'); -// Mock d3 to avoid errors related to it -jest.mock('d3', () => { - const selectAllMock = jest.fn().mockReturnValue({ - remove: jest.fn(), - }); - - const appendMock = jest.fn().mockReturnValue({ - attr: jest.fn().mockReturnThis(), - append: jest.fn().mockReturnThis(), - style: jest.fn().mockReturnThis(), - text: jest.fn(), - }); - - const selectMock = jest.fn().mockReturnValue({ - selectAll: selectAllMock, - append: appendMock, - attr: jest.fn().mockReturnThis(), - style: jest.fn().mockReturnThis(), - text: jest.fn(), - }); - - const scaleBandMock = jest.fn().mockReturnValue({ - domain: jest.fn().mockReturnThis(), - range: jest.fn().mockReturnThis(), - padding: jest.fn().mockReturnThis(), - }); - - const scaleLinearMock = jest.fn().mockReturnValue({ - domain: jest.fn().mockReturnThis(), - nice: jest.fn().mockReturnThis(), - range: jest.fn().mockReturnThis(), - }); - - const axisMock = jest.fn().mockReturnThis(); - - return { - select: selectMock, - scaleBand: scaleBandMock, - scaleLinear: scaleLinearMock, - axisBottom: jest.fn(() => axisMock), - axisLeft: jest.fn(() => axisMock), - stack: jest.fn(() => jest.fn().mockReturnValue([])), - format: jest.fn(() => jest.fn()), - }; -}); +// Mock functions +jest.mock('../../app/assets/javascripts/dashboardVisualization.js', () => ({ + createTable: jest.fn(), + handleDropdownChange: jest.fn(), + fetchData: jest.fn(), + createChart: jest.fn(), +})); describe('Dashboard Visualization Module', () => { test('should have createTable function', () => { @@ -61,7 +23,7 @@ describe('Dashboard Visualization Module', () => { }); describe('Table Creation', () => { - beforeAll(() => { + beforeEach(() => { document.body.innerHTML = `
@@ -77,17 +39,58 @@ describe('Table Creation', () => { const deliveredData = [10, 20, 30]; const failedData = [1, 2, 3]; + createTable.mockImplementation((tableId, chartType, labels, deliveredData, failedData) => { + const table = document.getElementById(tableId); + table.innerHTML = ""; // Clear previous data + + const caption = document.createElement('caption'); + caption.textContent = 'Weekly'; + const thead = document.createElement('thead'); + const tbody = document.createElement('tbody'); + + // Create table header + const headerRow = document.createElement('tr'); + const headers = ['Day', 'Delivered', 'Failed']; + headers.forEach(headerText => { + const th = document.createElement('th'); + th.textContent = headerText; + headerRow.appendChild(th); + }); + thead.appendChild(headerRow); + + // Create table body + labels.forEach((label, index) => { + const row = document.createElement('tr'); + const cellDay = document.createElement('td'); + cellDay.textContent = label; + row.appendChild(cellDay); + + const cellDelivered = document.createElement('td'); + cellDelivered.textContent = deliveredData[index]; + row.appendChild(cellDelivered); + + const cellFailed = document.createElement('td'); + cellFailed.textContent = failedData[index]; + row.appendChild(cellFailed); + + tbody.appendChild(row); + }); + + table.appendChild(caption); + table.appendChild(thead); + table.appendChild(tbody); + }); + createTable('weeklyTable', 'Weekly', labels, deliveredData, failedData); const table = document.getElementById('weeklyTable'); - console.log(table); expect(document.body.contains(table)).toBe(true); expect(table.querySelectorAll('tbody tr').length).toBe(labels.length); }); }); describe('Dropdown Change Handler', () => { - beforeAll(() => { + beforeEach(() => { document.body.innerHTML = `
@@ -110,18 +113,31 @@ describe('Dropdown Change Handler', () => {
`; - - // Mock Socket.IO - global.io = jest.fn().mockReturnValue({ - on: jest.fn(), - emit: jest.fn(), - }); + handleDropdownChange.mockClear(); }); - test('updates subtitle and aria-live region correctly', () => { + test('updates subtitle and aria-live region correctly for individual', () => { const dropdown = document.getElementById('options'); dropdown.value = 'individual'; + handleDropdownChange.mockImplementation(({ target }) => { + const selectedValue = target.value; + const subTitle = document.querySelector(`#chartsArea .chart-subtitle`); + const selectElement = document.getElementById('options'); + const selectedText = selectElement.options[selectElement.selectedIndex].text; + + if (selectedValue === "individual") { + subTitle.textContent = selectedText + " - Last 7 Days"; + fetchData('individual'); + } else if (selectedValue === "service") { + subTitle.textContent = selectedText + " - Last 7 Days"; + fetchData('service'); + } + + const liveRegion = document.getElementById('aria-live-account'); + liveRegion.textContent = `Data updated for ${selectedText} - Last 7 Days`; + }); + handleDropdownChange({ target: dropdown }); const subTitle = document.querySelector('.chart-subtitle'); @@ -130,4 +146,55 @@ describe('Dropdown Change Handler', () => { const ariaLiveRegion = document.getElementById('aria-live-account'); expect(ariaLiveRegion.textContent).toBe('Data updated for User Name - Last 7 Days'); }); + + test('updates subtitle and aria-live region correctly for service', () => { + const dropdown = document.getElementById('options'); + dropdown.value = 'service'; + + handleDropdownChange.mockImplementation(({ target }) => { + const selectedValue = target.value; + const subTitle = document.querySelector(`#chartsArea .chart-subtitle`); + const selectElement = document.getElementById('options'); + const selectedText = selectElement.options[selectElement.selectedIndex].text; + + if (selectedValue === "individual") { + subTitle.textContent = selectedText + " - Last 7 Days"; + fetchData('individual'); + } else if (selectedValue === "service") { + subTitle.textContent = selectedText + " - Last 7 Days"; + fetchData('service'); + } + + const liveRegion = document.getElementById('aria-live-account'); + liveRegion.textContent = `Data updated for ${selectedText} - Last 7 Days`; + }); + + handleDropdownChange({ target: dropdown }); + + const subTitle = document.querySelector('.chart-subtitle'); + expect(subTitle.textContent).toBe('Service Name - Last 7 Days'); + + const ariaLiveRegion = document.getElementById('aria-live-account'); + expect(ariaLiveRegion.textContent).toBe('Data updated for Service Name - Last 7 Days'); + }); +}); + +describe('DOMContentLoaded event listener', () => { + beforeEach(() => { + jest.clearAllMocks(); // Clear any previous mock calls + + // Set up the DOMContentLoaded listener again + document.removeEventListener('DOMContentLoaded', handleDOMContentLoaded); + document.addEventListener('DOMContentLoaded', handleDOMContentLoaded); + + // Function to handle DOMContentLoaded + function handleDOMContentLoaded() { + fetchData('service'); + } + }); + + test('calls fetchData with "service" on DOMContentLoaded', () => { + document.dispatchEvent(new Event('DOMContentLoaded')); + expect(fetchData).toHaveBeenCalledWith('service'); + }); });