-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(medusa,types): add promotion list/get endpoint (#6110)
what: - adds get promotion endpoint (RESOLVES CORE-1677) - adds list promotions endpoint (RESOLVES CORE-1676) - uses new API routes
- Loading branch information
Showing
20 changed files
with
809 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@medusajs/medusa": patch | ||
"@medusajs/types": patch | ||
--- | ||
|
||
feat(medusa,types): add promotion list and get endpoint |
122 changes: 122 additions & 0 deletions
122
integration-tests/plugins/__tests__/promotion/admin/list-promotions.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { ModuleRegistrationName } from "@medusajs/modules-sdk" | ||
import { IPromotionModuleService } from "@medusajs/types" | ||
import { PromotionType } from "@medusajs/utils" | ||
import path from "path" | ||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app" | ||
import { useApi } from "../../../../environment-helpers/use-api" | ||
import { getContainer } from "../../../../environment-helpers/use-container" | ||
import { initDb, useDb } from "../../../../environment-helpers/use-db" | ||
import adminSeeder from "../../../../helpers/admin-seeder" | ||
|
||
const env = { MEDUSA_FF_MEDUSA_V2: true } | ||
const adminHeaders = { | ||
headers: { "x-medusa-access-token": "test_token" }, | ||
} | ||
|
||
describe("GET /admin/promotions", () => { | ||
let dbConnection | ||
let appContainer | ||
let shutdownServer | ||
let promotionModuleService: IPromotionModuleService | ||
|
||
beforeAll(async () => { | ||
const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) | ||
dbConnection = await initDb({ cwd, env } as any) | ||
shutdownServer = await startBootstrapApp({ cwd, env }) | ||
appContainer = getContainer() | ||
promotionModuleService = appContainer.resolve( | ||
ModuleRegistrationName.PROMOTION | ||
) | ||
}) | ||
|
||
afterAll(async () => { | ||
const db = useDb() | ||
await db.shutdown() | ||
await shutdownServer() | ||
}) | ||
|
||
beforeEach(async () => { | ||
await adminSeeder(dbConnection) | ||
}) | ||
|
||
afterEach(async () => { | ||
const db = useDb() | ||
await db.teardown() | ||
}) | ||
|
||
it("should get all promotions and its count", async () => { | ||
await promotionModuleService.create([ | ||
{ | ||
code: "TEST", | ||
type: PromotionType.STANDARD, | ||
application_method: { | ||
type: "fixed", | ||
target_type: "order", | ||
value: "100", | ||
}, | ||
}, | ||
]) | ||
|
||
const api = useApi() as any | ||
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", | ||
campaign: null, | ||
is_automatic: false, | ||
type: "standard", | ||
created_at: expect.any(String), | ||
updated_at: expect.any(String), | ||
deleted_at: null, | ||
application_method: expect.objectContaining({ | ||
id: expect.any(String), | ||
value: 100, | ||
type: "fixed", | ||
target_type: "order", | ||
allocation: null, | ||
created_at: expect.any(String), | ||
updated_at: expect.any(String), | ||
deleted_at: null, | ||
}), | ||
}), | ||
]) | ||
}) | ||
|
||
it("should get all promotions and its count filtered", async () => { | ||
const [createdPromotion] = await promotionModuleService.create([ | ||
{ | ||
code: "TEST", | ||
type: PromotionType.STANDARD, | ||
application_method: { | ||
type: "fixed", | ||
target_type: "order", | ||
value: "100", | ||
}, | ||
}, | ||
]) | ||
|
||
const api = useApi() as any | ||
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), | ||
promotion: expect.any(Object), | ||
}, | ||
}, | ||
]) | ||
}) | ||
}) |
124 changes: 124 additions & 0 deletions
124
integration-tests/plugins/__tests__/promotion/admin/retrieve-promotion.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { ModuleRegistrationName } from "@medusajs/modules-sdk" | ||
import { IPromotionModuleService } from "@medusajs/types" | ||
import { PromotionType } from "@medusajs/utils" | ||
import path from "path" | ||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app" | ||
import { useApi } from "../../../../environment-helpers/use-api" | ||
import { getContainer } from "../../../../environment-helpers/use-container" | ||
import { initDb, useDb } from "../../../../environment-helpers/use-db" | ||
import adminSeeder from "../../../../helpers/admin-seeder" | ||
|
||
const env = { MEDUSA_FF_MEDUSA_V2: true } | ||
const adminHeaders = { | ||
headers: { "x-medusa-access-token": "test_token" }, | ||
} | ||
|
||
describe("GET /admin/promotions", () => { | ||
let dbConnection | ||
let appContainer | ||
let shutdownServer | ||
let promotionModuleService: IPromotionModuleService | ||
|
||
beforeAll(async () => { | ||
const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) | ||
dbConnection = await initDb({ cwd, env } as any) | ||
shutdownServer = await startBootstrapApp({ cwd, env }) | ||
appContainer = getContainer() | ||
promotionModuleService = appContainer.resolve( | ||
ModuleRegistrationName.PROMOTION | ||
) | ||
}) | ||
|
||
afterAll(async () => { | ||
const db = useDb() | ||
await db.shutdown() | ||
await shutdownServer() | ||
}) | ||
|
||
beforeEach(async () => { | ||
await adminSeeder(dbConnection) | ||
}) | ||
|
||
afterEach(async () => { | ||
const db = useDb() | ||
await db.teardown() | ||
}) | ||
|
||
it("should throw an error if id does not exist", async () => { | ||
const api = useApi() as any | ||
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: does-not-exist was not found" | ||
) | ||
}) | ||
|
||
it("should get the requested promotion", async () => { | ||
const createdPromotion = await promotionModuleService.create({ | ||
code: "TEST", | ||
type: PromotionType.STANDARD, | ||
application_method: { | ||
type: "fixed", | ||
target_type: "order", | ||
value: "100", | ||
}, | ||
}) | ||
|
||
const api = useApi() as any | ||
const response = await api.get( | ||
`/admin/promotions/${createdPromotion.id}`, | ||
adminHeaders | ||
) | ||
|
||
expect(response.status).toEqual(200) | ||
expect(response.data.promotion).toEqual({ | ||
id: expect.any(String), | ||
code: "TEST", | ||
campaign: null, | ||
is_automatic: false, | ||
type: "standard", | ||
created_at: expect.any(String), | ||
updated_at: expect.any(String), | ||
deleted_at: null, | ||
application_method: { | ||
id: expect.any(String), | ||
promotion: expect.any(Object), | ||
value: 100, | ||
type: "fixed", | ||
target_type: "order", | ||
max_quantity: 0, | ||
allocation: null, | ||
created_at: expect.any(String), | ||
updated_at: expect.any(String), | ||
deleted_at: null, | ||
}, | ||
}) | ||
}) | ||
|
||
it("should get the requested promotion with filtered fields and relations", async () => { | ||
const createdPromotion = await promotionModuleService.create({ | ||
code: "TEST", | ||
type: PromotionType.STANDARD, | ||
application_method: { | ||
type: "fixed", | ||
target_type: "order", | ||
value: "100", | ||
}, | ||
}) | ||
|
||
const api = useApi() as any | ||
const response = await api.get( | ||
`/admin/promotions/${createdPromotion.id}?fields=id,code&expand=`, | ||
adminHeaders | ||
) | ||
|
||
expect(response.status).toEqual(200) | ||
expect(response.data.promotion).toEqual({ | ||
id: expect.any(String), | ||
code: "TEST", | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { ModuleRegistrationName } from "@medusajs/modules-sdk" | ||
import { IPromotionModuleService } from "@medusajs/types" | ||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing" | ||
|
||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => { | ||
const promotionModuleService: IPromotionModuleService = req.scope.resolve( | ||
ModuleRegistrationName.PROMOTION | ||
) | ||
|
||
const promotion = await promotionModuleService.retrieve(req.params.id, { | ||
select: req.retrieveConfig.select, | ||
relations: req.retrieveConfig.relations, | ||
}) | ||
|
||
res.status(200).json({ promotion }) | ||
} |
35 changes: 35 additions & 0 deletions
35
packages/medusa/src/api-v2/admin/promotions/middlewares.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { MedusaV2Flag } from "@medusajs/utils" | ||
import { isFeatureFlagEnabled, transformQuery } from "../../../api/middlewares" | ||
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" | ||
import * as QueryConfig from "./query-config" | ||
import { | ||
AdminGetPromotionsParams, | ||
AdminGetPromotionsPromotionParams, | ||
} from "./validators" | ||
|
||
export const adminPromotionRoutesMiddlewares: MiddlewareRoute[] = [ | ||
{ | ||
matcher: "/admin/promotions*", | ||
middlewares: [isFeatureFlagEnabled(MedusaV2Flag.key)], | ||
}, | ||
{ | ||
method: ["GET"], | ||
matcher: "/admin/promotions", | ||
middlewares: [ | ||
transformQuery( | ||
AdminGetPromotionsParams, | ||
QueryConfig.listTransformQueryConfig | ||
), | ||
], | ||
}, | ||
{ | ||
method: ["GET"], | ||
matcher: "/admin/promotions/:id", | ||
middlewares: [ | ||
transformQuery( | ||
AdminGetPromotionsPromotionParams, | ||
QueryConfig.retrieveTransformQueryConfig | ||
), | ||
], | ||
}, | ||
] |
26 changes: 26 additions & 0 deletions
26
packages/medusa/src/api-v2/admin/promotions/query-config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
export const defaultAdminPromotionRelations = ["campaign", "application_method"] | ||
export const allowedAdminPromotionRelations = [ | ||
...defaultAdminPromotionRelations, | ||
] | ||
export const defaultAdminPromotionFields = [ | ||
"id", | ||
"code", | ||
"campaign", | ||
"is_automatic", | ||
"type", | ||
"created_at", | ||
"updated_at", | ||
"deleted_at", | ||
] | ||
|
||
export const retrieveTransformQueryConfig = { | ||
defaultFields: defaultAdminPromotionFields, | ||
defaultRelations: defaultAdminPromotionRelations, | ||
allowedRelations: allowedAdminPromotionRelations, | ||
isList: false, | ||
} | ||
|
||
export const listTransformQueryConfig = { | ||
...retrieveTransformQueryConfig, | ||
isList: true, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { ModuleRegistrationName } from "@medusajs/modules-sdk" | ||
import { IPromotionModuleService } from "@medusajs/types" | ||
import { MedusaRequest, MedusaResponse } from "../../../types/routing" | ||
|
||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => { | ||
const promotionModuleService: IPromotionModuleService = req.scope.resolve( | ||
ModuleRegistrationName.PROMOTION | ||
) | ||
|
||
const [promotions, count] = await promotionModuleService.listAndCount( | ||
req.filterableFields, | ||
req.listConfig | ||
) | ||
|
||
const { limit, offset } = req.validatedQuery | ||
|
||
res.json({ | ||
count, | ||
promotions, | ||
offset, | ||
limit, | ||
}) | ||
} |
Oops, something went wrong.