fix: project got corrupted sometimes
This commit is contained in:
@@ -229,6 +229,16 @@ describe('MediaEngine', () => {
|
||||
expect(mediaEngine.getProjectContext()).toBe('my-blog');
|
||||
});
|
||||
|
||||
it('should avoid duplicate context log when context is unchanged', () => {
|
||||
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
mediaEngine.setProjectContext('same-project', '/tmp/data', '/tmp/internal');
|
||||
mediaEngine.setProjectContext('same-project', '/tmp/data', '/tmp/internal');
|
||||
|
||||
expect(consoleLogSpy).toHaveBeenCalledTimes(1);
|
||||
consoleLogSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should allow changing project context multiple times', () => {
|
||||
mediaEngine.setProjectContext('blog-1');
|
||||
expect(mediaEngine.getProjectContext()).toBe('blog-1');
|
||||
|
||||
@@ -48,6 +48,27 @@ vi.mock('fs/promises', () => ({
|
||||
throw err;
|
||||
}
|
||||
}),
|
||||
rename: vi.fn(async (oldPath: string, newPath: string) => {
|
||||
const normalizedOldPath = oldPath.replace(/\\/g, '/');
|
||||
const normalizedNewPath = newPath.replace(/\\/g, '/');
|
||||
const content = mockFiles.get(normalizedOldPath);
|
||||
if (content === undefined) {
|
||||
const err = new Error(`ENOENT: no such file or directory, rename '${oldPath}' -> '${newPath}'`) as NodeJS.ErrnoException;
|
||||
err.code = 'ENOENT';
|
||||
throw err;
|
||||
}
|
||||
mockFiles.set(normalizedNewPath, content);
|
||||
mockFiles.delete(normalizedOldPath);
|
||||
}),
|
||||
unlink: vi.fn(async (filePath: string) => {
|
||||
const normalizedPath = filePath.replace(/\\/g, '/');
|
||||
if (!mockFiles.has(normalizedPath)) {
|
||||
const err = new Error(`ENOENT: no such file or directory, unlink '${filePath}'`) as NodeJS.ErrnoException;
|
||||
err.code = 'ENOENT';
|
||||
throw err;
|
||||
}
|
||||
mockFiles.delete(normalizedPath);
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock electron app
|
||||
@@ -986,6 +1007,27 @@ describe('MetaEngine', () => {
|
||||
expect(metaEngine.isInitialized()).toBe(false);
|
||||
});
|
||||
|
||||
it('should keep initialized flag when project context is unchanged', async () => {
|
||||
await metaEngine.syncOnStartup();
|
||||
expect(metaEngine.isInitialized()).toBe(true);
|
||||
|
||||
metaEngine.setProjectContext('test-project');
|
||||
expect(metaEngine.isInitialized()).toBe(true);
|
||||
});
|
||||
|
||||
it('should de-duplicate concurrent syncOnStartup calls', async () => {
|
||||
const collectTagsSpy = vi.spyOn(metaEngine as unknown as {
|
||||
collectTagsFromPosts: () => Promise<string[]>;
|
||||
}, 'collectTagsFromPosts');
|
||||
|
||||
await Promise.all([
|
||||
metaEngine.syncOnStartup(),
|
||||
metaEngine.syncOnStartup(),
|
||||
]);
|
||||
|
||||
expect(collectTagsSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should use custom dataDir when provided in setProjectContext', () => {
|
||||
const customDataDir = path.join('custom', 'data', 'path');
|
||||
metaEngine.setProjectContext('project-with-custom-dir', customDataDir);
|
||||
|
||||
@@ -154,6 +154,16 @@ describe('PostMediaEngine', () => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
|
||||
it('should avoid duplicate context log when context is unchanged', () => {
|
||||
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
engine.setProjectContext('same-project');
|
||||
engine.setProjectContext('same-project');
|
||||
|
||||
expect(consoleLogSpy).toHaveBeenCalledTimes(1);
|
||||
consoleLogSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should allow changing project context multiple times', () => {
|
||||
engine.setProjectContext('blog-1');
|
||||
engine.setProjectContext('blog-2');
|
||||
|
||||
@@ -339,6 +339,48 @@ describe('PreviewServer', () => {
|
||||
expect(lightboxLoadingImageResponse.headers.get('content-type')).toContain('image/gif');
|
||||
});
|
||||
|
||||
it('does not set project context or run startup sync for static asset requests', async () => {
|
||||
const postEngine = makeEngine([makePost()]);
|
||||
const mediaEngine = {
|
||||
setProjectContext: vi.fn(),
|
||||
async getAllMedia() {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
const postMediaEngine = makePostMediaEngine({});
|
||||
const syncOnStartup = vi.fn(async () => undefined);
|
||||
const settingsEngine = {
|
||||
setProjectContext: vi.fn(),
|
||||
isInitialized: vi.fn(() => false),
|
||||
syncOnStartup,
|
||||
async getProjectMetadata() {
|
||||
return { maxPostsPerPage: 50 };
|
||||
},
|
||||
};
|
||||
const menuEngine = makeMenuEngine({ items: [] });
|
||||
|
||||
server = new PreviewServer({
|
||||
postEngine,
|
||||
mediaEngine: mediaEngine as any,
|
||||
postMediaEngine,
|
||||
settingsEngine: settingsEngine as any,
|
||||
menuEngine,
|
||||
getActiveProjectContext: async () => ({ projectId: 'default', dataDir: '/tmp/default' }),
|
||||
});
|
||||
|
||||
await server.start(0);
|
||||
|
||||
const response = await fetch(`${server.getBaseUrl()}/assets/pico.min.css`);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
expect(postEngine.setProjectContext).not.toHaveBeenCalled();
|
||||
expect(mediaEngine.setProjectContext).not.toHaveBeenCalled();
|
||||
expect(postMediaEngine.setProjectContext).not.toHaveBeenCalled();
|
||||
expect(settingsEngine.setProjectContext).not.toHaveBeenCalled();
|
||||
expect(menuEngine.setProjectContext).not.toHaveBeenCalled();
|
||||
expect(syncOnStartup).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders tag_cloud macro with normalized tag usage and tag archive links', async () => {
|
||||
const posts = [
|
||||
makePost({
|
||||
|
||||
Reference in New Issue
Block a user