Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #38 from BonnierNews/feature/fake-cloud-tasks
Browse files Browse the repository at this point in the history
Fake cloud tasks
  • Loading branch information
MattiasOlla authored Mar 26, 2024
2 parents 4fa7fb4 + 09bfd13 commit 1e3ec00
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 210 deletions.
4 changes: 4 additions & 0 deletions config/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@
"accessKeyId": "REPLACED_BY_ENV",
"secretAccessKey": "REPLACED_BY_ENV"
},
"cloudTasks": {
"queue": "projects/project-id/locations/location/queues/foo-queue",
"selfUrl": "http://example.com"
},
"gcpProxy": { "url": "http://example.com", "audience": "some-audience" }
}
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export { assertRejected, assertRetry, assertUnrecoverable } from "./test/helpers
export { default as buildMessage } from "./test/helpers/build-message.js";
export { default as clone } from "./test/helpers/clone.js";
export { default as fakeApi } from "./test/helpers/fake-api.js";
export * as fakeCloudTask from "./test/helpers/fake-cloud-task.js";
export * as fakeCloudTasks from "./test/helpers/fake-cloud-tasks.js";
export * as fakeFtp from "./test/helpers/fake-ftp.js";
export * as fakeGcpAuth from "./test/helpers/fake-gcp-auth.js";
export * as fakeGcs from "./test/helpers/fake-gcs.js";
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bonniernews/lu-test",
"version": "8.2.1",
"version": "9.0.0",
"description": "Test helpers.",
"main": "index.js",
"engines": {
Expand All @@ -24,7 +24,7 @@
"dependencies": {
"@google-cloud/pubsub": "^4.0.7",
"@google-cloud/storage": "^7.7.0",
"@google-cloud/tasks": "^5.1.0",
"@google-cloud/tasks": "^5.1.1",
"basic-ftp": "^5.0.3",
"chai": "^4.3.10",
"csv-parse": "^5.5.2",
Expand Down
92 changes: 0 additions & 92 deletions test/feature/fake-cloud-task-feature.js

This file was deleted.

212 changes: 212 additions & 0 deletions test/feature/fake-cloud-tasks-feature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import { expect } from "chai";
import { CloudTasksClient } from "@google-cloud/tasks";
import config from "exp-config";
import express from "express";

import * as fakeCloudTasks from "../helpers/fake-cloud-tasks.js";

const expectedExports = [
"enablePublish",
"runSequence",
"processMessages",
"recordedMessages",
"recordedMessageHandlerResponses",
"reset",
];

describe("fake-cloud-task Exposed features", () => {
describe("Importing default export", () => {
it("The right stuff gets exposed", () => {
expect(Object.keys(fakeCloudTasks).sort().join(",")).to.equal(expectedExports.sort().join(","));
});
});
});

Feature("fake-cloud-task feature", () => {
beforeEachScenario(fakeCloudTasks.reset);

Scenario("successfully create a task", () => {
Given("we have enabled publish", async () => {
const app = express();
app.use(express.json());
app.post("/foo/bar", (req, res) => res.status(200).json({ status: "ok" }).send());

await fakeCloudTasks.enablePublish(app);
});

let cloudTask;
And("we have a cloud task instance", () => {
cloudTask = new CloudTasksClient();
});

let response;
When("creating a task", async () => {
response = await cloudTask.createTask({
parent: config.cloudTasks.queue,
task: {
httpRequest: {
url: `${config.cloudTasks.selfUrl}/foo/bar`,
httpMethod: "post",
body: Buffer.from(JSON.stringify({ type: "something", id: "some-id" })),
headers: { correlationId: "some-epic-id" },
},
},
});
});

And("the task has been run", async () => {
await fakeCloudTasks.processMessages();
});

Then("we should have received the task name", () => {
response.should.eql([ { name: "test-task" } ]);
});

And("we should have recorded the message", () => {
fakeCloudTasks.recordedMessages()[0].should.eql({
queue: config.cloudTasks.queue,
httpMethod: "post",
message: { type: "something", id: "some-id" },
url: "/foo/bar",
headers: { correlationId: "some-epic-id" },
correlationId: "some-epic-id",
});
});

And("we should have recorded a message handler response", () => {
fakeCloudTasks
.recordedMessageHandlerResponses()[0]
.should.deep.include({ body: { status: "ok" }, statusCode: 200 });
});
});

Scenario("successfully create a task with a GET request", () => {
Given("we have enabled publish", async () => {
const app = express();
app.use(express.json());
app.get("/foo/bar", (req, res) => res.status(200).json({ status: "ok" }).send());

await fakeCloudTasks.enablePublish(app);
});

let cloudTask;
And("we have a cloud task instance", () => {
cloudTask = new CloudTasksClient();
});

let response;
When("creating a task", async () => {
response = await cloudTask.createTask({
parent: config.cloudTasks.queue,
task: {
httpRequest: {
url: `${config.cloudTasks.selfUrl}/foo/bar`,
httpMethod: "get",
headers: { correlationId: "some-epic-id" },
},
},
});
});

And("the task has been run", async () => {
await fakeCloudTasks.processMessages();
});

Then("we should have received the task name", () => {
response.should.eql([ { name: "test-task" } ]);
});

And("we should have recorded the message", () => {
fakeCloudTasks.recordedMessages()[0].should.eql({
queue: config.cloudTasks.queue,
httpMethod: "get",
url: "/foo/bar",
headers: { correlationId: "some-epic-id" },
correlationId: "some-epic-id",
});
});

And("we should have recorded a message handler response", () => {
fakeCloudTasks
.recordedMessageHandlerResponses()[0]
.should.deep.include({ body: { status: "ok" }, statusCode: 200 });
});
});

Scenario("trying to run sequence without enabling publication", () => {
let error;
When("trying to process messages", async () => {
try {
await fakeCloudTasks.processMessages();
} catch (err) {
error = err;
}
});

Then("we should have received an error", () => {
error.message.should.eql("You must call `enablePublish` before processing messages");
});
});
});

Feature("cloud tasks run-sequence feature", () => {
beforeEachScenario(fakeCloudTasks.reset);

Scenario("successfully run a sequence", () => {
let app;
Given("a broker", () => {
app = express();
app.use(express.json());
app.post("/sequence", (req, res) => {
const cloudTask = new CloudTasksClient();
[ "task1", "task2" ].forEach((task) => {
cloudTask.createTask({
parent: config.cloudTasks.queue,
task: {
httpRequest: {
url: `${config.cloudTasks.selfUrl}/foo/bar`,
httpMethod: "post",
headers: { correlationId: "some-epic-id" },
body: Buffer.from(JSON.stringify({ task })),
},
},
});
});
res.status(200).json({ status: "ok" }).send();
});
app.post("/foo/bar", (req, res) => res.status(200).json({ task: req.body.task }).send());
});

let result;
When("running the sequence", async () => {
result = await fakeCloudTasks.runSequence(app, "/sequence");
});

Then("two messages should have been published", () => {
result.messages.should.eql([
{
message: { task: "task1" },
headers: { correlationId: "some-epic-id" },
httpMethod: "post",
queue: config.cloudTasks.queue,
url: "/foo/bar",
correlationId: "some-epic-id",
},
{
message: { task: "task2" },
headers: { correlationId: "some-epic-id" },
httpMethod: "post",
queue: config.cloudTasks.queue,
url: "/foo/bar",
correlationId: "some-epic-id",
},
]);
});

And("the messages should have been processed", () => {
result.messageHandlerResponses
.map((response) => response.body)
.should.eql([ { task: "task1" }, { task: "task2" } ]);
});
});
});
Loading

0 comments on commit 1e3ec00

Please sign in to comment.