feat: implement tests and coverage reports for KpiCards and scrapeLakes functionality
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { t } from '../translations';
|
||||
|
||||
describe('Translations', () => {
|
||||
it('should have exactly the same keys in English and Czech', () => {
|
||||
const enKeys = Object.keys(t.en).sort();
|
||||
const csKeys = Object.keys(t.cs).sort();
|
||||
|
||||
expect(enKeys).toEqual(csKeys);
|
||||
|
||||
// Deep check for nested keys
|
||||
for (const key of enKeys) {
|
||||
const enSubKeys = Object.keys((t.en as any)[key]).sort();
|
||||
const csSubKeys = Object.keys((t.cs as any)[key]).sort();
|
||||
|
||||
expect(enSubKeys).toEqual(csSubKeys);
|
||||
}
|
||||
});
|
||||
|
||||
it('should not have empty translation strings', () => {
|
||||
const checkEmpty = (obj: any) => {
|
||||
for (const val of Object.values(obj)) {
|
||||
if (typeof val === 'string') {
|
||||
expect(val.length).toBeGreaterThan(0);
|
||||
} else if (typeof val === 'object') {
|
||||
checkEmpty(val);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
checkEmpty(t.en);
|
||||
checkEmpty(t.cs);
|
||||
});
|
||||
});
|
||||
@@ -41,7 +41,12 @@ const CustomTooltip = ({ active, payload, label, language, isWeather }: any) =>
|
||||
return (
|
||||
<div style={{ backgroundColor: 'var(--bg-card)', padding: '1rem', border: '1px solid var(--border-color)', borderRadius: '0.5rem', boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)' }}>
|
||||
<p style={{ margin: '0 0 0.5rem 0', fontWeight: 'bold', color: 'var(--text-main)' }}>{label}</p>
|
||||
{payload.map((entry: any, index: number) => {
|
||||
{[...payload].sort((a: any, b: any) => {
|
||||
const order = ['level', 'inflow', 'outflow'];
|
||||
const indexA = order.indexOf(a.dataKey);
|
||||
const indexB = order.indexOf(b.dataKey);
|
||||
return (indexA === -1 ? 99 : indexA) - (indexB === -1 ? 99 : indexB);
|
||||
}).map((entry: any, index: number) => {
|
||||
let labelStr = '';
|
||||
let unit = '';
|
||||
let color = '';
|
||||
@@ -49,7 +54,7 @@ const CustomTooltip = ({ active, payload, label, language, isWeather }: any) =>
|
||||
else if (entry.dataKey === 'outflow') { labelStr = dict.outflow; unit = 'm³/s'; color = 'var(--color-orange)'; }
|
||||
else if (entry.dataKey === 'inflow') { labelStr = dict.inflow; unit = 'm³/s'; color = '#8b5cf6'; }
|
||||
|
||||
if (!labelStr || (entry.dataKey === 'inflow' && entry.value === 0)) return null;
|
||||
if (!labelStr || entry.value === null || entry.value === undefined) return null;
|
||||
|
||||
return (
|
||||
<div key={index} style={{ margin: 0, color: 'var(--text-main)', display: 'flex', alignItems: 'center', marginBottom: '4px' }}>
|
||||
@@ -125,8 +130,8 @@ const LakeDetail = ({ language, lakeId }: Props) => {
|
||||
const latestData = data[data.length - 1] || { level: 0, inflow: 0, outflow: 0, volume: 0, fullness: 0 };
|
||||
const curveType = isSmoothed ? 'monotone' : 'linear';
|
||||
|
||||
// Find the last record that actually has flow data (often the very last record is incomplete on PVL)
|
||||
const lastValidFlowData = [...data].reverse().find(d => d.outflow > 0) || latestData;
|
||||
// Find last valid values for KPIs, including 0
|
||||
const lastValidFlowData = [...data].reverse().find(d => d.outflow !== null && !isNaN(d.outflow) && d.outflow >= 0) || latestData;
|
||||
|
||||
const now = new Date().getTime();
|
||||
const getCutoff = () => {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import KpiCards from '../KpiCards';
|
||||
|
||||
describe('KpiCards Component', () => {
|
||||
const mockData = {
|
||||
level: 723.10,
|
||||
inflow: 5.5,
|
||||
outflow: 2.5,
|
||||
volume: 150,
|
||||
fullness: 80,
|
||||
storageDiff: -1.81
|
||||
};
|
||||
|
||||
it('renders correctly with negative storageDiff (red)', () => {
|
||||
const { container } = render(<KpiCards data={mockData} language="cs" />);
|
||||
|
||||
// ZÁSOBNÍ PROSTOR card should show -1.81 m
|
||||
expect(screen.getByText('-1.81 m')).toBeInTheDocument();
|
||||
|
||||
// Because it is negative, it should have the red color style applied
|
||||
const diffElement = screen.getByText('-1.81 m');
|
||||
expect(diffElement.parentElement?.outerHTML).toContain('var(--color-red)');
|
||||
});
|
||||
|
||||
it('renders correctly with positive storageDiff (cyan)', () => {
|
||||
const positiveData = { ...mockData, storageDiff: 0.5 };
|
||||
render(<KpiCards data={positiveData} language="cs" />);
|
||||
|
||||
expect(screen.getByText('+0.50 m')).toBeInTheDocument();
|
||||
const diffElement = screen.getByText('+0.50 m');
|
||||
expect(diffElement.parentElement?.outerHTML).toContain('var(--color-cyan)');
|
||||
});
|
||||
|
||||
it('falls back to percentage fullness if storageDiff is zero/undefined', () => {
|
||||
const noDiffData = { ...mockData, storageDiff: 0, fullness: 85.5 };
|
||||
render(<KpiCards data={noDiffData} language="cs" />);
|
||||
|
||||
expect(screen.getByText('85.5%')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
import '@testing-library/jest-dom';
|
||||
Reference in New Issue
Block a user