import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' import { setActivePinia, createPinia } from 'pinia' import { useSystemStore } from '../src/stores/system.js' // Which build am I running? Milestone 318 stopped publishing version image // tags, so the instance's own report is the ONLY answer — there is no registry // name left to check it against. That promotes this from a convenience to the // mechanism, and it means the three states below have to stay distinct: a // wrong answer here has nothing to contradict it. // // not asked yet -> render nothing // asked, no version -> render "unknown" // asked, has a version -> render it // // Collapsing the first two would show "unknown" during every page load, and // collapsing either into a blank would read as "no version", which is a // different and false claim. function stubHealth(body, { fail = false } = {}) { globalThis.fetch = vi.fn(async () => { if (fail) throw new Error('network down') return { ok: true, status: 200, statusText: '200', text: async () => JSON.stringify(body), } }) } describe('system store — build identity', () => { beforeEach(() => setActivePinia(createPinia())) afterEach(() => { vi.restoreAllMocks(); delete globalThis.fetch }) it('starts having asked nothing, so the footer renders nothing', () => { const s = useSystemStore() expect(s.buildLoaded).toBe(false) }) it('reports the version and channel the instance claims', async () => { stubHealth({ status: 'ok', version: '2026.08.28.1249', channel: 'dev' }) const s = useSystemStore() await s.refreshHealth() expect(s.buildLoaded).toBe(true) expect(s.buildVersion).toBe('2026.08.28.1249') expect(s.buildChannel).toBe('dev') }) it('keeps the channel OUT of the version string', async () => { // The tempting shortcut is a `-dev` suffix. The extension's comparator // parses each dotted segment with parseInt, so a suffixed segment reads as // 0 and every dev build compares equal to every other — #2993 exactly // (rule 149). If anyone ever "simplifies" by folding them together, the // version stops being the bare derived number and this fails. stubHealth({ status: 'ok', version: '2026.08.28.1249', channel: 'dev' }) const s = useSystemStore() await s.refreshHealth() expect(s.buildVersion).toBe('2026.08.28.1249') expect(s.buildVersion).not.toContain('dev') }) it('treats an absent version as "cannot say", not as a value', async () => { // A locally-built image, or one predating the field. The server omits the // key rather than sending an empty string; `?? ''` must preserve that // rather than inventing something. The view renders "unknown" from it. stubHealth({ status: 'ok' }) const s = useSystemStore() await s.refreshHealth() expect(s.buildLoaded).toBe(true) expect(s.buildVersion).toBe('') expect(s.buildChannel).toBe('') }) it('reports a version with no channel without inventing one', async () => { stubHealth({ status: 'ok', version: '2026.08.28.1249' }) const s = useSystemStore() await s.refreshHealth() expect(s.buildVersion).toBe('2026.08.28.1249') expect(s.buildChannel).toBe('') }) it('does not claim "unknown" when the health call itself failed', async () => { // A network blip says nothing about the build. Marking it loaded here // would present a transient failure as a defective image — and since // nothing else names the build, there would be no second source to // correct the impression. stubHealth(null, { fail: true }) const s = useSystemStore() await s.refreshHealth() expect(s.healthy).toBe(false) expect(s.buildLoaded).toBe(false) }) })