Files
Supra4E8C ebb5b7d0c0 Refactor provider credential weight normalization tests and update API key structure
- Updated test cases in `providerWeightTransformers.test.ts` to reflect changes in API key structure from 'api-key-entries' to 'keys'.
- Introduced new tests in `providerWorkbenchUi.test.ts` to verify the editing surface of provider workbench.
- Modified `sponsorCustomEndpoint.test.ts` to adapt to the new API key structure.
- Adjusted `visualConfigAntigravitySensitiveWords.test.ts` and `visualConfigConcurrency.test.ts` to accommodate new YAML structure for sensitive words and concurrency settings.
- Enhanced `visualConfigDefaults.test.ts` to ensure proper handling of boolean defaults and YAML structure.
- Updated `visualConfigDevinSensitiveWords.test.ts` to reflect changes in the YAML structure for sensitive words.
- Refined `visualConfigDisableImageGeneration.test.ts` to align with new multimedia settings.
- Added comprehensive tests in `visualConfigV8.test.ts` to validate the v8 visual config contract and ensure scalar read/write path parity.
- Improved validation tests in `visualConfigValidation.test.ts` to handle new routing and requests structure.
- Cleaned up `xaiApiKeyProvider.test.ts` by removing unnecessary API client mocks and focusing on normalization of the xAI API key contract.
2026-09-28 12:55:16 +08:00

108 lines
3.8 KiB
TypeScript

import { describe, expect, spyOn, test } from 'bun:test';
import { apiClient } from '@/services/api/client';
import { oauthApi, type BuiltInOAuthProvider } from '@/services/api/oauth';
describe('Devin Management OAuth v8 contract', () => {
test('starts a built-in Devin flow with web UI mode', async () => {
const provider: BuiltInOAuthProvider = 'devin';
const response = {
status: 'ok',
url: 'https://app.devin.ai/auth/cli/continue',
state: 'test-state',
};
const get = spyOn(apiClient, 'get').mockResolvedValue(response);
try {
expect(await oauthApi.startAuth(provider)).toEqual(response);
expect(get).toHaveBeenCalledWith('/oauth/auth-url', {
params: { provider: 'devin', is_webui: true },
});
} finally {
get.mockRestore();
}
});
test('submits the complete remote callback without rewriting its port or TLS mode', async () => {
const post = spyOn(apiClient, 'post').mockResolvedValue({ status: 'ok' });
const redirectUrl = 'https://127.0.0.1:9443/devin/callback?code=fixture-code&state=test-state';
try {
await oauthApi.submitCallback('devin', redirectUrl);
expect(post).toHaveBeenCalledWith(
'/oauth/callback',
{ provider: 'devin', redirect_url: redirectUrl },
undefined
);
} finally {
post.mockRestore();
}
});
test('polls using only the original attempt state', async () => {
const get = spyOn(apiClient, 'get').mockResolvedValue({ status: 'wait' });
try {
expect(await oauthApi.getAuthStatus('test-state')).toEqual({ status: 'wait' });
expect(get).toHaveBeenCalledWith('/oauth/status', { params: { state: 'test-state' } });
} finally {
get.mockRestore();
}
});
for (const cancelled of [true, false]) {
test(`preserves the server cancellation result (${cancelled})`, async () => {
const remove = spyOn(apiClient, 'delete').mockResolvedValue({ status: 'ok', cancelled });
try {
expect(await oauthApi.cancelSession('test-state')).toEqual({ status: 'ok', cancelled });
expect(remove).toHaveBeenCalledWith('/oauth/session', { params: { state: 'test-state' } });
} finally {
remove.mockRestore();
}
});
}
test('forwards attempt abort signals to every OAuth request', async () => {
const signal = new AbortController().signal;
const get = spyOn(apiClient, 'get').mockResolvedValue({});
const post = spyOn(apiClient, 'post').mockResolvedValue({});
const remove = spyOn(apiClient, 'delete').mockResolvedValue({});
try {
await oauthApi.startAuth('devin', signal);
expect(get).toHaveBeenLastCalledWith('/oauth/auth-url', {
params: { provider: 'devin', is_webui: true },
signal,
});
await oauthApi.getAuthStatus('test-state', signal);
expect(get).toHaveBeenLastCalledWith('/oauth/status', {
params: { state: 'test-state' },
signal,
});
await oauthApi.submitCallback('devin', 'fixture-callback', signal);
expect(post).toHaveBeenCalledWith(
'/oauth/callback',
{
provider: 'devin',
redirect_url: 'fixture-callback',
},
{ signal }
);
await oauthApi.cancelSession('test-state', signal);
expect(remove).toHaveBeenCalledWith('/oauth/session', {
params: { state: 'test-state' },
signal,
});
} finally {
get.mockRestore();
post.mockRestore();
remove.mockRestore();
}
});
test('propagates cancellation failures instead of claiming success', async () => {
const error = new Error('connection lost');
const remove = spyOn(apiClient, 'delete').mockRejectedValue(error);
try {
await expect(oauthApi.cancelSession('test-state')).rejects.toBe(error);
} finally {
remove.mockRestore();
}
});
});