first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import type { ICredentialDataDecryptedObject, IHttpRequestOptions } from 'n8n-workflow';
|
||||
|
||||
import { AnthropicApi } from '../AnthropicApi.credentials';
|
||||
|
||||
describe('AnthropicApi Credential', () => {
|
||||
const anthropicApi = new AnthropicApi();
|
||||
|
||||
it('should have correct properties', () => {
|
||||
expect(anthropicApi.name).toBe('anthropicApi');
|
||||
expect(anthropicApi.displayName).toBe('Anthropic');
|
||||
expect(anthropicApi.documentationUrl).toBe('anthropic');
|
||||
expect(anthropicApi.properties).toHaveLength(5);
|
||||
expect(anthropicApi.test.request.baseURL).toBe('={{$credentials?.url}}');
|
||||
expect(anthropicApi.test.request.url).toBe('/v1/messages');
|
||||
});
|
||||
|
||||
describe('authenticate', () => {
|
||||
it('should add x-api-key header with API key only', async () => {
|
||||
const credentials: ICredentialDataDecryptedObject = {
|
||||
apiKey: 'sk-ant-test123456789',
|
||||
};
|
||||
|
||||
const requestOptions: IHttpRequestOptions = {
|
||||
headers: {},
|
||||
url: '/v1/messages',
|
||||
baseURL: 'https://api.anthropic.com',
|
||||
};
|
||||
|
||||
const result = await anthropicApi.authenticate(credentials, requestOptions);
|
||||
|
||||
expect(result.headers).toEqual({
|
||||
'x-api-key': 'sk-ant-test123456789',
|
||||
});
|
||||
});
|
||||
|
||||
it('should add custom header when header toggle is enabled', async () => {
|
||||
const credentials: ICredentialDataDecryptedObject = {
|
||||
apiKey: 'sk-ant-test123456789',
|
||||
header: true,
|
||||
headerName: 'X-Custom-Header',
|
||||
headerValue: 'custom-value-123',
|
||||
};
|
||||
|
||||
const requestOptions: IHttpRequestOptions = {
|
||||
headers: {},
|
||||
url: '/v1/messages',
|
||||
baseURL: 'https://api.anthropic.com',
|
||||
};
|
||||
|
||||
const result = await anthropicApi.authenticate(credentials, requestOptions);
|
||||
|
||||
expect(result.headers).toEqual({
|
||||
'x-api-key': 'sk-ant-test123456789',
|
||||
'X-Custom-Header': 'custom-value-123',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not add custom header when header toggle is disabled', async () => {
|
||||
const credentials: ICredentialDataDecryptedObject = {
|
||||
apiKey: 'sk-ant-test123456789',
|
||||
header: false,
|
||||
headerName: 'X-Custom-Header',
|
||||
headerValue: 'custom-value-123',
|
||||
};
|
||||
|
||||
const requestOptions: IHttpRequestOptions = {
|
||||
headers: {},
|
||||
url: '/v1/messages',
|
||||
baseURL: 'https://api.anthropic.com',
|
||||
};
|
||||
|
||||
const result = await anthropicApi.authenticate(credentials, requestOptions);
|
||||
|
||||
expect(result.headers).toEqual({
|
||||
'x-api-key': 'sk-ant-test123456789',
|
||||
});
|
||||
expect(result.headers?.['X-Custom-Header']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should preserve existing headers', async () => {
|
||||
const credentials: ICredentialDataDecryptedObject = {
|
||||
apiKey: 'sk-ant-test123456789',
|
||||
header: true,
|
||||
headerName: 'X-Custom-Header',
|
||||
headerValue: 'custom-value-123',
|
||||
};
|
||||
|
||||
const requestOptions: IHttpRequestOptions = {
|
||||
url: '/v1/messages',
|
||||
baseURL: 'https://api.anthropic.com',
|
||||
};
|
||||
|
||||
const result = await anthropicApi.authenticate(credentials, requestOptions);
|
||||
|
||||
const raw =
|
||||
typeof (result.headers as any)?.get === 'function'
|
||||
? Object.fromEntries((result.headers as unknown as Headers).entries())
|
||||
: (result.headers as Record<string, string | undefined>);
|
||||
|
||||
const headers = Object.fromEntries(Object.entries(raw).map(([k, v]) => [k.toLowerCase(), v]));
|
||||
|
||||
expect(headers).toEqual(
|
||||
expect.objectContaining({
|
||||
'x-api-key': 'sk-ant-test123456789',
|
||||
'x-custom-header': 'custom-value-123',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should preserve existing headers when adding auth headers', async () => {
|
||||
const credentials: ICredentialDataDecryptedObject = {
|
||||
apiKey: 'sk-ant-test123456789',
|
||||
};
|
||||
|
||||
const requestOptions: IHttpRequestOptions = {
|
||||
headers: {
|
||||
'anthropic-version': '2023-06-01',
|
||||
},
|
||||
url: '/v1/messages',
|
||||
baseURL: 'https://api.anthropic.com',
|
||||
};
|
||||
|
||||
const result = await anthropicApi.authenticate(credentials, requestOptions);
|
||||
|
||||
expect(result.headers).toEqual({
|
||||
'anthropic-version': '2023-06-01',
|
||||
'x-api-key': 'sk-ant-test123456789',
|
||||
});
|
||||
});
|
||||
|
||||
it('should preserve existing headers even with custom header option enabled', async () => {
|
||||
const credentials: ICredentialDataDecryptedObject = {
|
||||
apiKey: 'sk-ant-test123456789',
|
||||
header: true,
|
||||
headerName: 'X-Additional-Header',
|
||||
headerValue: 'additional-value',
|
||||
};
|
||||
|
||||
const requestOptions: IHttpRequestOptions = {
|
||||
headers: {
|
||||
'anthropic-version': '2023-06-01',
|
||||
'X-Existing-Header': 'existing-value',
|
||||
},
|
||||
url: '/v1/messages',
|
||||
baseURL: 'https://api.anthropic.com',
|
||||
};
|
||||
|
||||
const result = await anthropicApi.authenticate(credentials, requestOptions);
|
||||
|
||||
expect(result.headers).toEqual({
|
||||
'anthropic-version': '2023-06-01',
|
||||
'X-Existing-Header': 'existing-value',
|
||||
'x-api-key': 'sk-ant-test123456789',
|
||||
'X-Additional-Header': 'additional-value',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { ChromaCloudApi } from '../ChromaCloudApi.credentials';
|
||||
|
||||
describe('ChromaCloudApi Credential', () => {
|
||||
const chromaCloudApi = new ChromaCloudApi();
|
||||
|
||||
it('should have correct properties', () => {
|
||||
expect(chromaCloudApi.name).toBe('chromaCloudApi');
|
||||
expect(chromaCloudApi.displayName).toBe('ChromaDB Cloud');
|
||||
expect(chromaCloudApi.documentationUrl).toBe('chroma');
|
||||
expect(chromaCloudApi.properties).toHaveLength(4);
|
||||
|
||||
const baseUrlProp = chromaCloudApi.properties.find((p) => p.name === 'baseUrl');
|
||||
expect(baseUrlProp).toBeDefined();
|
||||
expect(baseUrlProp?.default).toBe('https://api.trychroma.com');
|
||||
expect(baseUrlProp?.required).toBe(true);
|
||||
|
||||
expect(chromaCloudApi.test.request.baseURL).toBe('={{$credentials.baseUrl}}');
|
||||
expect(chromaCloudApi.test.request.url).toBe('/api/v2');
|
||||
});
|
||||
|
||||
it('should have correct authentication', () => {
|
||||
expect(chromaCloudApi.authenticate).toBeDefined();
|
||||
expect(chromaCloudApi.authenticate.type).toBe('generic');
|
||||
expect((chromaCloudApi.authenticate.properties as any).headers).toBeDefined();
|
||||
expect((chromaCloudApi.authenticate.properties as any).headers['x-chroma-token']).toBe(
|
||||
'={{$credentials.apiKey}}',
|
||||
);
|
||||
});
|
||||
const chromaCloudApi2 = new ChromaCloudApi();
|
||||
it('should use changed baseUrl in test request when property is modified', () => {
|
||||
const customBaseUrl = 'https://custom.chroma.example.com';
|
||||
|
||||
const baseUrlProp = chromaCloudApi2.properties.find((p) => p.name === 'baseUrl');
|
||||
expect(baseUrlProp).toBeDefined();
|
||||
baseUrlProp!.default = customBaseUrl;
|
||||
|
||||
expect(baseUrlProp!.default).toBe(customBaseUrl);
|
||||
|
||||
const baseURLExpression = chromaCloudApi2.test.request.baseURL;
|
||||
expect(baseURLExpression).toBe('={{$credentials.baseUrl}}');
|
||||
|
||||
const credentials = { baseUrl: baseUrlProp!.default };
|
||||
const resolvedBaseURL = baseURLExpression?.replace(
|
||||
/=\{\{\$credentials\.(\w+)\}\}/,
|
||||
(_, key) => credentials[key as keyof typeof credentials],
|
||||
);
|
||||
expect(resolvedBaseURL).toBe(customBaseUrl);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user