fix: test stabilization for windows

This commit is contained in:
2026-02-17 09:33:07 +01:00
parent cecbae9d27
commit 03cf6ae9e7
5 changed files with 52 additions and 37 deletions

View File

@@ -29,6 +29,7 @@ import { MediaEngine, MediaData } from '../../src/main/engine/MediaEngine';
const mockMedia = new Map<string, any>();
const mockPostMedia = new Map<string, any>();
const mockFiles = new Map<string, Buffer | string>();
const normalizePath = (value: string): string => value.replace(/\\/g, '/');
// Track database operations for testing
let mediaDeleteCalled = false;
@@ -126,7 +127,8 @@ vi.mock('../../src/main/database', () => ({
// Mock fs/promises
vi.mock('fs/promises', () => ({
readFile: vi.fn(async (path: string) => {
const content = mockFiles.get(path);
const normalizedPath = normalizePath(path);
const content = mockFiles.get(normalizedPath);
if (!content) {
const error = new Error(`ENOENT: no such file or directory, open '${path}'`);
(error as any).code = 'ENOENT';
@@ -135,29 +137,29 @@ vi.mock('fs/promises', () => ({
return content;
}),
writeFile: vi.fn(async (path: string, content: Buffer | string) => {
mockFiles.set(path, content);
mockFiles.set(normalizePath(path), content);
}),
unlink: vi.fn(async (path: string) => {
mockFiles.delete(path);
mockFiles.delete(normalizePath(path));
}),
mkdir: vi.fn(async () => {}),
readdir: vi.fn(async () => []),
stat: vi.fn(async (path: string) => ({
isFile: () => mockFiles.has(path),
isDirectory: () => !mockFiles.has(path),
size: mockFiles.get(path)?.length || 0,
isFile: () => mockFiles.has(normalizePath(path)),
isDirectory: () => !mockFiles.has(normalizePath(path)),
size: mockFiles.get(normalizePath(path))?.length || 0,
})),
access: vi.fn(async (path: string) => {
if (!mockFiles.has(path)) {
if (!mockFiles.has(normalizePath(path))) {
const error = new Error(`ENOENT`);
(error as any).code = 'ENOENT';
throw error;
}
}),
copyFile: vi.fn(async (src: string, dest: string) => {
const content = mockFiles.get(src);
const content = mockFiles.get(normalizePath(src));
if (content) {
mockFiles.set(dest, content);
mockFiles.set(normalizePath(dest), content);
}
}),
}));

View File

@@ -10,6 +10,7 @@
*/
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
import * as path from 'path';
// Mock data stores
const mockFiles = new Map<string, string>();
@@ -749,17 +750,20 @@ describe('MetaEngine', () => {
});
it('should use custom dataDir when provided in setProjectContext', () => {
metaEngine.setProjectContext('project-with-custom-dir', '/custom/data/path');
const customDataDir = path.join('custom', 'data', 'path');
metaEngine.setProjectContext('project-with-custom-dir', customDataDir);
const metaDir = metaEngine.getMetaDir();
expect(metaDir).toContain('/custom/data/path');
expect(normalizePath(metaDir)).toContain(normalizePath(customDataDir));
});
it('should sync dataPath from database to project.json if different', async () => {
const metaDir = metaEngine.getMetaDir();
const oldPath = path.join('old', 'path', 'from', 'file');
const newPath = path.join('new', 'path', 'from', 'database');
mockFiles.set(normalizePath(`${metaDir}/project.json`), JSON.stringify({
name: 'Project',
dataPath: '/old/path/from/file',
dataPath: oldPath,
}));
// Database has the currently selected (authoritative) path
@@ -767,7 +771,7 @@ describe('MetaEngine', () => {
id: 'test-project',
name: 'Project',
description: null,
dataPath: '/new/path/from/database',
dataPath: newPath,
slug: 'project',
createdAt: new Date(),
updatedAt: new Date(),
@@ -779,7 +783,7 @@ describe('MetaEngine', () => {
const savedProjectJson = mockFiles.get(normalizePath(`${metaDir}/project.json`));
expect(savedProjectJson).toBeDefined();
const parsed = JSON.parse(savedProjectJson!);
expect(parsed.dataPath).toBe('/new/path/from/database');
expect(normalizePath(parsed.dataPath)).toBe(normalizePath(newPath));
expect(mockLocalDb.update).not.toHaveBeenCalled();
});
});

View File

@@ -6,9 +6,12 @@
*/
import { describe, it, expect, beforeEach, vi } from 'vitest';
import * as path from 'path';
import { ProjectEngine, ProjectData } from '../../src/main/engine/ProjectEngine';
import { resetMockCounters } from '../utils/factories';
const normalizePath = (value: string): string => value.replace(/\\/g, '/');
// Create mock data stores
const mockProjects = new Map<string, any>();
@@ -550,7 +553,7 @@ describe('ProjectEngine', () => {
describe('Custom dataPath', () => {
it('should create project with custom dataPath', async () => {
const customPath = '/Users/test/Documents/MyBlog';
const customPath = path.join('Users', 'test', 'Documents', 'MyBlog');
const project = await projectEngine.createProject({
name: 'Custom Path Project',
dataPath: customPath,
@@ -561,7 +564,8 @@ describe('ProjectEngine', () => {
it('should create meta and thumbnails directories in custom dataPath', async () => {
const fs = await import('fs/promises');
const customPath = '/Users/test/Documents/MyBlog';
const customPath = path.join('Users', 'test', 'Documents', 'MyBlog');
const normalizedCustomPath = normalizePath(customPath);
await projectEngine.createProject({
name: 'Custom Dirs Project',
@@ -569,17 +573,18 @@ describe('ProjectEngine', () => {
});
const mkdirCalls = vi.mocked(fs.mkdir).mock.calls;
const createdPaths = mkdirCalls.map(call => call[0]);
const createdPaths = mkdirCalls.map(call => normalizePath(String(call[0])));
// Should create meta/ and thumbnails/ in custom dataPath
expect(createdPaths).toContainEqual(expect.stringContaining(customPath));
expect(createdPaths.some(p => String(p).includes(customPath) && String(p).includes('meta'))).toBe(true);
expect(createdPaths.some(p => String(p).includes(customPath) && String(p).includes('thumbnails'))).toBe(true);
expect(createdPaths).toContainEqual(expect.stringContaining(normalizedCustomPath));
expect(createdPaths.some(p => p.includes(normalizedCustomPath) && p.includes('meta'))).toBe(true);
expect(createdPaths.some(p => p.includes(normalizedCustomPath) && p.includes('thumbnails'))).toBe(true);
});
it('should create posts and media directories in custom dataPath', async () => {
const fs = await import('fs/promises');
const customPath = '/Users/test/Documents/MyBlog';
const customPath = path.join('Users', 'test', 'Documents', 'MyBlog');
const normalizedCustomPath = normalizePath(customPath);
await projectEngine.createProject({
name: 'Custom Data Project',
@@ -587,11 +592,11 @@ describe('ProjectEngine', () => {
});
const mkdirCalls = vi.mocked(fs.mkdir).mock.calls;
const createdPaths = mkdirCalls.map(call => call[0]);
const createdPaths = mkdirCalls.map(call => normalizePath(String(call[0])));
// Should create posts/ and media/ in custom dataPath
expect(createdPaths.some(p => String(p).includes(customPath) && String(p).includes('posts'))).toBe(true);
expect(createdPaths.some(p => String(p).includes(customPath) && String(p).includes('media'))).toBe(true);
expect(createdPaths.some(p => p.includes(normalizedCustomPath) && p.includes('posts'))).toBe(true);
expect(createdPaths.some(p => p.includes(normalizedCustomPath) && p.includes('media'))).toBe(true);
});
it('should create meta and thumbnails in internal storage when no dataPath', async () => {
@@ -611,7 +616,7 @@ describe('ProjectEngine', () => {
it('should use getDataDir with custom dataPath', () => {
const projectId = 'test-id';
const customPath = '/Users/test/MyBlog';
const customPath = path.join('Users', 'test', 'MyBlog');
const dataDir = projectEngine.getDataDir(projectId, customPath);
@@ -826,7 +831,7 @@ describe('ProjectEngine', () => {
name: 'My Project',
slug: 'my-project',
description: 'A test project',
dataPath: '/custom/path',
dataPath: path.join('custom', 'path'),
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-06-01'),
isActive: true,
@@ -848,7 +853,7 @@ describe('ProjectEngine', () => {
expect(result?.name).toBe('My Project');
expect(result?.slug).toBe('my-project');
expect(result?.description).toBe('A test project');
expect(result?.dataPath).toBe('/custom/path');
expect(result?.dataPath).toBe(path.join('custom', 'path'));
expect(result?.isActive).toBe(true);
});
@@ -1181,7 +1186,7 @@ describe('ProjectEngine', () => {
id: 'resolved-project',
name: 'Resolved Project',
slug: 'resolved',
dataPath: '/custom/data/path',
dataPath: path.join('custom', 'data', 'path'),
createdAt: new Date(),
updatedAt: new Date(),
isActive: false,
@@ -1198,8 +1203,9 @@ describe('ProjectEngine', () => {
const paths = await projectEngine.getProjectPathsResolved('resolved-project');
expect(paths.posts).toContain('/custom/data/path');
expect(paths.media).toContain('/custom/data/path');
const normalizedBasePath = normalizePath(projectWithPath.dataPath);
expect(normalizePath(paths.posts)).toContain(normalizedBasePath);
expect(normalizePath(paths.media)).toContain(normalizedBasePath);
});
it('should use internal path when project has no dataPath', async () => {