mirror of
https://github.com/coleam00/context-engineering-intro.git
synced 2025-12-29 16:14:56 +00:00
MCP Server Example with PRPs
This commit is contained in:
54
use-cases/mcp-server/tests/mocks/crypto.mock.ts
Normal file
54
use-cases/mcp-server/tests/mocks/crypto.mock.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { vi } from 'vitest'
|
||||
|
||||
// Mock crypto.subtle for cookie signing
|
||||
export const mockCryptoSubtle = {
|
||||
sign: vi.fn(),
|
||||
verify: vi.fn(),
|
||||
importKey: vi.fn(),
|
||||
}
|
||||
|
||||
// Mock crypto.getRandomValues
|
||||
export const mockGetRandomValues = vi.fn()
|
||||
|
||||
export function setupCryptoMocks() {
|
||||
// Mock HMAC signing
|
||||
mockCryptoSubtle.sign.mockResolvedValue(new ArrayBuffer(32))
|
||||
|
||||
// Mock signature verification
|
||||
mockCryptoSubtle.verify.mockResolvedValue(true)
|
||||
|
||||
// Mock key import
|
||||
mockCryptoSubtle.importKey.mockResolvedValue({} as CryptoKey)
|
||||
|
||||
// Mock random values
|
||||
mockGetRandomValues.mockImplementation((array: Uint8Array) => {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
array[i] = Math.floor(Math.random() * 256)
|
||||
}
|
||||
return array
|
||||
})
|
||||
}
|
||||
|
||||
export function setupCryptoError() {
|
||||
mockCryptoSubtle.sign.mockRejectedValue(new Error('Crypto signing failed'))
|
||||
mockCryptoSubtle.verify.mockRejectedValue(new Error('Crypto verification failed'))
|
||||
}
|
||||
|
||||
export function resetCryptoMocks() {
|
||||
vi.clearAllMocks()
|
||||
setupCryptoMocks()
|
||||
}
|
||||
|
||||
// Apply mocks to global crypto object
|
||||
if (!global.crypto) {
|
||||
Object.defineProperty(global, 'crypto', {
|
||||
value: {
|
||||
subtle: mockCryptoSubtle,
|
||||
getRandomValues: mockGetRandomValues,
|
||||
},
|
||||
writable: true,
|
||||
})
|
||||
} else {
|
||||
global.crypto.subtle = mockCryptoSubtle
|
||||
global.crypto.getRandomValues = mockGetRandomValues
|
||||
}
|
||||
57
use-cases/mcp-server/tests/mocks/database.mock.ts
Normal file
57
use-cases/mcp-server/tests/mocks/database.mock.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { vi } from 'vitest'
|
||||
import { mockTableColumns, mockQueryResult } from '../fixtures/database.fixtures'
|
||||
|
||||
// Mock postgres function
|
||||
export const mockPostgresInstance = {
|
||||
unsafe: vi.fn(),
|
||||
end: vi.fn(),
|
||||
// Template literal query method
|
||||
'`SELECT * FROM users`': vi.fn(),
|
||||
}
|
||||
|
||||
// Mock the postgres module
|
||||
vi.mock('postgres', () => ({
|
||||
default: vi.fn(() => mockPostgresInstance),
|
||||
}))
|
||||
|
||||
// Mock database connection functions
|
||||
vi.mock('../../src/database/connection', () => ({
|
||||
getDb: vi.fn(() => mockPostgresInstance),
|
||||
closeDb: vi.fn(),
|
||||
}))
|
||||
|
||||
// Mock database utils
|
||||
vi.mock('../../src/database/utils', () => ({
|
||||
withDatabase: vi.fn(async (url: string, operation: any) => {
|
||||
return await operation(mockPostgresInstance)
|
||||
}),
|
||||
}))
|
||||
|
||||
// Mock setup functions
|
||||
export function setupDatabaseMocks() {
|
||||
mockPostgresInstance.unsafe.mockImplementation((query: string) => {
|
||||
if (query.includes('information_schema.columns')) {
|
||||
return Promise.resolve(mockTableColumns)
|
||||
}
|
||||
if (query.includes('SELECT')) {
|
||||
return Promise.resolve(mockQueryResult)
|
||||
}
|
||||
if (query.includes('INSERT') || query.includes('UPDATE') || query.includes('DELETE')) {
|
||||
return Promise.resolve([{ affectedRows: 1 }])
|
||||
}
|
||||
return Promise.resolve([])
|
||||
})
|
||||
}
|
||||
|
||||
export function setupDatabaseError() {
|
||||
mockPostgresInstance.unsafe.mockRejectedValue(new Error('Database connection failed'))
|
||||
}
|
||||
|
||||
export function setupDatabaseTimeout() {
|
||||
mockPostgresInstance.unsafe.mockRejectedValue(new Error('Connection timeout'))
|
||||
}
|
||||
|
||||
export function resetDatabaseMocks() {
|
||||
vi.clearAllMocks()
|
||||
setupDatabaseMocks()
|
||||
}
|
||||
59
use-cases/mcp-server/tests/mocks/github.mock.ts
Normal file
59
use-cases/mcp-server/tests/mocks/github.mock.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { vi } from 'vitest'
|
||||
import { mockGitHubUser, mockAccessToken } from '../fixtures/auth.fixtures'
|
||||
|
||||
// Mock Octokit
|
||||
export const mockOctokit = {
|
||||
rest: {
|
||||
users: {
|
||||
getAuthenticated: vi.fn(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vi.mock('octokit', () => ({
|
||||
Octokit: vi.fn(() => mockOctokit),
|
||||
}))
|
||||
|
||||
// Mock GitHub API responses
|
||||
export function setupGitHubMocks() {
|
||||
mockOctokit.rest.users.getAuthenticated.mockResolvedValue(mockGitHubUser)
|
||||
}
|
||||
|
||||
export function setupGitHubError() {
|
||||
mockOctokit.rest.users.getAuthenticated.mockRejectedValue(new Error('GitHub API error'))
|
||||
}
|
||||
|
||||
export function setupGitHubUnauthorized() {
|
||||
mockOctokit.rest.users.getAuthenticated.mockRejectedValue(new Error('Bad credentials'))
|
||||
}
|
||||
|
||||
export function resetGitHubMocks() {
|
||||
vi.clearAllMocks()
|
||||
setupGitHubMocks()
|
||||
}
|
||||
|
||||
// Mock fetch for GitHub OAuth token exchange
|
||||
export function setupGitHubTokenExchange() {
|
||||
global.fetch = vi.fn((url: string) => {
|
||||
if (url.includes('github.com/login/oauth/access_token')) {
|
||||
return Promise.resolve({
|
||||
ok: true,
|
||||
text: () => Promise.resolve(`access_token=${mockAccessToken}&token_type=bearer&scope=read:user`),
|
||||
} as Response)
|
||||
}
|
||||
return Promise.reject(new Error('Unexpected fetch call'))
|
||||
})
|
||||
}
|
||||
|
||||
export function setupGitHubTokenExchangeError() {
|
||||
global.fetch = vi.fn((url: string) => {
|
||||
if (url.includes('github.com/login/oauth/access_token')) {
|
||||
return Promise.resolve({
|
||||
ok: false,
|
||||
status: 400,
|
||||
text: () => Promise.resolve('error=invalid_grant&error_description=Bad verification code.'),
|
||||
} as Response)
|
||||
}
|
||||
return Promise.reject(new Error('Unexpected fetch call'))
|
||||
})
|
||||
}
|
||||
47
use-cases/mcp-server/tests/mocks/oauth.mock.ts
Normal file
47
use-cases/mcp-server/tests/mocks/oauth.mock.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { vi } from 'vitest'
|
||||
import { mockAuthRequest, mockClientInfo } from '../fixtures/auth.fixtures'
|
||||
|
||||
// Mock OAuth provider
|
||||
export const mockOAuthProvider = {
|
||||
parseAuthRequest: vi.fn(),
|
||||
lookupClient: vi.fn(),
|
||||
completeAuthorization: vi.fn(),
|
||||
}
|
||||
|
||||
// Mock OAuth helpers
|
||||
export const mockOAuthHelpers = {
|
||||
...mockOAuthProvider,
|
||||
}
|
||||
|
||||
// Mock Cloudflare Workers OAuth Provider
|
||||
vi.mock('@cloudflare/workers-oauth-provider', () => ({
|
||||
default: vi.fn(() => ({
|
||||
fetch: vi.fn(),
|
||||
})),
|
||||
}))
|
||||
|
||||
export function setupOAuthMocks() {
|
||||
mockOAuthProvider.parseAuthRequest.mockResolvedValue(mockAuthRequest)
|
||||
mockOAuthProvider.lookupClient.mockResolvedValue(mockClientInfo)
|
||||
mockOAuthProvider.completeAuthorization.mockResolvedValue({
|
||||
redirectTo: 'http://localhost:3000/callback?code=success',
|
||||
})
|
||||
}
|
||||
|
||||
export function setupOAuthError() {
|
||||
mockOAuthProvider.parseAuthRequest.mockRejectedValue(new Error('Invalid OAuth request'))
|
||||
}
|
||||
|
||||
export function resetOAuthMocks() {
|
||||
vi.clearAllMocks()
|
||||
setupOAuthMocks()
|
||||
}
|
||||
|
||||
// Mock environment with OAuth provider
|
||||
export const mockEnv = {
|
||||
GITHUB_CLIENT_ID: 'test-client-id',
|
||||
GITHUB_CLIENT_SECRET: 'test-client-secret',
|
||||
COOKIE_ENCRYPTION_KEY: 'test-encryption-key',
|
||||
DATABASE_URL: 'postgresql://test:test@localhost:5432/test',
|
||||
OAUTH_PROVIDER: mockOAuthProvider,
|
||||
}
|
||||
Reference in New Issue
Block a user