diff --git a/web/src/lib/stores/folders.svelte.spec.ts b/web/src/lib/stores/folders.svelte.spec.ts new file mode 100644 index 0000000000..50e759966f --- /dev/null +++ b/web/src/lib/stores/folders.svelte.spec.ts @@ -0,0 +1,42 @@ +import { foldersStore } from '$lib/stores/folders.svelte'; +import { getUniqueOriginalPaths } from '@immich/sdk'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +vi.mock('$lib/managers/event-manager.svelte', () => ({ + eventManager: { + on: vi.fn(), + }, +})); + +vi.mock('@immich/sdk', () => ({ + getAssetsByOriginalPath: vi.fn(), + getUniqueOriginalPaths: vi.fn(), +})); + +describe('foldersStore', () => { + beforeEach(() => { + foldersStore.clearCache(); + vi.clearAllMocks(); + }); + + it('returns the same non-null tree for concurrent fetchTree calls', async () => { + let resolvePaths: (value: string[]) => void; + + vi.mocked(getUniqueOriginalPaths).mockReturnValue( + new Promise((resolve) => { + resolvePaths = resolve; + }), + ); + + const first = foldersStore.fetchTree(); + const second = foldersStore.fetchTree(); + + resolvePaths!(['/photos/2026']); + + const [firstTree, secondTree] = await Promise.all([first, second]); + + expect(firstTree).not.toBeNull(); + expect(secondTree).not.toBeNull(); + expect(secondTree).toEqual(firstTree); + }); +}); diff --git a/web/src/lib/stores/folders.svelte.ts b/web/src/lib/stores/folders.svelte.ts index 3adebf51f9..0408b15f23 100644 --- a/web/src/lib/stores/folders.svelte.ts +++ b/web/src/lib/stores/folders.svelte.ts @@ -28,10 +28,9 @@ class FoldersStore { if (this.initialized) { return this.folders!; } - this.initialized = true; - this.folders = TreeNode.fromPaths(await getUniqueOriginalPaths()); this.folders.collapse(); + this.initialized = true; return this.folders; }