Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,565 changes: 0 additions & 1,565 deletions apps/sim/app/api/__test-utils__/utils.ts

This file was deleted.

49 changes: 48 additions & 1 deletion apps/sim/app/api/auth/forget-password/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,60 @@
*
* @vitest-environment node
*/
import {
createMockRequest,
mockConsoleLogger,
mockCryptoUuid,
mockDrizzleOrm,
mockUuid,
setupCommonApiMocks,
} from '@sim/testing'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockRequest, setupAuthApiMocks } from '@/app/api/__test-utils__/utils'

vi.mock('@/lib/core/utils/urls', () => ({
getBaseUrl: vi.fn(() => 'https://app.example.com'),
}))

/** Setup auth API mocks for testing authentication routes */
function setupAuthApiMocks(
options: {
operations?: {
forgetPassword?: { success?: boolean; error?: string }
resetPassword?: { success?: boolean; error?: string }
}
} = {}
) {
setupCommonApiMocks()
mockUuid()
mockCryptoUuid()
mockConsoleLogger()
mockDrizzleOrm()

const { operations = {} } = options
const defaultOperations = {
forgetPassword: { success: true, error: 'Forget password error', ...operations.forgetPassword },
resetPassword: { success: true, error: 'Reset password error', ...operations.resetPassword },
}

const createAuthMethod = (config: { success?: boolean; error?: string }) => {
return vi.fn().mockImplementation(() => {
if (config.success) {
return Promise.resolve()
}
return Promise.reject(new Error(config.error))
})
}

vi.doMock('@/lib/auth', () => ({
auth: {
api: {
forgetPassword: createAuthMethod(defaultOperations.forgetPassword),
resetPassword: createAuthMethod(defaultOperations.resetPassword),
},
},
}))
}

describe('Forget Password API Route', () => {
beforeEach(() => {
vi.resetModules()
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/api/auth/oauth/connections/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
*
* @vitest-environment node
*/
import { createMockLogger, createMockRequest } from '@sim/testing'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockLogger, createMockRequest } from '@/app/api/__test-utils__/utils'

describe('OAuth Connections API Route', () => {
const mockGetSession = vi.fn()
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/api/auth/oauth/credentials/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* @vitest-environment node
*/

import { createMockLogger } from '@sim/testing'
import { NextRequest } from 'next/server'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockLogger } from '@/app/api/__test-utils__/utils'

describe('OAuth Credentials API Route', () => {
const mockGetSession = vi.fn()
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/api/auth/oauth/disconnect/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
*
* @vitest-environment node
*/
import { createMockLogger, createMockRequest } from '@sim/testing'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockLogger, createMockRequest } from '@/app/api/__test-utils__/utils'

describe('OAuth Disconnect API Route', () => {
const mockGetSession = vi.fn()
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/api/auth/oauth/token/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
*
* @vitest-environment node
*/
import { createMockLogger, createMockRequest } from '@sim/testing'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockLogger, createMockRequest } from '@/app/api/__test-utils__/utils'

describe('OAuth Token API Routes', () => {
const mockGetUserId = vi.fn()
Expand Down
49 changes: 48 additions & 1 deletion apps/sim/app/api/auth/reset-password/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,55 @@
*
* @vitest-environment node
*/
import {
createMockRequest,
mockConsoleLogger,
mockCryptoUuid,
mockDrizzleOrm,
mockUuid,
setupCommonApiMocks,
} from '@sim/testing'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockRequest, setupAuthApiMocks } from '@/app/api/__test-utils__/utils'

/** Setup auth API mocks for testing authentication routes */
function setupAuthApiMocks(
options: {
operations?: {
forgetPassword?: { success?: boolean; error?: string }
resetPassword?: { success?: boolean; error?: string }
}
} = {}
) {
setupCommonApiMocks()
mockUuid()
mockCryptoUuid()
mockConsoleLogger()
mockDrizzleOrm()

const { operations = {} } = options
const defaultOperations = {
forgetPassword: { success: true, error: 'Forget password error', ...operations.forgetPassword },
resetPassword: { success: true, error: 'Reset password error', ...operations.resetPassword },
}

const createAuthMethod = (config: { success?: boolean; error?: string }) => {
return vi.fn().mockImplementation(() => {
if (config.success) {
return Promise.resolve()
}
return Promise.reject(new Error(config.error))
})
}

vi.doMock('@/lib/auth', () => ({
auth: {
api: {
forgetPassword: createAuthMethod(defaultOperations.forgetPassword),
resetPassword: createAuthMethod(defaultOperations.resetPassword),
},
},
}))
}

describe('Reset Password API Route', () => {
beforeEach(() => {
Expand Down
72 changes: 56 additions & 16 deletions apps/sim/app/api/chat/[identifier]/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,34 @@
*/
import { loggerMock } from '@sim/testing'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockRequest } from '@/app/api/__test-utils__/utils'

/**
* Creates a mock NextRequest with cookies support for testing.
*/
function createMockNextRequest(
method = 'GET',
body?: unknown,
headers: Record<string, string> = {},
url = 'http://localhost:3000/api/test'
): any {
const headersObj = new Headers({
'Content-Type': 'application/json',
...headers,
})

return {
method,
headers: headersObj,
cookies: {
get: vi.fn().mockReturnValue(undefined),
},
json:
body !== undefined
? vi.fn().mockResolvedValue(body)
: vi.fn().mockRejectedValue(new Error('No body')),
url,
}
}

const createMockStream = () => {
return new ReadableStream({
Expand Down Expand Up @@ -71,10 +98,15 @@ vi.mock('@/lib/core/utils/request', () => ({
generateRequestId: vi.fn().mockReturnValue('test-request-id'),
}))

vi.mock('@/lib/core/security/encryption', () => ({
decryptSecret: vi.fn().mockResolvedValue({ decrypted: 'test-password' }),
}))

describe('Chat Identifier API Route', () => {
const mockAddCorsHeaders = vi.fn().mockImplementation((response) => response)
const mockValidateChatAuth = vi.fn().mockResolvedValue({ authorized: true })
const mockSetChatAuthCookie = vi.fn()
const mockValidateAuthToken = vi.fn().mockReturnValue(false)

const mockChatResult = [
{
Expand Down Expand Up @@ -114,11 +146,16 @@ describe('Chat Identifier API Route', () => {
beforeEach(() => {
vi.resetModules()

vi.doMock('@/app/api/chat/utils', () => ({
vi.doMock('@/lib/core/security/deployment', () => ({
addCorsHeaders: mockAddCorsHeaders,
validateAuthToken: mockValidateAuthToken,
setDeploymentAuthCookie: vi.fn(),
isEmailAllowed: vi.fn().mockReturnValue(false),
}))

vi.doMock('@/app/api/chat/utils', () => ({
validateChatAuth: mockValidateChatAuth,
setChatAuthCookie: mockSetChatAuthCookie,
validateAuthToken: vi.fn().mockReturnValue(true),
}))

// Mock logger - use loggerMock from @sim/testing
Expand Down Expand Up @@ -175,7 +212,7 @@ describe('Chat Identifier API Route', () => {

describe('GET endpoint', () => {
it('should return chat info for a valid identifier', async () => {
const req = createMockRequest('GET')
const req = createMockNextRequest('GET')
const params = Promise.resolve({ identifier: 'test-chat' })

const { GET } = await import('@/app/api/chat/[identifier]/route')
Expand Down Expand Up @@ -206,7 +243,7 @@ describe('Chat Identifier API Route', () => {
}
})

const req = createMockRequest('GET')
const req = createMockNextRequest('GET')
const params = Promise.resolve({ identifier: 'nonexistent' })

const { GET } = await import('@/app/api/chat/[identifier]/route')
Expand Down Expand Up @@ -240,7 +277,7 @@ describe('Chat Identifier API Route', () => {
}
})

const req = createMockRequest('GET')
const req = createMockNextRequest('GET')
const params = Promise.resolve({ identifier: 'inactive-chat' })

const { GET } = await import('@/app/api/chat/[identifier]/route')
Expand All @@ -261,7 +298,7 @@ describe('Chat Identifier API Route', () => {
error: 'auth_required_password',
}))

const req = createMockRequest('GET')
const req = createMockNextRequest('GET')
const params = Promise.resolve({ identifier: 'password-protected-chat' })

const { GET } = await import('@/app/api/chat/[identifier]/route')
Expand All @@ -282,7 +319,7 @@ describe('Chat Identifier API Route', () => {

describe('POST endpoint', () => {
it('should handle authentication requests without input', async () => {
const req = createMockRequest('POST', { password: 'test-password' })
const req = createMockNextRequest('POST', { password: 'test-password' })
const params = Promise.resolve({ identifier: 'password-protected-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand All @@ -298,7 +335,7 @@ describe('Chat Identifier API Route', () => {
})

it('should return 400 for requests without input', async () => {
const req = createMockRequest('POST', {})
const req = createMockNextRequest('POST', {})
const params = Promise.resolve({ identifier: 'test-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand All @@ -319,7 +356,7 @@ describe('Chat Identifier API Route', () => {
error: 'Authentication required',
}))

const req = createMockRequest('POST', { input: 'Hello' })
const req = createMockNextRequest('POST', { input: 'Hello' })
const params = Promise.resolve({ identifier: 'protected-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand Down Expand Up @@ -350,7 +387,7 @@ describe('Chat Identifier API Route', () => {
},
})

const req = createMockRequest('POST', { input: 'Hello' })
const req = createMockNextRequest('POST', { input: 'Hello' })
const params = Promise.resolve({ identifier: 'test-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand All @@ -369,7 +406,10 @@ describe('Chat Identifier API Route', () => {
})

it('should return streaming response for valid chat messages', async () => {
const req = createMockRequest('POST', { input: 'Hello world', conversationId: 'conv-123' })
const req = createMockNextRequest('POST', {
input: 'Hello world',
conversationId: 'conv-123',
})
const params = Promise.resolve({ identifier: 'test-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand Down Expand Up @@ -401,7 +441,7 @@ describe('Chat Identifier API Route', () => {
}, 10000)

it('should handle streaming response body correctly', async () => {
const req = createMockRequest('POST', { input: 'Hello world' })
const req = createMockNextRequest('POST', { input: 'Hello world' })
const params = Promise.resolve({ identifier: 'test-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand Down Expand Up @@ -431,7 +471,7 @@ describe('Chat Identifier API Route', () => {
throw new Error('Execution failed')
})

const req = createMockRequest('POST', { input: 'Trigger error' })
const req = createMockNextRequest('POST', { input: 'Trigger error' })
const params = Promise.resolve({ identifier: 'test-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand Down Expand Up @@ -470,7 +510,7 @@ describe('Chat Identifier API Route', () => {
})

it('should pass conversationId to streaming execution when provided', async () => {
const req = createMockRequest('POST', {
const req = createMockNextRequest('POST', {
input: 'Hello world',
conversationId: 'test-conversation-123',
})
Expand All @@ -492,7 +532,7 @@ describe('Chat Identifier API Route', () => {
})

it('should handle missing conversationId gracefully', async () => {
const req = createMockRequest('POST', { input: 'Hello world' })
const req = createMockNextRequest('POST', { input: 'Hello world' })
const params = Promise.resolve({ identifier: 'test-chat' })

const { POST } = await import('@/app/api/chat/[identifier]/route')
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/api/copilot/api-keys/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
*
* @vitest-environment node
*/
import { mockAuth, mockCryptoUuid, setupCommonApiMocks } from '@sim/testing'
import { NextRequest } from 'next/server'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mockAuth, mockCryptoUuid, setupCommonApiMocks } from '@/app/api/__test-utils__/utils'

describe('Copilot API Keys API Route', () => {
const mockFetch = vi.fn()
Expand Down
7 changes: 1 addition & 6 deletions apps/sim/app/api/copilot/chat/delete/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@
*
* @vitest-environment node
*/
import { createMockRequest, mockAuth, mockCryptoUuid, setupCommonApiMocks } from '@sim/testing'
import { NextRequest } from 'next/server'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import {
createMockRequest,
mockAuth,
mockCryptoUuid,
setupCommonApiMocks,
} from '@/app/api/__test-utils__/utils'

describe('Copilot Chat Delete API Route', () => {
const mockDelete = vi.fn()
Expand Down
7 changes: 1 addition & 6 deletions apps/sim/app/api/copilot/chat/update-messages/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@
*
* @vitest-environment node
*/
import { createMockRequest, mockAuth, mockCryptoUuid, setupCommonApiMocks } from '@sim/testing'
import { NextRequest } from 'next/server'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import {
createMockRequest,
mockAuth,
mockCryptoUuid,
setupCommonApiMocks,
} from '@/app/api/__test-utils__/utils'

describe('Copilot Chat Update Messages API Route', () => {
const mockSelect = vi.fn()
Expand Down
Loading