// @vitest-environment happy-dom import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { flushPromises } from '@vue/test-utils' import RelatedStrip from '../../src/components/modal/RelatedStrip.vue' import { useModalStore } from '../../src/stores/modal.js' import { freshPinia, mountComponent } from '../support/mountComponent.js' function stubFetch(handler) { globalThis.fetch = vi.fn(async (url) => { const { status, body } = handler(url) return { ok: status >= 200 && status < 300, status, statusText: String(status), text: async () => JSON.stringify(body), } }) } describe('RelatedStrip (modal "more like this")', () => { beforeEach(() => vi.useFakeTimers()) afterEach(() => { vi.useRealTimers(); vi.restoreAllMocks() }) it('stays hidden and never fetches when the image has no embedding', async () => { const pinia = freshPinia() useModalStore().current = { id: 1, has_embedding: false } const fetchSpy = vi.fn() globalThis.fetch = fetchSpy const w = mountComponent(RelatedStrip, { pinia }) await vi.advanceTimersByTimeAsync(500) expect(fetchSpy).not.toHaveBeenCalled() expect(w.find('.fc-related').exists()).toBe(false) }) it('deferred-fetches and renders similar thumbs for an embedded image', async () => { const pinia = freshPinia() useModalStore().current = { id: 1, has_embedding: true } stubFetch(() => ({ status: 200, body: { images: [{ id: 2, thumbnail_url: '/t2' }, { id: 3, thumbnail_url: '/t3' }] }, })) const w = mountComponent(RelatedStrip, { pinia }) // Nothing before the defer elapses (modal image gets priority). expect(globalThis.fetch).not.toHaveBeenCalled() await vi.advanceTimersByTimeAsync(250) await flushPromises() expect(globalThis.fetch).toHaveBeenCalledTimes(1) expect(w.findAll('.fc-related__item').length).toBe(2) }) it('collapses silently when the similar fetch returns nothing', async () => { const pinia = freshPinia() useModalStore().current = { id: 1, has_embedding: true } stubFetch(() => ({ status: 200, body: { images: [] } })) const w = mountComponent(RelatedStrip, { pinia }) await vi.advanceTimersByTimeAsync(250) await flushPromises() expect(w.find('.fc-related').exists()).toBe(false) }) it('clicking a thumb opens that image in the modal', async () => { const pinia = freshPinia() const modal = useModalStore() modal.current = { id: 1, has_embedding: true } const openSpy = vi.spyOn(modal, 'open').mockResolvedValue() stubFetch(() => ({ status: 200, body: { images: [{ id: 7, thumbnail_url: '/t7' }] } })) const w = mountComponent(RelatedStrip, { pinia }) await vi.advanceTimersByTimeAsync(250) await flushPromises() await w.find('.fc-related__item').trigger('click') expect(openSpy).toHaveBeenCalledWith(7) }) })