Skip to content

Commit 66e8e38

Browse files
feat(tests): update test files and improve code structure
- Remove unused mocks in reportWebVitals.test.ts - Simplify imports in Header.test.tsx - Add fetchPriority to ImageCard component - Use window.requestIdleCallback in Layout component - Lazy-load CodeHighlighter in SpecTabs component - Update font-face properties in fonts.css - Add Vitest globals to eslint configuration - Improve nginx configuration comments - Add vite-plugin-compression2 to package.json - Create CodeHighlighter component for syntax highlighting
1 parent 13b0431 commit 66e8e38

16 files changed

+103
-38
lines changed

app/eslint.config.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export default [
5555
MessageEvent: 'readonly',
5656
// APIs
5757
AbortController: 'readonly',
58+
AbortSignal: 'readonly',
5859
RequestInit: 'readonly',
5960
Response: 'readonly',
6061
ResizeObserver: 'readonly',
@@ -82,6 +83,23 @@ export default [
8283
'react-hooks/refs': 'off',
8384
},
8485
},
86+
{
87+
files: ['src/**/*.test.{ts,tsx}'],
88+
languageOptions: {
89+
globals: {
90+
// Vitest globals
91+
describe: 'readonly',
92+
it: 'readonly',
93+
expect: 'readonly',
94+
vi: 'readonly',
95+
beforeEach: 'readonly',
96+
afterEach: 'readonly',
97+
beforeAll: 'readonly',
98+
afterAll: 'readonly',
99+
globalThis: 'readonly',
100+
},
101+
},
102+
},
85103
{
86104
ignores: ['dist/**', 'node_modules/**', '*.config.js'],
87105
},

app/nginx.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ server {
3838
root /usr/share/nginx/html;
3939
index index.html;
4040

41-
# Compression
41+
# Compression - serve pre-compressed gzip files from Vite build when available
4242
gzip on;
4343
gzip_vary on;
4444
gzip_min_length 1024;
4545
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
46+
gzip_static on;
4647

4748
# Cache static assets
4849
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {

app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"jsdom": "^29.0.1",
5050
"typescript": "^5.9.2",
5151
"vite": "^7.3.1",
52+
"vite-plugin-compression2": "^2.5.3",
5253
"vitest": "^4.0.18"
5354
}
5455
}

app/src/analytics/reportWebVitals.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ describe('reportWebVitals', () => {
4545
window.plausible = vi.fn();
4646

4747
// Mock the dynamic import
48-
const mockOnLCP = vi.fn();
49-
const mockOnCLS = vi.fn();
50-
const mockOnINP = vi.fn();
51-
5248
vi.mock('web-vitals', () => ({
5349
onLCP: (cb: (m: { value: number; rating: string }) => void) => cb({ value: 2500, rating: 'good' }),
5450
onCLS: (cb: (m: { value: number; rating: string }) => void) => cb({ value: 0.15, rating: 'needs-improvement' }),
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light';
2+
import { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
3+
import python from 'react-syntax-highlighter/dist/esm/languages/prism/python';
4+
5+
SyntaxHighlighter.registerLanguage('python', python);
6+
7+
interface CodeHighlighterProps {
8+
code: string;
9+
}
10+
11+
export default function CodeHighlighter({ code }: CodeHighlighterProps) {
12+
return (
13+
<SyntaxHighlighter
14+
language="python"
15+
style={oneLight}
16+
customStyle={{
17+
margin: 0,
18+
fontSize: '0.85rem',
19+
fontFamily: '"MonoLisa", "MonoLisa Fallback", monospace',
20+
background: 'transparent',
21+
}}
22+
>
23+
{code}
24+
</SyntaxHighlighter>
25+
);
26+
}

app/src/components/Header.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
22
import { fireEvent } from '@testing-library/react';
33
import { render, screen, userEvent } from '../test-utils';
44
import { Header } from './Header';

app/src/components/ImageCard.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ export const ImageCard = memo(function ImageCard({
150150
<CardMedia
151151
component="img"
152152
loading={index < BATCH_SIZE ? 'eager' : 'lazy'}
153+
fetchPriority={index === 0 ? 'high' : undefined}
153154
image={image.thumb || image.url}
154155
alt={viewMode === 'library' ? `${image.spec_id} - ${image.library}` : `${selectedSpec} - ${image.library}`}
155156
sx={{

app/src/components/Layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function AppDataProvider({ children }: { children: ReactNode }) {
3636

3737
// Load shared data after browser is idle — gives /plots/filter bandwidth priority
3838
useEffect(() => {
39-
const id = requestIdleCallback(async () => {
39+
const id = window.requestIdleCallback(async () => {
4040
try {
4141
const [specsRes, libsRes, statsRes] = await Promise.all([
4242
fetch(`${API_URL}/specs`),
@@ -62,7 +62,7 @@ export function AppDataProvider({ children }: { children: ReactNode }) {
6262
console.error('Error loading initial data:', err);
6363
}
6464
});
65-
return () => cancelIdleCallback(id);
65+
return () => window.cancelIdleCallback(id);
6666
}, []);
6767

6868
return (

app/src/components/SpecTabs.tsx

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useCallback, useMemo } from 'react';
1+
import { useState, useCallback, lazy, Suspense } from 'react';
22
import Box from '@mui/material/Box';
33
import Tabs from '@mui/material/Tabs';
44
import Tab from '@mui/material/Tab';
@@ -15,11 +15,8 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
1515
import CheckIcon from '@mui/icons-material/Check';
1616
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
1717
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
18-
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light';
19-
import { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
20-
import python from 'react-syntax-highlighter/dist/esm/languages/prism/python';
2118

22-
SyntaxHighlighter.registerLanguage('python', python);
19+
const CodeHighlighter = lazy(() => import('./CodeHighlighter'));
2320

2421
// Map tag category names to URL parameter names
2522
const SPEC_TAG_PARAM_MAP: Record<string, string> = {
@@ -217,24 +214,16 @@ export function SpecTabs({
217214
}
218215
};
219216

220-
// Memoize syntax-highlighted code
221-
const highlightedCode = useMemo(() => {
222-
if (!code) return null;
223-
return (
224-
<SyntaxHighlighter
225-
language="python"
226-
style={oneLight}
227-
customStyle={{
228-
margin: 0,
229-
fontSize: '0.85rem',
230-
fontFamily: '"MonoLisa", "MonoLisa Fallback", monospace',
231-
background: 'transparent',
232-
}}
233-
>
217+
// Lazy-loaded syntax highlighter - only loads when Code tab is opened
218+
const highlightedCode = code ? (
219+
<Suspense fallback={
220+
<Box sx={{ fontFamily: '"MonoLisa", "MonoLisa Fallback", monospace', fontSize: '0.85rem', whiteSpace: 'pre-wrap', color: '#4b5563' }}>
234221
{code}
235-
</SyntaxHighlighter>
236-
);
237-
}, [code]);
222+
</Box>
223+
}>
224+
<CodeHighlighter code={code} />
225+
</Suspense>
226+
) : null;
238227

239228
// Format date
240229
const formatDate = (dateStr?: string) => {

app/src/hooks/useCopyCode.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect, vi, beforeEach } from 'vitest';
1+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
22
import { renderHook, act } from '@testing-library/react';
33
import { useCopyCode } from './useCopyCode';
44

0 commit comments

Comments
 (0)