MCP Server Example with PRPs

This commit is contained in:
Cole Medin
2025-07-12 11:48:38 -05:00
parent 73d08d2236
commit 8445f05b67
42 changed files with 18567 additions and 0 deletions

View 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
}

View 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()
}

View 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'))
})
}

View 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,
}