mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-08 10:58:52 +00:00
73c6bd1416
Bug fix: - markNotificationRead was using raw fetch() without auth headers, bypassing the shared client's Authorization header. Moved to api/client.ts to use fetchJSON with proper auth. New action buttons: - CertificatesPage: "New Certificate" modal with form fields - CertificateDetailPage: "Deploy" button with target selector modal, "Archive" button with confirmation - IssuersPage: "Test Connection" and "Delete" per-row actions - TargetsPage: "Delete" per-row action - PoliciesPage: "Enable/Disable" toggle and "Delete" per-row actions New API client functions: - updateCertificate, archiveCertificate, registerAgent, createPolicy, updatePolicy, deletePolicy, getPolicyViolations, createIssuer, testIssuerConnection, deleteIssuer, createTarget, deleteTarget, markNotificationRead Frontend tests (53 tests, 2 files): - client.test.ts: 35 tests covering all API endpoints, auth headers, 401 handling, error parsing, HTTP methods, request bodies - utils.test.ts: 18 tests covering formatDate, formatDateTime, timeAgo, daysUntil, expiryColor CI: Added "Run Frontend Tests" step to frontend-build job Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import { formatDate, formatDateTime, timeAgo, daysUntil, expiryColor } from './utils';
|
|
|
|
describe('Utility functions', () => {
|
|
describe('formatDate', () => {
|
|
it('returns dash for empty string', () => {
|
|
expect(formatDate('')).toBe('—');
|
|
});
|
|
|
|
it('formats ISO date string', () => {
|
|
const result = formatDate('2026-06-15T12:00:00Z');
|
|
expect(result).toContain('Jun');
|
|
expect(result).toContain('15');
|
|
expect(result).toContain('2026');
|
|
});
|
|
});
|
|
|
|
describe('formatDateTime', () => {
|
|
it('returns dash for empty string', () => {
|
|
expect(formatDateTime('')).toBe('—');
|
|
});
|
|
|
|
it('formats ISO datetime string with time', () => {
|
|
const result = formatDateTime('2026-06-15T14:30:00Z');
|
|
expect(result).toContain('Jun');
|
|
expect(result).toContain('15');
|
|
});
|
|
});
|
|
|
|
describe('timeAgo', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date('2026-03-15T12:00:00Z'));
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('returns dash for empty string', () => {
|
|
expect(timeAgo('')).toBe('—');
|
|
});
|
|
|
|
it('returns "just now" for recent times', () => {
|
|
expect(timeAgo('2026-03-15T11:59:45Z')).toBe('just now');
|
|
});
|
|
|
|
it('returns minutes ago', () => {
|
|
expect(timeAgo('2026-03-15T11:45:00Z')).toBe('15m ago');
|
|
});
|
|
|
|
it('returns hours ago', () => {
|
|
expect(timeAgo('2026-03-15T09:00:00Z')).toBe('3h ago');
|
|
});
|
|
|
|
it('returns days ago', () => {
|
|
expect(timeAgo('2026-03-12T12:00:00Z')).toBe('3d ago');
|
|
});
|
|
|
|
it('returns formatted date for old dates', () => {
|
|
const result = timeAgo('2025-01-15T12:00:00Z');
|
|
expect(result).toContain('2025');
|
|
});
|
|
});
|
|
|
|
describe('daysUntil', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date('2026-03-15T12:00:00Z'));
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('returns 0 for empty string', () => {
|
|
expect(daysUntil('')).toBe(0);
|
|
});
|
|
|
|
it('returns positive days for future date', () => {
|
|
expect(daysUntil('2026-03-25T12:00:00Z')).toBe(10);
|
|
});
|
|
|
|
it('returns negative days for past date', () => {
|
|
expect(daysUntil('2026-03-10T12:00:00Z')).toBeLessThan(0);
|
|
});
|
|
});
|
|
|
|
describe('expiryColor', () => {
|
|
it('returns red for expired (0 days)', () => {
|
|
expect(expiryColor(0)).toContain('red');
|
|
});
|
|
|
|
it('returns red for <= 7 days', () => {
|
|
expect(expiryColor(5)).toContain('red');
|
|
});
|
|
|
|
it('returns amber for <= 14 days', () => {
|
|
expect(expiryColor(12)).toContain('amber');
|
|
});
|
|
|
|
it('returns amber for <= 30 days', () => {
|
|
expect(expiryColor(25)).toContain('amber');
|
|
});
|
|
|
|
it('returns green for > 30 days', () => {
|
|
expect(expiryColor(60)).toContain('emerald');
|
|
});
|
|
});
|
|
});
|