test: split integration tests (@fehmer) (#6807)

- **trigger**
- **test: split integration tests (@fehmer)**
This commit is contained in:
Christian Fehmer 2025-07-30 13:22:40 +02:00 committed by GitHub
parent dd55a7257b
commit c1a681c17f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 321 additions and 172 deletions

View file

@ -1,10 +1,11 @@
import * as Migration from "../../__migration__/testActivity";
import * as UserTestData from "../__testData__/users";
import * as UserDal from "../../src/dal/user";
import * as ResultDal from "../../src/dal/result";
import { DBResult } from "../../src/utils/result";
import * as Migration from "../../../__migration__/testActivity";
import * as UserTestData from "../../__testData__/users";
import * as UserDal from "../../../src/dal/user";
import * as ResultDal from "../../../src/dal/result";
import { DBResult } from "../../../src/utils/result";
import { describeIntegration } from "..";
describe("testActivity migration", () => {
describeIntegration()("testActivity migration", () => {
it("migrates users without results", async () => {
//given
const user1 = await UserTestData.createUser();

View file

@ -1,7 +1,8 @@
import { ObjectId } from "mongodb";
import * as AdminUidsDal from "../../src/dal/admin-uids";
import * as AdminUidsDal from "../../../src/dal/admin-uids";
import { describeIntegration } from "..";
describe("AdminUidsDal", () => {
describeIntegration()("AdminUidsDal", () => {
describe("isAdmin", () => {
it("should return true for existing admin user", async () => {
//GIVEN

View file

@ -1,7 +1,8 @@
import { ObjectId } from "mongodb";
import { addApeKey } from "../../src/dal/ape-keys";
import { addApeKey } from "../../../src/dal/ape-keys";
import { describeIntegration } from "..";
describe("ApeKeysDal", () => {
describeIntegration()("ApeKeysDal", () => {
it("should be able to add a new ape key", async () => {
const apeKey = {
_id: new ObjectId(),

View file

@ -1,7 +1,8 @@
import { ObjectId } from "mongodb";
import * as BlacklistDal from "../../src/dal/blocklist";
import * as BlacklistDal from "../../../src/dal/blocklist";
import { describeIntegration } from "..";
describe("BlocklistDal", () => {
describeIntegration()("BlocklistDal", () => {
describe("add", () => {
beforeEach(() => {
vitest.useFakeTimers();

View file

@ -1,17 +1,19 @@
import _ from "lodash";
import { ObjectId } from "mongodb";
import * as UserDal from "../../src/dal/user";
import * as LeaderboardsDal from "../../src/dal/leaderboards";
import * as PublicDal from "../../src/dal/public";
import * as Configuration from "../../src/init/configuration";
import type { DBLeaderboardEntry } from "../../src/dal/leaderboards";
import * as UserDal from "../../../src/dal/user";
import * as LeaderboardsDal from "../../../src/dal/leaderboards";
import * as PublicDal from "../../../src/dal/public";
import * as Configuration from "../../../src/init/configuration";
import type { DBLeaderboardEntry } from "../../../src/dal/leaderboards";
import type { PersonalBest } from "@monkeytype/schemas/shared";
const configuration = Configuration.getCachedConfiguration();
import * as DB from "../../src/init/db";
import { LbPersonalBests } from "../../src/utils/pb";
import * as DB from "../../../src/init/db";
import { LbPersonalBests } from "../../../src/utils/pb";
import { describeIntegration } from "..";
import { pb } from "../../__testData__/users";
describe("LeaderboardsDal", () => {
describeIntegration()("LeaderboardsDal", () => {
describe("update", () => {
it("should ignore unapplicable users on leaderboard", async () => {
//GIVEN
@ -328,24 +330,6 @@ function lbBests(pb15?: PersonalBest, pb60?: PersonalBest): LbPersonalBests {
return result;
}
export function pb(
wpm: number,
acc: number = 90,
timestamp: number = 1
): PersonalBest {
return {
acc,
consistency: 100,
difficulty: "normal",
lazyMode: false,
language: "english",
punctuation: false,
raw: wpm + 1,
wpm,
timestamp,
};
}
function premium(expirationDeltaSeconds: number) {
return {
premium: {

View file

@ -1,8 +1,9 @@
import { ObjectId } from "mongodb";
import * as PresetDal from "../../src/dal/preset";
import * as PresetDal from "../../../src/dal/preset";
import _ from "lodash";
import { describeIntegration } from "..";
describe("PresetDal", () => {
describeIntegration()("PresetDal", () => {
describe("readPreset", () => {
it("should read", async () => {
//GIVEN

View file

@ -1,6 +1,7 @@
import * as PublicDAL from "../../src/dal/public";
import { describeIntegration } from "..";
import * as PublicDAL from "../../../src/dal/public";
describe("PublicDAL", function () {
describeIntegration()("PublicDAL", function () {
it("should be able to update stats", async function () {
// checks it doesn't throw an error. the actual values are checked in another test.
await PublicDAL.updateStats(1, 15);

View file

@ -1,7 +1,8 @@
import * as ResultDal from "../../src/dal/result";
import * as ResultDal from "../../../src/dal/result";
import { ObjectId } from "mongodb";
import * as UserDal from "../../src/dal/user";
import { DBResult } from "../../src/utils/result";
import * as UserDal from "../../../src/dal/user";
import { DBResult } from "../../../src/utils/result";
import { describeIntegration } from "..";
let uid: string;
const timestamp = Date.now() - 60000;
@ -62,7 +63,7 @@ async function createDummyData(
});
}
}
describe("ResultDal", () => {
describeIntegration()("ResultDal", () => {
beforeEach(() => {
uid = new ObjectId().toHexString();
});

View file

@ -1,10 +1,11 @@
import _ from "lodash";
import * as UserDAL from "../../src/dal/user";
import * as UserTestData from "../__testData__/users";
import * as UserDAL from "../../../src/dal/user";
import * as UserTestData from "../../__testData__/users";
import { ObjectId } from "mongodb";
import { MonkeyMail, ResultFilters } from "@monkeytype/schemas/users";
import { PersonalBest, PersonalBests } from "@monkeytype/schemas/shared";
import { CustomThemeColors } from "@monkeytype/schemas/configs";
import { describeIntegration } from "..";
const mockPersonalBest = {
acc: 1,
@ -85,7 +86,7 @@ const mockResultFilter: ResultFilters = {
const mockDbResultFilter = { ...mockResultFilter, _id: new ObjectId() };
describe("UserDal", () => {
describeIntegration()("UserDal", () => {
it("should be able to insert users", async () => {
// given
const newUser = {

View file

@ -0,0 +1,5 @@
export const isIntegrationTest = process.env["INTEGRATION_TESTS"] === "true";
export function describeIntegration() {
return describe.runIf(isIntegrationTest);
}

View file

@ -0,0 +1,65 @@
import { Collection, Db, MongoClient, WithId } from "mongodb";
import { afterAll, beforeAll, afterEach } from "vitest";
import * as MongoDbMock from "vitest-mongodb";
import { MongoDbMockConfig } from "../global-setup";
import { isIntegrationTest } from ".";
import { setupCommonMocks } from "../setup-common-mocks";
process.env["MODE"] = "dev";
//process.env["MONGOMS_DISTRO"] = "ubuntu-22.04";
if (!isIntegrationTest) {
console.error("wrong environment");
process.exit();
}
if (!process.env["REDIS_URI"]) {
// use mock if not set
process.env["REDIS_URI"] = "redis://mock";
}
let db: Db;
let client: MongoClient;
const collectionsForCleanUp = ["users"];
beforeAll(async () => {
//don't add any configuration here, add to global-setup.ts instead.
console.log("integration setup mongo");
await MongoDbMock.setup(MongoDbMockConfig);
client = new MongoClient(globalThis.__MONGO_URI__);
await client.connect();
db = client.db();
vi.mock("../../src/init/db", () => ({
__esModule: true,
getDb: (): Db => db,
collection: <T>(name: string): Collection<WithId<T>> =>
db.collection<WithId<T>>(name),
close: () => {
//
},
}));
setupCommonMocks();
});
afterEach(async () => {
if (globalThis.__MONGO_URI__) {
await Promise.all(
collectionsForCleanUp.map((collection) =>
db.collection(collection).deleteMany({})
)
);
}
});
afterAll(async () => {
await client?.close();
await MongoDbMock.teardown();
// @ts-ignore
db = undefined;
//@ts-ignore
client = undefined;
vi.resetAllMocks();
});

View file

@ -1,6 +1,7 @@
import * as DB from "../../src/init/db";
import * as UserDAL from "../../src/dal/user";
import { ObjectId } from "mongodb";
import { PersonalBest } from "@monkeytype/schemas/shared";
export async function createUser(
user?: Partial<UserDAL.DBUser>
@ -24,3 +25,21 @@ export async function createUserWithoutMigration(
return await UserDAL.getUser(uid, "test");
}
export function pb(
wpm: number,
acc: number = 90,
timestamp: number = 1
): PersonalBest {
return {
acc,
consistency: 100,
difficulty: "normal",
lazyMode: false,
language: "english",
punctuation: false,
raw: wpm + 1,
wpm,
timestamp,
};
}

View file

@ -36,16 +36,18 @@ describe("Loaderboard Controller", () => {
});
describe("get leaderboard", () => {
const getLeaderboardMock = vi.spyOn(LeaderboardDal, "get");
const getLeaderboardCountMock = vi.spyOn(LeaderboardDal, "getCount");
beforeEach(() => {
getLeaderboardMock.mockReset();
getLeaderboardCountMock.mockReset();
});
it("should get for english time 60", async () => {
//GIVEN
const resultData = {
count: 0,
count: 42,
pageSize: 50,
entries: [
{
@ -78,6 +80,7 @@ describe("Loaderboard Controller", () => {
_id: new ObjectId(),
}));
getLeaderboardMock.mockResolvedValue(mockData);
getLeaderboardCountMock.mockResolvedValue(42);
//WHEN
@ -104,6 +107,7 @@ describe("Loaderboard Controller", () => {
it("should get for english time 60 with page", async () => {
//GIVEN
getLeaderboardMock.mockResolvedValue([]);
getLeaderboardCountMock.mockResolvedValue(0);
const page = 0;
const pageSize = 25;

View file

@ -5,6 +5,7 @@ import * as Configuration from "../../../src/init/configuration";
import * as ResultDal from "../../../src/dal/result";
import * as UserDal from "../../../src/dal/user";
import * as LogsDal from "../../../src/dal/logs";
import * as PublicDal from "../../../src/dal/public";
import { ObjectId } from "mongodb";
import {
mockAuthenticateWithApeKey,
@ -504,6 +505,7 @@ describe("result controller test", () => {
it("should delete", async () => {
//GIVEN
mockAuth.modifyToken({ iat: Date.now() - 1000 });
deleteAllMock.mockResolvedValue(undefined as any);
//WHEN
const { body } = await mockApp
@ -672,22 +674,34 @@ describe("result controller test", () => {
describe("addResult", () => {
//TODO improve test coverage for addResult
const insertedId = new ObjectId();
const getUserMock = vi.spyOn(UserDal, "getUser");
const updateStreakMock = vi.spyOn(UserDal, "updateStreak");
const checkIfTagPbMock = vi.spyOn(UserDal, "checkIfTagPb");
const addResultMock = vi.spyOn(ResultDal, "addResult");
const userGetMock = vi.spyOn(UserDal, "getUser");
const userUpdateStreakMock = vi.spyOn(UserDal, "updateStreak");
const userCheckIfTagPbMock = vi.spyOn(UserDal, "checkIfTagPb");
const userCheckIfPbMock = vi.spyOn(UserDal, "checkIfPb");
const userIncrementXpMock = vi.spyOn(UserDal, "incrementXp");
const userUpdateTypingStatsMock = vi.spyOn(UserDal, "updateTypingStats");
const resultAddMock = vi.spyOn(ResultDal, "addResult");
const publicUpdateStatsMock = vi.spyOn(PublicDal, "updateStats");
beforeEach(async () => {
await enableResultsSaving(true);
[getUserMock, updateStreakMock, checkIfTagPbMock, addResultMock].forEach(
(it) => it.mockReset()
);
[
userGetMock,
userUpdateStreakMock,
userCheckIfTagPbMock,
userCheckIfPbMock,
userIncrementXpMock,
userUpdateTypingStatsMock,
resultAddMock,
publicUpdateStatsMock,
].forEach((it) => it.mockReset());
getUserMock.mockResolvedValue({ name: "bob" } as any);
updateStreakMock.mockResolvedValue(0);
checkIfTagPbMock.mockResolvedValue([]);
addResultMock.mockResolvedValue({ insertedId });
userGetMock.mockResolvedValue({ name: "bob" } as any);
userUpdateStreakMock.mockResolvedValue(0);
userCheckIfTagPbMock.mockResolvedValue([]);
userCheckIfPbMock.mockResolvedValue(true);
resultAddMock.mockResolvedValue({ insertedId });
});
it("should add result", async () => {
@ -749,7 +763,7 @@ describe("result controller test", () => {
insertedId: insertedId.toHexString(),
});
expect(addResultMock).toHaveBeenCalledWith(
expect(resultAddMock).toHaveBeenCalledWith(
uid,
expect.objectContaining({
acc: 86,
@ -783,6 +797,17 @@ describe("result controller test", () => {
wpm: 80,
})
);
expect(publicUpdateStatsMock).toHaveBeenCalledWith(
4,
15.1 + 2 - 5 //duration + incompleteTestSeconds-afk
);
expect(userIncrementXpMock).toHaveBeenCalledWith(uid, 0);
expect(userUpdateTypingStatsMock).toHaveBeenCalledWith(
uid,
4,
15.1 + 2 - 5 //duration + incompleteTestSeconds-afk
);
});
it("should fail if result saving is disabled", async () => {
//GIVEN

View file

@ -20,7 +20,6 @@ import * as ApeKeysDal from "../../../src/dal/ape-keys";
import * as LogDal from "../../../src/dal/logs";
import { ObjectId } from "mongodb";
import { PersonalBest } from "@monkeytype/schemas/shared";
import { pb } from "../../dal/leaderboards.spec";
import {
mockAuthenticateWithApeKey,
mockBearerAuthentication,
@ -31,6 +30,7 @@ import { MonkeyMail, UserStreak } from "@monkeytype/schemas/users";
import MonkeyError, { isFirebaseError } from "../../../src/utils/error";
import { LeaderboardEntry } from "@monkeytype/schemas/leaderboards";
import * as WeeklyXpLeaderboard from "../../../src/services/weekly-xp-leaderboard";
import { pb } from "../../__testData__/users";
const mockApp = request(app);
const configuration = Configuration.getCachedConfiguration();
@ -41,43 +41,7 @@ describe("user controller test", () => {
beforeEach(() => {
mockAuth.beforeEach();
});
describe("user creation flow", () => {
beforeEach(async () => {
await enableSignup(true);
});
it("should be able to check name, sign up, and get user data", async () => {
await mockApp.get("/users/checkName/NewUser").expect(200);
const newUser = {
name: "NewUser",
uid,
email: "newuser@mail.com",
captcha: "captcha",
};
await mockApp
.post("/users/signup")
.set("Authorization", `Bearer ${uid}`)
.send(newUser)
.expect(200);
const response = await mockApp
.get("/users")
.set("Authorization", `Bearer ${uid}`)
.send()
.expect(200);
const {
body: { data: userData },
} = response;
expect(userData.name).toBe(newUser.name);
expect(userData.email).toBe(newUser.email);
expect(userData.uid).toBe(newUser.uid);
await mockApp.get("/users/checkName/NewUser").expect(409);
});
});
describe("user signup", () => {
const blocklistContainsMock = vi.spyOn(BlocklistDal, "contains");
const firebaseDeleteUserMock = vi.spyOn(AuthUtils, "deleteUser");
@ -253,6 +217,64 @@ describe("user controller test", () => {
});
});
});
describe("checkName", () => {
const userIsNameAvailableMock = vi.spyOn(UserDal, "isNameAvailable");
beforeEach(() => {
userIsNameAvailableMock.mockReset();
});
it("returns ok if name is available", async () => {
//GIVEN
userIsNameAvailableMock.mockResolvedValue(true);
//WHEN
const { body } = await mockApp
.get("/users/checkName/bob")
//no authentication required
.expect(200);
//THEN
expect(body).toEqual({
message: "Username available",
data: null,
});
expect(userIsNameAvailableMock).toHaveBeenCalledWith("bob", "");
});
it("returns 409 if name is not available", async () => {
//GIVEN
userIsNameAvailableMock.mockResolvedValue(false);
//WHEN
const { body } = await mockApp
.get("/users/checkName/bob")
//no authentication required
.expect(409);
//THEN
expect(body.message).toEqual("Username unavailable");
expect(userIsNameAvailableMock).toHaveBeenCalledWith("bob", "");
});
it("returns ok if name is our own", async () => {
//GIVEN
userIsNameAvailableMock.mockResolvedValue(true);
//WHEN
const { body } = await mockApp
.get("/users/checkName/bob")
.set("Authorization", `Bearer ${uid}`)
.expect(200);
//THEN
expect(body).toEqual({
message: "Username available",
data: null,
});
expect(userIsNameAvailableMock).toHaveBeenCalledWith("bob", uid);
});
});
describe("sendVerificationEmail", () => {
const adminGetUserMock = vi.fn();
const adminGenerateVerificationLinkMock = vi.fn();
@ -602,6 +624,7 @@ describe("user controller test", () => {
"purgeUserFromXpLeaderboards"
);
const blocklistAddMock = vi.spyOn(BlocklistDal, "add");
const logsDeleteUserMock = vi.spyOn(LogDal, "deleteUserLogs");
beforeEach(() => {
mockAuth.beforeEach();
@ -631,6 +654,7 @@ describe("user controller test", () => {
deleteAllPresetsMock,
purgeUserFromDailyLeaderboardsMock,
purgeUserFromXpLeaderboardsMock,
logsDeleteUserMock,
].forEach((it) => it.mockReset());
});
@ -668,6 +692,7 @@ describe("user controller test", () => {
uid,
(await configuration).leaderboards.weeklyXp
);
expect(logsDeleteUserMock).toHaveBeenCalledWith(uid);
});
it("should delete user without adding to blocklist if not banned", async () => {
//GIVEN
@ -702,6 +727,7 @@ describe("user controller test", () => {
uid,
(await configuration).leaderboards.weeklyXp
);
expect(logsDeleteUserMock).toHaveBeenCalledWith(uid);
});
it("should not fail if userInfo cannot be found", async () => {
@ -731,6 +757,7 @@ describe("user controller test", () => {
uid,
(await configuration).leaderboards.weeklyXp
);
expect(logsDeleteUserMock).toHaveBeenCalledWith(uid);
});
it("should fail for unknown error from UserDal", async () => {
@ -759,6 +786,7 @@ describe("user controller test", () => {
uid,
(await configuration).leaderboards.weeklyXp
);
expect(logsDeleteUserMock).not.toHaveBeenCalled();
});
it("should not fail if firebase user cannot be found", async () => {
//GIVEN
@ -798,6 +826,7 @@ describe("user controller test", () => {
uid,
(await configuration).leaderboards.weeklyXp
);
expect(logsDeleteUserMock).toHaveBeenCalledWith(uid);
});
it("should fail for unknown error from firebase", async () => {
@ -3392,9 +3421,8 @@ describe("user controller test", () => {
//WHEN
const { body } = await mockApp
.patch("/users/inbox")
.set("Authorization", `Bearer ${uid}`);
//.expect(200);
console.log(body);
.set("Authorization", `Bearer ${uid}`)
.expect(200);
//THEN
expect(body).toEqual({

View file

@ -1,11 +1,17 @@
import * as MongoDbMock from "vitest-mongodb";
import { isIntegrationTest } from "./__integration__";
export async function setup(): Promise<void> {
process.env.TZ = "UTC";
await MongoDbMock.setup(MongoDbMockConfig);
if (isIntegrationTest) {
console.log("integration download mongomock");
await MongoDbMock.setup(MongoDbMockConfig);
}
}
export async function teardown(): Promise<void> {
await MongoDbMock.teardown();
if (isIntegrationTest) {
await MongoDbMock.teardown();
}
}
export const MongoDbMockConfig = {

View file

@ -0,0 +1,40 @@
export function setupCommonMocks() {
vi.mock("../src/utils/logger", () => ({
__esModule: true,
default: {
error: console.error,
warning: console.warn,
info: console.info,
success: console.info,
logToDb: console.info,
},
}));
vi.mock("swagger-stats", () => ({
getMiddleware:
() =>
(_: unknown, __: unknown, next: () => unknown): void => {
next();
},
}));
// TODO: better approach for this when needed
// https://firebase.google.com/docs/rules/unit-tests#run_local_unit_tests_with_the_version_9_javascript_sdk
vi.mock("firebase-admin", () => ({
__esModule: true,
default: {
auth: (): unknown => ({
verifyIdToken: (
_token: string,
_checkRevoked: boolean
): unknown /* Promise<DecodedIdToken> */ =>
Promise.resolve({
aud: "mockFirebaseProjectId",
auth_time: 123,
exp: 1000,
uid: "mockUid",
}),
}),
},
}));
}

View file

@ -1,94 +1,51 @@
import { Collection, Db, MongoClient, WithId } from "mongodb";
import { afterAll, beforeAll, afterEach } from "vitest";
import * as MongoDbMock from "vitest-mongodb";
import { MongoDbMockConfig } from "./global-setup";
import { isIntegrationTest } from "./__integration__";
import { BASE_CONFIGURATION } from "../src/constants/base-configuration";
import { setupCommonMocks } from "./setup-common-mocks";
process.env["MODE"] = "dev";
//process.env["MONGOMS_DISTRO"] = "ubuntu-22.04";
if (isIntegrationTest) {
console.error("wrong environment");
process.exit();
}
if (!process.env["REDIS_URI"]) {
// use mock if not set
process.env["REDIS_URI"] = "redis://mock";
}
let db: Db;
let client: MongoClient;
const collectionsForCleanUp = ["users"];
beforeAll(async () => {
//don't add any configuration here, add to global-setup.ts instead.
await MongoDbMock.setup(MongoDbMockConfig);
client = new MongoClient(globalThis.__MONGO_URI__);
await client.connect();
db = client.db();
vi.mock("../src/dal/logs", () => ({
addLog: vi.fn(),
addImportantLog: vi.fn(),
deleteUserLogs: vi.fn(),
}));
vi.mock("../src/init/configuration", () => ({
getLiveConfiguration: () => BASE_CONFIGURATION,
getCachedConfiguration: () => BASE_CONFIGURATION,
patchConfiguration: vi.fn(),
}));
vi.mock("../src/init/db", () => ({
__esModule: true,
getDb: (): Db => db,
collection: <T>(name: string): Collection<WithId<T>> =>
db.collection<WithId<T>>(name),
getDb: () => undefined,
collection: () => undefined,
close: () => {
//
},
}));
vi.mock("../src/utils/logger", () => ({
__esModule: true,
default: {
error: console.error,
warning: console.warn,
info: console.info,
success: console.info,
logToDb: console.info,
},
}));
vi.mock("swagger-stats", () => ({
getMiddleware:
() =>
(_: unknown, __: unknown, next: () => unknown): void => {
next();
},
}));
// TODO: better approach for this when needed
// https://firebase.google.com/docs/rules/unit-tests#run_local_unit_tests_with_the_version_9_javascript_sdk
vi.mock("firebase-admin", () => ({
__esModule: true,
default: {
auth: (): unknown => ({
verifyIdToken: (
_token: string,
_checkRevoked: boolean
): unknown /* Promise<DecodedIdToken> */ =>
Promise.resolve({
aud: "mockFirebaseProjectId",
auth_time: 123,
exp: 1000,
uid: "mockUid",
}),
}),
},
}));
setupCommonMocks();
});
afterEach(async () => {
if (globalThis.__MONGO_URI__) {
await Promise.all(
collectionsForCleanUp.map((collection) =>
db.collection(collection).deleteMany({})
)
);
}
//noting
});
afterAll(async () => {
await client?.close();
await MongoDbMock.teardown();
// @ts-ignore
db = undefined;
//@ts-ignore
client = undefined;
vi.resetAllMocks();
});

View file

@ -12,7 +12,8 @@
"clean": "tsc --build --clean",
"ts-check": "tsc --noEmit",
"start": "node ./dist/server.js",
"test": "vitest run",
"test": "vitest run --exclude '__tests__/__integration__'",
"integration-test": "INTEGRATION_TESTS=true vitest run __integration__",
"test-coverage": "vitest run --coverage",
"dev": "concurrently -p none \"tsx watch --clear-screen=false --inspect ./src/server.ts\" \"tsc --preserveWatchOutput --noEmit --watch\" \"esw src/ -w --ext .ts --cache --color\"",
"knip": "knip",

View file

@ -1,11 +1,14 @@
import { defineConfig } from "vitest/config";
const isIntegrationTest = process.env["INTEGRATION_TESTS"] === "true";
export default defineConfig({
test: {
globals: true,
environment: "node",
globalSetup: "__tests__/global-setup.ts",
setupFiles: ["__tests__/setup-tests.ts"],
setupFiles: isIntegrationTest
? ["__tests__/__integration__/setup-integration-tests.ts"]
: ["__tests__/setup-tests.ts"],
pool: "forks", //this should be the default value, however the CI fails without this set.
coverage: {

View file

@ -22,7 +22,7 @@
"build-fe": "turbo run build --filter @monkeytype/frontend",
"build-pkg": "turbo run build --filter=\"./packages/*\"",
"test": "turbo run test",
"test-be": "turbo run test --filter @monkeytype/backend",
"test-be": "turbo run test --filter @monkeytype/backend && turbo run integration-test --filter @monkeytype/backend",
"test-fe": "turbo run test --filter @monkeytype/frontend",
"test-pkg": "turbo run test --filter=\"./packages/*\"",
"dev": "turbo run dev --force",

View file

@ -19,6 +19,10 @@
"dependsOn": ["^build"],
"cache": false
},
"integration-test": {
"dependsOn": ["^build"],
"cache": false
},
"dev": {
"dependsOn": ["^build"],
"persistent": true,