Skip to content

Commit 5a9de1c

Browse files
Relocate tests under /test (#1220)
1 parent 7655eeb commit 5a9de1c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+630
-524
lines changed

docs/client.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Examples:
5151
- [`simpleOAuthClient.ts`](../src/examples/client/simpleOAuthClient.ts)
5252
- [`simpleOAuthClientProvider.ts`](../src/examples/client/simpleOAuthClientProvider.ts)
5353
- [`simpleClientCredentials.ts`](../src/examples/client/simpleClientCredentials.ts)
54-
- Server-side auth demo: [`demoInMemoryOAuthProvider.ts`](../src/examples/server/demoInMemoryOAuthProvider.ts)
54+
- Server-side auth demo: [`demoInMemoryOAuthProvider.ts`](../src/examples/server/demoInMemoryOAuthProvider.ts) (tests live under `test/examples/server/demoInMemoryOAuthProvider.test.ts`)
5555

5656
These examples show how to:
5757

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/client/auth-extensions.test.ts renamed to test/client/auth-extensions.test.ts

Lines changed: 53 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,16 @@
11
import { describe, it, expect } from 'vitest';
2-
import { auth } from './auth.js';
2+
import { auth } from '../../src/client/auth.js';
33
import {
44
ClientCredentialsProvider,
55
PrivateKeyJwtProvider,
66
StaticPrivateKeyJwtProvider,
77
createPrivateKeyJwtAuth
8-
} from './auth-extensions.js';
9-
import type { FetchLike } from '../shared/transport.js';
8+
} from '../../src/client/auth-extensions.js';
9+
import { createMockOAuthFetch } from '../helpers/oauth.js';
1010

1111
const RESOURCE_SERVER_URL = 'https://resource.example.com/';
1212
const AUTH_SERVER_URL = 'https://auth.example.com';
1313

14-
function createMockFetch(onTokenRequest?: (url: URL, init: RequestInit | undefined) => void | Promise<void>): FetchLike {
15-
return async (input: string | URL, init?: RequestInit): Promise<Response> => {
16-
const url = input instanceof URL ? input : new URL(input);
17-
18-
// Protected resource metadata discovery
19-
if (url.origin === RESOURCE_SERVER_URL.slice(0, -1) && url.pathname === '/.well-known/oauth-protected-resource') {
20-
return new Response(
21-
JSON.stringify({
22-
resource: RESOURCE_SERVER_URL,
23-
authorization_servers: [AUTH_SERVER_URL]
24-
}),
25-
{
26-
status: 200,
27-
headers: { 'Content-Type': 'application/json' }
28-
}
29-
);
30-
}
31-
32-
// Authorization server metadata discovery
33-
if (url.origin === AUTH_SERVER_URL && url.pathname === '/.well-known/oauth-authorization-server') {
34-
return new Response(
35-
JSON.stringify({
36-
issuer: AUTH_SERVER_URL,
37-
authorization_endpoint: `${AUTH_SERVER_URL}/authorize`,
38-
token_endpoint: `${AUTH_SERVER_URL}/token`,
39-
response_types_supported: ['code'],
40-
token_endpoint_auth_methods_supported: ['client_secret_basic', 'private_key_jwt']
41-
}),
42-
{
43-
status: 200,
44-
headers: { 'Content-Type': 'application/json' }
45-
}
46-
);
47-
}
48-
49-
// Token endpoint
50-
if (url.origin === AUTH_SERVER_URL && url.pathname === '/token') {
51-
if (onTokenRequest) {
52-
await onTokenRequest(url, init);
53-
}
54-
55-
return new Response(
56-
JSON.stringify({
57-
access_token: 'test-access-token',
58-
token_type: 'Bearer'
59-
}),
60-
{
61-
status: 200,
62-
headers: { 'Content-Type': 'application/json' }
63-
}
64-
);
65-
}
66-
67-
throw new Error(`Unexpected URL in mock fetch: ${url.toString()}`);
68-
};
69-
}
70-
7114
describe('auth-extensions providers (end-to-end with auth())', () => {
7215
it('authenticates using ClientCredentialsProvider with client_secret_basic', async () => {
7316
const provider = new ClientCredentialsProvider({
@@ -76,19 +19,23 @@ describe('auth-extensions providers (end-to-end with auth())', () => {
7619
clientName: 'test-client'
7720
});
7821

79-
const fetchMock = createMockFetch(async (_url, init) => {
80-
const params = init?.body as URLSearchParams;
81-
expect(params).toBeInstanceOf(URLSearchParams);
82-
expect(params.get('grant_type')).toBe('client_credentials');
83-
expect(params.get('resource')).toBe(RESOURCE_SERVER_URL);
84-
expect(params.get('client_assertion')).toBeNull();
85-
86-
const headers = new Headers(init?.headers);
87-
const authHeader = headers.get('Authorization');
88-
expect(authHeader).toBeTruthy();
89-
90-
const expectedCredentials = Buffer.from('my-client:my-secret').toString('base64');
91-
expect(authHeader).toBe(`Basic ${expectedCredentials}`);
22+
const fetchMock = createMockOAuthFetch({
23+
resourceServerUrl: RESOURCE_SERVER_URL,
24+
authServerUrl: AUTH_SERVER_URL,
25+
onTokenRequest: async (_url, init) => {
26+
const params = init?.body as URLSearchParams;
27+
expect(params).toBeInstanceOf(URLSearchParams);
28+
expect(params.get('grant_type')).toBe('client_credentials');
29+
expect(params.get('resource')).toBe(RESOURCE_SERVER_URL);
30+
expect(params.get('client_assertion')).toBeNull();
31+
32+
const headers = new Headers(init?.headers);
33+
const authHeader = headers.get('Authorization');
34+
expect(authHeader).toBeTruthy();
35+
36+
const expectedCredentials = Buffer.from('my-client:my-secret').toString('base64');
37+
expect(authHeader).toBe(`Basic ${expectedCredentials}`);
38+
}
9239
});
9340

9441
const result = await auth(provider, {
@@ -112,21 +59,25 @@ describe('auth-extensions providers (end-to-end with auth())', () => {
11259

11360
let assertionFromRequest: string | null = null;
11461

115-
const fetchMock = createMockFetch(async (_url, init) => {
116-
const params = init?.body as URLSearchParams;
117-
expect(params).toBeInstanceOf(URLSearchParams);
118-
expect(params.get('grant_type')).toBe('client_credentials');
119-
expect(params.get('resource')).toBe(RESOURCE_SERVER_URL);
62+
const fetchMock = createMockOAuthFetch({
63+
resourceServerUrl: RESOURCE_SERVER_URL,
64+
authServerUrl: AUTH_SERVER_URL,
65+
onTokenRequest: async (_url, init) => {
66+
const params = init?.body as URLSearchParams;
67+
expect(params).toBeInstanceOf(URLSearchParams);
68+
expect(params.get('grant_type')).toBe('client_credentials');
69+
expect(params.get('resource')).toBe(RESOURCE_SERVER_URL);
12070

121-
assertionFromRequest = params.get('client_assertion');
122-
expect(assertionFromRequest).toBeTruthy();
123-
expect(params.get('client_assertion_type')).toBe('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
71+
assertionFromRequest = params.get('client_assertion');
72+
expect(assertionFromRequest).toBeTruthy();
73+
expect(params.get('client_assertion_type')).toBe('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
12474

125-
const parts = assertionFromRequest!.split('.');
126-
expect(parts).toHaveLength(3);
75+
const parts = assertionFromRequest!.split('.');
76+
expect(parts).toHaveLength(3);
12777

128-
const headers = new Headers(init?.headers);
129-
expect(headers.get('Authorization')).toBeNull();
78+
const headers = new Headers(init?.headers);
79+
expect(headers.get('Authorization')).toBeNull();
80+
}
13081
});
13182

13283
const result = await auth(provider, {
@@ -149,7 +100,10 @@ describe('auth-extensions providers (end-to-end with auth())', () => {
149100
clientName: 'private-key-jwt-client'
150101
});
151102

152-
const fetchMock = createMockFetch();
103+
const fetchMock = createMockOAuthFetch({
104+
resourceServerUrl: RESOURCE_SERVER_URL,
105+
authServerUrl: AUTH_SERVER_URL
106+
});
153107

154108
await expect(
155109
auth(provider, {
@@ -168,17 +122,21 @@ describe('auth-extensions providers (end-to-end with auth())', () => {
168122
clientName: 'static-private-key-jwt-client'
169123
});
170124

171-
const fetchMock = createMockFetch(async (_url, init) => {
172-
const params = init?.body as URLSearchParams;
173-
expect(params).toBeInstanceOf(URLSearchParams);
174-
expect(params.get('grant_type')).toBe('client_credentials');
175-
expect(params.get('resource')).toBe(RESOURCE_SERVER_URL);
125+
const fetchMock = createMockOAuthFetch({
126+
resourceServerUrl: RESOURCE_SERVER_URL,
127+
authServerUrl: AUTH_SERVER_URL,
128+
onTokenRequest: async (_url, init) => {
129+
const params = init?.body as URLSearchParams;
130+
expect(params).toBeInstanceOf(URLSearchParams);
131+
expect(params.get('grant_type')).toBe('client_credentials');
132+
expect(params.get('resource')).toBe(RESOURCE_SERVER_URL);
176133

177-
expect(params.get('client_assertion')).toBe(staticAssertion);
178-
expect(params.get('client_assertion_type')).toBe('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
134+
expect(params.get('client_assertion')).toBe(staticAssertion);
135+
expect(params.get('client_assertion_type')).toBe('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
179136

180-
const headers = new Headers(init?.headers);
181-
expect(headers.get('Authorization')).toBeNull();
137+
const headers = new Headers(init?.headers);
138+
expect(headers.get('Authorization')).toBeNull();
139+
}
182140
});
183141

184142
const result = await auth(provider, {

src/client/auth.test.ts renamed to test/client/auth.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LATEST_PROTOCOL_VERSION } from '../types.js';
1+
import { LATEST_PROTOCOL_VERSION } from '../../src/types.js';
22
import {
33
discoverOAuthMetadata,
44
discoverAuthorizationServerMetadata,
@@ -13,10 +13,10 @@ import {
1313
type OAuthClientProvider,
1414
selectClientAuthMethod,
1515
isHttpsUrl
16-
} from './auth.js';
17-
import { createPrivateKeyJwtAuth } from './auth-extensions.js';
18-
import { InvalidClientMetadataError, ServerError } from '../server/auth/errors.js';
19-
import { AuthorizationServerMetadata, OAuthTokens } from '../shared/auth.js';
16+
} from '../../src/client/auth.js';
17+
import { createPrivateKeyJwtAuth } from '../../src/client/auth-extensions.js';
18+
import { InvalidClientMetadataError, ServerError } from '../../src/server/auth/errors.js';
19+
import { AuthorizationServerMetadata, OAuthTokens } from '../../src/shared/auth.js';
2020
import { expect, vi, type Mock } from 'vitest';
2121

2222
// Mock pkce-challenge
@@ -2836,7 +2836,7 @@ describe('OAuth Authorization', () => {
28362836

28372837
describe('RequestInit headers passthrough', () => {
28382838
it('custom headers from RequestInit are passed to auth discovery requests', async () => {
2839-
const { createFetchWithInit } = await import('../shared/transport.js');
2839+
const { createFetchWithInit } = await import('../../src/shared/transport.js');
28402840

28412841
const customFetch = vi.fn().mockResolvedValue({
28422842
ok: true,
@@ -2869,7 +2869,7 @@ describe('OAuth Authorization', () => {
28692869
});
28702870

28712871
it('auth-specific headers override base headers from RequestInit', async () => {
2872-
const { createFetchWithInit } = await import('../shared/transport.js');
2872+
const { createFetchWithInit } = await import('../../src/shared/transport.js');
28732873

28742874
const customFetch = vi.fn().mockResolvedValue({
28752875
ok: true,
@@ -2907,7 +2907,7 @@ describe('OAuth Authorization', () => {
29072907
});
29082908

29092909
it('other RequestInit options are passed through', async () => {
2910-
const { createFetchWithInit } = await import('../shared/transport.js');
2910+
const { createFetchWithInit } = await import('../../src/shared/transport.js');
29112911

29122912
const customFetch = vi.fn().mockResolvedValue({
29132913
ok: true,

src/client/cross-spawn.test.ts renamed to test/client/cross-spawn.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { StdioClientTransport, getDefaultEnvironment } from './stdio.js';
1+
import { StdioClientTransport, getDefaultEnvironment } from '../../src/client/stdio.js';
22
import spawn from 'cross-spawn';
3-
import { JSONRPCMessage } from '../types.js';
3+
import { JSONRPCMessage } from '../../src/types.js';
44
import { ChildProcess } from 'node:child_process';
55
import { Mock, MockedFunction } from 'vitest';
66

src/client/index.test.ts renamed to test/client/index.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-unused-vars */
22
/* eslint-disable no-constant-binary-expression */
33
/* eslint-disable @typescript-eslint/no-unused-expressions */
4-
import { Client, getSupportedElicitationModes } from './index.js';
4+
import { Client, getSupportedElicitationModes } from '../../src/client/index.js';
55
import {
66
RequestSchema,
77
NotificationSchema,
@@ -25,12 +25,12 @@ import {
2525
Tool,
2626
Prompt,
2727
Resource
28-
} from '../types.js';
29-
import { Transport } from '../shared/transport.js';
30-
import { Server } from '../server/index.js';
31-
import { McpServer } from '../server/mcp.js';
32-
import { InMemoryTransport } from '../inMemory.js';
33-
import { InMemoryTaskStore, InMemoryTaskMessageQueue } from '../experimental/tasks/stores/in-memory.js';
28+
} from '../../src/types.js';
29+
import { Transport } from '../../src/shared/transport.js';
30+
import { Server } from '../../src/server/index.js';
31+
import { McpServer } from '../../src/server/mcp.js';
32+
import { InMemoryTransport } from '../../src/inMemory.js';
33+
import { InMemoryTaskStore } from '../../src/experimental/tasks/stores/in-memory.js';
3434
import * as z3 from 'zod/v3';
3535
import * as z4 from 'zod/v4';
3636

src/client/middleware.test.ts renamed to test/client/middleware.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { withOAuth, withLogging, applyMiddlewares, createMiddleware } from './middleware.js';
2-
import { OAuthClientProvider } from './auth.js';
3-
import { FetchLike } from '../shared/transport.js';
1+
import { withOAuth, withLogging, applyMiddlewares, createMiddleware } from '../../src/client/middleware.js';
2+
import { OAuthClientProvider } from '../../src/client/auth.js';
3+
import { FetchLike } from '../../src/shared/transport.js';
44
import { MockInstance, Mocked, MockedFunction } from 'vitest';
55

6-
vi.mock('../client/auth.js', async () => {
7-
const actual = await vi.importActual<typeof import('../client/auth.js')>('../client/auth.js');
6+
vi.mock('../../src/client/auth.js', async () => {
7+
const actual = await vi.importActual<typeof import('../../src/client/auth.js')>('../../src/client/auth.js');
88
return {
99
...actual,
1010
auth: vi.fn(),
1111
extractWWWAuthenticateParams: vi.fn()
1212
};
1313
});
1414

15-
import { auth, extractWWWAuthenticateParams } from './auth.js';
15+
import { auth, extractWWWAuthenticateParams } from '../../src/client/auth.js';
1616

1717
const mockAuth = auth as MockedFunction<typeof auth>;
1818
const mockExtractWWWAuthenticateParams = extractWWWAuthenticateParams as MockedFunction<typeof extractWWWAuthenticateParams>;

0 commit comments

Comments
 (0)