From 6aad03a20a0d8367d5dcb156ae1eb33f1e6a207a Mon Sep 17 00:00:00 2001 From: Riqwan Thamir Date: Tue, 3 Sep 2024 13:50:59 +0200 Subject: [PATCH] chore: remove promotions in campaign validators + move tests to http --- .../campaigns}/admin/campaigns.spec.ts | 322 ++----- .../promotions/admin/promotions.spec.ts} | 843 +++++++++++++++--- .../promotion/admin/create-promotion.spec.ts | 321 ------- .../promotion/admin/delete-promotion.spec.ts | 58 -- .../promotion/admin/list-promotions.spec.ts | 138 --- .../admin/retrieve-promotion.spec.ts | 104 --- .../promotion/admin/update-promotion.spec.ts | 173 ---- .../src/api/admin/campaigns/validators.ts | 2 - 8 files changed, 749 insertions(+), 1212 deletions(-) rename integration-tests/{modules/__tests__/promotion => http/__tests__/campaigns}/admin/campaigns.spec.ts (52%) rename integration-tests/{modules/__tests__/promotion/admin/promotion-rules.spec.ts => http/__tests__/promotions/admin/promotions.spec.ts} (53%) delete mode 100644 integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts delete mode 100644 integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts delete mode 100644 integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts delete mode 100644 integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts delete mode 100644 integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts diff --git a/integration-tests/modules/__tests__/promotion/admin/campaigns.spec.ts b/integration-tests/http/__tests__/campaigns/admin/campaigns.spec.ts similarity index 52% rename from integration-tests/modules/__tests__/promotion/admin/campaigns.spec.ts rename to integration-tests/http/__tests__/campaigns/admin/campaigns.spec.ts index 3d2873ad262b6..59dc2c7eeb60b 100644 --- a/integration-tests/modules/__tests__/promotion/admin/campaigns.spec.ts +++ b/integration-tests/http/__tests__/campaigns/admin/campaigns.spec.ts @@ -1,9 +1,4 @@ -import { IPromotionModuleService } from "@medusajs/types" -import { - CampaignBudgetType, - ModuleRegistrationName, - PromotionType, -} from "@medusajs/utils" +import { CampaignBudgetType, PromotionType } from "@medusajs/utils" import { medusaIntegrationTestRunner } from "medusa-test-utils" import { createAdminUser } from "../../../../helpers/create-admin-user" @@ -24,7 +19,6 @@ export const campaignData = { export const campaignsData = [ { - id: "campaign-id-1", name: "campaign 1", description: "test description", campaign_identifier: "test-1", @@ -37,7 +31,6 @@ export const campaignsData = [ }, }, { - id: "campaign-id-2", name: "campaign 2", description: "test description", campaign_identifier: "test-2", @@ -88,17 +81,25 @@ medusaIntegrationTestRunner({ testSuite: ({ dbConnection, getContainer, api }) => { describe("Admin Campaigns API", () => { let appContainer - let promotionModuleService: IPromotionModuleService + let campaign1 + let campaign2 + let promotion beforeAll(async () => { appContainer = getContainer() - promotionModuleService = appContainer.resolve( - ModuleRegistrationName.PROMOTION - ) }) beforeEach(async () => { await createAdminUser(dbConnection, adminHeaders, appContainer) + campaign1 = ( + await api.post(`/admin/campaigns`, campaignsData[0], adminHeaders) + ).data.campaign + campaign2 = ( + await api.post(`/admin/campaigns`, campaignsData[1], adminHeaders) + ).data.campaign + promotion = ( + await api.post(`/admin/promotions`, promotionData, adminHeaders) + ).data.promotion }) const generatePromotionData = () => { @@ -122,10 +123,6 @@ medusaIntegrationTestRunner({ } describe("GET /admin/campaigns", () => { - beforeEach(async () => { - await promotionModuleService.createCampaigns(campaignsData) - }) - it("should get all campaigns and its count", async () => { const response = await api.get(`/admin/campaigns`, adminHeaders) @@ -134,62 +131,10 @@ medusaIntegrationTestRunner({ expect(response.data.campaigns).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: expect.any(String), - name: "campaign 1", - description: "test description", - campaign_identifier: "test-1", - starts_at: expect.any(String), - ends_at: expect.any(String), - budget: { - id: expect.any(String), - type: "spend", - currency_code: "USD", - limit: 1000, - used: 0, - raw_limit: { - precision: 20, - value: "1000", - }, - raw_used: { - precision: 20, - value: "0", - }, - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, - }, - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, + id: campaign1.id, }), expect.objectContaining({ - id: expect.any(String), - name: "campaign 2", - description: "test description", - campaign_identifier: "test-2", - starts_at: expect.any(String), - ends_at: expect.any(String), - budget: { - id: expect.any(String), - type: "usage", - limit: 1000, - used: 0, - currency_code: null, - raw_limit: { - precision: 20, - value: "1000", - }, - raw_used: { - precision: 20, - value: "0", - }, - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, - }, - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, + id: campaign2.id, }), ]) ) @@ -253,61 +198,29 @@ medusaIntegrationTestRunner({ }) it("should get the requested campaign", async () => { - const createdCampaign = await promotionModuleService.createCampaigns( - campaignData - ) - const response = await api.get( - `/admin/campaigns/${createdCampaign.id}`, + `/admin/campaigns/${campaign1.id}`, adminHeaders ) expect(response.status).toEqual(200) - expect(response.data.campaign).toEqual({ - id: expect.any(String), - name: "campaign 1", - description: "test description", - campaign_identifier: "test-1", - starts_at: expect.any(String), - ends_at: expect.any(String), - budget: { - id: expect.any(String), - type: "spend", - limit: 1000, - currency_code: "USD", - raw_limit: { - precision: 20, - value: "1000", - }, - raw_used: { - precision: 20, - value: "0", - }, - used: 0, - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, - }, - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, - }) + expect(response.data.campaign).toEqual( + expect.objectContaining({ + id: campaign1.id, + }) + ) }) it("should get the requested campaign with filtered fields and relations", async () => { - const createdCampaign = await promotionModuleService.createCampaigns( - campaignData - ) - const response = await api.get( - `/admin/campaigns/${createdCampaign.id}?fields=name`, + `/admin/campaigns/${campaign1.id}?fields=name`, adminHeaders ) expect(response.status).toEqual(200) expect(response.data.campaign).toEqual({ - id: expect.any(String), - name: "campaign 1", + id: campaign1.id, + name: campaign1.name, }) }) }) @@ -355,98 +268,6 @@ medusaIntegrationTestRunner({ }) ) }) - - it("should create 3 campaigns in parallel and have the context passed as argument when calling createCampaigns with different transactionId", async () => { - await api.post( - `/admin/promotions`, - { ...promotionData, code: "PARALLEL" }, - adminHeaders - ) - - const spyCreateCampaigns = jest.spyOn( - promotionModuleService.constructor.prototype, - "createCampaigns" - ) - - const a = async () => { - return await api.post( - `/admin/campaigns`, - { - name: "camp_1", - campaign_identifier: "camp_1", - starts_at: new Date("01/01/2024").toISOString(), - ends_at: new Date("01/02/2024").toISOString(), - budget: { - limit: 1000, - type: "usage", - }, - }, - adminHeaders - ) - } - - const b = async () => { - return await api.post( - `/admin/campaigns`, - { - name: "camp_2", - campaign_identifier: "camp_2", - starts_at: new Date("01/02/2024").toISOString(), - ends_at: new Date("01/03/2029").toISOString(), - budget: { - limit: 500, - type: "usage", - }, - }, - adminHeaders - ) - } - - const c = async () => { - return await api.post( - `/admin/campaigns`, - { - name: "camp_3", - campaign_identifier: "camp_3", - starts_at: new Date("01/03/2024").toISOString(), - ends_at: new Date("01/04/2029").toISOString(), - budget: { - limit: 250, - type: "usage", - }, - }, - { - headers: { - ...adminHeaders.headers, - "x-request-id": "my-custom-request-id", - }, - } - ) - } - - await Promise.all([a(), b(), c()]) - - expect(spyCreateCampaigns).toHaveBeenCalledTimes(3) - expect(spyCreateCampaigns.mock.calls[0][1].__type).toBe( - "MedusaContext" - ) - - const distinctTransactionId = [ - ...new Set( - spyCreateCampaigns.mock.calls.map((call) => call[1].transactionId) - ), - ] - expect(distinctTransactionId).toHaveLength(3) - - const distinctRequestId = [ - ...new Set( - spyCreateCampaigns.mock.calls.map((call) => call[1].requestId) - ), - ] - - expect(distinctRequestId).toHaveLength(3) - expect(distinctRequestId).toContain("my-custom-request-id") - }) }) describe("POST /admin/campaigns/:id", () => { @@ -462,37 +283,17 @@ medusaIntegrationTestRunner({ }) it("should update a campaign successfully", async () => { - const createdPromotion = ( - await api.post(`/admin/promotions`, promotionData, adminHeaders) - ).data.promotion - - const createdCampaign = ( - await api.post( - `/admin/campaigns`, - { - name: "test", - campaign_identifier: "test", - starts_at: new Date("01/01/2024").toISOString(), - ends_at: new Date("01/01/2029").toISOString(), - budget: { - limit: 1000, - type: "usage", - }, - }, - adminHeaders - ) - ).data.campaign - - await promotionModuleService.addPromotionsToCampaign({ - id: createdCampaign.id, - promotion_ids: [createdPromotion.id], - }) + await api.post( + `admin/campaigns/${campaign1.id}/promotions`, + { add: [promotion.id] }, + adminHeaders + ) const response = await api.post( - `/admin/campaigns/${createdCampaign.id}?fields=*promotions`, + `/admin/campaigns/${campaign1.id}?fields=*promotions`, { - name: "test-2", - campaign_identifier: "test-2", + name: "test-update", + campaign_identifier: "test-update", budget: { limit: 2000, }, @@ -503,16 +304,16 @@ medusaIntegrationTestRunner({ expect(response.status).toEqual(200) expect(response.data.campaign).toEqual( expect.objectContaining({ - id: expect.any(String), - name: "test-2", - campaign_identifier: "test-2", + id: campaign1.id, + name: "test-update", + campaign_identifier: "test-update", budget: expect.objectContaining({ limit: 2000, - type: "usage", + type: "spend", }), promotions: [ expect.objectContaining({ - id: createdPromotion.id, + id: promotion.id, }), ], }) @@ -522,37 +323,26 @@ medusaIntegrationTestRunner({ describe("DELETE /admin/campaigns/:id", () => { it("should delete campaign successfully", async () => { - const [createdCampaign] = - await promotionModuleService.createCampaigns([ - { - name: "test", - campaign_identifier: "test", - starts_at: new Date("01/01/2024"), - ends_at: new Date("01/01/2025"), - }, - ]) - const deleteRes = await api.delete( - `/admin/campaigns/${createdCampaign.id}`, + `/admin/campaigns/${campaign1.id}`, adminHeaders ) expect(deleteRes.status).toEqual(200) - const campaigns = await promotionModuleService.listCampaigns({ - id: [createdCampaign.id], - }) + const { response } = await api + .post(`/admin/campaigns/${campaign1.id}`, {}, adminHeaders) + .catch((e) => e) - expect(campaigns.length).toEqual(0) + expect(response.status).toEqual(404) + expect(response.data.message).toEqual( + `Campaign with id "${campaign1.id}" not found` + ) }) }) describe("POST /admin/campaigns/:id/promotions", () => { it("should add or remove promotions from campaign", async () => { - const campaign = ( - await api.post(`/admin/campaigns`, campaignData, adminHeaders) - ).data.campaign - const promotion1 = ( await api.post( `/admin/promotions`, @@ -561,17 +351,9 @@ medusaIntegrationTestRunner({ ) ).data.promotion - const promotion2 = ( - await api.post( - `/admin/promotions`, - generatePromotionData(), - adminHeaders - ) - ).data.promotion - let response = await api.post( - `/admin/campaigns/${campaign.id}/promotions`, - { add: [promotion1.id, promotion2.id] }, + `/admin/campaigns/${campaign1.id}/promotions`, + { add: [promotion1.id, promotion.id] }, adminHeaders ) @@ -583,7 +365,7 @@ medusaIntegrationTestRunner({ ) response = await api.get( - `/admin/promotions?campaign_id=${campaign.id}`, + `/admin/promotions?campaign_id=${campaign1.id}`, adminHeaders ) @@ -595,19 +377,19 @@ medusaIntegrationTestRunner({ id: promotion1.id, }), expect.objectContaining({ - id: promotion2.id, + id: promotion.id, }), ]) ) await api.post( - `/admin/campaigns/${campaign.id}/promotions`, + `/admin/campaigns/${campaign1.id}/promotions`, { remove: [promotion1.id] }, adminHeaders ) response = await api.get( - `/admin/promotions?campaign_id=${campaign.id}`, + `/admin/promotions?campaign_id=${campaign1.id}`, adminHeaders ) @@ -616,7 +398,7 @@ medusaIntegrationTestRunner({ expect(response.data.promotions).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: promotion2.id, + id: promotion.id, }), ]) ) diff --git a/integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts b/integration-tests/http/__tests__/promotions/admin/promotions.spec.ts similarity index 53% rename from integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts rename to integration-tests/http/__tests__/promotions/admin/promotions.spec.ts index b79c85047a70c..02dd4dec7f758 100644 --- a/integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts +++ b/integration-tests/http/__tests__/promotions/admin/promotions.spec.ts @@ -1,30 +1,19 @@ -import { - ICustomerModuleService, - IProductModuleService, - IPromotionModuleService, - IRegionModuleService, - ISalesChannelModuleService, -} from "@medusajs/types" -import { ModuleRegistrationName, PromotionType } from "@medusajs/utils" +import { PromotionType } from "@medusajs/utils" import { medusaIntegrationTestRunner } from "medusa-test-utils" import { createAdminUser } from "../../../../helpers/create-admin-user" jest.setTimeout(50000) -const env = { MEDUSA_FF_MEDUSA_V2: true } -const adminHeaders = { headers: { "x-medusa-access-token": "test_token" } } +const adminHeaders = { + headers: { "x-medusa-access-token": "test_token" }, +} medusaIntegrationTestRunner({ - env, testSuite: ({ dbConnection, getContainer, api }) => { - describe.skip("Admin: Promotion Rules API", () => { + describe("Admin Promotions API", () => { let appContainer + let promotion let standardPromotion - let promotionModule: IPromotionModuleService - let regionService: IRegionModuleService - let productService: IProductModuleService - let customerService: ICustomerModuleService - let salesChannelService: ISalesChannelModuleService const promotionRule = { operator: "eq", @@ -34,30 +23,542 @@ medusaIntegrationTestRunner({ beforeAll(async () => { appContainer = getContainer() - promotionModule = appContainer.resolve(ModuleRegistrationName.PROMOTION) - regionService = appContainer.resolve(ModuleRegistrationName.REGION) - productService = appContainer.resolve(ModuleRegistrationName.PRODUCT) - customerService = appContainer.resolve(ModuleRegistrationName.CUSTOMER) - salesChannelService = appContainer.resolve( - ModuleRegistrationName.SALES_CHANNEL - ) }) beforeEach(async () => { await createAdminUser(dbConnection, adminHeaders, appContainer) - standardPromotion = await promotionModule.createPromotions({ - code: "TEST_ACROSS", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - allocation: "across", - target_type: "items", - value: 100, - target_rules: [promotionRule], - currency_code: "USD", - }, - rules: [promotionRule], + promotion = standardPromotion = ( + await api.post( + `/admin/promotions`, + { + code: "TEST_ACROSS", + type: PromotionType.STANDARD, + application_method: { + type: "fixed", + allocation: "across", + target_type: "items", + value: 100, + target_rules: [promotionRule], + currency_code: "USD", + }, + rules: [promotionRule], + }, + adminHeaders + ) + ).data.promotion + }) + + describe("GET /admin/promotions/:id", () => { + it("should throw an error if id does not exist", async () => { + const { response } = await api + .get(`/admin/promotions/does-not-exist`, adminHeaders) + .catch((e) => e) + + expect(response.status).toEqual(404) + expect(response.data.message).toEqual( + "Promotion with id or code: does-not-exist was not found" + ) + }) + + it("should get the requested promotion by id or codde", async () => { + let response = await api.get( + `/admin/promotions/${promotion.id}`, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual( + expect.objectContaining({ + id: promotion.id, + }) + ) + + response = await api.get( + `/admin/promotions/${promotion.code}`, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual( + expect.objectContaining({ + id: promotion.id, + }) + ) + }) + + it("should get the requested promotion with filtered fields and relations", async () => { + const response = await api.get( + `/admin/promotions/${promotion.id}?fields=id,code`, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual({ + id: promotion.id, + code: promotion.code, + }) + }) + }) + + describe("GET /admin/promotions", () => { + it("should get all promotions and its count", async () => { + const response = await api.get(`/admin/promotions`, adminHeaders) + + expect(response.status).toEqual(200) + expect(response.data.count).toEqual(1) + expect(response.data.promotions).toEqual([ + expect.objectContaining({ + id: expect.any(String), + }), + ]) + }) + + it("should support search of promotions", async () => { + await api.post( + `/admin/promotions`, + { + code: "first", + type: PromotionType.STANDARD, + application_method: { + type: "fixed", + target_type: "order", + value: 100, + currency_code: "USD", + }, + }, + adminHeaders + ) + + const response = await api.get( + `/admin/promotions?q=fir`, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotions).toEqual([ + expect.objectContaining({ + code: "first", + }), + ]) + }) + + it("should get all promotions and its count filtered", async () => { + const response = await api.get( + `/admin/promotions?fields=code,created_at,application_method.id`, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.count).toEqual(1) + expect(response.data.promotions).toEqual([ + { + id: expect.any(String), + code: "TEST_ACROSS", + created_at: expect.any(String), + application_method: { + id: expect.any(String), + }, + }, + ]) + }) + }) + + describe("POST /admin/promotions", () => { + it("should throw an error if required params are not passed", async () => { + const { response } = await api + .post( + `/admin/promotions`, + { type: PromotionType.STANDARD }, + adminHeaders + ) + .catch((e) => e) + + expect(response.status).toEqual(400) + expect(response.data.message).toEqual( + "Invalid request: Field 'code' is required; Field 'application_method' is required" + ) + }) + + it("should create a standard promotion successfully", async () => { + const response = await api.post( + `/admin/promotions`, + { + code: "TEST", + type: PromotionType.STANDARD, + is_automatic: true, + campaign: { + name: "test", + campaign_identifier: "test-1", + budget: { + type: "usage", + limit: 100, + }, + }, + application_method: { + target_type: "items", + type: "fixed", + allocation: "each", + currency_code: "USD", + value: 100, + max_quantity: 100, + target_rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual( + expect.objectContaining({ + id: expect.any(String), + code: "TEST", + type: "standard", + is_automatic: true, + campaign: expect.objectContaining({ + name: "test", + campaign_identifier: "test-1", + budget: expect.objectContaining({ + currency_code: null, + type: "usage", + limit: 100, + }), + }), + application_method: expect.objectContaining({ + value: 100, + max_quantity: 100, + type: "fixed", + target_type: "items", + allocation: "each", + target_rules: [ + expect.objectContaining({ + operator: "eq", + attribute: "test.test", + values: expect.arrayContaining([ + expect.objectContaining({ value: "test1" }), + expect.objectContaining({ value: "test2" }), + ]), + }), + ], + }), + rules: [ + expect.objectContaining({ + operator: "eq", + attribute: "test.test", + values: expect.arrayContaining([ + expect.objectContaining({ value: "test1" }), + expect.objectContaining({ value: "test2" }), + ]), + }), + ], + }) + ) + }) + + it("should throw an error if buy_rules params are not passed", async () => { + const { response } = await api + .post( + `/admin/promotions`, + { + code: "TEST", + type: PromotionType.BUYGET, + is_automatic: true, + application_method: { + target_type: "items", + type: "fixed", + allocation: "each", + value: 100, + max_quantity: 100, + currency_code: "USD", + target_rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + adminHeaders + ) + .catch((e) => e) + + expect(response.status).toEqual(400) + expect(response.data.message).toEqual( + "Invalid request: Buyget promotions require at least one buy rule and quantities to be defined" + ) + }) + + it("should throw an error if buy_rules params are not passed", async () => { + const { response } = await api + .post( + `/admin/promotions`, + { + code: "TEST", + type: PromotionType.BUYGET, + is_automatic: true, + application_method: { + target_type: "items", + type: "fixed", + allocation: "each", + value: 100, + max_quantity: 100, + currency_code: "USD", + buy_rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + adminHeaders + ) + .catch((e) => e) + + expect(response.status).toEqual(400) + // expect(response.data.message).toEqual( + // "Target rules are required for buyget promotion type" + // ) + }) + + it("should create a buyget promotion successfully", async () => { + const response = await api.post( + `/admin/promotions`, + { + code: "TEST", + type: PromotionType.BUYGET, + is_automatic: true, + campaign: { + name: "test", + campaign_identifier: "test-1", + budget: { + type: "usage", + limit: 100, + }, + }, + application_method: { + target_type: "items", + type: "fixed", + allocation: "each", + value: 100, + max_quantity: 100, + apply_to_quantity: 1, + buy_rules_min_quantity: 1, + currency_code: "USD", + target_rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + buy_rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + rules: [ + { + attribute: "test.test", + operator: "eq", + values: ["test1", "test2"], + }, + ], + }, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual( + expect.objectContaining({ + id: expect.any(String), + code: "TEST", + type: "buyget", + is_automatic: true, + campaign: expect.objectContaining({ + name: "test", + campaign_identifier: "test-1", + budget: expect.objectContaining({ + type: "usage", + limit: 100, + }), + }), + application_method: expect.objectContaining({ + value: 100, + max_quantity: 100, + type: "fixed", + target_type: "items", + allocation: "each", + apply_to_quantity: 1, + buy_rules_min_quantity: 1, + target_rules: [ + expect.objectContaining({ + operator: "eq", + attribute: "test.test", + values: expect.arrayContaining([ + expect.objectContaining({ value: "test1" }), + expect.objectContaining({ value: "test2" }), + ]), + }), + ], + buy_rules: [ + expect.objectContaining({ + operator: "eq", + attribute: "test.test", + values: expect.arrayContaining([ + expect.objectContaining({ value: "test1" }), + expect.objectContaining({ value: "test2" }), + ]), + }), + ], + }), + rules: [ + expect.objectContaining({ + operator: "eq", + attribute: "test.test", + values: expect.arrayContaining([ + expect.objectContaining({ value: "test1" }), + expect.objectContaining({ value: "test2" }), + ]), + }), + ], + }) + ) + }) + }) + + describe("DELETE /admin/promotions/:id", () => { + it("should delete promotion successfully", async () => { + const deleteRes = await api.delete( + `/admin/promotions/${promotion.id}`, + adminHeaders + ) + + expect(deleteRes.status).toEqual(200) + + const { response } = await api + .get(`/admin/promotions/${promotion.id}`, adminHeaders) + .catch((e) => e) + + expect(response.status).toEqual(404) + expect(response.data.message).toEqual( + `Promotion with id or code: ${promotion.id} was not found` + ) + }) + }) + + describe("POST /admin/promotions/:id", () => { + it("should throw an error if id does not exist", async () => { + const { response } = await api + .post( + `/admin/promotions/does-not-exist`, + { type: PromotionType.STANDARD }, + adminHeaders + ) + .catch((e) => e) + + expect(response.status).toEqual(404) + expect(response.data.message).toEqual( + `Promotion with id "does-not-exist" not found` + ) + }) + + it("should throw an error when both campaign and campaign_id params are passed", async () => { + const { response } = await api + .post( + `/admin/promotions/${promotion.id}`, + { + campaign: { name: "test campaign" }, + campaign_id: "test", + }, + adminHeaders + ) + .catch((e) => e) + + expect(response.status).toEqual(400) + expect(response.data.message).toContain( + `Invalid request: Field 'campaign, campaign_identifier' is required` + ) + }) + + it("should update a promotion successfully", async () => { + const response = await api.post( + `/admin/promotions/${promotion.id}`, + { + code: "TEST_TWO", + application_method: { value: 200 }, + }, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual( + expect.objectContaining({ + id: expect.any(String), + code: "TEST_TWO", + application_method: expect.objectContaining({ + value: 200, + }), + }) + ) + }) + + it("should update a buyget promotion successfully", async () => { + const response = await api.post( + `/admin/promotions/${promotion.id}`, + { + code: "TEST_TWO", + application_method: { + value: 200, + buy_rules_min_quantity: 6, + }, + }, + adminHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.promotion).toEqual( + expect.objectContaining({ + id: promotion.id, + code: "TEST_TWO", + application_method: expect.objectContaining({ + value: 200, + buy_rules_min_quantity: 6, + }), + }) + ) }) }) @@ -133,6 +634,7 @@ medusaIntegrationTestRunner({ adminHeaders ) ).data.promotion + expect(promotion).toEqual( expect.objectContaining({ id: standardPromotion.id, @@ -225,6 +727,7 @@ medusaIntegrationTestRunner({ adminHeaders ) ).data.promotion + expect(promotion).toEqual( expect.objectContaining({ id: standardPromotion.id, @@ -321,22 +824,28 @@ medusaIntegrationTestRunner({ }) it("should add buy rules to a buyget promotion successfully", async () => { - const buyGetPromotion = await promotionModule.createPromotions({ - code: "TEST_BUYGET", - type: PromotionType.BUYGET, - application_method: { - type: "fixed", - target_type: "items", - allocation: "across", - value: 100, - apply_to_quantity: 1, - buy_rules_min_quantity: 1, - buy_rules: [promotionRule], - target_rules: [promotionRule], - currency_code: "USD", - }, - rules: [promotionRule], - }) + const buyGetPromotion = ( + await api.post( + `/admin/promotions`, + { + code: "TEST_BUYGET", + type: PromotionType.BUYGET, + application_method: { + type: "fixed", + target_type: "items", + allocation: "across", + value: 100, + apply_to_quantity: 1, + buy_rules_min_quantity: 1, + buy_rules: [promotionRule], + target_rules: [promotionRule], + currency_code: "USD", + }, + rules: [promotionRule], + }, + adminHeaders + ) + ).data.promotion const response = await api.post( `/admin/promotions/${buyGetPromotion.id}/buy-rules/batch`, @@ -413,10 +922,12 @@ medusaIntegrationTestRunner({ deleted: true, }) - const promotion = await promotionModule.retrievePromotion( - standardPromotion.id, - { relations: ["rules"] } - ) + const promotion = ( + await api.get( + `/admin/promotions/${standardPromotion.id}?fields=*rules`, + adminHeaders + ) + ).data.promotion expect(promotion.rules!.length).toEqual(0) }) @@ -454,10 +965,12 @@ medusaIntegrationTestRunner({ deleted: true, }) - const promotion = await promotionModule.retrievePromotion( - standardPromotion.id, - { relations: ["application_method.target_rules"] } - ) + const promotion = ( + await api.get( + `/admin/promotions/${standardPromotion.id}?fields=*application_method.target_rules`, + adminHeaders + ) + ).data.promotion expect(promotion.application_method!.target_rules!.length).toEqual(0) }) @@ -481,22 +994,28 @@ medusaIntegrationTestRunner({ }) it("should remove buy rules from a promotion successfully", async () => { - const buyGetPromotion = await promotionModule.createPromotions({ - code: "TEST_BUYGET", - type: PromotionType.BUYGET, - application_method: { - type: "fixed", - currency_code: "USD", - target_type: "items", - allocation: "across", - value: 100, - apply_to_quantity: 1, - buy_rules_min_quantity: 1, - buy_rules: [promotionRule], - target_rules: [promotionRule], - }, - rules: [promotionRule], - }) + const buyGetPromotion = ( + await api.post( + `/admin/promotions`, + { + code: "TEST_BUYGET", + type: PromotionType.BUYGET, + application_method: { + type: "fixed", + currency_code: "USD", + target_type: "items", + allocation: "across", + value: 100, + apply_to_quantity: 1, + buy_rules_min_quantity: 1, + buy_rules: [promotionRule], + target_rules: [promotionRule], + }, + rules: [promotionRule], + }, + adminHeaders + ) + ).data.promotion const ruleId = buyGetPromotion!.application_method!.buy_rules![0].id const response = await api.post( @@ -512,12 +1031,12 @@ medusaIntegrationTestRunner({ deleted: true, }) - const promotion = await promotionModule.retrievePromotion( - buyGetPromotion.id, - { - relations: ["application_method.buy_rules"], - } - ) + const promotion = ( + await api.get( + `/admin/promotions/${buyGetPromotion.id}?fields=*application_method.buy_rules`, + adminHeaders + ) + ).data.promotion expect(promotion.application_method!.buy_rules!.length).toEqual(0) }) @@ -598,6 +1117,7 @@ medusaIntegrationTestRunner({ adminHeaders ) ).data.promotion + expect(promotion).toEqual( expect.objectContaining({ id: standardPromotion.id, @@ -640,67 +1160,46 @@ medusaIntegrationTestRunner({ expect.arrayContaining([ expect.objectContaining({ id: "currency_code", - label: "Currency Code", - required: true, value: "currency_code", + label: "Currency Code", + field_type: "select", + required: false, + disguised: true, + hydrate: true, }), expect.objectContaining({ id: "customer_group", + value: "customer.groups.id", label: "Customer Group", required: false, - value: "customer_group.id", + field_type: "multiselect", }), expect.objectContaining({ id: "region", + value: "region.id", label: "Region", required: false, - value: "region.id", + field_type: "multiselect", }), expect.objectContaining({ id: "country", + value: "shipping_address.country_code", label: "Country", required: false, - value: "shipping_address.country_code", + field_type: "multiselect", }), expect.objectContaining({ id: "sales_channel", + value: "sales_channel_id", label: "Sales Channel", required: false, - value: "sales_channel.id", + field_type: "multiselect", }), ]) ) }) }) - describe("GET /admin/promotions/rule-operator-options", () => { - it("return all rule operators", async () => { - const response = await api.get( - `/admin/promotions/rule-operator-options`, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.operators).toEqual([ - { - id: "in", - label: "In", - value: "in", - }, - { - id: "eq", - label: "Equals", - value: "eq", - }, - { - id: "ne", - label: "Not In", - value: "ne", - }, - ]) - }) - }) - describe("GET /admin/promotions/rule-value-options/:ruleType/:ruleAttributeId", () => { it("should throw error when ruleType is invalid", async () => { const { response } = await api @@ -733,10 +1232,21 @@ medusaIntegrationTestRunner({ }) it("should return all values based on rule types", async () => { - const [region1, region2] = await regionService.createRegions([ - { name: "North America", currency_code: "usd" }, - { name: "Europe", currency_code: "eur" }, - ]) + const region1 = ( + await api.post( + "/admin/regions", + { name: "North America", currency_code: "usd" }, + adminHeaders + ) + ).data.region + + const region2 = ( + await api.post( + "/admin/regions", + { name: "Europe", currency_code: "eur" }, + adminHeaders + ) + ).data.region let response = await api.get( `/admin/promotions/rule-value-options/rules/region`, @@ -772,9 +1282,13 @@ medusaIntegrationTestRunner({ ]) ) - const group = await customerService.createCustomerGroups({ - name: "VIP", - }) + const group = ( + await api.post( + "/admin/customer-groups", + { name: "VIP" }, + adminHeaders + ) + ).data.customer_group response = await api.get( `/admin/promotions/rule-value-options/rules/customer_group`, @@ -789,9 +1303,13 @@ medusaIntegrationTestRunner({ }, ]) - const salesChannel = await salesChannelService.createSalesChannels({ - name: "Instagram", - }) + const salesChannel = ( + await api.post( + "/admin/sales-channels", + { name: "Instagram" }, + adminHeaders + ) + ).data.sales_channel response = await api.get( `/admin/promotions/rule-value-options/rules/sales_channel`, @@ -828,10 +1346,21 @@ medusaIntegrationTestRunner({ ]) ) - const [product1, product2] = await productService.createProducts([ - { title: "test product 1" }, - { title: "test product 2" }, - ]) + const product1 = ( + await api.post( + "/admin/products", + { title: "Test product 1" }, + adminHeaders + ) + ).data.product + + const product2 = ( + await api.post( + "/admin/products", + { title: "Test product 2" }, + adminHeaders + ) + ).data.product response = await api.get( `/admin/promotions/rule-value-options/target-rules/product`, @@ -842,15 +1371,18 @@ medusaIntegrationTestRunner({ expect(response.data.values.length).toEqual(2) expect(response.data.values).toEqual( expect.arrayContaining([ - { label: "test product 1", value: product1.id }, - { label: "test product 2", value: product2.id }, + { label: "Test product 1", value: product1.id }, + { label: "Test product 2", value: product2.id }, ]) ) - const category = await productService.createProductCategories({ - name: "test category 1", - parent_category_id: null, - }) + const category = ( + await api.post( + "/admin/product-categories", + { name: "test category 1" }, + adminHeaders + ) + ).data.product_category response = await api.get( `/admin/promotions/rule-value-options/target-rules/product_category`, @@ -862,9 +1394,13 @@ medusaIntegrationTestRunner({ { label: "test category 1", value: category.id }, ]) - const collection = await productService.createProductCollections({ - title: "test collection 1", - }) + const collection = ( + await api.post( + "/admin/collections", + { title: "test collection 1" }, + adminHeaders + ) + ).data.collection response = await api.get( `/admin/promotions/rule-value-options/target-rules/product_collection`, @@ -876,9 +1412,13 @@ medusaIntegrationTestRunner({ { label: "test collection 1", value: collection.id }, ]) - const type = await productService.createProductTypes({ - value: "test type", - }) + const type = ( + await api.post( + "/admin/product-types", + { value: "test type" }, + adminHeaders + ) + ).data.product_type response = await api.get( `/admin/promotions/rule-value-options/target-rules/product_type`, @@ -890,10 +1430,21 @@ medusaIntegrationTestRunner({ { label: "test type", value: type.id }, ]) - const [tag1, tag2] = await productService.createProductTags([ - { value: "test tag 1" }, - { value: "test tag 2" }, - ]) + const tag1 = ( + await api.post( + "/admin/product-tags", + { value: "test tag 1" }, + adminHeaders + ) + ).data.product_tag + + const tag2 = ( + await api.post( + "/admin/product-tags", + { value: "test tag 2" }, + adminHeaders + ) + ).data.product_tag response = await api.get( `/admin/promotions/rule-value-options/target-rules/product_tag`, diff --git a/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts deleted file mode 100644 index cabe38fe7704e..0000000000000 --- a/integration-tests/modules/__tests__/promotion/admin/create-promotion.spec.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { PromotionType } from "@medusajs/utils" -import { medusaIntegrationTestRunner } from "medusa-test-utils" -import { createAdminUser } from "../../../../helpers/create-admin-user" - -jest.setTimeout(50000) - -const env = { MEDUSA_FF_MEDUSA_V2: true } -const adminHeaders = { - headers: { "x-medusa-access-token": "test_token" }, -} - -medusaIntegrationTestRunner({ - env, - testSuite: ({ dbConnection, getContainer, api }) => { - describe("POST /admin/promotions", () => { - let appContainer - beforeAll(async () => { - appContainer = getContainer() - }) - - beforeEach(async () => { - await createAdminUser(dbConnection, adminHeaders, appContainer) - }) - - it("should throw an error if required params are not passed", async () => { - const { response } = await api - .post( - `/admin/promotions`, - { - type: PromotionType.STANDARD, - }, - adminHeaders - ) - .catch((e) => e) - - expect(response.status).toEqual(400) - // expect(response.data.message).toEqual( - // "code must be a string, code should not be empty, application_method should not be empty" - // ) - }) - - it("should create a standard promotion successfully", async () => { - const response = await api.post( - `/admin/promotions`, - { - code: "TEST", - type: PromotionType.STANDARD, - is_automatic: true, - campaign: { - name: "test", - campaign_identifier: "test-1", - budget: { - type: "usage", - limit: 100, - }, - }, - application_method: { - target_type: "items", - type: "fixed", - allocation: "each", - currency_code: "USD", - value: 100, - max_quantity: 100, - target_rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual( - expect.objectContaining({ - id: expect.any(String), - code: "TEST", - type: "standard", - is_automatic: true, - campaign: expect.objectContaining({ - name: "test", - campaign_identifier: "test-1", - budget: expect.objectContaining({ - currency_code: null, - type: "usage", - limit: 100, - }), - }), - application_method: expect.objectContaining({ - value: 100, - max_quantity: 100, - type: "fixed", - target_type: "items", - allocation: "each", - target_rules: [ - expect.objectContaining({ - operator: "eq", - attribute: "test.test", - values: expect.arrayContaining([ - expect.objectContaining({ value: "test1" }), - expect.objectContaining({ value: "test2" }), - ]), - }), - ], - }), - rules: [ - expect.objectContaining({ - operator: "eq", - attribute: "test.test", - values: expect.arrayContaining([ - expect.objectContaining({ value: "test1" }), - expect.objectContaining({ value: "test2" }), - ]), - }), - ], - }) - ) - }) - - it("should throw an error if buy_rules params are not passed", async () => { - const { response } = await api - .post( - `/admin/promotions`, - { - code: "TEST", - type: PromotionType.BUYGET, - is_automatic: true, - application_method: { - target_type: "items", - type: "fixed", - allocation: "each", - value: 100, - max_quantity: 100, - currency_code: "USD", - target_rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - adminHeaders - ) - .catch((e) => e) - - expect(response.status).toEqual(400) - // expect(response.data.message).toEqual( - // "Buy rules are required for buyget promotion type" - // ) - }) - - it("should throw an error if buy_rules params are not passed", async () => { - const { response } = await api - .post( - `/admin/promotions`, - { - code: "TEST", - type: PromotionType.BUYGET, - is_automatic: true, - application_method: { - target_type: "items", - type: "fixed", - allocation: "each", - value: 100, - max_quantity: 100, - currency_code: "USD", - buy_rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - adminHeaders - ) - .catch((e) => e) - - expect(response.status).toEqual(400) - // expect(response.data.message).toEqual( - // "Target rules are required for buyget promotion type" - // ) - }) - - it("should create a buyget promotion successfully", async () => { - const response = await api.post( - `/admin/promotions`, - { - code: "TEST", - type: PromotionType.BUYGET, - is_automatic: true, - campaign: { - name: "test", - campaign_identifier: "test-1", - budget: { - type: "usage", - limit: 100, - }, - }, - application_method: { - target_type: "items", - type: "fixed", - allocation: "each", - value: 100, - max_quantity: 100, - apply_to_quantity: 1, - buy_rules_min_quantity: 1, - currency_code: "USD", - target_rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - buy_rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - rules: [ - { - attribute: "test.test", - operator: "eq", - values: ["test1", "test2"], - }, - ], - }, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual( - expect.objectContaining({ - id: expect.any(String), - code: "TEST", - type: "buyget", - is_automatic: true, - campaign: expect.objectContaining({ - name: "test", - campaign_identifier: "test-1", - budget: expect.objectContaining({ - type: "usage", - limit: 100, - }), - }), - application_method: expect.objectContaining({ - value: 100, - max_quantity: 100, - type: "fixed", - target_type: "items", - allocation: "each", - apply_to_quantity: 1, - buy_rules_min_quantity: 1, - target_rules: [ - expect.objectContaining({ - operator: "eq", - attribute: "test.test", - values: expect.arrayContaining([ - expect.objectContaining({ value: "test1" }), - expect.objectContaining({ value: "test2" }), - ]), - }), - ], - buy_rules: [ - expect.objectContaining({ - operator: "eq", - attribute: "test.test", - values: expect.arrayContaining([ - expect.objectContaining({ value: "test1" }), - expect.objectContaining({ value: "test2" }), - ]), - }), - ], - }), - rules: [ - expect.objectContaining({ - operator: "eq", - attribute: "test.test", - values: expect.arrayContaining([ - expect.objectContaining({ value: "test1" }), - expect.objectContaining({ value: "test2" }), - ]), - }), - ], - }) - ) - }) - }) - }, -}) diff --git a/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts deleted file mode 100644 index 4ff9dfee80f85..0000000000000 --- a/integration-tests/modules/__tests__/promotion/admin/delete-promotion.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { IPromotionModuleService } from "@medusajs/types" -import { ModuleRegistrationName } from "@medusajs/utils" -import { medusaIntegrationTestRunner } from "medusa-test-utils" -import { createAdminUser } from "../../../../helpers/create-admin-user" - -jest.setTimeout(50000) - -const env = { MEDUSA_FF_MEDUSA_V2: true } -const adminHeaders = { - headers: { "x-medusa-access-token": "test_token" }, -} - -medusaIntegrationTestRunner({ - env, - testSuite: ({ dbConnection, getContainer, api }) => { - describe("DELETE /admin/promotions/:id", () => { - let appContainer - let promotionModuleService: IPromotionModuleService - - beforeAll(async () => { - appContainer = getContainer() - promotionModuleService = appContainer.resolve( - ModuleRegistrationName.PROMOTION - ) - }) - - beforeEach(async () => { - await createAdminUser(dbConnection, adminHeaders, appContainer) - }) - - it("should delete promotion successfully", async () => { - const createdPromotion = await promotionModuleService.createPromotions({ - code: "TEST", - type: "standard", - application_method: { - type: "fixed", - target_type: "order", - value: "100", - currency_code: "USD", - }, - }) - - const deleteRes = await api.delete( - `/admin/promotions/${createdPromotion.id}`, - adminHeaders - ) - - expect(deleteRes.status).toEqual(200) - - const promotions = await promotionModuleService.listPromotions({ - id: [createdPromotion.id], - }) - - expect(promotions.length).toEqual(0) - }) - }) - }, -}) diff --git a/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts b/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts deleted file mode 100644 index b898dd3f1a8a9..0000000000000 --- a/integration-tests/modules/__tests__/promotion/admin/list-promotions.spec.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { IPromotionModuleService } from "@medusajs/types" -import { ModuleRegistrationName, PromotionType } from "@medusajs/utils" -import { medusaIntegrationTestRunner } from "medusa-test-utils" -import { createAdminUser } from "../../../../helpers/create-admin-user" - -jest.setTimeout(50000) - -const env = { MEDUSA_FF_MEDUSA_V2: true } -const adminHeaders = { - headers: { "x-medusa-access-token": "test_token" }, -} - -medusaIntegrationTestRunner({ - env, - testSuite: ({ dbConnection, getContainer, api }) => { - describe("GET /admin/promotions", () => { - let appContainer - let promotionModuleService: IPromotionModuleService - - beforeAll(async () => { - appContainer = getContainer() - promotionModuleService = appContainer.resolve( - ModuleRegistrationName.PROMOTION - ) - }) - - beforeEach(async () => { - await createAdminUser(dbConnection, adminHeaders, appContainer) - }) - - it("should get all promotions and its count", async () => { - await promotionModuleService.createPromotions([ - { - code: "TEST", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - target_type: "order", - value: 100, - currency_code: "USD", - }, - }, - ]) - - const response = await api.get(`/admin/promotions`, adminHeaders) - - expect(response.status).toEqual(200) - expect(response.data.count).toEqual(1) - expect(response.data.promotions).toEqual([ - expect.objectContaining({ - id: expect.any(String), - code: "TEST", - is_automatic: false, - type: "standard", - created_at: expect.any(String), - updated_at: expect.any(String), - deleted_at: null, - rules: [], - application_method: expect.objectContaining({ - id: expect.any(String), - value: 100, - type: "fixed", - target_type: "order", - allocation: null, - }), - }), - ]) - }) - - it("should support search of promotions", async () => { - await promotionModuleService.createPromotions([ - { - code: "first", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - target_type: "order", - value: 100, - currency_code: "USD", - }, - }, - { - code: "second", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - target_type: "order", - value: 100, - currency_code: "USD", - }, - }, - ]) - - const response = await api.get(`/admin/promotions?q=fir`, adminHeaders) - - expect(response.status).toEqual(200) - expect(response.data.promotions).toEqual([ - expect.objectContaining({ - code: "first", - }), - ]) - }) - - it("should get all promotions and its count filtered", async () => { - await promotionModuleService.createPromotions([ - { - code: "TEST", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - target_type: "order", - value: 100, - currency_code: "USD", - }, - }, - ]) - - const response = await api.get( - `/admin/promotions?fields=code,created_at,application_method.id`, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.count).toEqual(1) - expect(response.data.promotions).toEqual([ - { - id: expect.any(String), - code: "TEST", - created_at: expect.any(String), - application_method: { - id: expect.any(String), - }, - }, - ]) - }) - }) - }, -}) diff --git a/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts deleted file mode 100644 index 6c42097d59e18..0000000000000 --- a/integration-tests/modules/__tests__/promotion/admin/retrieve-promotion.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { IPromotionModuleService } from "@medusajs/types" -import { ModuleRegistrationName, PromotionType } from "@medusajs/utils" -import { medusaIntegrationTestRunner } from "medusa-test-utils" -import { createAdminUser } from "../../../../helpers/create-admin-user" - -jest.setTimeout(50000) - -const env = { MEDUSA_FF_MEDUSA_V2: true } -const adminHeaders = { - headers: { "x-medusa-access-token": "test_token" }, -} - -medusaIntegrationTestRunner({ - env, - testSuite: ({ dbConnection, getContainer, api }) => { - describe("GET /admin/promotions/:id", () => { - let appContainer - let promotionModuleService: IPromotionModuleService - - beforeAll(async () => { - appContainer = getContainer() - promotionModuleService = appContainer.resolve( - ModuleRegistrationName.PROMOTION - ) - }) - - beforeEach(async () => { - await createAdminUser(dbConnection, adminHeaders, appContainer) - }) - - it("should throw an error if id does not exist", async () => { - const { response } = await api - .get(`/admin/promotions/does-not-exist`, adminHeaders) - .catch((e) => e) - - expect(response.status).toEqual(404) - expect(response.data.message).toEqual( - "Promotion with id or code: does-not-exist was not found" - ) - }) - - it("should get the requested promotion by id or codde", async () => { - const createdPromotion = await promotionModuleService.createPromotions({ - code: "TEST", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - target_type: "order", - value: "100", - currency_code: "USD", - }, - }) - - let response = await api.get( - `/admin/promotions/${createdPromotion.id}`, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual( - expect.objectContaining({ - id: createdPromotion.id, - }) - ) - - response = await api.get( - `/admin/promotions/${createdPromotion.code}`, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual( - expect.objectContaining({ - id: createdPromotion.id, - }) - ) - }) - - it("should get the requested promotion with filtered fields and relations", async () => { - const createdPromotion = await promotionModuleService.createPromotions({ - code: "TEST", - type: PromotionType.STANDARD, - application_method: { - type: "fixed", - target_type: "order", - value: "100", - currency_code: "USD", - }, - }) - - const response = await api.get( - `/admin/promotions/${createdPromotion.id}?fields=id,code`, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual({ - id: expect.any(String), - code: "TEST", - }) - }) - }) - }, -}) diff --git a/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts b/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts deleted file mode 100644 index 205e2f9f47c97..0000000000000 --- a/integration-tests/modules/__tests__/promotion/admin/update-promotion.spec.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { IPromotionModuleService } from "@medusajs/types" -import { ModuleRegistrationName, PromotionType } from "@medusajs/utils" -import { medusaIntegrationTestRunner } from "medusa-test-utils" -import { createAdminUser } from "../../../../helpers/create-admin-user" - -jest.setTimeout(50000) - -const env = { MEDUSA_FF_MEDUSA_V2: true } -const adminHeaders = { - headers: { "x-medusa-access-token": "test_token" }, -} - -medusaIntegrationTestRunner({ - env, - testSuite: ({ dbConnection, getContainer, api }) => { - describe("POST /admin/promotions/:id", () => { - let appContainer - let promotionModuleService: IPromotionModuleService - - beforeAll(async () => { - appContainer = getContainer() - promotionModuleService = appContainer.resolve( - ModuleRegistrationName.PROMOTION - ) - }) - - beforeEach(async () => { - await createAdminUser(dbConnection, adminHeaders, appContainer) - }) - - it("should throw an error if id does not exist", async () => { - const { response } = await api - .post( - `/admin/promotions/does-not-exist`, - { type: PromotionType.STANDARD }, - adminHeaders - ) - .catch((e) => e) - - expect(response.status).toEqual(404) - expect(response.data.message).toEqual( - `Promotion with id "does-not-exist" not found` - ) - }) - - it("should throw an error when both campaign and campaign_id params are passed", async () => { - const createdPromotion = await promotionModuleService.createPromotions({ - code: "TEST", - type: PromotionType.STANDARD, - is_automatic: true, - application_method: { - target_type: "items", - type: "fixed", - allocation: "each", - value: 100, - max_quantity: 100, - currency_code: "USD", - }, - }) - - const { response } = await api - .post( - `/admin/promotions/${createdPromotion.id}`, - { - campaign: { - name: "test campaign", - }, - campaign_id: "test", - }, - adminHeaders - ) - .catch((e) => e) - - expect(response.status).toEqual(400) - // expect(response.data.message).toContain( - // `Failed XOR relation between "campaign_id" and "campaign"` - // ) - }) - - it("should update a promotion successfully", async () => { - const createdPromotion = await promotionModuleService.createPromotions({ - code: "TEST", - type: PromotionType.STANDARD, - is_automatic: true, - application_method: { - target_type: "items", - type: "fixed", - allocation: "each", - value: 100, - max_quantity: 100, - currency_code: "USD", - }, - }) - - const response = await api.post( - `/admin/promotions/${createdPromotion.id}`, - { - code: "TEST_TWO", - application_method: { - value: 200, - }, - }, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual( - expect.objectContaining({ - id: expect.any(String), - code: "TEST_TWO", - application_method: expect.objectContaining({ - value: 200, - }), - }) - ) - }) - - it("should update a buyget promotion successfully", async () => { - const createdPromotion = await promotionModuleService.createPromotions({ - code: "PROMOTION_TEST", - type: PromotionType.BUYGET, - application_method: { - type: "fixed", - target_type: "items", - allocation: "across", - value: 100, - apply_to_quantity: 1, - buy_rules_min_quantity: 1, - currency_code: "USD", - buy_rules: [ - { - attribute: "product_collection.id", - operator: "eq", - values: ["pcol_towel"], - }, - ], - target_rules: [ - { - attribute: "product.id", - operator: "eq", - values: "prod_mat", - }, - ], - }, - }) - - const response = await api.post( - `/admin/promotions/${createdPromotion.id}`, - { - code: "TEST_TWO", - application_method: { - value: 200, - buy_rules_min_quantity: 6, - }, - }, - adminHeaders - ) - - expect(response.status).toEqual(200) - expect(response.data.promotion).toEqual( - expect.objectContaining({ - id: expect.any(String), - code: "TEST_TWO", - application_method: expect.objectContaining({ - value: 200, - buy_rules_min_quantity: 6, - }), - }) - ) - }) - }) - }, -}) diff --git a/packages/medusa/src/api/admin/campaigns/validators.ts b/packages/medusa/src/api/admin/campaigns/validators.ts index 559aaadb329ff..88f99c0546ea1 100644 --- a/packages/medusa/src/api/admin/campaigns/validators.ts +++ b/packages/medusa/src/api/admin/campaigns/validators.ts @@ -69,7 +69,6 @@ export const CreateCampaign = z budget: CreateCampaignBudget.nullish(), starts_at: z.coerce.date().nullish(), ends_at: z.coerce.date().nullish(), - promotions: z.array(z.object({ id: z.string() })).optional(), }) .strict() export const AdminCreateCampaign = WithAdditionalData(CreateCampaign) @@ -82,6 +81,5 @@ export const UpdateCampaign = z.object({ budget: UpdateCampaignBudget.optional(), starts_at: z.coerce.date().nullish(), ends_at: z.coerce.date().nullish(), - promotions: z.array(z.object({ id: z.string() })).optional(), }) export const AdminUpdateCampaign = WithAdditionalData(UpdateCampaign)