Files
makelore/tests/unit/coding-provider-auth.test.ts

75 lines
2.8 KiB
TypeScript

// @vitest-environment node
import { beforeEach, describe, expect, it, vi } from 'vitest';
const mocks = vi.hoisted(() => ({
getAccount: vi.fn(),
updateAccount: vi.fn(),
resolveCredential: vi.fn(),
getFreshCredential: vi.fn(),
markExpired: vi.fn(),
}));
vi.mock('../../electron/services/providers/provider-service', () => ({
getProviderService: () => ({
getAccount: mocks.getAccount,
updateAccount: mocks.updateAccount,
}),
}));
vi.mock('../../electron/coding-runtime/pi/provider-config', async (importOriginal) => ({
...await importOriginal<typeof import('../../electron/coding-runtime/pi/provider-config')>(),
resolvePiProviderCredentialFromSecretStore: mocks.resolveCredential,
}));
vi.mock('../../electron/services/works-square-ai-gateway', () => ({
getFreshWorksSquareAIGatewayCredential: mocks.getFreshCredential,
markWorksSquareAIGatewayCredentialExpired: mocks.markExpired,
}));
import {
CodingProviderCredentialRefreshError,
isCodingProviderAuthenticationError,
refreshCodingProviderCredential,
} from '../../electron/api/coding-provider-auth';
import { PiProviderConfigError } from '../../electron/coding-runtime/pi/provider-config';
describe('coding Provider credential refresh boundary', () => {
beforeEach(() => {
for (const mock of Object.values(mocks)) mock.mockReset();
});
it('types a rejected production refresh callback as an authentication failure', async () => {
mocks.getAccount.mockRejectedValueOnce(new Error('secure store unavailable'));
const failure = await refreshCodingProviderCredential('account-a').catch((error) => error);
expect(failure).toBeInstanceOf(CodingProviderCredentialRefreshError);
expect(isCodingProviderAuthenticationError(failure)).toBe(true);
});
it('types a missing refreshed Works credential as an authentication failure', async () => {
mocks.getAccount.mockResolvedValueOnce({
id: 'account-works',
enabled: true,
authMode: 'api_key',
metadata: { worksSquareCredentialMode: 'works_square_ai_gateway' },
});
mocks.getFreshCredential.mockResolvedValueOnce(null);
const failure = await refreshCodingProviderCredential('account-works').catch((error) => error);
expect(mocks.markExpired).toHaveBeenCalledTimes(1);
expect(failure).toBeInstanceOf(CodingProviderCredentialRefreshError);
expect(isCodingProviderAuthenticationError(failure)).toBe(true);
expect(mocks.updateAccount).not.toHaveBeenCalled();
});
it('classifies only the typed missing Provider credential as authentication-required', () => {
expect(isCodingProviderAuthenticationError(
new PiProviderConfigError('PROVIDER_AUTH_REQUIRED', 'Provider credential is unavailable'),
)).toBe(true);
expect(isCodingProviderAuthenticationError(
new PiProviderConfigError('PROVIDER_INVALID', 'Provider configuration is invalid'),
)).toBe(false);
});
});