This commit is contained in:
alorig
2025-11-18 06:50:35 +05:00
parent ef16ad760f
commit 873f97ea3f
27 changed files with 1717 additions and 4 deletions

View File

@@ -7,7 +7,10 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
},
"dependencies": {
"axios": "^1.13.2",
@@ -18,17 +21,23 @@
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@testing-library/jest-dom": "^6.1.5",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.1",
"@types/node": "^24.10.0",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0",
"@vitest/ui": "^1.0.4",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"jsdom": "^23.0.1",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.3",
"vite": "^7.2.2"
"vite": "^7.2.2",
"vitest": "^1.0.4"
}
}

View File

@@ -0,0 +1,55 @@
/**
* Tests for File Access
* Phase 5: Sites Renderer & Bulk Generation
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { getFileUrl, getImageUrl } from '../utils/fileAccess';
// Mock fetch
global.fetch = vi.fn();
describe('File Access', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('loads images correctly', async () => {
// Test: File access works (images, documents, media)
const mockImageUrl = 'https://example.com/images/test.jpg';
(global.fetch as any).mockResolvedValueOnce({
ok: true,
url: mockImageUrl,
});
const url = await getImageUrl(1, 'test.jpg', 1);
expect(url).toBeDefined();
});
it('loads documents correctly', async () => {
// Test: File access works (images, documents, media)
const mockDocUrl = 'https://example.com/documents/test.pdf';
(global.fetch as any).mockResolvedValueOnce({
ok: true,
url: mockDocUrl,
});
const url = await getFileUrl(1, 'documents', 'test.pdf', 1);
expect(url).toBeDefined();
});
it('loads media files correctly', async () => {
// Test: File access works (images, documents, media)
const mockMediaUrl = 'https://example.com/media/test.mp4';
(global.fetch as any).mockResolvedValueOnce({
ok: true,
url: mockMediaUrl,
});
const url = await getFileUrl(1, 'media', 'test.mp4', 1);
expect(url).toBeDefined();
});
});

View File

@@ -0,0 +1,86 @@
/**
* Tests for Layout Renderer
* Phase 5: Sites Renderer & Bulk Generation
*/
import { describe, it, expect } from 'vitest';
import { renderLayout } from '../utils/layoutRenderer';
describe('Layout Renderer', () => {
it('renders default layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'default',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
it('renders minimal layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'minimal',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
it('renders magazine layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'magazine',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
it('renders ecommerce layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'ecommerce',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
it('renders portfolio layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'portfolio',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
it('renders blog layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'blog',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
it('renders corporate layout correctly', () => {
// Test: Multiple layouts work correctly
const siteDefinition = {
layout: 'corporate',
pages: [],
};
const result = renderLayout(siteDefinition);
expect(result).toBeDefined();
});
});

View File

@@ -0,0 +1,49 @@
/**
* Tests for Site Definition Loader
* Phase 5: Sites Renderer & Bulk Generation
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { loadSiteDefinition } from '../loaders/loadSiteDefinition';
// Mock fetch
global.fetch = vi.fn();
describe('Site Definition Loader', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('loads site definitions from API', async () => {
// Test: Sites renderer loads site definitions
const mockSiteDefinition = {
id: 1,
name: 'Test Site',
pages: [
{ id: 1, slug: 'home', title: 'Home' },
{ id: 2, slug: 'about', title: 'About' },
],
};
(global.fetch as any).mockResolvedValueOnce({
ok: true,
json: async () => ({ data: mockSiteDefinition }),
});
const result = await loadSiteDefinition(1);
expect(result).toBeDefined();
expect(result.name).toBe('Test Site');
expect(result.pages).toHaveLength(2);
expect(global.fetch).toHaveBeenCalledWith(
expect.stringContaining('/api/v1/site-builder/blueprints/1/')
);
});
it('handles API errors gracefully', async () => {
// Test: Sites renderer loads site definitions
(global.fetch as any).mockRejectedValueOnce(new Error('API Error'));
await expect(loadSiteDefinition(1)).rejects.toThrow('API Error');
});
});

View File

@@ -0,0 +1,28 @@
/**
* Test Setup
* Phase 5: Sites Renderer Tests
*/
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
import '@testing-library/jest-dom';
// Cleanup after each test
afterEach(() => {
cleanup();
});
// Mock window.matchMedia
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: (query: string) => ({
matches: false,
media: query,
onchange: null,
addListener: () => {},
removeListener: () => {},
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => {},
}),
});

18
sites/vitest.config.ts Normal file
View File

@@ -0,0 +1,18 @@
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./src/__tests__/setup.ts'],
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
});