import { describe, it, expect, vi } from 'vitest';
import { checkSetupRequired, createInitialAdmin, isDatabaseUnavailableError, isSchemaMissingError, } from '../../setup/index.js';
function connectionError(code) {
    const err = new Error(`Can't reach database server`);
    err.code = code;
    return err;
}
function schemaMissingError() {
    const err = new Error('The table `public.actuate_users` does not exist in the current database.');
    err.code = 'P2021';
    return err;
}
describe('isDatabaseUnavailableError', () => {
    it('detects Prisma connection codes', () => {
        expect(isDatabaseUnavailableError(connectionError('P1001'))).toBe(true);
        expect(isDatabaseUnavailableError(connectionError('ECONNREFUSED'))).toBe(true);
    });
    it('detects PrismaClientInitializationError by name', () => {
        const err = new Error('init failed');
        err.name = 'PrismaClientInitializationError';
        expect(isDatabaseUnavailableError(err)).toBe(true);
    });
    it('detects connection failures by message', () => {
        expect(isDatabaseUnavailableError(new Error("Can't reach database server at db:5432"))).toBe(true);
    });
    it('does not flag ordinary errors', () => {
        expect(isDatabaseUnavailableError(new Error('something else'))).toBe(false);
        expect(isDatabaseUnavailableError(null)).toBe(false);
        expect(isDatabaseUnavailableError('nope')).toBe(false);
    });
});
describe('checkSetupRequired', () => {
    it('reports setupRequired when the users table is empty', async () => {
        const db = { user: { count: vi.fn().mockResolvedValue(0) } };
        await expect(checkSetupRequired(db)).resolves.toEqual({ setupRequired: true, userCount: 0 });
    });
    it('reports not-required when users exist', async () => {
        const db = { user: { count: vi.fn().mockResolvedValue(3) } };
        await expect(checkSetupRequired(db)).resolves.toEqual({ setupRequired: false, userCount: 3 });
    });
    it('rethrows connection failures instead of masking them as setup-required', async () => {
        const db = { user: { count: vi.fn().mockRejectedValue(connectionError('ECONNREFUSED')) } };
        await expect(checkSetupRequired(db)).rejects.toThrow(/reach database/i);
    });
    it('still treats unknown non-connection errors as setup-required', async () => {
        const db = { user: { count: vi.fn().mockRejectedValue(new Error('table missing')) } };
        await expect(checkSetupRequired(db)).resolves.toEqual({ setupRequired: true, userCount: 0 });
    });
    it('reports migrationsRequired when the tables do not exist yet', async () => {
        const db = { user: { count: vi.fn().mockRejectedValue(schemaMissingError()) } };
        await expect(checkSetupRequired(db)).resolves.toEqual({
            setupRequired: false,
            userCount: 0,
            migrationsRequired: true,
        });
    });
});
describe('isSchemaMissingError', () => {
    it('detects Prisma P2021/P2022 codes', () => {
        expect(isSchemaMissingError(schemaMissingError())).toBe(true);
        const colErr = new Error('column missing');
        colErr.code = 'P2022';
        expect(isSchemaMissingError(colErr)).toBe(true);
    });
    it('detects table-missing errors by message', () => {
        expect(isSchemaMissingError(new Error('relation "actuate_users" does not exist'))).toBe(true);
    });
    it('does not flag connection errors or ordinary errors', () => {
        expect(isSchemaMissingError(connectionError('P1001'))).toBe(false);
        expect(isSchemaMissingError(new Error('something else'))).toBe(false);
        expect(isSchemaMissingError(null)).toBe(false);
    });
});
describe('createInitialAdmin', () => {
    const validInput = {
        name: 'Admin',
        email: 'Admin@Example.com',
        password: 'a-very-strong-password',
    };
    it('rejects passwords shorter than 12 characters', async () => {
        const db = {};
        const result = await createInitialAdmin(db, { ...validInput, password: 'short' });
        expect(result).toEqual({ success: false, error: 'Password must be at least 12 characters' });
    });
    it('rethrows connection failures so the route can return a 5xx, not a 400', async () => {
        const db = {
            $transaction: vi.fn().mockRejectedValue(connectionError('P1001')),
        };
        await expect(createInitialAdmin(db, validInput)).rejects.toThrow(/reach database/i);
    });
    it('rethrows schema-missing errors so the route can prompt for migrations', async () => {
        const db = {
            $transaction: vi.fn().mockRejectedValue(schemaMissingError()),
        };
        await expect(createInitialAdmin(db, validInput)).rejects.toThrow(/does not exist/i);
    });
    it('returns a friendly error when setup was already completed', async () => {
        const db = {
            $transaction: vi.fn(async (fn) => fn({ user: { count: vi.fn().mockResolvedValue(1) } })),
        };
        const result = await createInitialAdmin(db, validInput);
        expect(result.success).toBe(false);
        expect(result.error).toMatch(/already completed/i);
    });
    it('creates the admin (normalizing email) when the database is empty', async () => {
        const create = vi.fn().mockResolvedValue({ id: 'user_1' });
        const db = {
            $transaction: vi.fn(async (fn) => fn({ user: { count: vi.fn().mockResolvedValue(0), create } })),
        };
        const result = await createInitialAdmin(db, validInput);
        expect(result).toEqual({ success: true, userId: 'user_1' });
        expect(create).toHaveBeenCalledWith(expect.objectContaining({
            data: expect.objectContaining({ email: 'admin@example.com', role: 'ADMIN' }),
        }));
    });
});
//# sourceMappingURL=index.test.js.map