From e85463b2a717751de2e21c39a4c745449b31affe Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Mon, 12 Feb 2024 19:07:15 +0100 Subject: [PATCH] chore(): Fix database test utils and utils (#6383) **What** Fix the test utils database to trully run the migrations, the migration path is deprecated and not used anymore as umzung infer the path under the hood. It also fix the schema so that it is possible to specify different schema if needed. The index helper can now create named constraints for uniqueness. extracted [from](https://github.com/medusajs/medusa/pull/6381) --- .changeset/warm-garlics-drive.md | 6 ++ .../src/migrations/Migration20240124154000.ts | 2 +- packages/medusa-test-utils/src/database.ts | 74 +++++++++++++------ .../__tests__/create-psql-index-helper.ts | 31 ++++++-- .../src/common/create-psql-index-helper.ts | 9 ++- 5 files changed, 90 insertions(+), 32 deletions(-) create mode 100644 .changeset/warm-garlics-drive.md diff --git a/.changeset/warm-garlics-drive.md b/.changeset/warm-garlics-drive.md new file mode 100644 index 0000000000..0bc9237dd4 --- /dev/null +++ b/.changeset/warm-garlics-drive.md @@ -0,0 +1,6 @@ +--- +"medusa-test-utils": patch +"@medusajs/utils": patch +--- + +chore(): Fix database test utils and utils diff --git a/packages/customer/src/migrations/Migration20240124154000.ts b/packages/customer/src/migrations/Migration20240124154000.ts index c44f78d7f2..93c61f3d72 100644 --- a/packages/customer/src/migrations/Migration20240124154000.ts +++ b/packages/customer/src/migrations/Migration20240124154000.ts @@ -23,7 +23,7 @@ export class Migration20240124154000 extends Migration { 'create index if not exists "IDX_customer_address_customer_id" on "customer_address" ("customer_id");' ) this.addSql( - 'create unique index "IDX_customer_address_unqiue_customer_billing" on "customer_address" ("customer_id") where "is_default_billing" = true;' + 'create unique index "IDX_customer_address_unique_customer_billing" on "customer_address" ("customer_id") where "is_default_billing" = true;' ) this.addSql( 'create unique index "IDX_customer_address_unique_customer_shipping" on "customer_address" ("customer_id") where "is_default_shipping" = true;' diff --git a/packages/medusa-test-utils/src/database.ts b/packages/medusa-test-utils/src/database.ts index 3f694a1aca..30b513ef7a 100644 --- a/packages/medusa-test-utils/src/database.ts +++ b/packages/medusa-test-utils/src/database.ts @@ -1,6 +1,6 @@ -import { TSMigrationGenerator } from "@mikro-orm/migrations" import { MikroORM, Options, SqlEntityManager } from "@mikro-orm/postgresql" import * as process from "process" +import { Migrator } from "@mikro-orm/migrations" export function getDatabaseURL(): string { const DB_HOST = process.env.DB_HOST ?? "localhost" @@ -15,7 +15,8 @@ export function getDatabaseURL(): string { export function getMikroOrmConfig( mikroOrmEntities: any[], - pathToMigrations: string + pathToMigrations: string, // deprecated, auto inferred + schema?: string ): Options { const DB_URL = getDatabaseURL() @@ -23,23 +24,17 @@ export function getMikroOrmConfig( type: "postgresql", clientUrl: DB_URL, entities: Object.values(mikroOrmEntities), - schema: process.env.MEDUSA_DB_SCHEMA, + schema: schema ?? process.env.MEDUSA_DB_SCHEMA, debug: false, - migrations: { - path: pathToMigrations, - pathTs: pathToMigrations, - glob: "!(*.d).{js,ts}", - silent: true, - dropTables: true, - transactional: true, - allOrNothing: true, - safe: false, - generator: TSMigrationGenerator, - }, + extensions: [Migrator], } } export interface TestDatabase { + mikroOrmEntities: any[] + pathToMigrations: any // deprecated, auto inferred + schema?: string + orm: MikroORM | null manager: SqlEntityManager | null @@ -52,9 +47,14 @@ export interface TestDatabase { export function getMikroOrmWrapper( mikroOrmEntities: any[], - pathToMigrations: string + pathToMigrations: string, // deprecated, auto inferred + schema?: string ): TestDatabase { return { + mikroOrmEntities, + pathToMigrations, // deprecated, auto inferred + schema: schema ?? process.env.MEDUSA_DB_SCHEMA, + orm: null, manager: null, @@ -83,18 +83,36 @@ export function getMikroOrmWrapper( }, async setupDatabase() { - const OrmConfig = getMikroOrmConfig(mikroOrmEntities, pathToMigrations) + const OrmConfig = getMikroOrmConfig( + this.mikroOrmEntities, + this.pathToMigrations, + this.schema + ) // Initializing the ORM this.orm = await MikroORM.init(OrmConfig) - if (this.orm === null) { - throw new Error("ORM not configured") + this.manager = this.orm.em + + try { + await this.orm.getSchemaGenerator().ensureDatabase() + } catch (err) {} + + await this.manager?.execute( + `CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";` + ) + + const pendingMigrations = await this.orm + .getMigrator() + .getPendingMigrations() + + if (pendingMigrations && pendingMigrations.length > 0) { + await this.orm + .getMigrator() + .up({ migrations: pendingMigrations.map((m) => m.name!) }) + } else { + await this.orm.schema.refreshDatabase() // ensure db exists and is fresh } - - this.manager = await this.orm.em - - await this.orm.schema.refreshDatabase() // ensure db exists and is fresh }, async clearDatabase() { @@ -102,7 +120,17 @@ export function getMikroOrmWrapper( throw new Error("ORM not configured") } - await this.orm.close() + await this.manager?.execute( + `DROP SCHEMA IF EXISTS "${this.schema ?? "public"}" CASCADE;` + ) + + await this.manager?.execute( + `CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";` + ) + + try { + await this.orm.close() + } catch {} this.orm = null this.manager = null diff --git a/packages/utils/src/common/__tests__/create-psql-index-helper.ts b/packages/utils/src/common/__tests__/create-psql-index-helper.ts index 56166a2656..ec2c70178e 100644 --- a/packages/utils/src/common/__tests__/create-psql-index-helper.ts +++ b/packages/utils/src/common/__tests__/create-psql-index-helper.ts @@ -10,7 +10,7 @@ describe("createPsqlIndexStatementHelper", function () { const indexStatement = createPsqlIndexStatementHelper(options) expect(indexStatement).toEqual( - `CREATE INDEX IF NOT EXISTS ${options.name} ON ${options.tableName} (${options.columns})` + `CREATE INDEX IF NOT EXISTS "${options.name}" ON "${options.tableName}" (${options.columns})` ) }) @@ -23,9 +23,9 @@ describe("createPsqlIndexStatementHelper", function () { const indexStatement = createPsqlIndexStatementHelper(options) expect(indexStatement).toEqual( - `CREATE INDEX IF NOT EXISTS ${options.name} ON ${ + `CREATE INDEX IF NOT EXISTS "${options.name}" ON "${ options.tableName - } (${options.columns.join(", ")})` + }" (${options.columns.join(", ")})` ) }) @@ -39,9 +39,9 @@ describe("createPsqlIndexStatementHelper", function () { const indexStatement = createPsqlIndexStatementHelper(options) expect(indexStatement).toEqual( - `CREATE INDEX IF NOT EXISTS ${options.name} ON ${ + `CREATE INDEX IF NOT EXISTS "${options.name}" ON "${ options.tableName - } (${options.columns.join(", ")}) WHERE ${options.where}` + }" (${options.columns.join(", ")}) WHERE ${options.where}` ) }) @@ -56,9 +56,26 @@ describe("createPsqlIndexStatementHelper", function () { const indexStatement = createPsqlIndexStatementHelper(options) expect(indexStatement).toEqual( - `CREATE INDEX IF NOT EXISTS ${options.name} ON ${ + `CREATE INDEX IF NOT EXISTS "${options.name}" ON "${ options.tableName - } USING GIN (${options.columns.join(", ")}) WHERE ${options.where}` + }" USING GIN (${options.columns.join(", ")}) WHERE ${options.where}` + ) + }) + + it("should generate unique constraint", function () { + const options = { + name: "index_name", + tableName: "table_name", + columns: ["column_name_1", "column_name_2"], + unique: true, + where: "column_name_1 IS NOT NULL", + } + + const indexStatement = createPsqlIndexStatementHelper(options) + expect(indexStatement).toEqual( + `ALTER TABLE IF EXISTS "${options.tableName}" ADD CONSTRAINT "${ + options.name + }" UNIQUE (${options.columns.join(", ")}) WHERE ${options.where}` ) }) }) diff --git a/packages/utils/src/common/create-psql-index-helper.ts b/packages/utils/src/common/create-psql-index-helper.ts index a2a030dcbc..8d7529d582 100644 --- a/packages/utils/src/common/create-psql-index-helper.ts +++ b/packages/utils/src/common/create-psql-index-helper.ts @@ -5,6 +5,7 @@ * @param columns The columns to index * @param type The type of index (e.g GIN, GIST, BTREE, etc) * @param where The where clause + * @param unique If the index should be a unique index * * @example * createPsqlIndexStatementHelper({ @@ -32,16 +33,22 @@ export function createPsqlIndexStatementHelper({ columns, type, where, + unique, }: { name: string tableName: string columns: string | string[] type?: string where?: string + unique?: boolean }) { columns = Array.isArray(columns) ? columns.join(", ") : columns const typeStr = type ? ` USING ${type}` : "" const optionsStr = where ? ` WHERE ${where}` : "" - return `CREATE INDEX IF NOT EXISTS ${name} ON ${tableName}${typeStr} (${columns})${optionsStr}` + if (!unique) { + return `CREATE INDEX IF NOT EXISTS "${name}" ON "${tableName}"${typeStr} (${columns})${optionsStr}` + } else { + return `ALTER TABLE IF EXISTS "${tableName}" ADD CONSTRAINT "${name}" UNIQUE (${columns})${optionsStr}` + } }