ca-grow-ops-manager/frontend/src/__tests__/app.test.ts
fullsizemalt 4663b0ac86
Some checks failed
Deploy to Production / deploy (push) Failing after 0s
Test / backend-test (push) Failing after 0s
Test / frontend-test (push) Failing after 0s
feat: Navigation refactor with RBAC, DevTools for quick user switching, enhanced seed data
- Refactored navigation with grouped sections (Operations, Cultivation, Analytics, etc.)
- Added RBAC-based navigation filtering by user role
- Created DevTools panel for quick user switching during testing
- Added collapsible sidebar sections on desktop
- Mobile: bottom nav bar (4 items + More) with slide-up sheet
- Enhanced seed data with [DEMO] prefix markers
- Added multiple demo users: Owner, Manager, Cultivator, Worker
- Fixed domain to runfoo.run
- Added Audit Log and SOP Library pages to navigation
- Created usePermissions hook and RoleBadge component
2025-12-11 11:07:22 -08:00

128 lines
4.2 KiB
TypeScript

import { describe, it, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
// Mock auth context
vi.mock('../context/AuthContext', () => ({
useAuth: () => ({
user: { id: '1', name: 'Test User', email: 'test@test.com', role: 'ADMIN' },
isAuthenticated: true,
login: vi.fn(),
logout: vi.fn(),
}),
AuthProvider: ({ children }: { children: React.ReactNode }) => children,
}));
describe('App', () => {
it('renders without crashing', () => {
// Basic smoke test
expect(true).toBe(true);
});
});
describe('Utility Functions', () => {
describe('formatFileSize', () => {
it('formats bytes correctly', async () => {
const { formatFileSize } = await import('../lib/photoCompression');
expect(formatFileSize(500)).toBe('500 B');
expect(formatFileSize(1024)).toBe('1.0 KB');
expect(formatFileSize(1536)).toBe('1.5 KB');
expect(formatFileSize(1048576)).toBe('1.0 MB');
});
});
describe('isValidImageType', () => {
it('validates image types', async () => {
const { isValidImageType } = await import('../lib/photoCompression');
const jpegFile = new File([''], 'test.jpg', { type: 'image/jpeg' });
const pngFile = new File([''], 'test.png', { type: 'image/png' });
const textFile = new File([''], 'test.txt', { type: 'text/plain' });
expect(isValidImageType(jpegFile)).toBe(true);
expect(isValidImageType(pngFile)).toBe(true);
expect(isValidImageType(textFile)).toBe(false);
});
});
});
describe('QR Code Utils', () => {
it('generates batch QR data', async () => {
const { generateBatchQRData } = await import('../lib/qrcode');
const data = generateBatchQRData('batch-123', 'Test Batch');
const parsed = JSON.parse(data);
expect(parsed.type).toBe('batch');
expect(parsed.id).toBe('batch-123');
expect(parsed.name).toBe('Test Batch');
});
it('parses QR data', async () => {
const { parseQRData } = await import('../lib/qrcode');
const data = JSON.stringify({ type: 'plant', id: 'plant-456' });
const parsed = parseQRData(data);
expect(parsed?.type).toBe('plant');
expect(parsed?.id).toBe('plant-456');
});
it('handles invalid QR data', async () => {
const { parseQRData } = await import('../lib/qrcode');
const result = parseQRData('not-json');
expect(result.type).toBe('unknown');
});
});
describe('Accessibility Utils', () => {
it('generates ARIA IDs', async () => {
const { generateAriaId } = await import('../lib/accessibility');
const id1 = generateAriaId('button');
const id2 = generateAriaId('button');
expect(id1).toContain('button');
expect(id1).not.toBe(id2); // Should be unique
});
});
describe('API Clients', () => {
describe('Batches API', () => {
it('exports required functions', async () => {
const { batchesApi } = await import('../lib/batchesApi');
expect(typeof batchesApi.getAll).toBe('function');
expect(typeof batchesApi.create).toBe('function');
});
});
describe('Rooms API', () => {
it('exports required functions', async () => {
const { roomsApi } = await import('../lib/roomsApi');
expect(typeof roomsApi.getAll).toBe('function');
});
});
describe('Visitors API', () => {
it('exports required functions', async () => {
const { visitorsApi } = await import('../lib/visitorsApi');
expect(typeof visitorsApi.getAll).toBe('function');
expect(typeof visitorsApi.checkIn).toBe('function');
expect(typeof visitorsApi.checkOut).toBe('function');
});
});
describe('Messaging API', () => {
it('exports required functions', async () => {
const { messagingApi } = await import('../lib/messagingApi');
expect(typeof messagingApi.getAnnouncements).toBe('function');
expect(typeof messagingApi.acknowledge).toBe('function');
});
});
});