feat: implement tests and coverage reports for KpiCards and scrapeLakes functionality

This commit is contained in:
David Fencl
2026-06-05 23:08:44 +02:00
parent 0030dca448
commit 8193ce818a
37 changed files with 4309 additions and 31 deletions
+9 -4
View File
@@ -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();
});
});