import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' import { setActivePinia, createPinia } from 'pinia' import { useGalleryStore } from '../src/stores/gallery.js' function stubFetch(handler) { globalThis.fetch = vi.fn(async (url, init) => { const { status, body } = handler(url, init) return { ok: status >= 200 && status < 300, status, statusText: String(status), text: async () => (body == null ? '' : JSON.stringify(body)) } }) } const EMPTY = { images: [], date_groups: [], next_cursor: null } describe('gallery store: tag/post filter exclusivity', () => { beforeEach(() => setActivePinia(createPinia())) afterEach(() => vi.restoreAllMocks()) it('setPostFilter sets post_id and clears tag_id', () => { const s = useGalleryStore() stubFetch(() => ({ status: 200, body: EMPTY })) s.setTagFilter(3) expect(s.filter.tag_id).toBe(3) s.setPostFilter(7) expect(s.filter.post_id).toBe(7) expect(s.filter.tag_id).toBe(null) }) it('setTagFilter clears post_id', () => { const s = useGalleryStore() stubFetch(() => ({ status: 200, body: EMPTY })) s.setPostFilter(7) s.setTagFilter(3) expect(s.filter.tag_id).toBe(3) expect(s.filter.post_id).toBe(null) }) it('loadMore sends exactly the active filter param', async () => { const s = useGalleryStore() const urls = [] stubFetch((url) => { urls.push(url); return { status: 200, body: EMPTY } }) s.setPostFilter(7) await s.loadMore() const scrollCall = urls.filter(u => u.includes('/api/gallery/scroll')).pop() expect(scrollCall).toContain('post_id=7') expect(scrollCall).not.toContain('tag_id=') }) })