Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: trcp recipes #1237

Merged
merged 12 commits into from
Jan 14, 2024
7 changes: 7 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ jobs:
- run:
name: migrate
command: npx prisma migrate dev
- run:
name: start api
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

command: npx ts-node --swc --project packages/backend/tsconfig.json packages/backend/src/bin/www
background: true
- run:
name: wait for api
command: dockerize -wait tcp://localhost:3000 -timeout 30s
- run:
name: lint, typecheck, test, build
command: npx nx run-many --targets=lint,typecheck,test,build
Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"@angular/language-service": "16.1.0",
"@babel/preset-env": "^7.23.3",
"@capacitor/cli": "5.5.1",
"@faker-js/faker": "^8.3.1",
"@ionic/angular-toolkit": "9.0.0",
"@nx/devkit": "17.1.2",
"@nx/eslint": "17.1.2",
Expand Down
1 change: 0 additions & 1 deletion packages/backend/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ export default {
preset: "../../jest.preset.js",
testEnvironment: "node",
testPathIgnorePatterns: ["dist/"],
testTimeout: 20000,
};
7 changes: 7 additions & 0 deletions packages/trpc/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable */
export default {
displayName: "trpc",
preset: "../../jest.preset.js",
testEnvironment: "node",
testPathIgnorePatterns: ["dist/"],
};
8 changes: 8 additions & 0 deletions packages/trpc/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
"lintFilePatterns": ["packages/trpc/**/*.ts"],
"maxWarnings": 0
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": [],
"options": {
"jestConfig": "packages/trpc/jest.config.ts",
"runInBand": true
}
}
}
}
46 changes: 46 additions & 0 deletions packages/trpc/src/procedures/recipes/createRecipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { trpcSetup, tearDown } from "../../testutils";
import { prisma } from "@recipesage/prisma";
import { User } from "@prisma/client";
import type { CreateTRPCProxyClient } from "@trpc/client";
import type { AppRouter } from "../../index";
import { faker } from "@faker-js/faker";

describe("createRecipe", () => {
let user: User;
let trpc: CreateTRPCProxyClient<AppRouter>;

beforeAll(async () => {
({ user, trpc } = await trpcSetup());
});

afterAll(() => {
return tearDown(user.id);
});

it("creates a recipe with all parameters provided", async () => {
const recipe = await trpc.recipes.createRecipe.mutate({
title: faker.string.alphanumeric(10),
description: faker.string.alphanumeric(10),
yield: faker.string.alphanumeric(10),
folder: "main",
activeTime: faker.string.alphanumeric(10),
totalTime: faker.string.alphanumeric(10),
source: faker.string.alphanumeric(10),
url: faker.string.alphanumeric(10),
notes: faker.string.alphanumeric(10),
ingredients: faker.string.alphanumeric(10),
instructions: faker.string.alphanumeric(10),
rating: faker.number.int({ min: 1, max: 5 }),
labelIds: [],
imageIds: [],
});

expect(typeof recipe.id).toBe("string");
const response = await prisma.recipe.findUnique({
where: {
id: recipe.id,
},
});
expect(typeof response?.id).toBe("string");
});
});
52 changes: 52 additions & 0 deletions packages/trpc/src/procedures/recipes/deleteRecipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { trpcSetup, tearDown } from "../../testutils";
import { prisma } from "@recipesage/prisma";
import { User } from "@prisma/client";
import type { CreateTRPCProxyClient } from "@trpc/client";
import type { AppRouter } from "../../index";
import { faker } from "@faker-js/faker";

describe("deleteRecipe", () => {
let user: User;
let trpc: CreateTRPCProxyClient<AppRouter>;

beforeAll(async () => {
({ user, trpc } = await trpcSetup());
});

afterAll(() => {
return tearDown(user.id);
});

it("deletes a recipe", async () => {
const recipe = await prisma.recipe.create({
data: {
userId: user.id,
title: faker.string.alphanumeric(10),
description: faker.string.alphanumeric(10),
yield: faker.string.alphanumeric(10),
folder: "inbox",
activeTime: faker.string.alphanumeric(10),
totalTime: faker.string.alphanumeric(10),
source: faker.string.alphanumeric(10),
url: faker.string.alphanumeric(10),
notes: faker.string.alphanumeric(10),
ingredients: faker.string.alphanumeric(10),
instructions: faker.string.alphanumeric(10),
rating: faker.number.int({ min: 1, max: 5 }),
},
});

const response = await trpc.recipes.deleteRecipe.mutate({
id: recipe.id,
});

expect(response).toEqual("Ok");

const response2 = await prisma.recipe.findUnique({
where: {
id: recipe.id,
},
});
expect(response2).toEqual(null);
});
});
49 changes: 49 additions & 0 deletions packages/trpc/src/procedures/recipes/getRecipes.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { trpcSetup, tearDown } from "../../testutils";
import { prisma } from "@recipesage/prisma";
import { User } from "@prisma/client";
import type { CreateTRPCProxyClient } from "@trpc/client";
import type { AppRouter } from "../../index";
import { faker } from "@faker-js/faker";

describe("getRecipes", () => {
let user: User;
let trpc: CreateTRPCProxyClient<AppRouter>;

beforeAll(async () => {
({ user, trpc } = await trpcSetup());
});

afterAll(() => {
return tearDown(user.id);
});

it("returns a list of recipes given no filters", async () => {
await prisma.recipe.create({
data: {
userId: user.id,
title: faker.string.alphanumeric(10),
description: faker.string.alphanumeric(10),
yield: faker.string.alphanumeric(10),
folder: "main",
activeTime: faker.string.alphanumeric(10),
totalTime: faker.string.alphanumeric(10),
source: faker.string.alphanumeric(10),
url: faker.string.alphanumeric(10),
notes: faker.string.alphanumeric(10),
ingredients: faker.string.alphanumeric(10),
instructions: faker.string.alphanumeric(10),
rating: faker.number.int({ min: 1, max: 5 }),
},
});

const response = await trpc.recipes.getRecipes.query({
limit: 3,
folder: "main",
orderBy: "title",
orderDirection: "asc",
offset: 0,
});

expect(typeof response.recipes[0].id).toBe("string");
});
});
65 changes: 65 additions & 0 deletions packages/trpc/src/testutils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { prisma } from "@recipesage/prisma";
import { createTRPCProxyClient, httpLink } from "@trpc/client";
import type { AppRouter } from "./index";
import superjson from "superjson";
import { faker } from "@faker-js/faker";

export async function trpcSetup() {
const user = await createUser();
const session = await createSession(user.id);
const trpc = await createTrpcClient(session.token as string);
return { user, session, trpc };
}

export async function tearDown(userId: string) {
await prisma.user.delete({
where: {
id: userId,
},
});
}

export async function createTrpcClient(token: string) {
return createTRPCProxyClient<AppRouter>({
links: [
httpLink({
url: "http://localhost:3000/trpc",
headers: () => {
return {
Authorization: token ? `Bearer ${token}` : undefined,
};
},
}),
],
transformer: superjson,
});
}

export async function createUser() {
return prisma.user.create({
data: {
name: faker.person.fullName(),
email: faker.internet.email(),
passwordHash:
"SaVNC9ubXV8BHykB2wAD0mhxPwh/W7O7Rz+qRy/PeV+GeeakLzkv2TSghPQvLTe07b7TqxdsRUt39lC3RaaWmhORkVS9UbtEIh9dzvcbj9VzHA0ex0k97nv0lE56Jh6D6M5Laxe2BrkpiUibP3yCDCk75vCHtLGTZVjqtabTGheIs/QwiD72C7H+bK4QSL2RYSOEbB0wysNAC5nF8r1m36FB/DS5wEixOWiQH470H1s9yHODAALNag9Lom+It4P3cMSSa83mxPNvFOniEpuDDcI5W/Oxef/XiA3EhMLL8n4+CSV1Z891g65U7j7RIKSCjK1LbCvQ5JuS/jZCErNBW9472TXdGKGeYY6RTDgSBzqISyxlMCSRBsNjToWHJyPEyEbt0BTSjTkliB+0wSQpdzUiDDiJNrLVimAriH/AcU/eFvpU5YyyY1coY8Kc80LxKxP/p881Q0DABCmaRcDH+/1iEz3SoWNvSsw/Xq8u9LcgKCjccDoD8tKBDkMijS7TBPu9zJd2nUqblPO+KTGz7hVqh/u0VQ+xEdvRQuKSc+4OnUtQRVCAFQGB99hfXfQvffeGosNy3BABEuZkobaUgs8m8RTaRFGqy8qk6BYw1bk5I5KjjmA8GNOtNHlKQ+1EZO83pIKbG61Jfm93FJ6CsWji9fXsxaBsv+JNBhRgmUw=",
passwordSalt:
"dM4YXu5N5XY4c0LXnf30vtshh7dgsBYZ/5pZockgcJofPkWhMOplVAoWKhyqODZhO3mSUBqMqo3kXC2+7fOMt1NFB0Q1iRcJ4zaqAqdTenyjXu7rJ8WpgR1qnTcnpP8g/frQ+sk8Kcv49OC84R3v+FD8RrGm0rz8dDt7m7c/+Rw=",
passwordVersion: 2,
},
});
}

export const createSession = (userId: string) => {
const today = new Date();
const tomorrow = new Date();
tomorrow.setDate(today.getDate() + 1);

return prisma.session.create({
data: {
userId,
token: faker.string.alphanumeric(40),
type: "user",
expires: tomorrow,
},
});
};
4 changes: 3 additions & 1 deletion packages/trpc/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist"
"outDir": "./dist",
"allowJs": true,
"module": "commonjs"
},
"include": ["src/**/*.ts"]
}
14 changes: 14 additions & 0 deletions packages/trpc/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}