From 0c0c510a371af67c97b8c3f1d10e70bf0c95230d Mon Sep 17 00:00:00 2001 From: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:25:43 +0200 Subject: [PATCH] chore: Move admin region tests (#7582) --- .../api/__tests__/admin/region.js | 482 ------------------ .../__tests__/region/admin/region.spec.ts | 274 ++++++++++ .../src/api/admin/regions/[id]/route.ts | 9 + .../region/src/services/region-module.ts | 2 +- 4 files changed, 284 insertions(+), 483 deletions(-) delete mode 100644 integration-tests/api/__tests__/admin/region.js create mode 100644 integration-tests/http/__tests__/region/admin/region.spec.ts diff --git a/integration-tests/api/__tests__/admin/region.js b/integration-tests/api/__tests__/admin/region.js deleted file mode 100644 index e0b9f57e07..0000000000 --- a/integration-tests/api/__tests__/admin/region.js +++ /dev/null @@ -1,482 +0,0 @@ -const path = require("path") -const { Region } = require("@medusajs/medusa") - -const setupServer = require("../../../environment-helpers/setup-server") -const startServerWithEnvironment = - require("../../../environment-helpers/start-server-with-environment").default -const { useApi } = require("../../../environment-helpers/use-api") -const { initDb, useDb } = require("../../../environment-helpers/use-db") -const adminSeeder = require("../../../helpers/admin-seeder") -const { simpleRegionFactory } = require("../../../factories") - -const adminReqConfig = { - headers: { - "x-medusa-access-token": "test_token", - }, -} - -jest.setTimeout(30000) - -describe("/admin/regions", () => { - let medusaProcess - let dbConnection - const cwd = path.resolve(path.join(__dirname, "..", "..")) - - beforeAll(async () => { - dbConnection = await initDb({ cwd }) - medusaProcess = await setupServer({ cwd }) - }) - - afterAll(async () => { - const db = useDb() - await db.shutdown() - - medusaProcess.kill() - }) - - describe("Remove region from country on delete", () => { - beforeEach(async () => { - await adminSeeder(dbConnection) - const manager = dbConnection.manager - await manager.insert(Region, { - id: "test-region", - name: "Test Region", - currency_code: "usd", - tax_rate: 0, - }) - - await manager.query( - `UPDATE "country" SET region_id='test-region' WHERE iso_2 = 'us'` - ) - }) - - afterEach(async () => { - const db = useDb() - await db.teardown() - }) - - it("should successfully creates a region with countries from a previously deleted region", async () => { - const api = useApi() - - const response = await api - .delete(`/admin/regions/test-region`, adminReqConfig) - .catch((err) => { - console.log(err) - }) - - expect(response.status).toEqual(200) - expect(response.data).toMatchSnapshot({ - id: "test-region", - object: "region", - deleted: true, - }) - - const newReg = await api.post( - `/admin/regions`, - { - name: "World", - currency_code: "usd", - tax_rate: 0, - payment_providers: ["test-pay"], - fulfillment_providers: ["test-ful"], - countries: ["us"], - }, - adminReqConfig - ) - - expect(newReg.status).toEqual(200) - expect(newReg.data.region).toMatchSnapshot({ - id: expect.any(String), - name: "World", - currency_code: "usd", - countries: [ - { - region_id: expect.any(String), - }, - ], - tax_rate: 0, - fulfillment_providers: [ - { - id: "test-ful", - is_installed: true, - }, - ], - created_at: expect.any(String), - updated_at: expect.any(String), - }) - }) - }) - - describe("GET /admin/regions", () => { - beforeEach(async () => { - const manager = dbConnection.manager - await adminSeeder(dbConnection) - await manager.insert(Region, { - id: "test-region", - name: "Test Region", - currency_code: "usd", - tax_rate: 0, - }) - await manager.insert(Region, { - id: "test-region-deleted", - name: "Test Region", - currency_code: "usd", - tax_rate: 0, - deleted_at: new Date(), - }) - await manager.insert(Region, { - id: "test-region-updated", - name: "Test Region updated", - currency_code: "usd", - tax_rate: 0, - updated_at: new Date(), - }) - await manager.insert(Region, { - id: "test-region-updated-1", - name: "Test Region updated 1", - currency_code: "usd", - tax_rate: 0, - updated_at: new Date("10/10/2000"), - }) - await manager.insert(Region, { - id: "us-region", - name: "United States", - currency_code: "usd", - tax_rate: 0, - updated_at: new Date("10/10/2000"), - }) - await manager.insert(Region, { - id: "uk-region", - name: "United Kingdom", - currency_code: "gbp", - tax_rate: 0, - updated_at: new Date("10/10/2000"), - }) - }) - - afterEach(async () => { - const db = useDb() - await db.teardown() - }) - - it("should list the regions with expand currency relation", async () => { - const api = useApi() - - const response = await api.get( - "/admin/regions?limit=1&offset=1&expand=currency", - adminReqConfig - ) - - expect(response.status).toEqual(200) - - expect(response.data.regions[0].currency).toEqual( - expect.objectContaining({ - code: "usd", - }) - ) - }) - - it("should list the regions with q and order params", async () => { - const api = useApi() - - const response = await api.get( - "/admin/regions?q=united&order=currency_code", - adminReqConfig - ) - - expect(response.status).toEqual(200) - - expect(response.data.regions).toEqual([ - expect.objectContaining({ - name: "United Kingdom", - currency_code: "gbp", - }), - expect.objectContaining({ - name: "United States", - currency_code: "usd", - }), - ]) - }) - - it("should only return non-deleted regions", async () => { - const api = useApi() - - const response = await api - .get(`/admin/regions`, adminReqConfig) - .catch((err) => { - console.log(err) - }) - - expect(response.data.regions).toHaveLength(5) - expect(response.data.regions).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: "test-region-updated-1", - }), - expect.objectContaining({ - id: "test-region", - }), - expect.objectContaining({ - id: "test-region-updated", - }), - ]) - ) - expect(response.status).toEqual(200) - }) - - it("should return count of total regions", async () => { - const api = useApi() - - const response = await api.get(`/admin/regions?limit=2`, adminReqConfig) - - expect(response.data.regions).toHaveLength(2) - expect(response.data.count).toEqual(5) - expect(response.status).toEqual(200) - }) - - it("should filter correctly on update", async () => { - const api = useApi() - - const response = await api - .get(`/admin/regions?updated_at[gt]=10-10-2005`, adminReqConfig) - .catch((err) => { - console.log(err) - }) - - expect(response.data.regions).toHaveLength(2) - expect(response.data.regions).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: "test-region", - }), - expect.objectContaining({ - id: "test-region-updated", - }), - ]) - ) - expect(response.status).toEqual(200) - }) - }) - - describe("GET /admin/regions/:id", () => { - beforeEach(async () => { - const manager = dbConnection.manager - await adminSeeder(dbConnection) - - await manager.insert(Region, { - id: "region-id", - name: "Test Region", - currency_code: "usd", - tax_rate: 0, - }) - }) - - afterEach(async () => { - const db = useDb() - await db.teardown() - }) - - it("should retrieve the region from ID", async () => { - const api = useApi() - - const response = await api.get( - `/admin/regions/region-id?expand=currency`, - adminReqConfig - ) - - expect(response.status).toEqual(200) - expect(response.data.region).toEqual( - expect.objectContaining({ - id: "region-id", - currency: expect.objectContaining({ - code: "usd", - }), - }) - ) - }) - - it("should throw an error when region ID is invalid", async () => { - const api = useApi() - - const error = await api - .get(`/admin/regions/invalid-region-id`, adminReqConfig) - .catch((e) => e) - - expect(error.response.status).toEqual(404) - - expect(error.response.data).toEqual({ - type: "not_found", - message: "Region with invalid-region-id was not found", - }) - }) - }) - - describe("DELETE /admin/regions/:id", () => { - beforeEach(async () => { - await adminSeeder(dbConnection) - const manager = dbConnection.manager - await manager.insert(Region, { - id: "test-region", - name: "Test Region", - currency_code: "usd", - tax_rate: 0, - }) - - await manager.query( - `UPDATE "country" SET region_id='test-region' WHERE iso_2 = 'us'` - ) - }) - - afterEach(async () => { - const db = useDb() - await db.teardown() - }) - - it("should successfully deletes a region with a fulfillment provider", async () => { - const api = useApi() - - // add fulfillment provider to the region - await api.post( - "/admin/regions/test-region", - { - fulfillment_providers: ["test-ful"], - }, - adminReqConfig - ) - - const response = await api - .delete(`/admin/regions/test-region`, adminReqConfig) - .catch((err) => { - console.log(err) - }) - - expect(response.data).toEqual({ - id: "test-region", - object: "region", - deleted: true, - }) - expect(response.status).toEqual(200) - }) - - it("should fails to create when countries exists in different region", async () => { - const api = useApi() - - try { - await api.post( - `/admin/regions`, - { - name: "World", - currency_code: "usd", - tax_rate: 0, - payment_providers: ["test-pay"], - fulfillment_providers: ["test-ful"], - countries: ["us"], - }, - adminReqConfig - ) - } catch (error) { - expect(error.response.status).toEqual(422) - expect(error.response.data.message).toEqual( - "United States already exists in region test-region" - ) - } - }) - }) -}) - -describe("[MEDUSA_FF_TAX_INCLUSIVE_PRICING] /admin/regions", () => { - let medusaProcess - let dbConnection - - beforeAll(async () => { - const cwd = path.resolve(path.join(__dirname, "..", "..")) - const [process, connection] = await startServerWithEnvironment({ - cwd, - env: { MEDUSA_FF_TAX_INCLUSIVE_PRICING: true }, - }) - dbConnection = connection - medusaProcess = process - }) - - afterAll(async () => { - const db = useDb() - await db.shutdown() - - medusaProcess.kill() - }) - - describe("POST /admin/regions/:id", () => { - const region1TaxInclusiveId = "region-1-tax-inclusive" - - beforeEach(async () => { - try { - await adminSeeder(dbConnection) - await simpleRegionFactory(dbConnection, { - id: region1TaxInclusiveId, - countries: ["fr"], - }) - } catch (err) { - console.log(err) - throw err - } - }) - - afterEach(async () => { - const db = useDb() - await db.teardown() - }) - - it("should allow to create a region that includes tax", async function () { - const api = useApi() - - const payload = { - name: "region-including-taxes", - currency_code: "usd", - tax_rate: 0, - payment_providers: ["test-pay"], - fulfillment_providers: ["test-ful"], - countries: ["us"], - includes_tax: true, - } - - const response = await api - .post(`/admin/regions`, payload, adminReqConfig) - .catch((err) => { - console.log(err) - }) - - expect(response.data.region).toEqual( - expect.objectContaining({ - id: expect.any(String), - includes_tax: true, - name: "region-including-taxes", - }) - ) - }) - - it("should allow to update a region that includes tax", async function () { - const api = useApi() - let response = await api - .get(`/admin/regions/${region1TaxInclusiveId}`, adminReqConfig) - .catch((err) => { - console.log(err) - }) - - expect(response.data.region.includes_tax).toBe(false) - - response = await api - .post( - `/admin/regions/${region1TaxInclusiveId}`, - { - includes_tax: true, - }, - adminReqConfig - ) - .catch((err) => { - console.log(err) - }) - - expect(response.data.region.includes_tax).toBe(true) - }) - }) -}) diff --git a/integration-tests/http/__tests__/region/admin/region.spec.ts b/integration-tests/http/__tests__/region/admin/region.spec.ts new file mode 100644 index 0000000000..db330d9666 --- /dev/null +++ b/integration-tests/http/__tests__/region/admin/region.spec.ts @@ -0,0 +1,274 @@ +import { medusaIntegrationTestRunner } from "medusa-test-utils" +import { + adminHeaders, + createAdminUser, +} from "../../../../helpers/create-admin-user" + +jest.setTimeout(30000) + +medusaIntegrationTestRunner({ + testSuite: ({ dbConnection, getContainer, api }) => { + beforeAll(() => {}) + + beforeEach(async () => { + const container = getContainer() + await createAdminUser(dbConnection, adminHeaders, container) + }) + + describe("GET /admin/regions", () => { + let region1 + let region2 + + beforeEach(async () => { + region1 = ( + await api.post( + "/admin/regions", + { + name: "United Kingdom", + currency_code: "gbp", + }, + adminHeaders + ) + ).data.region + + region2 = ( + await api.post( + "/admin/regions", + { + name: "United States", + currency_code: "usd", + }, + adminHeaders + ) + ).data.region + }) + + it("should list regions", async () => { + const response = await api.get("/admin/regions", adminHeaders) + + expect(response.status).toEqual(200) + expect(response.data.regions).toEqual([ + expect.objectContaining({ + name: "United Kingdom", + }), + expect.objectContaining({ + name: "United States", + }), + ]) + }) + + it("should list the regions with q and order params", async () => { + const response = await api.get( + "/admin/regions?q=united&order=-currency_code", + adminHeaders + ) + + expect(response.status).toEqual(200) + + expect(response.data.regions).toEqual([ + expect.objectContaining({ + name: "United States", + currency_code: "usd", + }), + expect.objectContaining({ + name: "United Kingdom", + currency_code: "gbp", + }), + ]) + }) + }) + + describe("GET /admin/regions/:id", () => { + let region1 + beforeEach(async () => { + region1 = ( + await api.post( + "/admin/regions", + { + name: "United Kingdom", + currency_code: "gbp", + }, + adminHeaders + ) + ).data.region + }) + + it("should retrieve the region from ID", async () => { + const response = await api.get( + `/admin/regions/${region1.id}`, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.region).toEqual( + expect.objectContaining({ + id: region1.id, + }) + ) + }) + + it("should throw an error when region ID is invalid", async () => { + await api + .get(`/admin/regions/invalid-region-id`, adminHeaders) + .catch((e) => { + expect(e.response.status).toEqual(404) + expect(e.response.data.type).toEqual("not_found") + expect(e.response.data.message).toEqual( + `Region with id: invalid-region-id not found` + ) + }) + }) + }) + + describe("POST /admin/regions", () => { + beforeEach(async () => { + await api.post( + "/admin/regions", + { + name: "United States", + currency_code: "usd", + countries: ["us"], + }, + adminHeaders + ) + }) + + it("should create a region", async () => { + const region = ( + await api.post( + "/admin/regions", + { + name: "Test", + currency_code: "usd", + }, + adminHeaders + ) + ).data.region + + expect(region).toEqual( + expect.objectContaining({ + name: "Test", + currency_code: "usd", + }) + ) + }) + + it("should fails to create when countries exists in different region", async () => { + try { + await api.post( + `/admin/regions`, + { + name: "World", + currency_code: "usd", + countries: ["us"], + }, + adminHeaders + ) + } catch (error) { + expect(error.response.status).toEqual(400) + expect(error.response.data.message).toEqual( + `Countries with codes: \"us\" are already assigned to a region` + ) + } + }) + }) + + // TODO: Migrate when tax_inclusive_pricing is implemented + // describe("[MEDUSA_FF_TAX_INCLUSIVE_PRICING] /admin/regions", () => { + // let medusaProcess + // let dbConnection + + // beforeAll(async () => { + // const cwd = path.resolve(path.join(__dirname, "..", "..")) + // const [process, connection] = await startServerWithEnvironment({ + // cwd, + // env: { MEDUSA_FF_TAX_INCLUSIVE_PRICING: true }, + // }) + // dbConnection = connection + // medusaProcess = process + // }) + + // afterAll(async () => { + // const db = useDb() + // await db.shutdown() + + // medusaProcess.kill() + // }) + + // describe("POST /admin/regions/:id", () => { + // const region1TaxInclusiveId = "region-1-tax-inclusive" + + // beforeEach(async () => { + // try { + // await adminSeeder(dbConnection) + // await simpleRegionFactory(dbConnection, { + // id: region1TaxInclusiveId, + // countries: ["fr"], + // }) + // } catch (err) { + // console.log(err) + // throw err + // } + // }) + + // afterEach(async () => { + // const db = useDb() + // await db.teardown() + // }) + + // it("should allow to create a region that includes tax", async function () { + // const api = useApi() + + // const payload = { + // name: "region-including-taxes", + // currency_code: "usd", + // tax_rate: 0, + // payment_providers: ["test-pay"], + // fulfillment_providers: ["test-ful"], + // countries: ["us"], + // includes_tax: true, + // } + + // const response = await api + // .post(`/admin/regions`, payload, adminReqConfig) + // .catch((err) => { + // console.log(err) + // }) + + // expect(response.data.region).toEqual( + // expect.objectContaining({ + // id: expect.any(String), + // includes_tax: true, + // name: "region-including-taxes", + // }) + // ) + // }) + + // it("should allow to update a region that includes tax", async function () { + // const api = useApi() + // let response = await api + // .get(`/admin/regions/${region1TaxInclusiveId}`, adminReqConfig) + // .catch((err) => { + // console.log(err) + // }) + + // expect(response.data.region.includes_tax).toBe(false) + + // response = await api + // .post( + // `/admin/regions/${region1TaxInclusiveId}`, + // { + // includes_tax: true, + // }, + // adminReqConfig + // ) + // .catch((err) => { + // console.log(err) + // }) + + // expect(response.data.region.includes_tax).toBe(true) + // }) + // }) + // }) + }, +}) diff --git a/packages/medusa/src/api/admin/regions/[id]/route.ts b/packages/medusa/src/api/admin/regions/[id]/route.ts index 4342f8f1e9..1a39eb782e 100644 --- a/packages/medusa/src/api/admin/regions/[id]/route.ts +++ b/packages/medusa/src/api/admin/regions/[id]/route.ts @@ -2,6 +2,7 @@ import { deleteRegionsWorkflow, updateRegionsWorkflow, } from "@medusajs/core-flows" +import { MedusaError } from "@medusajs/utils" import { AuthenticatedMedusaRequest, MedusaResponse, @@ -18,6 +19,14 @@ export const GET = async ( req.scope, req.remoteQueryConfig.fields ) + + if (!region) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + `Region with id: ${req.params.id} not found` + ) + } + res.status(200).json({ region }) } diff --git a/packages/modules/region/src/services/region-module.ts b/packages/modules/region/src/services/region-module.ts index f387fcbfa6..4b7b66e481 100644 --- a/packages/modules/region/src/services/region-module.ts +++ b/packages/modules/region/src/services/region-module.ts @@ -14,6 +14,7 @@ import { } from "@medusajs/types" import { arrayDifference, + getDuplicates, InjectManager, InjectTransactionManager, isString, @@ -22,7 +23,6 @@ import { ModulesSdkUtils, promiseAll, removeUndefined, - getDuplicates, } from "@medusajs/utils" import { Country, Region } from "@models"