Skip to content

Commit

Permalink
fix: add env typebox validator to worker, fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Keyrxng committed Aug 27, 2024
1 parent 5158cbe commit f5bc1d5
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 22 deletions.
4 changes: 3 additions & 1 deletion src/handlers/shared/check-assignments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ async function getUserStopComments(context: Context, username: string): Promise<
}

export async function hasUserBeenUnassigned(context: Context, username: string): Promise<boolean> {
const { env: { APP_ID } } = context
const {
env: { APP_ID },
} = context;
const events = await getAssignmentEvents(context);
const userAssignments = events.filter((event) => event.assignee === username);

Expand Down
2 changes: 0 additions & 2 deletions src/handlers/shared/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ export async function start(context: Context, issue: Context["payload"]["issue"]
return userId;
});



const assignmentComment = await generateAssignmentComment(context, issue.created_at, issue.number, sender.id, duration);
const logMessage = logger.info("Task assigned successfully", {
taskDeadline: assignmentComment.deadline,
Expand Down
26 changes: 20 additions & 6 deletions src/types/env.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import { Type as T } from "@sinclair/typebox";
import { StaticDecode } from "@sinclair/typebox";
import { StandardValidator } from "typebox-validators";

const ERROR_MSG = "Invalid APP_ID";
export const envSchema = T.Object({
SUPABASE_URL: T.String(),
SUPABASE_KEY: T.String(),
APP_ID: T.Transform(T.Union([T.String(), T.Number()]))
.Decode((val) => {
if (isNaN(Number(val))) {
throw new Error("Invalid APP_ID");
APP_ID: T.Transform(T.Union([T.String(), T.Number()], { examples: 123456 }))
.Decode((value) => {
if (typeof value === "string" && !isNaN(Number(value))) {
return Number(value);
}
return Number(val);
if (typeof value === "number") {
return value;
}
throw new Error(ERROR_MSG);
})
.Encode((encoded) => encoded.toString())
.Encode((value) => {
if (typeof value === "number") {
return value.toString();
}
if (typeof value === "string") {
return value;
}
throw new Error(ERROR_MSG);
}),
});

export type Env = StaticDecode<typeof envSchema>;
export const envConfigValidator = new StandardValidator(envSchema);
6 changes: 2 additions & 4 deletions src/utils/shared.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import ms from "ms";
import { Context, Label } from "../types";
import { Type } from "@sinclair/typebox";
import { Value } from "@sinclair/typebox/value";
import { Label } from "../types";

export function calculateDurations(labels: Label[]): number[] {
// from shortest to longest
Expand All @@ -18,4 +16,4 @@ export function calculateDurations(labels: Label[]): number[] {
});

return durations.sort((a, b) => a - b);
}
}
13 changes: 12 additions & 1 deletion src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Value } from "@sinclair/typebox/value";
import { startStopTask } from "./plugin";
import { Env, startStopSchema, startStopSettingsValidator } from "./types";
import { Env, envConfigValidator, startStopSchema, startStopSettingsValidator } from "./types";
import manifest from "../manifest.json";

export default {
Expand Down Expand Up @@ -36,6 +36,17 @@ export default {
throw new Error("Invalid settings provided");
}

if (!envConfigValidator.test(env)) {
const errorDetails: string[] = [];
for (const error of envConfigValidator.errors(env)) {
errorDetails.push(`${error.path}: ${error.message}`);
}
return new Response(JSON.stringify({ error: `Bad Request: the environment is invalid. ${errorDetails.join("; ")}` }), {
status: 400,
headers: { "content-type": "application/json" },
});
}

webhookPayload.settings = settings;
await startStopTask(webhookPayload, env);
return new Response(JSON.stringify("OK"), { status: 200, headers: { "content-type": "application/json" } });
Expand Down
29 changes: 21 additions & 8 deletions tests/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { drop } from "@mswjs/data";
import { Context, Sender, SupportedEventsU } from "../src/types";
import { Context, envConfigValidator, Sender, SupportedEventsU } from "../src/types";
import { db } from "./__mocks__/db";
import { server } from "./__mocks__/node";
import usersGet from "./__mocks__/users-get.json";
Expand Down Expand Up @@ -198,22 +198,35 @@ describe("User start/stop", () => {
const issue = db.issue.findFirst({ where: { id: { equals: 1 } } }) as unknown as Issue;
const sender = db.users.findFirst({ where: { id: { equals: 1 } } }) as unknown as PayloadSender;

const context = createContext(issue, sender, "/start", null);
const context = createContext(issue, sender, "/start", undefined);

context.env.APP_ID = null as unknown as string;
context.adapters = createAdapters(getSupabase(), context);
const env = { ...context.env };
Reflect.deleteProperty(env, "APP_ID");
if (!envConfigValidator.test(env)) {
const errorDetails: string[] = [];
for (const error of envConfigValidator.errors(env)) {
errorDetails.push(`${error.path}: ${error.message}`);
}

await expect(userStartStop(context)).rejects.toThrow("Invalid APP_ID");
expect(errorDetails).toContain("/APP_ID: Required property");
}
});

test("Should throw if APP_ID is not a number", async () => {
const issue = db.issue.findFirst({ where: { id: { equals: 1 } } }) as unknown as Issue;
const sender = db.users.findFirst({ where: { id: { equals: 1 } } }) as unknown as PayloadSender;

const context = createContext(issue, sender, "/start", "testing-one");
context.adapters = createAdapters(getSupabase(), context);
const env = { ...context.env };

if (!envConfigValidator.test(env)) {
const errorDetails: string[] = [];
for (const error of envConfigValidator.errors(env)) {
errorDetails.push(`${error.path}: ${error.message}`);
}

await expect(userStartStop(context)).rejects.toThrow("Invalid APP_ID");
expect(errorDetails).toContain("Invalid APP_ID");
}
});
});

Expand Down Expand Up @@ -559,7 +572,7 @@ function createContext(
env: {
SUPABASE_KEY: "key",
SUPABASE_URL: "url",
APP_ID: appId as string,
APP_ID: appId as unknown as number,
},
};
}
Expand Down

0 comments on commit f5bc1d5

Please sign in to comment.