Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/byok/node/test/azureOpenAIEndpoint.spec.ts
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
7
import { IChatModelInformation, ModelSupportedEndpoint } from '../../../../platform/endpoint/common/endpointProvider';
8
import { ITestingServicesAccessor } from '../../../../platform/test/node/services';
9
import { TokenizerType } from '../../../../util/common/tokenizer';
10
import { DisposableStore } from '../../../../util/vs/base/common/lifecycle';
11
import { IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation';
12
import { createExtensionUnitTestingServices } from '../../../test/node/services';
13
import { AzureOpenAIEndpoint } from '../azureOpenAIEndpoint';
14
15
describe('AzureOpenAIEndpoint', () => {
16
let modelMetadata: IChatModelInformation;
17
const disposables = new DisposableStore();
18
let accessor: ITestingServicesAccessor;
19
let instaService: IInstantiationService;
20
21
beforeEach(() => {
22
modelMetadata = {
23
id: 'test-azure-model',
24
vendor: 'Microsoft Azure',
25
name: 'Test Azure Model',
26
version: '1.0',
27
model_picker_enabled: true,
28
is_chat_default: false,
29
is_chat_fallback: false,
30
supported_endpoints: [ModelSupportedEndpoint.ChatCompletions],
31
capabilities: {
32
type: 'chat',
33
family: 'openai',
34
tokenizer: TokenizerType.O200K,
35
supports: {
36
parallel_tool_calls: false,
37
streaming: true,
38
tool_calls: false,
39
vision: false,
40
prediction: false,
41
thinking: false
42
},
43
limits: {
44
max_prompt_tokens: 128000,
45
max_output_tokens: 4096,
46
max_context_window_tokens: 132096
47
}
48
}
49
};
50
51
const testingServiceCollection = createExtensionUnitTestingServices();
52
accessor = disposables.add(testingServiceCollection.createTestingAccessor());
53
instaService = accessor.get(IInstantiationService);
54
});
55
56
afterEach(() => {
57
disposables.clear();
58
});
59
60
describe('getExtraHeaders', () => {
61
it('should use Authorization header with Bearer token for Entra ID authentication', () => {
62
const entraToken = 'test-entra-token-abc123';
63
const endpoint = instaService.createInstance(
64
AzureOpenAIEndpoint,
65
modelMetadata,
66
entraToken,
67
'https://example-endpoint.example.com/v1/chat/completions'
68
);
69
const headers = endpoint.getExtraHeaders();
70
71
// Should have Authorization header with Bearer token
72
expect(headers['Authorization']).toBe(`Bearer ${entraToken}`);
73
74
// Should NOT have api-key header (Azure API key auth)
75
expect(headers['api-key']).toBeUndefined();
76
77
// Should have standard headers
78
expect(headers['Content-Type']).toBe('application/json');
79
});
80
81
it('should override parent class headers to replace api-key with Authorization', () => {
82
const entraToken = 'test-entra-token-xyz789';
83
const endpoint = instaService.createInstance(
84
AzureOpenAIEndpoint,
85
modelMetadata,
86
entraToken,
87
'https://example-endpoint.example.com/v1/chat/completions'
88
);
89
const headers = endpoint.getExtraHeaders();
90
91
// Verify the override worked correctly
92
expect(headers['Authorization']).toBe(`Bearer ${entraToken}`);
93
expect(headers['api-key']).toBeUndefined();
94
expect(Object.keys(headers)).not.toContain('api-key');
95
});
96
97
it('should work with different Azure OpenAI endpoint URLs', () => {
98
const entraToken = 'test-token-456';
99
100
// Test with different endpoint formats
101
const urls = [
102
'https://example-endpoint-1.example.com/v1/chat/completions',
103
'https://example-endpoint-2.example.com/v1/chat/completions',
104
'https://example-endpoint-3.example.com/v1/chat/completions'
105
];
106
107
for (const url of urls) {
108
const endpoint = instaService.createInstance(
109
AzureOpenAIEndpoint,
110
modelMetadata,
111
entraToken,
112
url
113
);
114
115
const headers = endpoint.getExtraHeaders();
116
117
expect(headers['Authorization']).toBe(`Bearer ${entraToken}`);
118
expect(headers['api-key']).toBeUndefined();
119
}
120
});
121
122
it('should preserve other headers from parent class', () => {
123
const entraToken = 'test-token-789';
124
const endpoint = instaService.createInstance(
125
AzureOpenAIEndpoint,
126
modelMetadata,
127
entraToken,
128
'https://example-endpoint.example.com/v1/chat/completions'
129
);
130
131
const headers = endpoint.getExtraHeaders();
132
133
// Should preserve Content-Type from parent
134
expect(headers['Content-Type']).toBe('application/json');
135
136
// Should have Authorization header
137
expect(headers['Authorization']).toBeDefined();
138
expect(headers['Authorization']).toContain('Bearer');
139
});
140
});
141
142
describe('inheritance', () => {
143
it('should inherit from OpenAIEndpoint and maintain same constructor signature', () => {
144
const entraToken = 'test-token-inheritance';
145
146
// Should be able to instantiate with same parameters as OpenAIEndpoint
147
const endpoint = instaService.createInstance(
148
AzureOpenAIEndpoint,
149
modelMetadata,
150
entraToken,
151
'https://example-endpoint.example.com/v1/chat/completions'
152
);
153
154
// Should be an instance of AzureOpenAIEndpoint
155
expect(endpoint).toBeInstanceOf(AzureOpenAIEndpoint);
156
157
// Should have getExtraHeaders method
158
expect(typeof endpoint.getExtraHeaders).toBe('function');
159
});
160
});
161
});
162
163