Skip to content

Commit 11c5bd6

Browse files
committed
fix(zoho-desk): let an unsupported receivedInDays reach the tool's validation
The block mapper filtered on shape before forwarding, so a fractional or non-numeric value was dropped and List Tickets then ran with no window at all — returning the whole queue as though the requested filter had applied. The tool owns that validation, so the mapper now passes the value straight through. Adds a block-to-tool seam test: neither side's own tests could catch a value lost between them.
1 parent fa86518 commit 11c5bd6

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

apps/sim/blocks/blocks/zoho-desk.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,13 +621,17 @@ export const ZohoDeskBlock: BlockConfig<ZohoDeskResponse> = {
621621
if (typeof rawChannelFilter === 'string' && rawChannelFilter.trim()) {
622622
result.channel = rawChannelFilter.trim()
623623
}
624+
// Forward whatever was supplied and let the tool judge it. Filtering
625+
// here on shape would swallow 30.5 or a non-numeric value, and the
626+
// tool would then run without the filter and return the entire queue
627+
// as though the requested window had applied. Only the empty
628+
// "Any time" option is dropped, because that genuinely means no filter.
624629
if (
625630
rawReceivedInDays !== undefined &&
626631
rawReceivedInDays !== null &&
627632
rawReceivedInDays !== ''
628633
) {
629-
const receivedInDays = Number(rawReceivedInDays)
630-
if (Number.isInteger(receivedInDays)) result.receivedInDays = receivedInDays
634+
result.receivedInDays = Number(rawReceivedInDays)
631635
}
632636
}
633637

apps/sim/tools/zoho_desk/list_tickets.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* @vitest-environment node
33
*/
44
import { describe, expect, it } from 'vitest'
5+
import { ZohoDeskBlock } from '@/blocks/blocks/zoho-desk'
56
import { zohoDeskListTicketsTool } from '@/tools/zoho_desk/list_tickets'
67

78
describe('zohoDeskListTicketsTool request url', () => {
@@ -50,3 +51,36 @@ describe('zohoDeskListTicketsTool request url', () => {
5051
expect(query.get('status')).toBe('Open,On Hold')
5152
})
5253
})
54+
55+
/**
56+
* The block maps subBlock values onto tool params, so a value the mapper drops
57+
* never reaches the tool's validation and the request silently runs unfiltered.
58+
* These cover the seam rather than either side of it.
59+
*/
60+
describe('ZohoDeskBlock receivedInDays reaches the tool intact', () => {
61+
const buildParams = ZohoDeskBlock.tools.config?.params
62+
const buildUrl = zohoDeskListTicketsTool.request.url as (p: Record<string, unknown>) => string
63+
64+
const throughBlock = (receivedInDays: unknown) => {
65+
if (!buildParams) throw new Error('ZohoDeskBlock is missing tools.config.params')
66+
const mapped = buildParams({ operation: 'list_tickets', receivedInDays }) as Record<
67+
string,
68+
unknown
69+
>
70+
return buildUrl({ accessToken: 'tok', orgId: '700', ...mapped })
71+
}
72+
73+
it('carries a supported window through to the query', () => {
74+
expect(new URL(throughBlock('30')).searchParams.get('receivedInDays')).toBe('30')
75+
})
76+
77+
it('lets an unsupported value reach the tool and throw instead of silently unfiltering', () => {
78+
for (const value of [7, '7', 30.5, 'abc']) {
79+
expect(() => throughBlock(value)).toThrow(/must be 15, 30, or 90/)
80+
}
81+
})
82+
83+
it('treats the "Any time" option as no filter at all', () => {
84+
expect(new URL(throughBlock('')).searchParams.has('receivedInDays')).toBe(false)
85+
})
86+
})

0 commit comments

Comments
 (0)