Files
caddy-proxy-manager/tests/unit/l4-ports-apply-banner.test.ts
akanealw 99819b70ff
Some checks failed
Build and Push Docker Images (Trusted) / build-and-push (., docker/caddy/Dockerfile, caddy) (push) Has been cancelled
Build and Push Docker Images (Trusted) / build-and-push (., docker/l4-port-manager/Dockerfile, l4-port-manager) (push) Has been cancelled
Build and Push Docker Images (Trusted) / build-and-push (., docker/web/Dockerfile, web) (push) Has been cancelled
Tests / test (push) Has been cancelled
added caddy-proxy-manager for testing
2026-04-21 22:49:08 +00:00

74 lines
2.8 KiB
TypeScript
Executable File

/**
* Unit tests for the L4PortsApplyBanner refresh-signal contract.
*
* Verifies that the banner component re-fetches port status whenever
* refreshSignal changes — so changes are reflected immediately after
* create/edit/delete/toggle without a page reload.
*
* These tests inspect the component source rather than rendering it,
* to avoid the cost of a jsdom environment.
*/
import { describe, it, expect } from 'vitest';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
const BANNER_PATH = resolve(__dirname, '../../src/components/l4-proxy-hosts/L4PortsApplyBanner.tsx');
const banner = readFileSync(BANNER_PATH, 'utf-8');
const CLIENT_PATH = resolve(__dirname, '../../app/(dashboard)/l4-proxy-hosts/L4ProxyHostsClient.tsx');
const client = readFileSync(CLIENT_PATH, 'utf-8');
describe('L4PortsApplyBanner', () => {
it('accepts a refreshSignal prop', () => {
expect(banner).toContain('refreshSignal');
});
it('re-fetches when refreshSignal changes via useEffect', () => {
// Must have a useEffect that depends on refreshSignal
expect(banner).toMatch(/useEffect\s*\(\s*\(\s*\)\s*=>/);
expect(banner).toContain('refreshSignal');
// The effect must call fetchStatus
expect(banner).toContain('fetchStatus');
});
it('skips fetch when refreshSignal is falsy (avoids double-fetch on mount)', () => {
// The effect should guard against firing on initial 0/undefined value
// so the mount effect and the signal effect don't both fire on load.
expect(banner).toMatch(/if\s*\(!\s*refreshSignal\s*\)/);
});
});
describe('L4ProxyHostsClient banner integration', () => {
it('tracks bannerRefresh state', () => {
expect(client).toContain('bannerRefresh');
expect(client).toContain('setBannerRefresh');
});
it('passes refreshSignal to L4PortsApplyBanner', () => {
expect(client).toContain('refreshSignal={bannerRefresh}');
});
it('increments bannerRefresh after toggle', () => {
// The toggle handler must signal the banner after the action completes
expect(client).toMatch(/toggleL4ProxyHostAction[\s\S]{0,200}signalBannerRefresh/);
});
it('increments bannerRefresh when create dialog closes', () => {
expect(client).toMatch(/CreateL4HostDialog[\s\S]{0,400}signalBannerRefresh/);
});
it('increments bannerRefresh when edit dialog closes', () => {
expect(client).toMatch(/EditL4HostDialog[\s\S]{0,400}signalBannerRefresh/);
});
it('increments bannerRefresh when delete dialog closes', () => {
expect(client).toMatch(/DeleteL4HostDialog[\s\S]{0,400}signalBannerRefresh/);
});
it('defines signalBannerRefresh as a function that increments the counter', () => {
// Must use functional update form to avoid stale closure
expect(client).toMatch(/signalBannerRefresh\s*=\s*\(\s*\)\s*=>\s*setBannerRefresh\s*\(/);
expect(client).toContain('n + 1');
});
});