Skip to content

Comments

Add unit tests for various dashboards including Coalition, Committees, Election Cycle, Ministry, Pre-Election, and Seasonal Patterns#112

Merged
pethers merged 12 commits intomainfrom
unitest
Feb 12, 2026
Merged

Add unit tests for various dashboards including Coalition, Committees, Election Cycle, Ministry, Pre-Election, and Seasonal Patterns#112
pethers merged 12 commits intomainfrom
unitest

Conversation

@pethers
Copy link
Member

@pethers pethers commented Feb 11, 2026

  • Implement tests for DOM structure, accessibility, data processing, and chart configuration for each dashboard.
  • Ensure proper ARIA labels and heading hierarchy for accessibility compliance.
  • Validate data parsing and processing logic for CSV data in each dashboard context.
  • Include loading state tests to verify UI behavior during data fetching.

…, Election Cycle, Ministry, Pre-Election, and Seasonal Patterns

- Implement tests for DOM structure, accessibility, data processing, and chart configuration for each dashboard.
- Ensure proper ARIA labels and heading hierarchy for accessibility compliance.
- Validate data parsing and processing logic for CSV data in each dashboard context.
- Include loading state tests to verify UI behavior during data fetching.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…ltiple language files; enhance data transformation in JavaScript files for improved chart compatibility and accuracy; refactor mock data generation and anomaly handling in coalition and committee dashboards.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

- Implemented a new script `refresh-dashboard-data.sh` to download and refresh CSV files used by various dashboard JavaScript files.
- Created comprehensive tests for the Politician Career & Productivity Analytics Dashboard, covering DOM structure, data sources, CSV parsing, rendering, and error handling.
- Included tests for data processing related to risk summary, influence metrics, experience distribution, and behavioral trends.
- Ensured accessibility features and error handling in the dashboard components.
globalThis.fetch = mockFetch;

try {
const response = await globalThis.fetch('fake-url.csv');
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…gration

- Introduced `distribution_person_status.csv` for tracking active MPs and their statuses.
- Added `distribution_risk_evolution_temporal.csv` for risk severity assessments over time.
- Implemented `stats-loader.js` to fetch and parse CSV data, updating DOM elements with real-time statistics.
- Created unit tests in `stats-loader.test.js` to validate CSV parsing, DOM updates, and error handling.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json


// Should not throw, should fall back to mock data
try {
const response = await fetch('cia-data/nonexistent.csv');
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…s, election predictions, and initialization

- Implement tests for Dashboard CIA Visualizations Renderer covering key metrics, party performance, rankings, voting patterns, and committee network visualizations.
- Create tests for Election 2026 Predictions Module focusing on seat predictions, coalition scenarios, key factors, and summary statistics.
- Develop tests for Dashboard Initialization Module to ensure proper loading state management, error handling, and DOM structure validation.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

it('should display error message from exception', () => {
const error = new Error('Network timeout');
const errorMessage = document.getElementById('error-message');
errorMessage.textContent = (error && error.message) || 'An unknown error occurred';
it('should handle falsy error message', () => {
const error = null;
const errorMessage = document.getElementById('error-message');
errorMessage.textContent = (error && error.message) || 'An unknown error occurred while loading dashboard data.';

it('should handle missing forecast data gracefully', () => {
const data = null;
if (!data || !data.forecast || !Array.isArray(data.forecast.parties)) {

it('should handle invalid voting patterns data', () => {
const votingPatterns = { votingMatrix: null };
const isValid = votingPatterns && votingPatterns.votingMatrix &&

it('should handle missing election date', () => {
const data = { electionDate: null };
if (!data || !data.electionDate) {

it('should handle missing forecast data', () => {
const data = null;
if (!data || !data.forecast || !Array.isArray(data.forecast.parties)) {
…urces

- Updated test descriptions to reflect CSV parsing and loading logic.
- Introduced new tests for CSV parsing, including handling of headers, quoted fields, and numeric conversions.
- Implemented tests for loading CSV data with fallback mechanisms.
- Maintained existing JSON loading tests for election analysis while adapting others to CSV.
- Enhanced parallel loading tests to include all relevant data sources.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…shboard

- Created index_nl.html for Dutch language support with localized content and metadata.
- Created index_no.html for Norwegian language support with localized content and metadata.
- Created index_zh.html for Chinese language support with localized content and metadata.
- Included hreflang tags for all language versions to improve SEO and accessibility.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…nguages

- Updated sitemap files for Spanish, Finnish, French, Hebrew, Japanese, Korean, Dutch, Norwegian, Swedish, and Chinese to include links and descriptions for the CIA Intelligence Dashboard in Danish, Norwegian, Finnish, German, French, Spanish, Dutch, Arabic, Hebrew, Japanese, Korean, and Chinese.
- Modified vite.config.js to include new dashboard pages for each language.
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR broadens dashboard support across languages by adding localized dashboard entrypoints, new dashboard UI sections on multiple index pages, local-first CSV loading helpers, and a large set of Vitest-based DOM/data/config tests. It also updates sitemaps and dashboard pages with expanded SEO metadata and hreflang coverage.

Changes:

  • Add/expand Vitest tests for multiple dashboards (DOM structure, accessibility attributes, CSV schema checks, loading/error states).
  • Introduce/extend local-first CSV loading (hero stats loader; party dashboard local-first fetch; committees dashboard now uses loaded CSV data instead of random mock values).
  • Expand multilingual dashboard discoverability (Vite multi-page inputs, sitemap links, sitemap.xml alternates, dashboard page SEO/hreflang/JSON-LD).

Reviewed changes

Copilot reviewed 84 out of 85 changed files in this pull request and generated 20 comments.

Show a summary per file
File Description
vite.config.js Adds all localized dashboard/index_*.html pages to Vite multi-page inputs.
tests/stats-loader.test.js Adds tests for hero stats DOM and CSV parsing assumptions.
tests/seasonal-patterns-dashboard.test.js Adds Seasonal Patterns dashboard DOM/CSV schema/accessibility tests.
tests/pre-election-dashboard.test.js Adds Pre-Election dashboard DOM/CSV schema/chart/accessibility tests.
tests/party-dashboard.test.js Extends party dashboard tests (but currently mismatched with implementation paths).
tests/ministry-dashboard.test.js Adds Ministry dashboard DOM/CSV schema/data fetching/accessibility tests.
tests/election-cycle-dashboard.test.js Adds Election Cycle dashboard DOM/CSV schema/chart/accessibility tests.
tests/dashboard-init.test.js Adds tests for dashboard init loading/error/content orchestration structure.
tests/committees-dashboard.test.js Adds Committees dashboard DOM/CSV schema/accessibility tests.
sitemap.html Adds links for all localized dashboard pages.
sitemap.xml Adds hreflang alternates for dashboard pages and new <url> entries for localized dashboards.
sitemap_sv.html Adds localized dashboard links to Swedish sitemap page.
sitemap_zh.html Adds localized dashboard links to Chinese sitemap page.
sitemap_no.html Adds localized dashboard links to Norwegian sitemap page.
sitemap_nl.html Adds localized dashboard links to Dutch sitemap page.
sitemap_ko.html Adds localized dashboard links to Korean sitemap page.
sitemap_ja.html Adds localized dashboard links to Japanese sitemap page.
sitemap_he.html Adds localized dashboard links to Hebrew sitemap page.
sitemap_fr.html Adds localized dashboard links to French sitemap page.
sitemap_fi.html Adds localized dashboard links to Finnish sitemap page.
sitemap_es.html Adds localized dashboard links to Spanish sitemap page.
sitemap_de.html Adds localized dashboard links to German sitemap page.
sitemap_da.html Adds localized dashboard links to Danish sitemap page.
sitemap_ar.html Adds localized dashboard links to Arabic sitemap page.
scripts/committees-dashboard.js Replaces mock/random committee network/heatmap/productivity values with values derived from loaded CSV data.
js/stats-loader.js Adds a hero “stats loader” to populate homepage hero stats from CSV (local-first + remote fallback).
js/party-dashboard.js Updates party dashboard fetching to local-first (cia-data/party/...) with remote fallback + caching.
index.html Updates event date copy; adds hero stat element IDs; includes js/stats-loader.js.
index_sv.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
index_no.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
index_da.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
index_de.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
index_nl.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
index_zh.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
index_ja.html Adds Election Cycle + Committee dashboard sections and includes stats loader + module scripts.
dashboard/index.html Adds hreflang set, enriched OG/Twitter meta, JSON-LD, and a <noscript> notice; adds “Key Election Factors” container.
dashboard/index_sv.html Same SEO/hreflang/JSON-LD additions for Swedish dashboard; updates footer language links; adds “Key Election Factors” container.
dashboard/dashboard-init.js Switches init to loader.loadAll() and calls renderKeyFactors().
cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv Resolves previously conflicted content / keeps sample anomaly data.
cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv Resolves previously conflicted content / keeps sample seasonal data.
cia-data/refresh-dashboard-data.sh Adds a “refresh” script to download referenced dashboard CSV files.
cia-data/download-csv.sh Simplifies/updates the CSV download script.
cia-data/party/distribution_coalition_alignment.csv Updates local coalition alignment CSV (currently header-only).
cia-data/anomaly/distribution_anomaly_by_party.csv Updates anomaly-by-party CSV (currently header-only).
cia-data/distribution_politician_risk_levels.csv Updates local risk-level counts/percentages.
cia-data/distribution_party_effectiveness_trends.csv Adds local party effectiveness trends CSV at root.
cia-data/distribution_risk_evolution_temporal.csv Adds local temporal risk evolution CSV at root.
cia-data/distribution_ministry_risk_levels.csv Adds local ministry risk levels CSV at root.
cia-data/distribution_ministry_risk_quarterly.csv Adds local ministry risk quarterly CSV at root.
cia-data/distribution_ministry_productivity_matrix.csv Adds local ministry productivity matrix CSV at root.
cia-data/distribution_ministry_effectiveness.csv Adds local ministry effectiveness CSV at root.
cia-data/distribution_influence_buckets.csv Adds local influence buckets CSV at root.
cia-data/distribution_experience_levels.csv Adds local experience levels CSV at root.
cia-data/distribution_experience_by_party.csv Adds local experience-by-party CSV at root.
Comments suppressed due to low confidence (2)

cia-data/party/distribution_coalition_alignment.csv:2

  • This local CSV is effectively empty (header only). Dashboards using a local-first strategy will have no coalition alignment data when running offline/without remote fallback. Either include the intended rows in this committed sample CSV, or remove/rename it so the app doesn't prefer an empty local file over a populated remote source.
party1,party2,shared_votes,aligned_votes,opposed_votes,alignment_rate,coalition_likelihood,bloc_relationship

cia-data/anomaly/distribution_anomaly_by_party.csv:2

  • This local CSV is effectively empty (header only). The coalition/anomaly dashboards prefer local-first data, so an empty committed file will prevent meaningful offline behavior and may hide data issues. Commit the expected data rows (or avoid shipping an empty local file so remote fallback can work).
party,anomaly_classification,politician_count,avg_rebellions

Comment on lines 180 to 206
@@ -145,10 +201,15 @@ describe('Party Performance Dashboard', () => {
);

global.fetch = mockFetch;

const response = await fetch('test-url');
const response = await fetch('cia-data/distribution_party_effectiveness_trends.csv');
expect(response.ok).toBe(false);
});
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test overwrites global.fetch but never restores it, which can leak into subsequent tests because the global fetch mock is set once in tests/setup.js. Add cleanup (e.g., restore the original fetch in afterEach or use vi.stubGlobal/vi.unstubAllGlobals) to keep tests isolated.

Copilot uses AI. Check for mistakes.
Comment on lines +123 to +130
// Calculate risk rules from risk levels data
if (riskText) {
const risks = parseCSV(riskText);
const totalPoliticians = risks.reduce((sum, r) => sum + (parseInt(r.politician_count) || 0), 0);
if (totalPoliticians > 0) {
// Update the risk rules with total politicians monitored by risk assessment
updateStat('stat-risk-rules', '45');
}
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The risk-levels fetch computes totalPoliticians but then hard-codes stat-risk-rules to "45". The comment says it updates based on the risk assessment, but the actual value is constant, which is misleading and adds unnecessary network work. Either remove the risk-level fetch/aggregation if the value is meant to be static, or update the UI/logic so the fetched value is actually reflected.

Copilot uses AI. Check for mistakes.
Comment on lines +1135 to +1140
<script src="js/stats-loader.js"></script>

<script type="module" src="scripts/committees-dashboard.js"></script>

<script type="module" src="js/election-cycle-dashboard.js"></script>

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stats-loader.js is included on this page, but the hero stat numbers do not have the expected IDs (stat-mps, stat-parties, etc.). This causes CSV fetches without any DOM updates. Add the IDs to the hero stats in this file or remove the script include to avoid wasted requests.

Copilot uses AI. Check for mistakes.
Comment on lines +1124 to +1129
<script src="js/stats-loader.js"></script>

<script type="module" src="scripts/committees-dashboard.js"></script>

<script type="module" src="js/election-cycle-dashboard.js"></script>

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stats-loader.js is included on this page, but the hero stat numbers do not have the expected IDs (stat-mps, stat-parties, etc.), so the loader can't update anything. Either add the IDs to this file's hero stats or remove the script include to prevent wasted network calls.

Copilot uses AI. Check for mistakes.
Comment on lines +892 to +897
<script src="js/stats-loader.js"></script>

<script type="module" src="scripts/committees-dashboard.js"></script>

<script type="module" src="js/election-cycle-dashboard.js"></script>

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stats-loader.js is included on this page, but the hero stat numbers do not have the expected IDs (stat-mps, stat-parties, etc.), so the loader will fetch CSVs but not update the UI. Add the IDs to the hero stats markup in this file or remove the script include.

Copilot uses AI. Check for mistakes.

it('should handle invalid voting patterns data', () => {
const votingPatterns = { votingMatrix: null };
const isValid = votingPatterns && votingPatterns.votingMatrix &&
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard always evaluates to true.

Copilot uses AI. Check for mistakes.

it('should handle missing election date', () => {
const data = { electionDate: null };
if (!data || !data.electionDate) {
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard always evaluates to false.

Copilot uses AI. Check for mistakes.

it('should handle missing forecast data', () => {
const data = null;
if (!data || !data.forecast || !Array.isArray(data.forecast.parties)) {
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard always evaluates to true.

Copilot uses AI. Check for mistakes.

// Should not throw, should fall back to mock data
try {
const response = await fetch('cia-data/nonexistent.csv');
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable response.

Copilot uses AI. Check for mistakes.
globalThis.fetch = mockFetch;

try {
const response = await globalThis.fetch('fake-url.csv');
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable response.

Copilot uses AI. Check for mistakes.
@pethers pethers merged commit b430386 into main Feb 12, 2026
21 checks passed
@pethers pethers deleted the unitest branch February 12, 2026 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant