Skip to content

Commit a65f3b8

Browse files
committed
fix tests
1 parent 5ecbf6c commit a65f3b8

File tree

3 files changed

+84
-33
lines changed

3 files changed

+84
-33
lines changed

apps/sim/blocks/blocks.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,17 @@ describe('Blocks Module', () => {
442442
})
443443

444444
it('should have valid output types', () => {
445-
const validPrimitiveTypes = ['string', 'number', 'boolean', 'json', 'array', 'files', 'any']
445+
const validPrimitiveTypes = [
446+
'string',
447+
'number',
448+
'boolean',
449+
'json',
450+
'array',
451+
'files',
452+
'file',
453+
'file[]',
454+
'any',
455+
]
446456
const blocks = getAllBlocks()
447457
for (const block of blocks) {
448458
for (const [key, outputConfig] of Object.entries(block.outputs)) {

apps/sim/executor/handlers/api/api-handler.test.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import '@sim/testing/mocks/executor'
22

33
import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest'
4+
import { validateUrlWithDNS } from '@/lib/core/security/input-validation.server'
45
import { BlockType } from '@/executor/constants'
56
import { ApiBlockHandler } from '@/executor/handlers/api/api-handler'
67
import type { ExecutionContext } from '@/executor/types'
@@ -9,8 +10,13 @@ import { executeTool } from '@/tools'
910
import type { ToolConfig } from '@/tools/types'
1011
import { getTool } from '@/tools/utils'
1112

13+
vi.mock('@/lib/core/security/input-validation.server', () => ({
14+
validateUrlWithDNS: vi.fn(),
15+
}))
16+
1217
const mockGetTool = vi.mocked(getTool)
1318
const mockExecuteTool = executeTool as Mock
19+
const mockValidateUrlWithDNS = vi.mocked(validateUrlWithDNS)
1420

1521
describe('ApiBlockHandler', () => {
1622
let handler: ApiBlockHandler
@@ -63,6 +69,12 @@ describe('ApiBlockHandler', () => {
6369
// Reset mocks using vi
6470
vi.clearAllMocks()
6571

72+
mockValidateUrlWithDNS.mockResolvedValue({
73+
isValid: true,
74+
resolvedIP: '93.184.216.34',
75+
originalHostname: 'example.com',
76+
})
77+
6678
// Set up mockGetTool to return the mockApiTool
6779
mockGetTool.mockImplementation((toolId) => {
6880
if (toolId === 'http_request') {
@@ -130,17 +142,27 @@ describe('ApiBlockHandler', () => {
130142
it('should throw error for invalid URL format (no protocol)', async () => {
131143
const inputs = { url: 'example.com/api' }
132144

145+
mockValidateUrlWithDNS.mockResolvedValueOnce({
146+
isValid: false,
147+
error: 'url must be a valid URL',
148+
})
149+
133150
await expect(handler.execute(mockContext, mockBlock, inputs)).rejects.toThrow(
134-
'Invalid URL: "example.com/api" - URL must include protocol (try "https://example.com/api")'
151+
'url must be a valid URL'
135152
)
136153
expect(mockExecuteTool).not.toHaveBeenCalled()
137154
})
138155

139156
it('should throw error for generally invalid URL format', async () => {
140157
const inputs = { url: 'htp:/invalid-url' }
141158

159+
mockValidateUrlWithDNS.mockResolvedValueOnce({
160+
isValid: false,
161+
error: 'url must use https:// protocol',
162+
})
163+
142164
await expect(handler.execute(mockContext, mockBlock, inputs)).rejects.toThrow(
143-
/^Invalid URL: "htp:\/invalid-url" - URL must include protocol/
165+
'url must use https:// protocol'
144166
)
145167
expect(mockExecuteTool).not.toHaveBeenCalled()
146168
})

apps/sim/tools/utils.test.ts

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { createMockFetch, loggerMock } from '@sim/testing'
1+
import { createMockResponse, loggerMock } from '@sim/testing'
22
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
3+
import {
4+
secureFetchWithPinnedIP,
5+
validateUrlWithDNS,
6+
} from '@/lib/core/security/input-validation.server'
37
import { transformTable } from '@/tools/shared/table'
48
import type { ToolConfig } from '@/tools/types'
59
import {
@@ -12,6 +16,10 @@ import {
1216
import { executeRequest } from '@/tools/utils.server'
1317

1418
vi.mock('@sim/logger', () => loggerMock)
19+
vi.mock('@/lib/core/security/input-validation.server', () => ({
20+
validateUrlWithDNS: vi.fn(),
21+
secureFetchWithPinnedIP: vi.fn(),
22+
}))
1523

1624
vi.mock('@/stores/settings/environment', () => {
1725
const mockStore = {
@@ -406,11 +414,18 @@ describe('validateRequiredParametersAfterMerge', () => {
406414

407415
describe('executeRequest', () => {
408416
let mockTool: ToolConfig
409-
let mockFetch: ReturnType<typeof createMockFetch>
417+
const mockValidateUrlWithDNS = vi.mocked(validateUrlWithDNS)
418+
const mockSecureFetchWithPinnedIP = vi.mocked(secureFetchWithPinnedIP)
410419

411420
beforeEach(() => {
412-
mockFetch = createMockFetch({ json: { result: 'success' }, status: 200 })
413-
global.fetch = mockFetch
421+
mockValidateUrlWithDNS.mockResolvedValue({
422+
isValid: true,
423+
resolvedIP: '93.184.216.34',
424+
originalHostname: 'api.example.com',
425+
})
426+
mockSecureFetchWithPinnedIP.mockResolvedValue(
427+
createMockResponse({ json: { result: 'success' }, status: 200 })
428+
)
414429

415430
mockTool = {
416431
id: 'test-tool',
@@ -441,11 +456,15 @@ describe('executeRequest', () => {
441456
headers: {},
442457
})
443458

444-
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com', {
445-
method: 'GET',
446-
headers: {},
447-
body: undefined,
448-
})
459+
expect(mockSecureFetchWithPinnedIP).toHaveBeenCalledWith(
460+
'https://api.example.com',
461+
'93.184.216.34',
462+
{
463+
method: 'GET',
464+
headers: {},
465+
body: undefined,
466+
}
467+
)
449468
expect(mockTool.transformResponse).toHaveBeenCalled()
450469
expect(result).toEqual({
451470
success: true,
@@ -455,8 +474,6 @@ describe('executeRequest', () => {
455474

456475
it.concurrent('should use default transform response if not provided', async () => {
457476
mockTool.transformResponse = undefined
458-
const localMockFetch = createMockFetch({ json: { result: 'success' }, status: 200 })
459-
global.fetch = localMockFetch
460477

461478
const result = await executeRequest('test-tool', mockTool, {
462479
url: 'https://api.example.com',
@@ -471,13 +488,14 @@ describe('executeRequest', () => {
471488
})
472489

473490
it('should handle error responses', async () => {
474-
const errorFetch = createMockFetch({
475-
ok: false,
476-
status: 400,
477-
statusText: 'Bad Request',
478-
json: { message: 'Invalid input' },
479-
})
480-
global.fetch = errorFetch
491+
mockSecureFetchWithPinnedIP.mockResolvedValueOnce(
492+
createMockResponse({
493+
ok: false,
494+
status: 400,
495+
statusText: 'Bad Request',
496+
json: { message: 'Invalid input' },
497+
})
498+
)
481499

482500
const result = await executeRequest('test-tool', mockTool, {
483501
url: 'https://api.example.com',
@@ -493,8 +511,7 @@ describe('executeRequest', () => {
493511
})
494512

495513
it.concurrent('should handle network errors', async () => {
496-
const errorFetch = vi.fn().mockRejectedValueOnce(new Error('Network error'))
497-
global.fetch = errorFetch
514+
mockSecureFetchWithPinnedIP.mockRejectedValueOnce(new Error('Network error'))
498515

499516
const result = await executeRequest('test-tool', mockTool, {
500517
url: 'https://api.example.com',
@@ -510,15 +527,16 @@ describe('executeRequest', () => {
510527
})
511528

512529
it('should handle JSON parse errors in error response', async () => {
513-
const errorFetch = vi.fn().mockResolvedValueOnce({
530+
const errorResponse = createMockResponse({
514531
ok: false,
515532
status: 500,
516533
statusText: 'Server Error',
517-
json: async () => {
518-
throw new Error('Invalid JSON')
519-
},
520534
})
521-
global.fetch = errorFetch
535+
errorResponse.json = vi.fn(async () => {
536+
throw new Error('Invalid JSON')
537+
})
538+
errorResponse.text = vi.fn(async () => '')
539+
mockSecureFetchWithPinnedIP.mockResolvedValueOnce(errorResponse)
522540

523541
const result = await executeRequest('test-tool', mockTool, {
524542
url: 'https://api.example.com',
@@ -548,11 +566,12 @@ describe('executeRequest', () => {
548566
},
549567
}
550568

551-
const xmlFetch = createMockFetch({
552-
status: 200,
553-
text: '<xml><test>Mock XML response</test></xml>',
554-
})
555-
global.fetch = xmlFetch
569+
mockSecureFetchWithPinnedIP.mockResolvedValueOnce(
570+
createMockResponse({
571+
status: 200,
572+
text: '<xml><test>Mock XML response</test></xml>',
573+
})
574+
)
556575

557576
const result = await executeRequest('test-tool', toolWithTransform, {
558577
url: 'https://api.example.com',

0 commit comments

Comments
 (0)