diff --git a/integration-tests/api/__tests__/admin/__snapshots__/store.js.snap b/integration-tests/api/__tests__/admin/__snapshots__/store.js.snap deleted file mode 100644 index 0162ad57ef..0000000000 --- a/integration-tests/api/__tests__/admin/__snapshots__/store.js.snap +++ /dev/null @@ -1,8 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`/admin/store POST /admin/store fails to update default currency if not in store currencies 1`] = ` -Object { - "message": "Store does not have currency: eur", - "type": "invalid_data", -} -`; diff --git a/integration-tests/api/__tests__/admin/store.js b/integration-tests/api/__tests__/admin/store.js index 558496c87d..f159b5e4bc 100644 --- a/integration-tests/api/__tests__/admin/store.js +++ b/integration-tests/api/__tests__/admin/store.js @@ -1,242 +1,250 @@ -const { Store } = require("@medusajs/medusa") -const path = require("path") +const { + createAdminUser, + adminHeaders, +} = require("../../../helpers/create-admin-user") +const { breaking } = require("../../../helpers/breaking") +const { ModuleRegistrationName } = require("@medusajs/modules-sdk") +const { medusaIntegrationTestRunner } = require("medusa-test-utils") -const setupServer = require("../../../environment-helpers/setup-server") -const { useApi } = require("../../../environment-helpers/use-api") -const { initDb, useDb } = require("../../../environment-helpers/use-db") +jest.setTimeout(90000) -const adminSeeder = require("../../../helpers/admin-seeder") +medusaIntegrationTestRunner({ + testSuite: ({ dbConnection, getContainer, api }) => { + describe("/admin/store", () => { + let dbStore + let container -jest.setTimeout(30000) + // Note: The tests rely on the loader running and populating clean data before and after the test, so we have to do this in a beforeEach + beforeEach(async () => { + container = getContainer() -describe("/admin/store", () => { - let dbConnection - const cwd = path.resolve(path.join(__dirname, "..", "..")) - - beforeAll(async () => { - dbConnection = await initDb({ cwd }) - }) - - afterAll(async () => { - const db = useDb() - await db.shutdown() - }) - - describe("Store creation", () => { - let medusaProcess - - beforeEach(async () => { - await adminSeeder(dbConnection) - medusaProcess = await setupServer({ cwd }) - }) - - afterEach(async () => { - const db = useDb() - await db.teardown({ forceDelete: ["store"] }) - await medusaProcess.kill() - }) - - it("has created store with default currency", async () => { - const api = useApi() - - const response = await api.get("/admin/store", { - headers: { "x-medusa-access-token": "test_token " }, + await createAdminUser(dbConnection, adminHeaders, container) + await breaking( + async () => { + const { Store } = require("@medusajs/medusa/dist/models/store") + const manager = dbConnection.manager + dbStore = await manager.findOne(Store, { + where: { name: "Medusa Store" }, + }) + await manager.query( + `INSERT INTO store_currencies (store_id, currency_code) + VALUES ('${dbStore.id}', 'dkk')` + ) + }, + async () => { + const service = container.resolve(ModuleRegistrationName.STORE) + dbStore = await service.create({ + supported_currency_codes: ["usd", "dkk"], + default_currency_code: "usd", + default_sales_channel_id: "sc_12345", + }) + } + ) }) - expect(response.status).toEqual(200) - expect(response.data.store).toEqual( - expect.objectContaining({ - id: expect.any(String), - default_sales_channel_id: expect.any(String), - default_sales_channel: expect.objectContaining({ - id: expect.any(String), - }), - name: "Medusa Store", - currencies: expect.arrayContaining([ + describe("Store creation", () => { + it("has created store with default currency", async () => { + const store = await breaking( + () => + api.get("/admin/store", adminHeaders).then((r) => r.data.store), + () => + api + .get("/admin/stores", adminHeaders) + .then((r) => r.data.stores[0]) + ) + + expect(store).toEqual( expect.objectContaining({ - code: "usd", - }), - ]), - modules: expect.any(Array), - feature_flags: expect.any(Array), - default_currency_code: "usd", - created_at: expect.any(String), - updated_at: expect.any(String), + id: expect.any(String), + name: "Medusa Store", + default_currency_code: "usd", + default_sales_channel_id: expect.any(String), + ...breaking( + () => ({ + default_sales_channel: expect.objectContaining({ + id: expect.any(String), + }), + currencies: expect.arrayContaining([ + expect.objectContaining({ + code: "usd", + }), + ]), + modules: expect.any(Array), + feature_flags: expect.any(Array), + }), + () => ({ + supported_currency_codes: ["usd", "dkk"], + }) + ), + created_at: expect.any(String), + updated_at: expect.any(String), + }) + ) }) - ) - }) - }) - - describe("POST /admin/store", () => { - let medusaProcess - - beforeEach(async () => { - await adminSeeder(dbConnection) - medusaProcess = await setupServer({ cwd }) - - const manager = dbConnection.manager - const store = await manager.findOne(Store, { - where: { name: "Medusa Store" }, }) - await manager.query( - `INSERT INTO store_currencies (store_id, currency_code) VALUES ('${store.id}', 'dkk')` - ) - }) - afterEach(async () => { - const db = useDb() - await db.teardown({ forceDelete: ["store"] }) - await medusaProcess.kill() - }) - - it("fails to update default currency if not in store currencies", async () => { - const api = useApi() - - try { - await api.post( - "/admin/store", - { - default_currency_code: "eur", - }, - { - headers: { "x-medusa-access-token": "test_token " }, + describe("POST /admin/store", () => { + it("fails to update default currency if not in store currencies", async () => { + try { + await api.post( + breaking( + () => "/admin/store", + () => `/admin/stores/${dbStore.id}` + ), + { + default_currency_code: "eur", + }, + adminHeaders + ) + } catch (e) { + expect(e.response.data).toEqual( + expect.objectContaining({ + type: "invalid_data", + message: "Store does not have currency: eur", + }) + ) + expect(e.response.status).toBe(400) } - ) - } catch (e) { - expect(e.response.data).toMatchSnapshot({ - type: "invalid_data", - message: "Store does not have currency: eur", }) - expect(e.response.status).toBe(400) - } - }) - it("fails to remove default currency from currencies without replacing it", async () => { - const api = useApi() - - try { - await api.post( - "/admin/store", - { - currencies: ["usd"], - }, - { - headers: { "x-medusa-access-token": "test_token " }, + it("fails to remove default currency from currencies without replacing it", async () => { + try { + await api.post( + breaking( + () => "/admin/store", + () => `/admin/stores/${dbStore.id}` + ), + breaking( + () => ({ + currencies: ["usd"], + }), + () => ({ supported_currency_codes: ["dkk"] }) + ), + adminHeaders + ) + } catch (e) { + expect(e.response.data).toEqual( + expect.objectContaining({ + type: "invalid_data", + message: + "You are not allowed to remove default currency from store currencies without replacing it as well", + }) + ) + expect(e.response.status).toBe(400) } - ) - } catch (e) { - expect(e.response.data).toMatchSnapshot({ - type: "invalid_data", - message: - "You are not allowed to remove default currency from store currencies without replacing it as well", }) - expect(e.response.status).toBe(400) - } - }) - it("successfully updates default currency code", async () => { - const api = useApi() + it("successfully updates default currency code", async () => { + const response = await api + .post( + breaking( + () => "/admin/store", + () => `/admin/stores/${dbStore.id}` + ), + { + default_currency_code: "dkk", + }, + adminHeaders + ) + .catch((err) => console.log(err)) - const response = await api - .post( - "/admin/store", - { - default_currency_code: "dkk", - }, - { - headers: { "x-medusa-access-token": "test_token " }, - } - ) - .catch((err) => console.log(err)) - - expect(response.status).toEqual(200) - expect(response.data.store).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: "Medusa Store", - default_sales_channel_id: expect.any(String), - currencies: expect.arrayContaining([ + expect(response.status).toEqual(200) + expect(response.data.store).toEqual( expect.objectContaining({ - code: "usd", - }), - expect.objectContaining({ - code: "dkk", - }), - ]), - default_currency_code: "dkk", - created_at: expect.any(String), - updated_at: expect.any(String), + id: expect.any(String), + name: "Medusa Store", + default_currency_code: "dkk", + created_at: expect.any(String), + updated_at: expect.any(String), + }) + ) }) - ) - }) - it("successfully updates default currency and store currencies", async () => { - const api = useApi() + it("successfully updates default currency and store currencies", async () => { + const response = await api.post( + breaking( + () => "/admin/store", + () => `/admin/stores/${dbStore.id}` + ), + { + default_currency_code: "jpy", + ...breaking( + () => ({ currencies: ["jpy", "usd"] }), + () => ({ supported_currency_codes: ["jpy", "usd"] }) + ), + }, + adminHeaders + ) - const response = await api.post( - "/admin/store", - { - default_currency_code: "jpy", - currencies: ["jpy", "usd"], - }, - { - headers: { "x-medusa-access-token": "test_token " }, - } - ) - - expect(response.status).toEqual(200) - expect(response.data.store).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: "Medusa Store", - default_sales_channel_id: expect.any(String), - currencies: expect.arrayContaining([ + expect(response.status).toEqual(200) + expect(response.data.store).toEqual( expect.objectContaining({ - code: "jpy", - }), - expect.objectContaining({ - code: "usd", - }), - ]), - default_currency_code: "jpy", - created_at: expect.any(String), - updated_at: expect.any(String), + id: expect.any(String), + name: "Medusa Store", + default_sales_channel_id: expect.any(String), + ...breaking( + () => ({ + currencies: expect.arrayContaining([ + expect.objectContaining({ + code: "jpy", + }), + expect.objectContaining({ + code: "usd", + }), + ]), + }), + () => ({ supported_currency_codes: ["jpy", "usd"] }) + ), + default_currency_code: "jpy", + created_at: expect.any(String), + updated_at: expect.any(String), + }) + ) }) - ) - }) - it("successfully updates and store currencies", async () => { - const api = useApi() + it("successfully updates and store currencies", async () => { + const response = await api.post( + breaking( + () => "/admin/store", + () => `/admin/stores/${dbStore.id}` + ), + breaking( + () => ({ + currencies: ["jpy", "usd"], + }), + () => ({ + supported_currency_codes: ["jpy", "usd"], + }) + ), + adminHeaders + ) - const response = await api.post( - "/admin/store", - { - currencies: ["jpy", "usd"], - }, - { - headers: { "x-medusa-access-token": "test_token " }, - } - ) - - expect(response.status).toEqual(200) - expect(response.data.store).toEqual( - expect.objectContaining({ - id: expect.any(String), - default_sales_channel_id: expect.any(String), - name: "Medusa Store", - currencies: expect.arrayContaining([ + expect(response.status).toEqual(200) + expect(response.data.store).toEqual( expect.objectContaining({ - code: "jpy", - }), - expect.objectContaining({ - code: "usd", - }), - ]), - default_currency_code: "usd", - created_at: expect.any(String), - updated_at: expect.any(String), + id: expect.any(String), + default_sales_channel_id: expect.any(String), + name: "Medusa Store", + ...breaking( + () => ({ + currencies: expect.arrayContaining([ + expect.objectContaining({ + code: "jpy", + }), + expect.objectContaining({ + code: "usd", + }), + ]), + }), + () => ({ supported_currency_codes: ["jpy", "usd"] }) + ), + default_currency_code: "usd", + created_at: expect.any(String), + updated_at: expect.any(String), + }) + ) }) - ) + }) }) - }) + }, }) diff --git a/integration-tests/api/medusa-config.js b/integration-tests/api/medusa-config.js index e3ff70f29f..ab637f6c06 100644 --- a/integration-tests/api/medusa-config.js +++ b/integration-tests/api/medusa-config.js @@ -1,18 +1,25 @@ +const { Modules } = require("@medusajs/modules-sdk") + const DB_HOST = process.env.DB_HOST const DB_USERNAME = process.env.DB_USERNAME const DB_PASSWORD = process.env.DB_PASSWORD const DB_NAME = process.env.DB_TEMP_NAME +const DB_URL = `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}` -const redisUrl = process.env.REDIS_URL || "redis://localhost:6379" +const redisUrl = process.env.REDIS_URL const cacheTTL = process.env.CACHE_TTL ?? 15 const enableResponseCompression = process.env.ENABLE_RESPONSE_COMPRESSION || true +const enableMedusaV2 = process.env.MEDUSA_FF_MEDUSA_V2 == "true" + +process.env.POSTGRES_URL = DB_URL +process.env.LOG_LEVEL = "error" module.exports = { plugins: [], projectConfig: { redis_url: redisUrl, - database_url: `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`, + database_url: DB_URL, database_type: "postgres", jwt_secret: "test", cookie_secret: "test", @@ -20,11 +27,62 @@ module.exports = { enabled: enableResponseCompression, }, }, + featureFlags: { + medusa_v2: enableMedusaV2, + }, modules: { cacheService: { resolve: "@medusajs/cache-inmemory", options: { ttl: cacheTTL }, }, workflows: true, + // We don't want to load the modules if v2 is not enabled, as they run data operations and migrations on load. + ...(enableMedusaV2 + ? { + [Modules.AUTH]: { + scope: "internal", + resources: "shared", + resolve: "@medusajs/auth", + options: { + providers: [ + { + name: "emailpass", + scopes: { + admin: {}, + store: {}, + }, + }, + ], + }, + }, + [Modules.USER]: { + scope: "internal", + resources: "shared", + resolve: "@medusajs/user", + options: { + jwt_secret: "test", + }, + }, + [Modules.CACHE]: { + resolve: "@medusajs/cache-inmemory", + options: { ttl: 0 }, // Cache disabled + }, + [Modules.STOCK_LOCATION]: true, + [Modules.INVENTORY]: true, + [Modules.PRODUCT]: true, + [Modules.PRICING]: true, + [Modules.PROMOTION]: true, + [Modules.CUSTOMER]: true, + [Modules.SALES_CHANNEL]: true, + [Modules.CART]: true, + [Modules.WORKFLOW_ENGINE]: true, + [Modules.REGION]: true, + [Modules.API_KEY]: true, + [Modules.STORE]: true, + [Modules.TAX]: true, + [Modules.CURRENCY]: true, + [Modules.PAYMENT]: true, + } + : {}), }, } diff --git a/integration-tests/api/package.json b/integration-tests/api/package.json index c2c76e1ebc..89d4ddc792 100644 --- a/integration-tests/api/package.json +++ b/integration-tests/api/package.json @@ -5,16 +5,31 @@ "license": "MIT", "private": true, "scripts": { - "test:integration": "jest --silent=false --maxWorkers=50% --bail --detectOpenHandles --forceExit --logHeapUsage", + "test:integration": "jest --silent --maxWorkers=50% --bail --detectOpenHandles --forceExit --logHeapUsage", "build": "babel src -d dist --extensions \".ts,.js\"" }, "dependencies": { + "@medusajs/api-key": "workspace:^", + "@medusajs/auth": "workspace:*", "@medusajs/cache-inmemory": "workspace:*", + "@medusajs/customer": "workspace:^", "@medusajs/event-bus-local": "workspace:*", + "@medusajs/inventory": "workspace:^", "@medusajs/medusa": "workspace:*", + "@medusajs/modules-sdk": "workspace:^", + "@medusajs/pricing": "workspace:^", + "@medusajs/product": "workspace:^", + "@medusajs/promotion": "workspace:^", + "@medusajs/region": "workspace:^", + "@medusajs/store": "workspace:^", + "@medusajs/tax": "workspace:^", + "@medusajs/user": "workspace:^", + "@medusajs/utils": "workspace:^", "@medusajs/workflow-engine-inmemory": "workspace:*", "faker": "^5.5.3", + "medusa-fulfillment-webshipper": "workspace:*", "medusa-interfaces": "workspace:*", + "medusa-plugin-sendgrid": "workspace:*", "pg": "^8.11.0", "typeorm": "^0.3.16" }, diff --git a/integration-tests/helpers/breaking.ts b/integration-tests/helpers/breaking.ts new file mode 100644 index 0000000000..3da96f1ce2 --- /dev/null +++ b/integration-tests/helpers/breaking.ts @@ -0,0 +1,10 @@ +export const breaking = ( + v1Fn: (() => any) | null, + v2Fn?: (() => any) | null +) => { + if (process.env.MEDUSA_FF_MEDUSA_V2 === "true") { + return v2Fn?.() + } + + return v1Fn?.() +} diff --git a/integration-tests/helpers/create-admin-user.ts b/integration-tests/helpers/create-admin-user.ts new file mode 100644 index 0000000000..b105913b5b --- /dev/null +++ b/integration-tests/helpers/create-admin-user.ts @@ -0,0 +1,35 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { IAuthModuleService } from "@medusajs/types" +import jwt from "jsonwebtoken" +import { getContainer } from "../environment-helpers/use-container" +import adminSeeder from "./admin-seeder" + +export const adminHeaders = { + headers: { "x-medusa-access-token": "test_token" }, +} + +export const createAdminUser = async ( + dbConnection, + adminHeaders, + container? +) => { + await adminSeeder(dbConnection) + const appContainer = container ?? getContainer()! + + const authModule: IAuthModuleService = appContainer.resolve( + ModuleRegistrationName.AUTH + ) + if (authModule) { + const authUser = await authModule.create({ + provider: "emailpass", + entity_id: "admin@medusa.js", + scope: "admin", + app_metadata: { + user_id: "admin_user", + }, + }) + + const token = jwt.sign(authUser, "test") + adminHeaders.headers["authorization"] = `Bearer ${token}` + } +} diff --git a/integration-tests/modules/__tests__/api-key/admin/api-key.spec.ts b/integration-tests/modules/__tests__/api-key/admin/api-key.spec.ts index 0b2559d44b..3196c79851 100644 --- a/integration-tests/modules/__tests__/api-key/admin/api-key.spec.ts +++ b/integration-tests/modules/__tests__/api-key/admin/api-key.spec.ts @@ -1,7 +1,7 @@ import { ApiKeyType } from "@medusajs/utils" import { IRegionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/currency/admin/currency.spec.ts b/integration-tests/modules/__tests__/currency/admin/currency.spec.ts index 3101f1aac7..2a22543d69 100644 --- a/integration-tests/modules/__tests__/currency/admin/currency.spec.ts +++ b/integration-tests/modules/__tests__/currency/admin/currency.spec.ts @@ -1,4 +1,4 @@ -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts index 53b58c17be..a93431887a 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts index 70bf486cdc..7832c3a037 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/create-customer-group.ts b/integration-tests/modules/__tests__/customer-group/admin/create-customer-group.ts index 4027709837..82f747caf6 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/create-customer-group.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/create-customer-group.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/delete-customer-group.ts b/integration-tests/modules/__tests__/customer-group/admin/delete-customer-group.ts index 56d297e9a4..8c9d618076 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/delete-customer-group.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/delete-customer-group.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts index 04d74a99b5..87a953dd40 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/list-customer-groups.spec.ts b/integration-tests/modules/__tests__/customer-group/admin/list-customer-groups.spec.ts index 794e897a71..5a546787fd 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/list-customer-groups.spec.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/list-customer-groups.spec.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/retrieve-customer-group.ts b/integration-tests/modules/__tests__/customer-group/admin/retrieve-customer-group.ts index b300a7892f..24f854159e 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/retrieve-customer-group.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/retrieve-customer-group.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer-group/admin/update-customer-group.ts b/integration-tests/modules/__tests__/customer-group/admin/update-customer-group.ts index 7f915584e5..9970789aba 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/update-customer-group.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/update-customer-group.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts b/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts index ad25b42557..e8f5609908 100644 --- a/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts +++ b/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/create-customer.ts b/integration-tests/modules/__tests__/customer/admin/create-customer.ts index abf0dadbcb..60c707abb2 100644 --- a/integration-tests/modules/__tests__/customer/admin/create-customer.ts +++ b/integration-tests/modules/__tests__/customer/admin/create-customer.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/delete-customer-address.spec.ts b/integration-tests/modules/__tests__/customer/admin/delete-customer-address.spec.ts index 6015b31290..25612aaf40 100644 --- a/integration-tests/modules/__tests__/customer/admin/delete-customer-address.spec.ts +++ b/integration-tests/modules/__tests__/customer/admin/delete-customer-address.spec.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/delete-customer.ts b/integration-tests/modules/__tests__/customer/admin/delete-customer.ts index cf2213efaf..1c2ae9e03c 100644 --- a/integration-tests/modules/__tests__/customer/admin/delete-customer.ts +++ b/integration-tests/modules/__tests__/customer/admin/delete-customer.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/list-customer-addresses.ts b/integration-tests/modules/__tests__/customer/admin/list-customer-addresses.ts index d0d35a0e84..433d071d70 100644 --- a/integration-tests/modules/__tests__/customer/admin/list-customer-addresses.ts +++ b/integration-tests/modules/__tests__/customer/admin/list-customer-addresses.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/list-customers.spec.ts b/integration-tests/modules/__tests__/customer/admin/list-customers.spec.ts index 583921c489..c7c1279f90 100644 --- a/integration-tests/modules/__tests__/customer/admin/list-customers.spec.ts +++ b/integration-tests/modules/__tests__/customer/admin/list-customers.spec.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts b/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts index bed711345d..817b0d06be 100644 --- a/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts +++ b/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/customer/admin/update-customer.ts b/integration-tests/modules/__tests__/customer/admin/update-customer.ts index 7a584a8762..c6ffb858f6 100644 --- a/integration-tests/modules/__tests__/customer/admin/update-customer.ts +++ b/integration-tests/modules/__tests__/customer/admin/update-customer.ts @@ -1,6 +1,6 @@ import { ICustomerModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/invites/accept-invite.spec.ts b/integration-tests/modules/__tests__/invites/accept-invite.spec.ts index a1f715005c..7eab2d8836 100644 --- a/integration-tests/modules/__tests__/invites/accept-invite.spec.ts +++ b/integration-tests/modules/__tests__/invites/accept-invite.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/invites/create-invite.spec.ts b/integration-tests/modules/__tests__/invites/create-invite.spec.ts index 14fa28b48b..ce2ffb82c6 100644 --- a/integration-tests/modules/__tests__/invites/create-invite.spec.ts +++ b/integration-tests/modules/__tests__/invites/create-invite.spec.ts @@ -1,4 +1,4 @@ -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/invites/delete-invite.spec.ts b/integration-tests/modules/__tests__/invites/delete-invite.spec.ts index b062178eb0..be4a8ce27a 100644 --- a/integration-tests/modules/__tests__/invites/delete-invite.spec.ts +++ b/integration-tests/modules/__tests__/invites/delete-invite.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/invites/list-invites.spec.ts b/integration-tests/modules/__tests__/invites/list-invites.spec.ts index 412ad9573b..238ed3f8da 100644 --- a/integration-tests/modules/__tests__/invites/list-invites.spec.ts +++ b/integration-tests/modules/__tests__/invites/list-invites.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/invites/resend-invite.spec.ts b/integration-tests/modules/__tests__/invites/resend-invite.spec.ts index a17be34635..bbaddd7f9b 100644 --- a/integration-tests/modules/__tests__/invites/resend-invite.spec.ts +++ b/integration-tests/modules/__tests__/invites/resend-invite.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/invites/retrieve-invite.spec.ts b/integration-tests/modules/__tests__/invites/retrieve-invite.spec.ts index bbe30c5306..4966a0d056 100644 --- a/integration-tests/modules/__tests__/invites/retrieve-invite.spec.ts +++ b/integration-tests/modules/__tests__/invites/retrieve-invite.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/link-modules/index.ts b/integration-tests/modules/__tests__/link-modules/index.ts index 511b23e8ee..6d3b2f9715 100644 --- a/integration-tests/modules/__tests__/link-modules/index.ts +++ b/integration-tests/modules/__tests__/link-modules/index.ts @@ -56,7 +56,22 @@ medusaIntegrationTestRunner({ } jest.spyOn(MedusaModule, "getLoadedModules").mockImplementation((() => { - return [{ moduleA: [{}] }, { moduleB: [{}] }] + return [ + { + moduleA: { + __definition: { + key: "moduleA", + }, + }, + }, + { + moduleB: { + __definition: { + key: "moduleB", + }, + }, + }, + ] }) as any) await runMigrations({ options: dbConfig }, linkDefinition) diff --git a/integration-tests/modules/__tests__/product/admin/create-product.spec.ts b/integration-tests/modules/__tests__/product/admin/create-product.spec.ts index a811e90795..93a4fc340b 100644 --- a/integration-tests/modules/__tests__/product/admin/create-product.spec.ts +++ b/integration-tests/modules/__tests__/product/admin/create-product.spec.ts @@ -1,4 +1,4 @@ -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils/dist" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/create-campaign.spec.ts b/integration-tests/modules/__tests__/promotion/admin/create-campaign.spec.ts index dd6ce50958..b2cbb4bfe9 100644 --- a/integration-tests/modules/__tests__/promotion/admin/create-campaign.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/create-campaign.spec.ts @@ -1,6 +1,6 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts index e3c01b4d18..33acf26aad 100644 --- a/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts @@ -1,7 +1,7 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { PromotionType } from "@medusajs/utils" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/delete-campaign.spec.ts b/integration-tests/modules/__tests__/promotion/admin/delete-campaign.spec.ts index ab701aecce..bc1a65c7ab 100644 --- a/integration-tests/modules/__tests__/promotion/admin/delete-campaign.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/delete-campaign.spec.ts @@ -1,6 +1,6 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts index 24b2a3c8ba..a948a5708d 100644 --- a/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts @@ -1,6 +1,6 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/list-campaigns.spec.ts b/integration-tests/modules/__tests__/promotion/admin/list-campaigns.spec.ts index 06a69b75ab..331a66bb9e 100644 --- a/integration-tests/modules/__tests__/promotion/admin/list-campaigns.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/list-campaigns.spec.ts @@ -1,7 +1,7 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { IPromotionModuleService } from "@medusajs/types" import { CampaignBudgetType } from "@medusajs/utils" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts b/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts index baab7091e0..173c0c594f 100644 --- a/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts @@ -1,7 +1,7 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { PromotionType } from "@medusajs/utils" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/retrieve-campaign.spec.ts b/integration-tests/modules/__tests__/promotion/admin/retrieve-campaign.spec.ts index 2be28ab928..73bc6da008 100644 --- a/integration-tests/modules/__tests__/promotion/admin/retrieve-campaign.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/retrieve-campaign.spec.ts @@ -1,7 +1,7 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { IPromotionModuleService } from "@medusajs/types" import { CampaignBudgetType } from "@medusajs/utils" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts index 91241b3dfd..a9fcf2f159 100644 --- a/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts @@ -1,7 +1,7 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { PromotionType } from "@medusajs/utils" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/update-campaign.spec.ts b/integration-tests/modules/__tests__/promotion/admin/update-campaign.spec.ts index aeb68ef360..2d5e76b3de 100644 --- a/integration-tests/modules/__tests__/promotion/admin/update-campaign.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/update-campaign.spec.ts @@ -1,6 +1,6 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts index 669bfe22d0..63dcb66fab 100644 --- a/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts @@ -1,7 +1,7 @@ import { IPromotionModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { PromotionType } from "@medusajs/utils" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/regions/admin/regions.spec.ts b/integration-tests/modules/__tests__/regions/admin/regions.spec.ts index dfc988f387..db46dad999 100644 --- a/integration-tests/modules/__tests__/regions/admin/regions.spec.ts +++ b/integration-tests/modules/__tests__/regions/admin/regions.spec.ts @@ -1,6 +1,6 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { IRegionModuleService } from "@medusajs/types" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) @@ -26,12 +26,6 @@ medusaIntegrationTestRunner({ await createAdminUser(dbConnection, adminHeaders, appContainer) }) - afterEach(async () => { - // TODO: Once teardown doesn't skip constraint checks and cascades, we can remove this - const existingRegions = await service.list({}) - await service.delete(existingRegions.map((r) => r.id)) - }) - it("should create, update, and delete a region", async () => { const created = await api.post( `/admin/regions`, diff --git a/integration-tests/modules/__tests__/store/admin/store.spec.ts b/integration-tests/modules/__tests__/store/admin/store.spec.ts index b46a304205..149c57144b 100644 --- a/integration-tests/modules/__tests__/store/admin/store.spec.ts +++ b/integration-tests/modules/__tests__/store/admin/store.spec.ts @@ -1,6 +1,6 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { IStoreModuleService } from "@medusajs/types" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/tax/admin/tax.spec.ts b/integration-tests/modules/__tests__/tax/admin/tax.spec.ts index 8112758c36..6172f4da11 100644 --- a/integration-tests/modules/__tests__/tax/admin/tax.spec.ts +++ b/integration-tests/modules/__tests__/tax/admin/tax.spec.ts @@ -1,7 +1,7 @@ import { ITaxModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/tax/workflow/tax.spec.ts b/integration-tests/modules/__tests__/tax/workflow/tax.spec.ts index df3e9f8488..7d906b4524 100644 --- a/integration-tests/modules/__tests__/tax/workflow/tax.spec.ts +++ b/integration-tests/modules/__tests__/tax/workflow/tax.spec.ts @@ -1,7 +1,7 @@ import { ITaxModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../../helpers/create-admin-user" +import { createAdminUser } from "../../../../helpers/create-admin-user" import { createTaxRateRulesStepId, updateTaxRatesWorkflow, diff --git a/integration-tests/modules/__tests__/users/create-user.spec.ts b/integration-tests/modules/__tests__/users/create-user.spec.ts index 04a855aa82..fb86248def 100644 --- a/integration-tests/modules/__tests__/users/create-user.spec.ts +++ b/integration-tests/modules/__tests__/users/create-user.spec.ts @@ -1,4 +1,4 @@ -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/users/delete-user.spec.ts b/integration-tests/modules/__tests__/users/delete-user.spec.ts index 5ae237315c..ca270094d3 100644 --- a/integration-tests/modules/__tests__/users/delete-user.spec.ts +++ b/integration-tests/modules/__tests__/users/delete-user.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/users/get-me.spec.ts b/integration-tests/modules/__tests__/users/get-me.spec.ts index 1116a424e0..b8d283c7a0 100644 --- a/integration-tests/modules/__tests__/users/get-me.spec.ts +++ b/integration-tests/modules/__tests__/users/get-me.spec.ts @@ -1,4 +1,4 @@ -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils/dist" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/users/list-users.spec.ts b/integration-tests/modules/__tests__/users/list-users.spec.ts index 17a3311364..85f9cc3c5e 100644 --- a/integration-tests/modules/__tests__/users/list-users.spec.ts +++ b/integration-tests/modules/__tests__/users/list-users.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/users/retrieve-user.spec.ts b/integration-tests/modules/__tests__/users/retrieve-user.spec.ts index d4aacc5aac..4139a09fe6 100644 --- a/integration-tests/modules/__tests__/users/retrieve-user.spec.ts +++ b/integration-tests/modules/__tests__/users/retrieve-user.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/users/update-user.spec.ts b/integration-tests/modules/__tests__/users/update-user.spec.ts index fe75de1530..3ae251ca78 100644 --- a/integration-tests/modules/__tests__/users/update-user.spec.ts +++ b/integration-tests/modules/__tests__/users/update-user.spec.ts @@ -1,6 +1,6 @@ import { IUserModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(50000) diff --git a/integration-tests/modules/__tests__/workflow-engine/tests.ts b/integration-tests/modules/__tests__/workflow-engine/tests.ts index b5aa4608c7..3030853d39 100644 --- a/integration-tests/modules/__tests__/workflow-engine/tests.ts +++ b/integration-tests/modules/__tests__/workflow-engine/tests.ts @@ -4,7 +4,7 @@ import { StepResponse, WorkflowData, } from "@medusajs/workflows-sdk" -import { createAdminUser } from "../../helpers/create-admin-user" +import { createAdminUser } from "../../../helpers/create-admin-user" import { medusaIntegrationTestRunner } from "medusa-test-utils" export const workflowEngineTestSuite = ( diff --git a/integration-tests/modules/helpers/create-admin-user.ts b/integration-tests/modules/helpers/create-admin-user.ts deleted file mode 100644 index cbc90a2970..0000000000 --- a/integration-tests/modules/helpers/create-admin-user.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { IAuthModuleService } from "@medusajs/types" -import jwt from "jsonwebtoken" -import { getContainer } from "../../environment-helpers/use-container" -import adminSeeder from "../../helpers/admin-seeder" - -export const createAdminUser = async ( - dbConnection, - adminHeaders, - container? -) => { - await adminSeeder(dbConnection) - const appContainer = container ?? getContainer()! - - const authModule: IAuthModuleService = appContainer.resolve( - ModuleRegistrationName.AUTH - ) - const authUser = await authModule.create({ - provider: "emailpass", - entity_id: "admin@medusa.js", - scope: "admin", - app_metadata: { - user_id: "admin_user", - }, - }) - - const token = jwt.sign(authUser, "test") - adminHeaders.headers["authorization"] = `Bearer ${token}` -} diff --git a/packages/medusa-test-utils/src/medusa-test-runner.ts b/packages/medusa-test-utils/src/medusa-test-runner.ts index b4b5cd0c51..f33df322fe 100644 --- a/packages/medusa-test-utils/src/medusa-test-runner.ts +++ b/packages/medusa-test-utils/src/medusa-test-runner.ts @@ -3,12 +3,13 @@ import { initDb } from "./medusa-test-runner-utils/use-db" import { startBootstrapApp } from "./medusa-test-runner-utils/bootstrap-app" import { createDatabase, dropDatabase } from "pg-god" import { ContainerLike } from "@medusajs/types" +import { createMedusaContainer } from "@medusajs/utils" const axios = require("axios").default const keepTables = [ - "store", - "staged_job", + /*"store",*/ + /* "staged_job", "shipping_profile", "fulfillment_provider", "payment_provider", @@ -16,7 +17,7 @@ const keepTables = [ "region_country", "currency", "migrations", - "mikro_orm_migrations", + "mikro_orm_migrations",*/ ] const DB_HOST = process.env.DB_HOST @@ -45,26 +46,19 @@ const dbTestUtilFactory = (): any => ({ forceDelete, schema, }: { forceDelete?: string[]; schema?: string } = {}) { - forceDelete = forceDelete || [] + forceDelete ??= [] const manager = this.db_.manager + schema ??= "public" + await manager.query(`SET session_replication_role = 'replica';`) const tableNames = await manager.query(`SELECT table_name FROM information_schema.tables - WHERE table_schema = '${ - schema ?? "public" - }';`) + WHERE table_schema = '${schema}';`) for (const { table_name } of tableNames) { - if ( - keepTables.includes(table_name) && - !forceDelete.includes(table_name) - ) { - continue - } - await manager.query(`DELETE - FROM "${table_name}";`) + FROM ${schema}."${table_name}";`) } await manager.query(`SET session_replication_role = 'origin';`) @@ -209,9 +203,29 @@ export function medusaIntegrationTestRunner({ shutdown = shutdown_ } + const beforeEach_ = async () => { + const container = options.getContainer() + const copiedContainer = createMedusaContainer({}, container) + + if (process.env.MEDUSA_FF_MEDUSA_V2 != "true") { + const defaultLoader = + require("@medusajs/medusa/dist/loaders/defaults").default + await defaultLoader({ + container: copiedContainer, + }) + } + + const medusaAppLoaderRunner = + require("@medusajs/medusa/dist/loaders/medusa-app").runModulesLoader + await medusaAppLoaderRunner({ + container: copiedContainer, + configModule: container.resolve("configModule"), + }) + } + const afterEach_ = async () => { try { - await dbUtils.teardown({ forceDelete: [], schema }) + await dbUtils.teardown({ schema }) } catch (error) { console.error("Error tearing down database:", error) } @@ -219,6 +233,7 @@ export function medusaIntegrationTestRunner({ return describe("", () => { beforeAll(beforeAll_) + beforeEach(beforeEach_) afterEach(afterEach_) afterAll(async () => { await dbUtils.shutdown(dbName) diff --git a/packages/medusa/src/api-v2/admin/stores/query-config.ts b/packages/medusa/src/api-v2/admin/stores/query-config.ts index 908cab05a0..dc879e64c5 100644 --- a/packages/medusa/src/api-v2/admin/stores/query-config.ts +++ b/packages/medusa/src/api-v2/admin/stores/query-config.ts @@ -4,10 +4,13 @@ export const defaultAdminStoreFields = [ "id", "name", "supported_currency_codes", + "default_currency_code", "default_sales_channel_id", "default_region_id", "default_location_id", "metadata", + "created_at", + "updated_at", ] export const retrieveTransformQueryConfig = { diff --git a/packages/medusa/src/api-v2/admin/stores/route.ts b/packages/medusa/src/api-v2/admin/stores/route.ts index 0c63f37b9d..5f6750481b 100644 --- a/packages/medusa/src/api-v2/admin/stores/route.ts +++ b/packages/medusa/src/api-v2/admin/stores/route.ts @@ -1,9 +1,12 @@ -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString +} from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../types/routing" import { defaultAdminStoreFields } from "./query-config" export const GET = async (req: MedusaRequest, res: MedusaResponse) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) const queryObject = remoteQueryObjectFromString({ entryPoint: "store", diff --git a/packages/medusa/src/api-v2/admin/stores/validators.ts b/packages/medusa/src/api-v2/admin/stores/validators.ts index 8a8295d9f8..ab761f3252 100644 --- a/packages/medusa/src/api-v2/admin/stores/validators.ts +++ b/packages/medusa/src/api-v2/admin/stores/validators.ts @@ -51,6 +51,10 @@ export class AdminPostStoresStoreReq { @IsArray() supported_currency_codes?: string[] + @IsOptional() + @IsString() + default_currency_code?: string + @IsOptional() @IsString() default_sales_channel_id?: string diff --git a/packages/medusa/src/loaders/medusa-app.ts b/packages/medusa/src/loaders/medusa-app.ts index 02e852b0d5..95135b93cb 100644 --- a/packages/medusa/src/loaders/medusa-app.ts +++ b/packages/medusa/src/loaders/medusa-app.ts @@ -231,4 +231,72 @@ export const loadMedusaApp = async ( return medusaApp } +/** + * Run the modules loader without taking care of anything else. This is useful for running the loader as a separate action or to re run all modules loaders. + * + * @param configModule + * @param container + */ +export async function runModulesLoader({ + configModule, + container, +}: { + configModule: { + modules?: CommonTypes.ConfigModule["modules"] + projectConfig: CommonTypes.ConfigModule["projectConfig"] + } + container: MedusaContainer +}): Promise { + const featureFlagRouter = container.resolve("featureFlagRouter") + const injectedDependencies = { + [ContainerRegistrationKeys.PG_CONNECTION]: container.resolve( + ContainerRegistrationKeys.PG_CONNECTION + ), + [ContainerRegistrationKeys.LOGGER]: container.resolve( + ContainerRegistrationKeys.LOGGER + ), + } + + const sharedResourcesConfig = { + database: { + clientUrl: configModule.projectConfig.database_url, + driverOptions: configModule.projectConfig.database_extra, + debug: !!(configModule.projectConfig.database_logging ?? false), + }, + } + + const configModules = mergeDefaultModules(configModule.modules) + + // Apply default options to legacy modules + for (const moduleKey of Object.keys(configModules)) { + if (!ModulesDefinition[moduleKey]?.isLegacy) { + continue + } + + if (isObject(configModules[moduleKey])) { + ;( + configModules[moduleKey] as Partial + ).options ??= { + database: { + type: "postgres", + url: configModule.projectConfig.database_url, + extra: configModule.projectConfig.database_extra, + schema: configModule.projectConfig.database_schema, + logging: configModule.projectConfig.database_logging, + }, + } + } + } + + await MedusaApp({ + modulesConfig: configModules, + servicesConfig: joinerConfig, + remoteFetchData: remoteQueryFetchData(container), + sharedContainer: container, + sharedResourcesConfig, + injectedDependencies, + loaderOnly: true, + }) +} + export default loadMedusaApp diff --git a/packages/modules-sdk/medusajs-modules-sdk-1.12.6.tgz b/packages/modules-sdk/medusajs-modules-sdk-1.12.6.tgz deleted file mode 100644 index 968452f203..0000000000 Binary files a/packages/modules-sdk/medusajs-modules-sdk-1.12.6.tgz and /dev/null differ diff --git a/packages/modules-sdk/src/loaders/module-loader.ts b/packages/modules-sdk/src/loaders/module-loader.ts index ed11bfdda2..5c84e7f013 100644 --- a/packages/modules-sdk/src/loaders/module-loader.ts +++ b/packages/modules-sdk/src/loaders/module-loader.ts @@ -14,18 +14,21 @@ export const moduleLoader = async ({ moduleResolutions, logger, migrationOnly, + loaderOnly, }: { container: MedusaContainer moduleResolutions: Record logger: Logger migrationOnly?: boolean + loaderOnly?: boolean }): Promise => { for (const resolution of Object.values(moduleResolutions ?? {})) { const registrationResult = await loadModule( container, resolution, logger!, - migrationOnly + migrationOnly, + loaderOnly ) if (registrationResult?.error) { @@ -48,7 +51,8 @@ async function loadModule( container: MedusaContainer, resolution: ModuleResolution, logger: Logger, - migrationOnly?: boolean + migrationOnly?: boolean, + loaderOnly?: boolean ): Promise<{ error?: Error } | void> { const modDefinition = resolution.definition const registrationName = modDefinition.registrationName @@ -85,5 +89,11 @@ async function loadModule( return } - return await loadInternalModule(container, resolution, logger, migrationOnly) + return await loadInternalModule( + container, + resolution, + logger, + migrationOnly, + loaderOnly + ) } diff --git a/packages/modules-sdk/src/loaders/utils/load-internal.ts b/packages/modules-sdk/src/loaders/utils/load-internal.ts index e8f8bdb524..bbe11a5122 100644 --- a/packages/modules-sdk/src/loaders/utils/load-internal.ts +++ b/packages/modules-sdk/src/loaders/utils/load-internal.ts @@ -17,7 +17,8 @@ export async function loadInternalModule( container: MedusaContainer, resolution: ModuleResolution, logger: Logger, - migrationOnly?: boolean + migrationOnly?: boolean, + loaderOnly?: boolean ): Promise<{ error?: Error } | void> { const registrationName = resolution.definition.registrationName @@ -121,6 +122,10 @@ export async function loadInternalModule( } } + if (loaderOnly) { + return + } + const moduleService = loadedModule.service container.register({ [registrationName]: asFunction((cradle) => { diff --git a/packages/modules-sdk/src/medusa-app.ts b/packages/modules-sdk/src/medusa-app.ts index 305626ad52..9e4030fb5a 100644 --- a/packages/modules-sdk/src/medusa-app.ts +++ b/packages/modules-sdk/src/medusa-app.ts @@ -67,10 +67,11 @@ export type SharedResources = { } } -async function loadModules( +export async function loadModules( modulesConfig, sharedContainer, - migrationOnly = false + migrationOnly = false, + loaderOnly = false ) { const allModules = {} @@ -111,8 +112,13 @@ async function loadModules( moduleDefinition: definition as ModuleDefinition, moduleExports, migrationOnly, + loaderOnly, })) as LoadedModule + if (loaderOnly) { + return + } + const service = loaded[moduleName] sharedContainer.register({ [service.__definition.registrationName]: asValue(service), @@ -207,6 +213,10 @@ export type MedusaAppOptions = { remoteFetchData?: RemoteFetchDataCallback injectedDependencies?: any onApplicationStartCb?: () => void + /** + * Forces the modules bootstrapper to only run the modules loaders and return prematurely + */ + loaderOnly?: boolean } async function MedusaApp_({ @@ -221,6 +231,7 @@ async function MedusaApp_({ injectedDependencies = {}, onApplicationStartCb, migrationOnly = false, + loaderOnly = false, }: MedusaAppOptions & { migrationOnly?: boolean } = {}): Promise<{ modules: Record link: RemoteLink | undefined @@ -285,7 +296,25 @@ async function MedusaApp_({ }) } - const allModules = await loadModules(modules, sharedContainer_, migrationOnly) + const allModules = await loadModules( + modules, + sharedContainer_, + migrationOnly, + loaderOnly + ) + + if (loaderOnly) { + return { + modules: allModules, + link: undefined, + query: async () => { + throw new Error("Querying not allowed in loaderOnly mode") + }, + runMigrations: async () => { + throw new Error("Migrations not allowed in loaderOnly mode") + }, + } + } // Share Event bus with link modules injectedDependencies[ModuleRegistrationName.EVENT_BUS] = diff --git a/packages/modules-sdk/src/medusa-module.ts b/packages/modules-sdk/src/medusa-module.ts index 39e6cf96fd..ec8d875437 100644 --- a/packages/modules-sdk/src/medusa-module.ts +++ b/packages/modules-sdk/src/medusa-module.ts @@ -65,6 +65,10 @@ export type ModuleBootstrapOptions = { * Don't forget to clear the instances (MedusaModule.clearInstances()) after the migration are done. */ migrationOnly?: boolean + /** + * Forces the modules bootstrapper to only run the modules loaders and return prematurely + */ + loaderOnly?: boolean } export type LinkModuleBootstrapOptions = { @@ -220,6 +224,7 @@ export class MedusaModule { moduleDefinition, injectedDependencies, migrationOnly, + loaderOnly, }: ModuleBootstrapOptions): Promise<{ [key: string]: T }> { @@ -227,25 +232,28 @@ export class MedusaModule { stringifyCircular({ moduleKey, defaultPath, declaration }) ) - if (MedusaModule.instances_.has(hashKey)) { + if (!loaderOnly && MedusaModule.instances_.has(hashKey)) { return MedusaModule.instances_.get(hashKey)! as { [key: string]: T } } - if (MedusaModule.loading_.has(hashKey)) { + if (!loaderOnly && MedusaModule.loading_.has(hashKey)) { return MedusaModule.loading_.get(hashKey) } let finishLoading: any let errorLoading: any - MedusaModule.loading_.set( - hashKey, - new Promise((resolve, reject) => { - finishLoading = resolve - errorLoading = reject - }) - ) + + if (!loaderOnly) { + MedusaModule.loading_.set( + hashKey, + new Promise((resolve, reject) => { + finishLoading = resolve + errorLoading = reject + }) + ) + } let modDeclaration = declaration ?? @@ -294,6 +302,7 @@ export class MedusaModule { moduleResolutions, logger: logger_, migrationOnly, + loaderOnly }) } catch (err) { errorLoading(err) @@ -302,6 +311,10 @@ export class MedusaModule { const services = {} + if (loaderOnly) { + return services + } + for (const resolution of Object.values( moduleResolutions ) as ModuleResolution[]) { diff --git a/packages/region/mikro-orm.config.dev.ts b/packages/region/mikro-orm.config.dev.ts index e6385291c7..b5f6f37912 100644 --- a/packages/region/mikro-orm.config.dev.ts +++ b/packages/region/mikro-orm.config.dev.ts @@ -1,8 +1,12 @@ import * as entities from "./src/models" +import { TSMigrationGenerator } from "@medusajs/utils" module.exports = { entities: Object.values(entities), schema: "public", clientUrl: "postgres://postgres@localhost/medusa-region", type: "postgresql", + migrations: { + generator: TSMigrationGenerator, + }, } diff --git a/packages/region/src/joiner-config.ts b/packages/region/src/joiner-config.ts index ea3587749c..85f7a7bc59 100644 --- a/packages/region/src/joiner-config.ts +++ b/packages/region/src/joiner-config.ts @@ -5,7 +5,7 @@ import { Country, Region } from "@models" export const LinkableKeys = { region_id: Region.name, - country_id: Region.name, + country_iso: Country.name, } const entityLinkableKeysMap: MapToConfig = {} diff --git a/packages/region/src/migrations/RegionModuleSetup20240205173216.ts b/packages/region/src/migrations/RegionModuleSetup20240205173216.ts index 2eb6b65a09..f350b25095 100644 --- a/packages/region/src/migrations/RegionModuleSetup20240205173216.ts +++ b/packages/region/src/migrations/RegionModuleSetup20240205173216.ts @@ -26,14 +26,13 @@ ${generatePostgresAlterColummnIfExistStatement( CREATE INDEX IF NOT EXISTS "IDX_region_deleted_at" ON "region" ("deleted_at") WHERE "deleted_at" IS NOT NULL; -- Create or update "region_country" table CREATE TABLE IF NOT EXISTS "region_country" ( - "id" text NOT NULL, "iso_2" text NOT NULL, "iso_3" text NOT NULL, "num_code" int NOT NULL, "name" text NOT NULL, "display_name" text NOT NULL, "region_id" text NULL, - CONSTRAINT "region_country_pkey" PRIMARY KEY ("id") + CONSTRAINT "region_country_pkey" PRIMARY KEY ("iso_2") ); CREATE UNIQUE INDEX IF NOT EXISTS "IDX_region_country_region_id_iso_2_unique" ON "region_country" (region_id, iso_2); -- Adjust foreign keys for "region_country" diff --git a/packages/region/src/models/country.ts b/packages/region/src/models/country.ts index 1e1ae59f36..85b640f44a 100644 --- a/packages/region/src/models/country.ts +++ b/packages/region/src/models/country.ts @@ -1,18 +1,6 @@ -import { - BeforeCreate, - Entity, - Unique, - ManyToOne, - OnInit, - PrimaryKey, - Property, - Index, -} from "@mikro-orm/core" +import { Entity, ManyToOne, PrimaryKey, Property } from "@mikro-orm/core" -import { - createPsqlIndexStatementHelper, - generateEntityId, -} from "@medusajs/utils" +import { createPsqlIndexStatementHelper } from "@medusajs/utils" import Region from "./region" // We don't need a partial index on deleted_at here since we don't support soft deletes on countries @@ -28,8 +16,6 @@ RegionIdIsoIndexStatement.MikroORMIndex() @Entity({ tableName: "region_country" }) export default class Country { @PrimaryKey({ columnType: "text" }) - id: string - @Property({ columnType: "text" }) iso_2: string @@ -55,14 +41,4 @@ export default class Country { onDelete: "set null", }) region?: Region | null - - @BeforeCreate() - onCreate() { - this.id = generateEntityId(this.id, "reg_ctry") - } - - @OnInit() - onInit() { - this.id = generateEntityId(this.id, "reg_ctry") - } } diff --git a/packages/store/integration-tests/__tests__/store-module-service.spec.ts b/packages/store/integration-tests/__tests__/store-module-service.spec.ts index 470f236731..f0c92bb06a 100644 --- a/packages/store/integration-tests/__tests__/store-module-service.spec.ts +++ b/packages/store/integration-tests/__tests__/store-module-service.spec.ts @@ -30,6 +30,14 @@ moduleIntegrationTestRunner({ }) }) + it("should fail to get created if default currency code is not in list of supported currency codes", async function () { + const err = await service + .create({ ...createStoreFixture, default_currency_code: "jpy" }) + .catch((err) => err.message) + + expect(err).toEqual("Store does not have currency: jpy") + }) + describe("upserting a store", () => { it("should get created if it does not exist", async function () { const store = await service.upsert(createStoreFixture) @@ -67,6 +75,45 @@ moduleIntegrationTestRunner({ }) expect(updatedStore.title).toEqual("Updated store") }) + + it("should fail updating default currency code to an unsupported one", async function () { + const createdStore = await service.create(createStoreFixture) + const updateErr = await service + .update(createdStore.id, { + default_currency_code: "jpy", + }) + .catch((err) => err.message) + + expect(updateErr).toEqual("Store does not have currency: jpy") + }) + + it("should fail updating default currency code to an unsupported one if the supported currencies are also updated", async function () { + const createdStore = await service.create(createStoreFixture) + const updateErr = await service + .update(createdStore.id, { + supported_currency_codes: ["mkd"], + default_currency_code: "jpy", + }) + .catch((err) => err.message) + + expect(updateErr).toEqual("Store does not have currency: jpy") + }) + + it("should fail updating supported currencies if one of them is used as a default one", async function () { + const createdStore = await service.create({ + ...createStoreFixture, + default_currency_code: "eur", + }) + const updateErr = await service + .update(createdStore.id, { + supported_currency_codes: ["jpy"], + }) + .catch((err) => err.message) + + expect(updateErr).toEqual( + "You are not allowed to remove default currency from store currencies without replacing it as well" + ) + }) }) describe("deleting a store", () => { diff --git a/packages/store/src/migrations/.snapshot-medusa-store.json b/packages/store/src/migrations/.snapshot-medusa-store.json index 5faa1a6990..8dc9b84d92 100644 --- a/packages/store/src/migrations/.snapshot-medusa-store.json +++ b/packages/store/src/migrations/.snapshot-medusa-store.json @@ -35,6 +35,15 @@ "default": "'{}'", "mappedType": "array" }, + "default_currency_code": { + "name": "default_currency_code", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, "default_sales_channel_id": { "name": "default_sales_channel_id", "type": "text", diff --git a/packages/store/src/migrations/InitialSetup20240227075933.ts b/packages/store/src/migrations/InitialSetup20240227075933.ts index 668c1ab991..d27a4d1b12 100644 --- a/packages/store/src/migrations/InitialSetup20240227075933.ts +++ b/packages/store/src/migrations/InitialSetup20240227075933.ts @@ -13,6 +13,12 @@ export class InitialSetup20240226130829 extends Migration { this.addSql( `alter table "store" alter column "name" SET DEFAULT 'Medusa Store';` ) + this.addSql( + `alter table "store" alter column "default_currency_code" TYPE text;` + ) + this.addSql( + `alter table "store" alter column "default_currency_code" drop not null;` + ) this.addSql( `alter table "store" alter column "default_sales_channel_id" TYPE text;` ) @@ -20,7 +26,9 @@ export class InitialSetup20240226130829 extends Migration { `alter table "store" alter column "default_location_id" TYPE text;` ) - this.addSql(`alter table "store" add column "default_region_id" text;`) + this.addSql( + `alter table "store" add column "default_region_id" text null;` + ) this.addSql( `alter table "store" add column "deleted_at" timestamptz null;` ) @@ -32,6 +40,13 @@ export class InitialSetup20240226130829 extends Migration { 'create index if not exists "IDX_store_deleted_at" on "store" (deleted_at) where deleted_at is not null;' ) + this.addSql( + `alter table "store" drop constraint if exists "FK_61b0f48cccbb5f41c750bac7286";` + ) + this.addSql( + `alter table "store" drop constraint if exists "FK_55beebaa09e947cccca554af222";` + ) + // this.addSql(`alter table "store" drop column "default_currency_code";`) // this.addSql(`alter table "store" drop column "swap_link_template";`) // this.addSql(`alter table "store" drop column "payment_link_template";`) @@ -39,7 +54,7 @@ export class InitialSetup20240226130829 extends Migration { } else { this.addSql(`create table if not exists "store" ("id" text not null, "name" text not null default \'Medusa Store\', "supported_currency_codes" text[] not null default \'{}\', - "default_sales_channel_id" text null, "default_region_id" text null, "default_location_id" text null, + "default_currency_code" text null, "default_sales_channel_id" text null, "default_region_id" text null, "default_location_id" text null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "store_pkey" primary key ("id"));`) diff --git a/packages/store/src/models/store.ts b/packages/store/src/models/store.ts index 8c9015fac2..ab45877f50 100644 --- a/packages/store/src/models/store.ts +++ b/packages/store/src/models/store.ts @@ -38,6 +38,9 @@ export default class Store { @Property({ type: "array", default: "{}" }) supported_currency_codes: string[] = [] + @Property({ columnType: "text", nullable: true }) + default_currency_code: string | null = null + @Property({ columnType: "text", nullable: true }) default_sales_channel_id: string | null = null diff --git a/packages/store/src/services/store-module-service.ts b/packages/store/src/services/store-module-service.ts index adc269aaa3..0c8d77e716 100644 --- a/packages/store/src/services/store-module-service.ts +++ b/packages/store/src/services/store-module-service.ts @@ -11,6 +11,7 @@ import { InjectManager, InjectTransactionManager, MedusaContext, + MedusaError, ModulesSdkUtils, isString, promiseAll, @@ -83,6 +84,8 @@ export default class StoreModuleService @MedusaContext() sharedContext: Context = {} ): Promise { let normalizedInput = StoreModuleService.normalizeInput(data) + StoreModuleService.validateCreateRequest(normalizedInput) + return await this.storeService_.create(normalizedInput, sharedContext) } @@ -169,6 +172,7 @@ export default class StoreModuleService @MedusaContext() sharedContext: Context = {} ): Promise { const normalizedInput = StoreModuleService.normalizeInput(data) + await this.validateUpdateRequest(normalizedInput) return await this.storeService_.update(normalizedInput, sharedContext) } @@ -182,4 +186,80 @@ export default class StoreModuleService }) ) } + + private static validateCreateRequest(stores: StoreTypes.CreateStoreDTO[]) { + for (const store of stores) { + // If we are setting the default currency code on creating, make sure it is supported + if (store.default_currency_code) { + if ( + !store.supported_currency_codes?.includes( + store.default_currency_code ?? "" + ) + ) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Store does not have currency: ${store.default_currency_code}` + ) + } + } + } + } + + private async validateUpdateRequest(stores: UpdateStoreInput[]) { + const dbStores = await this.storeService_.list( + { id: stores.map((s) => s.id) }, + { take: null } + ) + + const dbStoresMap = new Map( + dbStores.map((dbStore) => [dbStore.id, dbStore]) + ) + + for (const store of stores) { + const dbStore = dbStoresMap.get(store.id) + + // If it is updating both the supported currency codes and the default one, look in that list + if (store.supported_currency_codes && store.default_currency_code) { + if ( + !store.supported_currency_codes.includes( + store.default_currency_code ?? "" + ) + ) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Store does not have currency: ${store.default_currency_code}` + ) + } + return + } + + // If it is updating only the default currency code, look in the db store + if (store.default_currency_code) { + if ( + !dbStore?.supported_currency_codes?.includes( + store.default_currency_code + ) + ) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Store does not have currency: ${store.default_currency_code}` + ) + } + } + + // If it is updating only the supported currency codes, make sure one of them is not set as a default one + if (store.supported_currency_codes) { + if ( + !store.supported_currency_codes.includes( + dbStore?.default_currency_code ?? "" + ) + ) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "You are not allowed to remove default currency from store currencies without replacing it as well" + ) + } + } + } + } } diff --git a/packages/types/src/store/common/store.ts b/packages/types/src/store/common/store.ts index a852771d5f..d255dd6c42 100644 --- a/packages/types/src/store/common/store.ts +++ b/packages/types/src/store/common/store.ts @@ -4,10 +4,13 @@ export interface StoreDTO { id: string name: string supported_currency_codes: string[] + default_currency_code?: string default_sales_channel_id?: string default_region_id?: string default_location_id?: string metadata: Record | null + created_at: string + updated_at: string } export interface FilterableStoreProps extends BaseFilterable { diff --git a/packages/types/src/store/mutations/store.ts b/packages/types/src/store/mutations/store.ts index eaf391b3e0..e7ea565819 100644 --- a/packages/types/src/store/mutations/store.ts +++ b/packages/types/src/store/mutations/store.ts @@ -1,6 +1,7 @@ export interface CreateStoreDTO { name?: string supported_currency_codes?: string[] + default_currency_code?: string default_sales_channel_id?: string default_region_id?: string default_location_id?: string @@ -11,6 +12,7 @@ export interface UpsertStoreDTO { id?: string name?: string supported_currency_codes?: string[] + default_currency_code?: string default_sales_channel_id?: string default_region_id?: string default_location_id?: string @@ -20,6 +22,7 @@ export interface UpsertStoreDTO { export interface UpdateStoreDTO { name?: string supported_currency_codes?: string[] + default_currency_code?: string default_sales_channel_id?: string default_region_id?: string default_location_id?: string diff --git a/yarn.lock b/yarn.lock index 6e89889f4f..0ae66844e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31765,15 +31765,30 @@ __metadata: "@babel/cli": ^7.12.10 "@babel/core": ^7.12.10 "@babel/node": ^7.12.10 + "@medusajs/api-key": "workspace:^" + "@medusajs/auth": "workspace:*" "@medusajs/cache-inmemory": "workspace:*" + "@medusajs/customer": "workspace:^" "@medusajs/event-bus-local": "workspace:*" + "@medusajs/inventory": "workspace:^" "@medusajs/medusa": "workspace:*" + "@medusajs/modules-sdk": "workspace:^" + "@medusajs/pricing": "workspace:^" + "@medusajs/product": "workspace:^" + "@medusajs/promotion": "workspace:^" + "@medusajs/region": "workspace:^" + "@medusajs/store": "workspace:^" + "@medusajs/tax": "workspace:^" + "@medusajs/user": "workspace:^" + "@medusajs/utils": "workspace:^" "@medusajs/workflow-engine-inmemory": "workspace:*" babel-preset-medusa-package: "*" faker: ^5.5.3 jest: ^26.6.3 jest-environment-node: 26.6.2 + medusa-fulfillment-webshipper: "workspace:*" medusa-interfaces: "workspace:*" + medusa-plugin-sendgrid: "workspace:*" pg: ^8.11.0 typeorm: ^0.3.16 languageName: unknown