import { GraphQLError } from 'graphql';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { encryptCredential } from '../../helpers/encryption.js';
import { ProviderCredentialsProvider } from '../provider-credentials.provider.js';
const TEST_KEY = 'a'.repeat(64);
const env = { credentialsEncryptionKey: TEST_KEY };
describe('ProviderCredentialsProvider', () => {
    let provider;
    let db;
    beforeEach(() => {
        db = {
            pool: { query: vi.fn() },
            healthCheck: vi.fn(),
            query: vi.fn(),
        };
        provider = new ProviderCredentialsProvider(db, env);
    });
    describe('setCredentials', () => {
        it('calls db.query once with INSERT and provider_credentials; payload is encrypted', async () => {
            db.query.mockResolvedValue({ rows: [], rowCount: 0 });
            const validPayload = { id: 'my-id', secret: 'my-secret' };
            await provider.setCredentials('green_invoice', validPayload);
            expect(db.query).toHaveBeenCalledTimes(1);
            const [sql, params] = db.query.mock.calls[0];
            expect(sql).toMatch(/INSERT/i);
            expect(sql).toMatch(/provider_credentials/i);
            // The encrypted blob should not equal the plaintext
            expect(params[1]).not.toContain('my-secret');
        });
        it('throws GraphQLError BAD_USER_INPUT and does not call db.query when payload is invalid', async () => {
            await expect(provider.setCredentials('green_invoice', { id: '' })).rejects.toThrow(GraphQLError);
            let thrownError;
            try {
                await provider.setCredentials('green_invoice', { id: '' });
            }
            catch (err) {
                thrownError = err;
            }
            expect(thrownError?.extensions?.code).toBe('BAD_USER_INPUT');
            expect(db.query).not.toHaveBeenCalled();
        });
    });
    describe('getProviderStatuses', () => {
        it('returns array of { provider, configuredAt } without payload field', async () => {
            const now = new Date();
            db.query.mockResolvedValue({
                rows: [
                    { provider: 'green_invoice', updated_at: now },
                    { provider: 'deel', updated_at: now },
                ],
                rowCount: 2,
            });
            const statuses = await provider.getProviderStatuses();
            expect(statuses).toHaveLength(2);
            expect(statuses[0]).toEqual({ provider: 'green_invoice', configuredAt: now.toISOString() });
            expect(statuses[1]).toEqual({ provider: 'deel', configuredAt: now.toISOString() });
            for (const s of statuses) {
                expect(s).not.toHaveProperty('payload');
            }
        });
    });
    describe('getGreenInvoiceCredentials', () => {
        it('returns null when no row exists', async () => {
            db.query.mockResolvedValue({
                rows: [],
                rowCount: 0,
            });
            const result = await provider.getGreenInvoiceCredentials();
            expect(result).toBeNull();
        });
        it('returns decrypted payload when a valid encrypted row exists', async () => {
            const original = { id: 'gi-id', secret: 'gi-secret' };
            const blob = encryptCredential(JSON.stringify(original), TEST_KEY);
            db.query.mockResolvedValue({
                rows: [{ payload: blob }],
                rowCount: 1,
            });
            const result = await provider.getGreenInvoiceCredentials();
            expect(result).toEqual(original);
        });
    });
    describe('deleteCredentials', () => {
        it('calls db.query with a DELETE statement', async () => {
            db.query.mockResolvedValue({ rows: [], rowCount: 1 });
            await provider.deleteCredentials('deel');
            expect(db.query).toHaveBeenCalledTimes(1);
            const [sql] = db.query.mock.calls[0];
            expect(sql).toMatch(/DELETE/i);
        });
    });
});
//# sourceMappingURL=provider-credentials.provider.test.js.map