Skip to content

Commit 774d97f

Browse files
authored
stringify/parse step.out (#5)
1 parent 24c7694 commit 774d97f

12 files changed

+137
-77
lines changed

src/context/auto-executor.test.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ describe("auto-executor", () => {
129129
"upstash-workflow-init": "false",
130130
"upstash-workflow-url": WORKFLOW_ENDPOINT,
131131
},
132-
body: JSON.stringify(singleStep),
132+
body: JSON.stringify({
133+
...singleStep,
134+
out: JSON.stringify(singleStep.out),
135+
}),
133136
},
134137
],
135138
},

src/context/auto-executor.ts

+2
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ export class AutoExecutor {
377377
// if the step is a single step execution or a plan step, we can add sleep headers
378378
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
379379

380+
singleStep.out = JSON.stringify(singleStep.out);
381+
380382
return singleStep.callUrl
381383
? // if the step is a third party call, we call the third party
382384
// url (singleStep.callUrl) and pass information about the workflow

src/context/context.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ describe("context tests", () => {
134134
token,
135135
body: [
136136
{
137-
body: '{"stepId":1,"stepName":"my-step","stepType":"Run","out":"my-result","concurrent":1}',
137+
body: '{"stepId":1,"stepName":"my-step","stepType":"Run","out":"\\"my-result\\"","concurrent":1}',
138138
destination: WORKFLOW_ENDPOINT,
139139
headers: {
140140
"upstash-feature-set": "WF_NoDelete",

src/integration.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ const testEndpoint = async <TInitialPayload = unknown>({
125125
const { POST: endpoint } = workflowServe<TInitialPayload>(routeFunction, {
126126
qstashClient,
127127
url: `http://localhost:${port}`,
128-
// verbose: true,
128+
verbose: true,
129129
failureFunction,
130130
retries,
131131
});

src/receiver.test.ts

+24-5
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ async function createSignedRequest({
7474
const currentSigningKey = nanoid();
7575
const nextSigningKey = nanoid();
7676

77-
const randomBody = btoa(nanoid());
77+
const randomBodyRaw = nanoid();
78+
const randomBody = btoa(randomBodyRaw);
7879

7980
const token = nanoid();
8081
const qstashClient = new Client({ baseUrl: MOCK_QSTASH_SERVER_URL, token });
@@ -145,6 +146,7 @@ describe("receiver", () => {
145146
await mockQStashServer({
146147
execute: async () => {
147148
const response = await endpoint(requestWithoutSignature);
149+
expect(response.status).toBe(500);
148150
const body = (await response.json()) as FailureFunctionPayload;
149151
expect(body.message).toBe(
150152
"Failed to verify that the Workflow request comes from QStash: Error: `Upstash-Signature` header is not passed.\n\nIf signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.\n\nIf you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY"
@@ -167,6 +169,7 @@ describe("receiver", () => {
167169
await mockQStashServer({
168170
execute: async () => {
169171
const response = await endpoint(requestWithoutSignature);
172+
expect(response.status).toBe(500);
170173
const body = (await response.json()) as FailureFunctionPayload;
171174
expect(body.message).toBe(
172175
"Failed to verify that the Workflow request comes from QStash: SignatureError: Invalid Compact JWS\n\nIf signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.\n\nIf you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY"
@@ -190,7 +193,8 @@ describe("receiver", () => {
190193
await mockQStashServer({
191194
execute: async () => {
192195
called = true;
193-
await endpoint(requestWithHeader);
196+
const response = await endpoint(requestWithHeader);
197+
expect(response.status).toBe(200);
194198
},
195199
responseFields: { body: "msgId", status: 200 },
196200
receivesRequest: {
@@ -223,6 +227,7 @@ describe("receiver", () => {
223227
await mockQStashServer({
224228
execute: async () => {
225229
const response = await endpoint(thirdPartyRequestWithoutHeader);
230+
expect(response.status).toBe(500);
226231
const body = (await response.json()) as FailureFunctionPayload;
227232
expect(body.message).toBe(
228233
"Failed to verify that the Workflow request comes from QStash: Error: `Upstash-Signature` header is not passed.\n\nIf signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.\n\nIf you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY"
@@ -252,6 +257,7 @@ describe("receiver", () => {
252257
await mockQStashServer({
253258
execute: async () => {
254259
const response = await endpoint(thirdPartyRequestWithoutHeader);
260+
expect(response.status).toBe(500);
255261
const body = (await response.json()) as FailureFunctionPayload;
256262
expect(body.message).toBe(
257263
"Failed to verify that the Workflow request comes from QStash: SignatureError: Invalid Compact JWS\n\nIf signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.\n\nIf you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY"
@@ -263,7 +269,13 @@ describe("receiver", () => {
263269
});
264270

265271
test("should allow request with signature", async () => {
266-
const body = JSON.stringify({ status: 200, body: randomBody });
272+
const header = { myHeader: ["my-value"] };
273+
const body = JSON.stringify({
274+
status: 200,
275+
body: randomBody,
276+
header,
277+
otherField: 1,
278+
});
267279
const thirdPartyRequestWithHeader = await createSignedRequest({
268280
url: WORKFLOW_ENDPOINT,
269281
method: "POST",
@@ -284,7 +296,8 @@ describe("receiver", () => {
284296
await mockQStashServer({
285297
execute: async () => {
286298
called = true;
287-
await endpoint(thirdPartyRequestWithHeader);
299+
const response = await endpoint(thirdPartyRequestWithHeader);
300+
expect(response.status).toBe(200);
288301
},
289302
responseFields: { body: "msgId", status: 200 },
290303
receivesRequest: {
@@ -295,7 +308,11 @@ describe("receiver", () => {
295308
stepId: 4,
296309
stepName: "my-step",
297310
stepType: "Run",
298-
out: atob(randomBody),
311+
out: JSON.stringify({
312+
status: 200,
313+
body: randomBodyRaw,
314+
header,
315+
}),
299316
concurrent: 1,
300317
},
301318
},
@@ -328,6 +345,7 @@ describe("receiver", () => {
328345
await mockQStashServer({
329346
execute: async () => {
330347
const response = await endpoint(requestWithoutHeader);
348+
expect(response.status).toBe(500);
331349
const body = (await response.json()) as FailureFunctionPayload;
332350
expect(body.message).toBe(
333351
"Failed to verify that the Workflow request comes from QStash: Error: `Upstash-Signature` header is not passed.\n\nIf signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.\n\nIf you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY"
@@ -351,6 +369,7 @@ describe("receiver", () => {
351369
await mockQStashServer({
352370
execute: async () => {
353371
const response = await endpoint(requestWithoutHeader);
372+
expect(response.status).toBe(500);
354373
const body = (await response.json()) as FailureFunctionPayload;
355374
expect(body.message).toBe(
356375
"Failed to verify that the Workflow request comes from QStash: SignatureError: Invalid Compact JWS\n\nIf signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.\n\nIf you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY"

src/serve/authorization.test.ts

+21-3
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,13 @@ describe("disabled workflow context", () => {
197197
token,
198198
body: [
199199
{
200-
body: '{"stepId":1,"stepName":"step","stepType":"Run","out":"result","concurrent":1}',
200+
body: JSON.stringify({
201+
stepId: 1,
202+
stepName: "step",
203+
stepType: "Run",
204+
out: '"result"',
205+
concurrent: 1,
206+
}),
201207
destination: WORKFLOW_ENDPOINT,
202208
headers: {
203209
"upstash-feature-set": "WF_NoDelete",
@@ -245,7 +251,13 @@ describe("disabled workflow context", () => {
245251
token,
246252
body: [
247253
{
248-
body: '{"stepId":1,"stepName":"step","stepType":"Run","out":"result","concurrent":1}',
254+
body: JSON.stringify({
255+
stepId: 1,
256+
stepName: "step",
257+
stepType: "Run",
258+
out: '"result"',
259+
concurrent: 1,
260+
}),
249261
destination: WORKFLOW_ENDPOINT,
250262
headers: {
251263
"upstash-feature-set": "WF_NoDelete",
@@ -294,7 +306,13 @@ describe("disabled workflow context", () => {
294306
token,
295307
body: [
296308
{
297-
body: '{"stepId":1,"stepName":"step","stepType":"Run","out":"result","concurrent":1}',
309+
body: JSON.stringify({
310+
stepId: 1,
311+
stepName: "step",
312+
stepType: "Run",
313+
out: '"result"',
314+
concurrent: 1,
315+
}),
298316
destination: WORKFLOW_ENDPOINT,
299317
headers: {
300318
"upstash-feature-set": "WF_NoDelete",

src/serve/serve.test.ts

+18-8
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ describe("serve", () => {
4949
});
5050
await mockQStashServer({
5151
execute: async () => {
52-
await endpoint(request);
52+
const response = await endpoint(request);
53+
expect(response.status).toBe(200);
5354
},
5455
responseFields: { body: "msgId", status: 200 },
5556
receivesRequest: {
@@ -93,22 +94,23 @@ describe("serve", () => {
9394
stepId: 1,
9495
stepName: "step1",
9596
stepType: "Run",
96-
out: `processed '${initialPayload}'`,
97+
out: JSON.stringify(`processed '${initialPayload}'`),
9798
concurrent: 1,
9899
},
99100
{
100101
stepId: 2,
101102
stepName: "step2",
102103
stepType: "Run",
103-
out: `processed 'processed '${initialPayload}''`,
104+
out: JSON.stringify(`processed 'processed '${initialPayload}''`),
104105
concurrent: 1,
105106
},
106107
];
107108

108109
await driveWorkflow({
109110
execute: async (initialPayload, steps) => {
110111
const request = getRequest(WORKFLOW_ENDPOINT, workflowRunId, initialPayload, steps);
111-
await endpoint(request);
112+
const response = await endpoint(request);
113+
expect(response.status).toBe(200);
112114
},
113115
initialPayload,
114116
iterations: [
@@ -129,6 +131,7 @@ describe("serve", () => {
129131
headers: {
130132
"content-type": "application/json",
131133
"upstash-forward-upstash-workflow-sdk-version": "1",
134+
"upstash-feature-set": "WF_NoDelete",
132135
"upstash-retries": "3",
133136
"upstash-method": "POST",
134137
"upstash-workflow-runid": workflowRunId,
@@ -155,6 +158,7 @@ describe("serve", () => {
155158
headers: {
156159
"content-type": "application/json",
157160
"upstash-forward-upstash-workflow-sdk-version": "1",
161+
"upstash-feature-set": "WF_NoDelete",
158162
"upstash-method": "POST",
159163
"upstash-retries": "3",
160164
"upstash-workflow-runid": workflowRunId,
@@ -335,7 +339,7 @@ describe("serve", () => {
335339
"upstash-workflow-runid": "wfr-foo",
336340
"upstash-workflow-url": WORKFLOW_ENDPOINT,
337341
},
338-
body: '{"stepId":3,"stepName":"step 3","stepType":"Run","out":"combined results: result 1,result 2","concurrent":1}',
342+
body: '{"stepId":3,"stepName":"step 3","stepType":"Run","out":"\\"combined results: result 1,result 2\\"","concurrent":1}',
339343
},
340344
],
341345
},
@@ -358,7 +362,8 @@ describe("serve", () => {
358362
let called = false;
359363
await mockQStashServer({
360364
execute: async () => {
361-
await endpoint(request);
365+
const result = await endpoint(request);
366+
expect(result.status).toBe(200);
362367
called = true;
363368
},
364369
responseFields: { body: { messageId: "some-message-id" }, status: 200 },
@@ -372,6 +377,7 @@ describe("serve", () => {
372377
headers: {
373378
"content-type": "application/json",
374379
"upstash-delay": "1s",
380+
"upstash-feature-set": "WF_NoDelete",
375381
"upstash-forward-upstash-workflow-sdk-version": "1",
376382
"upstash-method": "POST",
377383
"upstash-retries": "3",
@@ -398,7 +404,8 @@ describe("serve", () => {
398404
let called = false;
399405
await mockQStashServer({
400406
execute: async () => {
401-
await endpoint(request);
407+
const response = await endpoint(request);
408+
expect(response.status).toBe(200);
402409
called = true;
403410
},
404411
responseFields: { body: { messageId: "some-message-id" }, status: 200 },
@@ -415,6 +422,7 @@ describe("serve", () => {
415422
"upstash-forward-upstash-workflow-sdk-version": "1",
416423
"upstash-method": "POST",
417424
"upstash-retries": "3",
425+
"upstash-feature-set": "WF_NoDelete",
418426
"upstash-workflow-init": "false",
419427
"upstash-workflow-runid": "wfr-bar",
420428
"upstash-workflow-url": WORKFLOW_ENDPOINT,
@@ -446,7 +454,8 @@ describe("serve", () => {
446454
});
447455
await mockQStashServer({
448456
execute: async () => {
449-
await endpoint(request);
457+
const response = await endpoint(request);
458+
expect(response.status).toBe(200);
450459
called = true;
451460
},
452461
responseFields: { body: { messageId: "some-message-id" }, status: 200 },
@@ -463,6 +472,7 @@ describe("serve", () => {
463472
"upstash-forward-upstash-workflow-sdk-version": "1",
464473
"upstash-method": "POST",
465474
"upstash-retries": "3",
475+
"upstash-feature-set": "WF_NoDelete",
466476
"upstash-workflow-init": "false",
467477
"upstash-workflow-runid": "wfr-bar",
468478
"upstash-workflow-url": WORKFLOW_ENDPOINT,

src/test-utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export const driveWorkflow = async ({
121121
for (const { stepsToAdd, responseFields, receivesRequest } of iterations) {
122122
steps.push(...stepsToAdd);
123123
await mockQStashServer({
124-
execute: () => execute(initialPayload, steps),
124+
execute: async () => execute(initialPayload, steps),
125125
responseFields,
126126
receivesRequest,
127127
});

0 commit comments

Comments
 (0)