import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { checkForUpdatesViaServer, getUpdateStatus } from '../../upgrade/version-check.js';
const SERVER = 'https://updates.test.example';
function serverPayload() {
    return {
        latestVersion: '0.46.0',
        currentVersion: '0.45.0',
        severity: 'security',
        changelog: [
            {
                version: '0.46.0',
                date: '2026-01-02',
                summary: 'Patch a security issue',
                type: 'security',
            },
        ],
        hasMigrations: true,
        breakingChanges: ['Removed legacy API'],
        pluginCompatibility: [
            { name: '@actuate-media/plugin-seo', compatible: true, minVersion: '0.46.0' },
        ],
        updateCommand: 'npm update ...',
    };
}
function npmPayload(latest = '0.46.0') {
    return {
        'dist-tags': { latest },
        time: { [latest]: '2026-01-02T00:00:00.000Z' },
        versions: { '0.45.0': {}, [latest]: {} },
    };
}
beforeEach(() => {
    process.env.ACTUATE_UPDATE_SERVER_URL = SERVER;
});
afterEach(() => {
    vi.restoreAllMocks();
    delete process.env.ACTUATE_UPDATE_SERVER_URL;
});
describe('checkForUpdatesViaServer', () => {
    it('maps a rich server response into VersionInfo', async () => {
        vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response(JSON.stringify(serverPayload()), { status: 200 }));
        const info = await checkForUpdatesViaServer('0.45.0', SERVER);
        expect(info).not.toBeNull();
        expect(info.updateAvailable).toBe(true);
        expect(info.severity).toBe('security');
        expect(info.hasMigrations).toBe(true);
        expect(info.breakingChanges).toEqual(['Removed legacy API']);
        expect(info.changelog?.[0]?.type).toBe('security');
        expect(info.source).toBe('update-server');
    });
    it('returns null on a non-2xx response (caller falls back)', async () => {
        vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('nope', { status: 503 }));
        expect(await checkForUpdatesViaServer('0.45.0', SERVER)).toBeNull();
    });
    it('returns null on a network error', async () => {
        vi.spyOn(globalThis, 'fetch').mockRejectedValue(new Error('boom'));
        expect(await checkForUpdatesViaServer('0.45.0', SERVER)).toBeNull();
    });
    it('returns null for an unparseable current version', async () => {
        expect(await checkForUpdatesViaServer('garbage', SERVER)).toBeNull();
    });
    it('reports no update when the server says up-to-date', async () => {
        vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response(JSON.stringify({ latestVersion: '0.45.0', currentVersion: '0.45.0', upToDate: true }), {
            status: 200,
        }));
        const info = await checkForUpdatesViaServer('0.45.0', SERVER);
        expect(info.updateAvailable).toBe(false);
    });
});
describe('getUpdateStatus (hybrid)', () => {
    it('prefers the update server when available', async () => {
        vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
            if (String(input).includes(SERVER)) {
                return new Response(JSON.stringify(serverPayload()), { status: 200 });
            }
            throw new Error('npm should not be called');
        });
        const info = await getUpdateStatus('0.45.0');
        expect(info.source).toBe('update-server');
        expect(info.severity).toBe('security');
    });
    it('falls back to the npm registry when the server fails', async () => {
        vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
            const url = String(input);
            if (url.includes(SERVER))
                return new Response('down', { status: 502 });
            if (url.includes('registry.npmjs.org')) {
                return new Response(JSON.stringify(npmPayload('0.46.0')), { status: 200 });
            }
            throw new Error(`unexpected fetch: ${url}`);
        });
        const info = await getUpdateStatus('0.45.0');
        expect(info.source).toBe('npm');
        expect(info.latest).toBe('0.46.0');
        expect(info.updateAvailable).toBe(true);
    });
});
//# sourceMappingURL=version-check.test.js.map