Skip to content

Commit f0582c9

Browse files
committed
test(ashby): type webhook fixtures
1 parent 4fbcb9f commit f0582c9

1 file changed

Lines changed: 73 additions & 64 deletions

File tree

‎apps/sim/lib/webhooks/providers/ashby.test.ts‎

Lines changed: 73 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,49 @@ import crypto from 'crypto'
55
import { createMockRequest } from '@sim/testing'
66
import { afterEach, describe, expect, it, vi } from 'vitest'
77
import { ashbyHandler } from '@/lib/webhooks/providers/ashby'
8+
import type {
9+
AuthContext,
10+
EventMatchContext,
11+
FormatInputContext,
12+
} from '@/lib/webhooks/providers/types'
13+
14+
function authContext(
15+
request: AuthContext['request'],
16+
rawBody: string,
17+
providerConfig: Record<string, unknown>
18+
): AuthContext {
19+
return {
20+
request,
21+
rawBody,
22+
requestId: 'r1',
23+
providerConfig,
24+
webhook: {},
25+
workflow: {},
26+
}
27+
}
28+
29+
function eventMatchContext(body: unknown, triggerId: string): EventMatchContext {
30+
return {
31+
webhook: { id: 'w1' },
32+
workflow: {},
33+
body,
34+
request: createMockRequest('POST', body),
35+
requestId: 'r1',
36+
providerConfig: { triggerId },
37+
}
38+
}
39+
40+
function formatInputContext(body: unknown): FormatInputContext {
41+
return {
42+
webhook: { id: 'w1' },
43+
workflow: { id: 'workflow-1', userId: 'user-1' },
44+
body,
45+
headers: {},
46+
query: {},
47+
method: 'POST',
48+
requestId: 'r1',
49+
}
50+
}
851

952
describe('ashbyHandler', () => {
1053
describe('verifyAuth', () => {
@@ -16,99 +59,65 @@ describe('ashbyHandler', () => {
1659
const request = createMockRequest('POST', JSON.parse(rawBody), {
1760
'ashby-signature': signature,
1861
})
19-
const res = ashbyHandler.verifyAuth!({
20-
request: request as any,
21-
rawBody,
22-
requestId: 'r1',
23-
providerConfig: {},
24-
webhook: {},
25-
workflow: {},
26-
})
62+
const res = ashbyHandler.verifyAuth!(authContext(request, rawBody, {}))
2763
expect(res?.status).toBe(401)
2864
})
2965

3066
it('returns 401 when signature header is missing', () => {
3167
const request = createMockRequest('POST', JSON.parse(rawBody), {})
32-
const res = ashbyHandler.verifyAuth!({
33-
request: request as any,
34-
rawBody,
35-
requestId: 'r1',
36-
providerConfig: { secretToken: secret },
37-
webhook: {},
38-
workflow: {},
39-
})
68+
const res = ashbyHandler.verifyAuth!(authContext(request, rawBody, { secretToken: secret }))
4069
expect(res?.status).toBe(401)
4170
})
4271

4372
it('returns 401 when signature is invalid', () => {
4473
const request = createMockRequest('POST', JSON.parse(rawBody), {
4574
'ashby-signature': 'sha256=deadbeef',
4675
})
47-
const res = ashbyHandler.verifyAuth!({
48-
request: request as any,
49-
rawBody,
50-
requestId: 'r1',
51-
providerConfig: { secretToken: secret },
52-
webhook: {},
53-
workflow: {},
54-
})
76+
const res = ashbyHandler.verifyAuth!(authContext(request, rawBody, { secretToken: secret }))
5577
expect(res?.status).toBe(401)
5678
})
5779

5880
it('returns null when signature is valid', () => {
5981
const request = createMockRequest('POST', JSON.parse(rawBody), {
6082
'ashby-signature': signature,
6183
})
62-
const res = ashbyHandler.verifyAuth!({
63-
request: request as any,
64-
rawBody,
65-
requestId: 'r1',
66-
providerConfig: { secretToken: secret },
67-
webhook: {},
68-
workflow: {},
69-
})
84+
const res = ashbyHandler.verifyAuth!(authContext(request, rawBody, { secretToken: secret }))
7085
expect(res).toBeNull()
7186
})
7287
})
7388

7489
describe('matchEvent', () => {
7590
it('rejects ping events', async () => {
76-
const matched = await ashbyHandler.matchEvent!({
77-
webhook: { id: 'w1' } as any,
78-
body: { action: 'ping', data: { webhookActionType: 'ping' } },
79-
requestId: 'r1',
80-
providerConfig: { triggerId: 'ashby_application_submit' },
81-
} as any)
91+
const matched = await ashbyHandler.matchEvent!(
92+
eventMatchContext(
93+
{ action: 'ping', data: { webhookActionType: 'ping' } },
94+
'ashby_application_submit'
95+
)
96+
)
8297
expect(matched).toBe(false)
8398
})
8499

85100
it('matches when action equals the configured trigger event', async () => {
86-
const matched = await ashbyHandler.matchEvent!({
87-
webhook: { id: 'w1' } as any,
88-
body: { action: 'applicationSubmit', data: {} },
89-
requestId: 'r1',
90-
providerConfig: { triggerId: 'ashby_application_submit' },
91-
} as any)
101+
const matched = await ashbyHandler.matchEvent!(
102+
eventMatchContext({ action: 'applicationSubmit', data: {} }, 'ashby_application_submit')
103+
)
92104
expect(matched).toBe(true)
93105
})
94106

95107
it('rejects when action does not match the configured trigger event', async () => {
96-
const matched = await ashbyHandler.matchEvent!({
97-
webhook: { id: 'w1' } as any,
98-
body: { action: 'jobCreate', data: {} },
99-
requestId: 'r1',
100-
providerConfig: { triggerId: 'ashby_application_submit' },
101-
} as any)
108+
const matched = await ashbyHandler.matchEvent!(
109+
eventMatchContext({ action: 'jobCreate', data: {} }, 'ashby_application_submit')
110+
)
102111
expect(matched).toBe(false)
103112
})
104113

105114
it('matches newly supported Ashby events', async () => {
106-
const matched = await ashbyHandler.matchEvent!({
107-
webhook: { id: 'w1' } as any,
108-
body: { action: 'signatureRequestUpdate', data: {} },
109-
requestId: 'r1',
110-
providerConfig: { triggerId: 'ashby_signature_request_update' },
111-
} as any)
115+
const matched = await ashbyHandler.matchEvent!(
116+
eventMatchContext(
117+
{ action: 'signatureRequestUpdate', data: {} },
118+
'ashby_signature_request_update'
119+
)
120+
)
112121
expect(matched).toBe(true)
113122
})
114123
})
@@ -126,30 +135,30 @@ describe('ashbyHandler', () => {
126135

127136
describe('formatInput', () => {
128137
it('spreads data fields to the top level alongside action', async () => {
129-
const result = await ashbyHandler.formatInput!({
130-
body: {
138+
const result = await ashbyHandler.formatInput!(
139+
formatInputContext({
131140
action: 'applicationSubmit',
132141
data: { application: { id: 'app-1', status: 'Active' } },
133-
},
134-
} as any)
142+
})
143+
)
135144
expect(result.input).toEqual({
136145
action: 'applicationSubmit',
137146
application: { id: 'app-1', status: 'Active' },
138147
})
139148
})
140149

141150
it('renames currentInterviewStage.type to stageType, matching the trigger output schema', async () => {
142-
const result = await ashbyHandler.formatInput!({
143-
body: {
151+
const result = await ashbyHandler.formatInput!(
152+
formatInputContext({
144153
action: 'candidateStageChange',
145154
data: {
146155
application: {
147156
id: 'app-1',
148157
currentInterviewStage: { id: 'stage-1', title: 'Offer', type: 'Offer' },
149158
},
150159
},
151-
},
152-
} as any)
160+
})
161+
)
153162
expect(result.input.application).toEqual({
154163
id: 'app-1',
155164
currentInterviewStage: { id: 'stage-1', title: 'Offer', stageType: 'Offer' },

0 commit comments

Comments
 (0)