chore: address clawpatch review findings (test scope, deps, legal-page hardening)

- frontend: `npm test` now runs all 7 vitest suites instead of one hardcoded
  file; the previously skipped ProtectedImage / Skeleton / usePublicSettings /
  contrast / themeMigration / url suites are now active in CI
- frontend: wrap ThemeCustomizerEnhanced test in QueryClientProvider so the
  newly-enabled run passes (component uses useQuery internally)
- root: drop unused better-sqlite3 / canvas / node-fetch + their
  prebuild-install/tar-fs override (backend keeps its own copies); add dotenv
  so playwright.config.ts can load on a clean install; add name/version/private
- LegalPage: scheme-validate external_url before window.location.replace so a
  CMS edit can't redirect visitors to javascript:/data:
- LegalPage: force rel="noopener noreferrer" on target="_blank" anchors in
  sanitized CMS HTML to block reverse-tabnabbing
This commit is contained in:
Paul Nothaft
2026-05-21 17:10:34 +02:00
parent efa6b4a205
commit dba98f1325
5 changed files with 72 additions and 489 deletions
@@ -1,6 +1,8 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { vi } from 'vitest';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import { ThemeCustomizerEnhanced } from '../ThemeCustomizerEnhanced';
import type { ThemeConfig } from '../../../types/theme.types';
@@ -15,6 +17,16 @@ vi.mock('react-i18next', async () => {
};
});
// Component uses useQuery for admin-settings + fonts; tests don't exercise
// those data paths, so just give them a client that won't retry on the
// (intentionally absent) network.
const renderWithQueryClient = (ui: ReactElement) => {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } }
});
return render(<QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>);
};
describe('ThemeCustomizerEnhanced', () => {
const baseTheme: ThemeConfig = {
primaryColor: '#000000',
@@ -32,7 +44,7 @@ describe('ThemeCustomizerEnhanced', () => {
const handleChange = vi.fn();
const handleApply = vi.fn().mockResolvedValue(undefined);
render(
renderWithQueryClient(
<ThemeCustomizerEnhanced
value={baseTheme}
onChange={handleChange}
@@ -55,7 +67,7 @@ describe('ThemeCustomizerEnhanced', () => {
it('disables the Apply button while applying', () => {
const handleChange = vi.fn();
render(
renderWithQueryClient(
<ThemeCustomizerEnhanced
value={baseTheme}
onChange={handleChange}