Skip to content

Commit

Permalink
ci: add deployed cf and nextjs-12 tests
Browse files Browse the repository at this point in the history
  • Loading branch information
CahidArda committed Nov 10, 2024
1 parent 0509131 commit b0fefce
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 73 deletions.
2 changes: 1 addition & 1 deletion examples/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/vercel": "^7.8.2",
"@upstash/workflow": "0.1.2-canary-astro",
"@upstash/workflow": "latest",
"astro": "^4.16.7",
"typescript": "^5.6.3"
},
Expand Down
65 changes: 65 additions & 0 deletions examples/cloudflare-workers-hono/ci.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

import { Client } from "@upstash/qstash"
import { Redis } from "@upstash/redis"
import { serve } from "@upstash/workflow/nextjs"
import { describe, test, expect } from "bun:test"

const qstashClient = new Client({
baseUrl: "https://workflow-tests.requestcatcher.com/",
token: "mock"
})

// @ts-expect-error mocking publishJSON
qstashClient.publishJSON = async () => {
return { messageId: "msgId" }
}

const { POST: serveHandler } = serve(
async (context) => {
await context.sleep("sleeping", 10)
}, {
qstashClient,
receiver: undefined
}
)

describe("cloudflare workers tests", () => {
test("should send first invocation", async () => {
const request = new Request("https://workflow-tests.requestcatcher.com/")
const response = await serveHandler(request)

// it should send a request, but get failed to parse error because
// request catcher returns string
expect(response.status).toBe(200)
const result = await response.json() as { workflowRunId: string }
expect(result.workflowRunId).toBeTruthy()
})

if (process.env.DEPLOYMENT_URL) {
test("should run workflow successfully", async () => {
const redis = Redis.fromEnv()
const client = new Client({ token: process.env.QSTASH_TOKEN! })

const secret = "secret" + Math.floor(Math.random() * 10000).toString()
await client.publishJSON({
url: `${process.env.DEPLOYMENT_URL}/ci`,
body: { text: "hello world!" },
method: "POST",
headers: {
"Content-type": "text/plain",
"secret-header": secret
}
})

await new Promise(r => setTimeout(r, 3000));

const result = await redis.get<string>(`ci-cf-ran-${secret}`)

if (result !== secret) {
throw new Error("Cloudflare workflow didn't run")
}
})
} else {
console.log("skipping workflow run tests because DEPLOYMENT_URL is not set");
}
})
1 change: 1 addition & 0 deletions examples/cloudflare-workers-hono/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.0.0",
"dependencies": {
"@upstash/qstash": "latest",
"@upstash/redis": "^1.34.3",
"@upstash/workflow": "latest",
"hono": "^4.5.8"
},
Expand Down
34 changes: 34 additions & 0 deletions examples/cloudflare-workers-hono/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Hono } from "hono";
import { serve, WorkflowBindings } from "@upstash/workflow/hono";
import { landingPage } from "./page";
import { Redis } from "@upstash/redis/cloudflare";

const app = new Hono<{ Bindings: WorkflowBindings }>();

Expand Down Expand Up @@ -34,4 +35,37 @@ app.post(
),
);

/**
* endpoint for the ci tests
*/
app.post(
"/ci",
serve<{ text: string }>(
async (context) => {
const input = context.requestPayload.text;
const result1 = await context.run("step1", async () => {
const output = someWork(input);
console.log("step 1 input", input, "output", output);
return output;
});

await context.sleep("sleep", 1);

const secret = context.headers.get("secret-header")
if (!secret) {
console.error("secret not found");
throw new Error("secret not found. can't end the CI workflow")
} else {
console.log("saving secret to redis");
// @ts-expect-error env isn't typed
const redis = Redis.fromEnv(context.env)
await redis.set(`ci-cf-ran-${secret}`, secret)
}
},
{
receiver: undefined,
},
),
);

export default app;
2 changes: 1 addition & 1 deletion examples/cloudflare-workers-hono/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
name = "upstash-workflow-cf-hono"
main = "src/index.ts"
compatibility_date = "2024-08-15"
compatibility_flags = ["nodejs_compat"]
compatibility_flags = ["nodejs_compat"]
34 changes: 0 additions & 34 deletions examples/cloudflare-workers/ci.test.ts

This file was deleted.

25 changes: 0 additions & 25 deletions examples/cloudflare-workers/test/index.spec.ts

This file was deleted.

39 changes: 38 additions & 1 deletion examples/nextjs-12/ci.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// this file is need for the Node 18 test

import { Client } from "@upstash/qstash"
import { Redis } from "@upstash/redis"
import { serve } from "@upstash/workflow/nextjs"

const qstashClient = new Client({
Expand All @@ -12,6 +13,8 @@ qstashClient.publishJSON = async () => {
return { messageId: "msgId" }
}

console.log(">>> TESTING INITIAL INVOCATION")

const { POST: serveHandler } = serve(
async (context) => {
await context.sleep("sleeping", 10)
Expand All @@ -33,4 +36,38 @@ if (status !== 200) {
if (!body.workflowRunId) {
throw new Error(`ci failed. body doesn't have workflowRunId field. status: ${status}, body: ${body}`)
}
console.log(">>> CI SUCCESFUL")

console.log(">>> TESTED INITIAL INVOCATION SUCCESFULLY")

const deploymentUrl = process.env.DEPLOYMENT_URL
if (deploymentUrl) {
console.log(">>> TESTING WORKFLOW RUN")

const client = new Client({
token: process.env.QSTASH_TOKEN,
})
const redis = Redis.fromEnv()

const secret = Math.floor(Math.random() * 10000).toString()
await client.publishJSON({
url: `${deploymentUrl}/api/ci`,
method: "POST",
body: "hello world!",
headers: {
"Content-type": "text/plain",
"secret-header": secret
}
})

await new Promise(r => setTimeout(r, 3000));

const result = await redis.get(`ci-cf-ran-${secret}`)

if (result.toString() !== secret) {
throw new Error("Cloudflare workflow didn't run")
}

console.log(">>> TESTED WORKFLOW RUN SUCCESFULLY")
} else {
console.warn(">>> SKIPPING WORKFLOW RUN TEST. DEPLOYMENT_URL NOT SET")
}
4 changes: 3 additions & 1 deletion examples/nextjs-12/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"lint": "next lint"
},
"dependencies": {
"@upstash/workflow": "^0.1.2",
"@upstash/redis": "^1.34.3",
"@upstash/qstash": "latest",
"@upstash/workflow": "latest",
"next": "12.3.4",
"react": "18.3.1",
"react-dom": "18.3.1"
Expand Down
49 changes: 49 additions & 0 deletions examples/nextjs-12/pages/api/ci.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* this endpoint is for the CI of @upstash/workflow.
*
* refer to workflow.js for a simpler example.
*/
import { servePagesRouter } from "@upstash/workflow/nextjs";
import { Redis } from "@upstash/redis"

const someWork = (input) => {
return `processed '${JSON.stringify(input)}'`
}

const baseUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: process.env.UPSTASH_WORKFLOW_URL
? process.env.UPSTASH_WORKFLOW_URL
: "http://localhost:3001"

const endpointUrl = `${baseUrl}/api/ci`

const redis = Redis.fromEnv()

const { handler } = servePagesRouter(
async (context) => {
const input = context.requestPayload
const result1 = await context.run("step1", async () => {
const output = someWork(input)
console.log("step 1 input", input, "output", output)
return output
});

await context.sleep("sleep", 1);

const secret = context.headers.get("secret-header")
if (!secret) {
console.error("secret not found");
throw new Error("secret not found. can't end the CI workflow")
} else {
console.log("saving secret to redis");
await redis.set(`ci-cf-ran-${secret}`, secret)
}
},
{
retries: 0,
url: endpointUrl
}
)

export default handler
5 changes: 1 addition & 4 deletions examples/nextjs-12/pages/api/workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ const { handler } = servePagesRouter(
});
},
{
receiver: undefined,
url: endpointUrl
}
)

export default async (request, response) => {
return handler(request, response)
}
export default handler
15 changes: 9 additions & 6 deletions examples/nextjs/ci.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ const qstashClient = new Client({
token: "mock"
})

// @ts-expect-error mocking publishJSON
qstashClient.publishJSON = async () => {
return { messageId: "msgId" }
}

const { POST: serveHandler } = serve(
async (context) => {
await context.sleep("sleeping", 10)
Expand All @@ -18,16 +23,14 @@ const { POST: serveHandler } = serve(
)

describe("nextjs tests", () => {
test("first invocation", async () => {
test("should send first invocation", async () => {
const request = new Request("https://workflow-tests.requestcatcher.com/")
const response = await serveHandler(request)

// it should send a request, but get failed to parse error because
// request catcher returns string
expect(response.status).toBe(500)
expect(await response.json()).toEqual({
error: "SyntaxError",
message: "Failed to parse JSON",
})
expect(response.status).toBe(200)
const result = await response.json()
expect(result.workflowRunId).toBeTruthy()
})
})

0 comments on commit b0fefce

Please sign in to comment.