feat(infisical-pg): added e2e test setup

This commit is contained in:
Akhil Mohan
2023-12-12 16:20:36 +05:30
parent 3670b16657
commit 1df7b88abf
16 changed files with 2854 additions and 46 deletions

3
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# backend
node_modules
.env
.env.test
.env.dev
.env.gamma
.env.prod
@@ -61,4 +62,4 @@ yarn-error.log*
# Editor specific
.vscode/*
frontend-build
frontend-build

View File

@@ -1 +1,3 @@
.eslintrc.js
vitest-environment-infisical.ts
vitest.config.ts

View File

@@ -0,0 +1,10 @@
import { TSmtpSendMail, TSmtpService } from "@app/services/smtp/smtp-service";
export const mockSmtpServer = (): TSmtpService => {
const storage: TSmtpSendMail[] = [];
return {
sendMail: async (data) => {
storage.push(data);
}
};
};

View File

@@ -0,0 +1,9 @@
describe("Status V1 Router", async () => {
test("Simple check", async () => {
const res = await testServer.inject({
method: "GET",
url: "/api/status"
});
expect(res.statusCode).toBe(200);
});
});

View File

@@ -0,0 +1,56 @@
// import { main } from "@app/server/app";
import { initEnvConfig } from "@app/lib/config/env";
import dotenv from "dotenv";
import knex from "knex";
import path from "path";
import { mockSmtpServer } from "./mocks/smtp";
import { initLogger } from "@app/lib/logger";
import "ts-node/register";
import { main } from "@app/server/app";
dotenv.config({ path: path.join(__dirname, "../.env.test") });
export default {
name: "knex-env",
transformMode: "ssr",
async setup() {
const db = knex({
client: "pg",
connection: process.env.DB_CONNECTION_URI,
migrations: {
directory: path.join(__dirname, "../src/db/migrations"),
extension: "ts"
},
seeds: {
directory: path.join(__dirname, "../src/db/seeds"),
extension: "ts"
}
});
try {
await db.migrate.latest();
await db.seed.run();
const smtp = mockSmtpServer();
const logger = await initLogger();
initEnvConfig(logger);
const server = await main({ db, smtp, logger });
// @ts-expect-error type
globalThis.testServer = server;
} catch (error) {
await db.destroy();
throw error;
}
// custom setup
return {
async teardown() {
// @ts-expect-error type
await globalThis.testServer.close();
// @ts-expect-error type
delete globalThis.testServer;
// called after all tests with this env have been run
await db.migrate.rollback({}, true);
await db.destroy();
}
};
}
};

View File

@@ -2,5 +2,5 @@
"watch": ["src"],
"ext": ".ts,.js",
"ignore": [],
"exec": "tsx ./src/server/app.ts | pino-pretty --colorize --colorizeObjects --singleLine"
"exec": "tsx ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine"
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,11 +5,16 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "tsx watch --clear-screen=false ./src/server/app.ts | pino-pretty --colorize --colorizeObjects --singleLine",
"dev": "tsx watch --clear-screen=false ./src/main.ts | pino-pretty --colorize --colorizeObjects --singleLine",
"dev:docker": "nodemon",
"build": "rimraf dist && tsup src --out-dir dist --loader '.handlebars=copy' --loader '.md=copy'",
"start": "node dist/server/app.js",
"type:check": "tsc --noEmit",
"lint:fix": "eslint --fix --ext js,ts ./src",
"lint": "eslint 'src/**/*.ts'",
"test:e2e": "vitest run -c vitest.e2e.config.ts",
"test:e2e-watch": "vitest -c vitest.e2e.config.ts",
"test:e2e-coverage": "vitest run --coverage -c vitest.e2e.config.ts",
"generate:component": "tsx ./scripts/create-backend-file.ts",
"generate:schema": "tsx ./scripts/generate-schema-types.ts",
"migration:new": "tsx ./scripts/create-migration.ts",
@@ -33,6 +38,7 @@
"@types/nodemailer": "^6.4.14",
"@types/passport-github": "^1.1.12",
"@types/passport-google-oauth20": "^2.0.14",
"@types/pg": "^8.10.9",
"@types/picomatch": "^2.3.3",
"@types/prompt-sync": "^4.2.3",
"@typescript-eslint/eslint-plugin": "^6.13.2",
@@ -47,9 +53,13 @@
"nodemon": "^3.0.2",
"pino-pretty": "^10.2.3",
"prompt-sync": "^4.2.0",
"rimraf": "^5.0.5",
"ts-node": "^10.9.1",
"tsup": "^8.0.1",
"tsx": "^4.4.0",
"typescript": "^5.3.2"
"typescript": "^5.3.2",
"vite-tsconfig-paths": "^4.2.2",
"vitest": "^1.0.4"
},
"dependencies": {
"@casl/ability": "^6.5.0",

View File

@@ -16,4 +16,7 @@ declare global {
Readonly<Logger>,
ZodTypeProvider
>;
// used only for testing
const testServer: FastifyZodProvider;
}

View File

@@ -40,7 +40,7 @@ import {
} from "@app/db/schemas";
declare module "knex/types/tables" {
interface Tables extends { [key in TableName]: Knex.CompositeTableType<any> } {
interface Tables {
[TableName.Users]: Knex.CompositeTableType<TUsers, TUsersInsert, TUsersUpdate>;
[TableName.UserEncryptionKey]: Knex.CompositeTableType<
TUserEncryptionKeys,

32
backend-pg/src/main.ts Normal file
View File

@@ -0,0 +1,32 @@
import dotenv from "dotenv";
import { formatSmtpConfig, initEnvConfig } from "./lib/config/env";
import { initLogger } from "./lib/logger";
import { main } from "./server/app";
import { smtpServiceFactory } from "./services/smtp/smtp-service";
import { initDbConnection } from "./db";
dotenv.config();
const run = async () => {
const logger = await initLogger();
const appCfg = initEnvConfig(logger);
const db = initDbConnection(appCfg.DB_CONNECTION_URI);
const smtp = smtpServiceFactory(formatSmtpConfig());
const server = await main({ db, smtp, logger });
process.on("SIGINT", async () => {
await server.close();
await db.destroy();
process.exit(0);
});
process.on("SIGTERM", async () => {
await server.close();
await db.destroy();
process.exit(0);
});
await server.listen({ port: appCfg.PORT, host: appCfg.HOST });
};
run();

View File

@@ -1,5 +1,6 @@
import dotenv from "dotenv";
import fasitfy from "fastify";
import { Knex } from "knex";
import { Logger } from "pino";
import type { FastifyCookieOptions } from "@fastify/cookie";
import cookie from "@fastify/cookie";
import type { FastifyCorsOptions } from "@fastify/cors";
@@ -8,11 +9,9 @@ import helmet from "@fastify/helmet";
import type { FastifyRateLimitOptions } from "@fastify/rate-limit";
import ratelimiter from "@fastify/rate-limit";
import { initDbConnection } from "@app/db";
import { smtpServiceFactory } from "@app/services/smtp/smtp-service";
import { TSmtpService } from "@app/services/smtp/smtp-service";
import { formatSmtpConfig, initEnvConfig } from "@lib/config/env";
import { initLogger } from "@lib/logger";
import { getConfig } from "@lib/config/env";
import { globalRateLimiterCfg } from "./config/rateLimiter";
import { serializerCompiler, validatorCompiler, ZodTypeProvider } from "./plugins/fastify-zod";
@@ -20,13 +19,15 @@ import { fastifyIp } from "./plugins/ip";
import { fastifySwagger } from "./plugins/swagger";
import { registerRoutes } from "./routes";
dotenv.config();
type TMain = {
db: Knex;
smtp: TSmtpService;
logger?: Logger;
};
// Run the server!
const main = async () => {
const logger = await initLogger();
const envCfg = initEnvConfig(logger);
export const main = async ({ db, smtp, logger }: TMain) => {
const appCfg = getConfig();
const server = fasitfy({
logger,
trustProxy: true
@@ -35,12 +36,9 @@ const main = async () => {
server.setValidatorCompiler(validatorCompiler);
server.setSerializerCompiler(serializerCompiler);
const db = initDbConnection(envCfg.DB_CONNECTION_URI);
const smtp = smtpServiceFactory(formatSmtpConfig());
try {
await server.register<FastifyCookieOptions>(cookie, {
secret: envCfg.COOKIE_SECRET_SIGN_KEY
secret: appCfg.COOKIE_SECRET_SIGN_KEY
});
await server.register<FastifyCorsOptions>(cors, {
@@ -59,11 +57,9 @@ const main = async () => {
await server.register(registerRoutes, { prefix: "/api", smtp, db });
await server.ready();
server.swagger();
await server.listen({ port: envCfg.PORT, host: envCfg.HOST });
return server;
} catch (err) {
server.log.error(err);
process.exit(1);
}
};
main();

View File

@@ -4,11 +4,20 @@
"module": "commonjs",
"allowJs": true,
"resolveJsonModule": true,
"typeRoots": ["./node_modules/@types", "./src/@types"],
"types": [
"vitest/globals"
],
"typeRoots": [
"./node_modules/@types",
"./src/@types",
"./node_modules"
],
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": ["esnext"],
"lib": [
"esnext"
],
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"experimentalDecorators": true,
@@ -17,11 +26,23 @@
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@app/*": ["./src/*"],
"@lib/*": ["./src/lib/*"],
"@server/*": ["./src/server/*"]
"@app/*": [
"./src/*"
],
"@lib/*": [
"./src/lib/*"
],
"@server/*": [
"./src/server/*"
]
}
},
"include": ["src/**/*","scripts/**/*"],
"exclude": ["node_modules"]
"include": [
"src/**/*",
"scripts/**/*",
"e2e-test/**/*"
],
"exclude": [
"node_modules"
]
}

View File

@@ -0,0 +1,11 @@
import tsconfigPaths from "vite-tsconfig-paths"; // only if you are using custom tsconfig paths
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
globals: true,
environment: "./e2e-test/vitest-environment-knex.ts",
include: ["./e2e-test/**/*.spec.ts"]
},
plugins: [tsconfigPaths()] // only if you are using custom tsconfig paths,
});

View File

@@ -24,6 +24,16 @@ services:
POSTGRES_USER: infisical
POSTGRES_DB: infisical
db-test:
profiles: ["test"]
image: postgres:14-alpine
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: infisical
POSTGRES_USER: infisical
POSTGRES_DB: infisical-test
backend:
container_name: infisical-dev-api
build: