- Add frontend unit tests with Vitest for components, hooks, pages, and utilities - Add backend tests for webhooks, notifications, middleware, and edge cases - Add ForgotPassword, NotFound, and ResetPassword pages - Add migration for orphaned staff resources conversion - Add coverage directory to gitignore (generated reports) - Various bug fixes and improvements from previous work 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
209 lines
5.9 KiB
TypeScript
209 lines
5.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
// Mock apiClient
|
|
vi.mock('../client', () => ({
|
|
default: {
|
|
get: vi.fn(),
|
|
post: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
import {
|
|
getSandboxStatus,
|
|
toggleSandboxMode,
|
|
resetSandboxData,
|
|
} from '../sandbox';
|
|
import apiClient from '../client';
|
|
|
|
describe('sandbox API', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('getSandboxStatus', () => {
|
|
it('fetches sandbox status from API', async () => {
|
|
const mockStatus = {
|
|
sandbox_mode: true,
|
|
sandbox_enabled: true,
|
|
sandbox_schema: 'test_business_sandbox',
|
|
};
|
|
vi.mocked(apiClient.get).mockResolvedValue({ data: mockStatus });
|
|
|
|
const result = await getSandboxStatus();
|
|
|
|
expect(apiClient.get).toHaveBeenCalledWith('/sandbox/status/');
|
|
expect(result).toEqual(mockStatus);
|
|
});
|
|
|
|
it('returns sandbox disabled status', async () => {
|
|
const mockStatus = {
|
|
sandbox_mode: false,
|
|
sandbox_enabled: false,
|
|
sandbox_schema: null,
|
|
};
|
|
vi.mocked(apiClient.get).mockResolvedValue({ data: mockStatus });
|
|
|
|
const result = await getSandboxStatus();
|
|
|
|
expect(result.sandbox_mode).toBe(false);
|
|
expect(result.sandbox_enabled).toBe(false);
|
|
expect(result.sandbox_schema).toBeNull();
|
|
});
|
|
|
|
it('returns sandbox enabled but not active', async () => {
|
|
const mockStatus = {
|
|
sandbox_mode: false,
|
|
sandbox_enabled: true,
|
|
sandbox_schema: 'test_business_sandbox',
|
|
};
|
|
vi.mocked(apiClient.get).mockResolvedValue({ data: mockStatus });
|
|
|
|
const result = await getSandboxStatus();
|
|
|
|
expect(result.sandbox_mode).toBe(false);
|
|
expect(result.sandbox_enabled).toBe(true);
|
|
expect(result.sandbox_schema).toBe('test_business_sandbox');
|
|
});
|
|
});
|
|
|
|
describe('toggleSandboxMode', () => {
|
|
it('enables sandbox mode', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
sandbox_mode: true,
|
|
message: 'Sandbox mode enabled',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
const result = await toggleSandboxMode(true);
|
|
|
|
expect(apiClient.post).toHaveBeenCalledWith('/sandbox/toggle/', {
|
|
sandbox: true,
|
|
});
|
|
expect(result.sandbox_mode).toBe(true);
|
|
expect(result.message).toBe('Sandbox mode enabled');
|
|
});
|
|
|
|
it('disables sandbox mode', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
sandbox_mode: false,
|
|
message: 'Sandbox mode disabled',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
const result = await toggleSandboxMode(false);
|
|
|
|
expect(apiClient.post).toHaveBeenCalledWith('/sandbox/toggle/', {
|
|
sandbox: false,
|
|
});
|
|
expect(result.sandbox_mode).toBe(false);
|
|
expect(result.message).toBe('Sandbox mode disabled');
|
|
});
|
|
|
|
it('handles toggle with true parameter', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
sandbox_mode: true,
|
|
message: 'Switched to test data',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
await toggleSandboxMode(true);
|
|
|
|
expect(apiClient.post).toHaveBeenCalledWith('/sandbox/toggle/', {
|
|
sandbox: true,
|
|
});
|
|
});
|
|
|
|
it('handles toggle with false parameter', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
sandbox_mode: false,
|
|
message: 'Switched to live data',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
await toggleSandboxMode(false);
|
|
|
|
expect(apiClient.post).toHaveBeenCalledWith('/sandbox/toggle/', {
|
|
sandbox: false,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('resetSandboxData', () => {
|
|
it('resets sandbox data successfully', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
message: 'Sandbox data reset successfully',
|
|
sandbox_schema: 'test_business_sandbox',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
const result = await resetSandboxData();
|
|
|
|
expect(apiClient.post).toHaveBeenCalledWith('/sandbox/reset/');
|
|
expect(result.message).toBe('Sandbox data reset successfully');
|
|
expect(result.sandbox_schema).toBe('test_business_sandbox');
|
|
});
|
|
|
|
it('returns schema name after reset', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
message: 'Data reset complete',
|
|
sandbox_schema: 'my_company_sandbox',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
const result = await resetSandboxData();
|
|
|
|
expect(result.sandbox_schema).toBe('my_company_sandbox');
|
|
});
|
|
|
|
it('calls reset endpoint without parameters', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
message: 'Reset successful',
|
|
sandbox_schema: 'test_sandbox',
|
|
},
|
|
};
|
|
vi.mocked(apiClient.post).mockResolvedValue(mockResponse);
|
|
|
|
await resetSandboxData();
|
|
|
|
expect(apiClient.post).toHaveBeenCalledWith('/sandbox/reset/');
|
|
expect(apiClient.post).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
describe('error handling', () => {
|
|
it('propagates errors from getSandboxStatus', async () => {
|
|
const error = new Error('Network error');
|
|
vi.mocked(apiClient.get).mockRejectedValue(error);
|
|
|
|
await expect(getSandboxStatus()).rejects.toThrow('Network error');
|
|
});
|
|
|
|
it('propagates errors from toggleSandboxMode', async () => {
|
|
const error = new Error('Unauthorized');
|
|
vi.mocked(apiClient.post).mockRejectedValue(error);
|
|
|
|
await expect(toggleSandboxMode(true)).rejects.toThrow('Unauthorized');
|
|
});
|
|
|
|
it('propagates errors from resetSandboxData', async () => {
|
|
const error = new Error('Forbidden');
|
|
vi.mocked(apiClient.post).mockRejectedValue(error);
|
|
|
|
await expect(resetSandboxData()).rejects.toThrow('Forbidden');
|
|
});
|
|
});
|
|
});
|