feat(medusa): Adds set and delete metadata endpoints for region and orders (#131)
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { OrderServiceMock } from "../../../../../services/__mocks__/order"
|
||||||
|
|
||||||
|
describe("DELETE /admin/orders/:id/metadata/key", () => {
|
||||||
|
describe("successfully deletes metadata on order", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"DELETE",
|
||||||
|
`/admin/orders/${IdMap.getId("test-order")}/metadata/test-key`,
|
||||||
|
{
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls OrderService deleteMetadata", () => {
|
||||||
|
expect(OrderServiceMock.deleteMetadata).toHaveBeenCalledTimes(1)
|
||||||
|
expect(OrderServiceMock.deleteMetadata).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("test-order"),
|
||||||
|
"test-key"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { OrderServiceMock } from "../../../../../services/__mocks__/order"
|
||||||
|
|
||||||
|
describe("POST /admin/orders/:id/metadata", () => {
|
||||||
|
describe("successfully sets metadata on order", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/orders/${IdMap.getId("test-order")}/metadata`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
key: "Test key",
|
||||||
|
value: "Test value",
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls OrderService setMetadata", () => {
|
||||||
|
expect(OrderServiceMock.setMetadata).toHaveBeenCalledTimes(1)
|
||||||
|
expect(OrderServiceMock.setMetadata).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("test-order"),
|
||||||
|
"Test key",
|
||||||
|
"Test value"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export default async (req, res) => {
|
||||||
|
const { id, key } = req.params
|
||||||
|
|
||||||
|
try {
|
||||||
|
const orderService = req.scope.resolve("orderService")
|
||||||
|
let order = await orderService.deleteMetadata(id, key)
|
||||||
|
order = await orderService.decorate(order, [], ["region"])
|
||||||
|
|
||||||
|
res.status(200).json({ order })
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,5 +95,21 @@ export default app => {
|
|||||||
middlewares.wrap(require("./archive-order").default)
|
middlewares.wrap(require("./archive-order").default)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set metadata key / value pair.
|
||||||
|
*/
|
||||||
|
route.post(
|
||||||
|
"/:id/metadata",
|
||||||
|
middlewares.wrap(require("./set-metadata").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete metadata key / value pair.
|
||||||
|
*/
|
||||||
|
route.delete(
|
||||||
|
"/:id/metadata/:key",
|
||||||
|
middlewares.wrap(require("./delete-metadata").default)
|
||||||
|
)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
key: Validator.string().required(),
|
||||||
|
value: Validator.string().required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const orderService = req.scope.resolve("orderService")
|
||||||
|
let order = await orderService.setMetadata(id, value.key, value.value)
|
||||||
|
order = await orderService.decorate(order, [], ["region"])
|
||||||
|
|
||||||
|
res.status(200).json({ order })
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export default async (req, res) => {
|
||||||
|
const { id, key } = req.params
|
||||||
|
|
||||||
|
try {
|
||||||
|
const regionService = req.scope.resolve("regionService")
|
||||||
|
const region = await regionService.deleteMetadata(id, key)
|
||||||
|
|
||||||
|
res.status(200).json({ region })
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,5 +52,21 @@ export default app => {
|
|||||||
middlewares.wrap(require("./remove-fulfillment-provider").default)
|
middlewares.wrap(require("./remove-fulfillment-provider").default)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set metadata key / value pair.
|
||||||
|
*/
|
||||||
|
route.post(
|
||||||
|
"/:id/metadata",
|
||||||
|
middlewares.wrap(require("./set-metadata").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete metadata key / value pair.
|
||||||
|
*/
|
||||||
|
route.delete(
|
||||||
|
"/:id/metadata/:key",
|
||||||
|
middlewares.wrap(require("./delete-metadata").default)
|
||||||
|
)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
key: Validator.string().required(),
|
||||||
|
value: Validator.string().required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const regionService = req.scope.resolve("regionService")
|
||||||
|
const region = await regionService.setMetadata(id, value.key, value.value)
|
||||||
|
|
||||||
|
res.status(200).json({ region })
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -137,6 +137,18 @@ export const OrderServiceMock = {
|
|||||||
}
|
}
|
||||||
return Promise.resolve(undefined)
|
return Promise.resolve(undefined)
|
||||||
}),
|
}),
|
||||||
|
setMetadata: jest.fn().mockImplementation((id, key, value) => {
|
||||||
|
if (id === IdMap.getId("test-order")) {
|
||||||
|
return Promise.resolve(orders.testOrder)
|
||||||
|
}
|
||||||
|
return Promise.resolve(undefined)
|
||||||
|
}),
|
||||||
|
deleteMetadata: jest.fn().mockImplementation((id, key, value) => {
|
||||||
|
if (id === IdMap.getId("test-order")) {
|
||||||
|
return Promise.resolve(orders.testOrder)
|
||||||
|
}
|
||||||
|
return Promise.resolve(undefined)
|
||||||
|
}),
|
||||||
retrieve: jest.fn().mockImplementation(orderId => {
|
retrieve: jest.fn().mockImplementation(orderId => {
|
||||||
if (orderId === IdMap.getId("test-order")) {
|
if (orderId === IdMap.getId("test-order")) {
|
||||||
return Promise.resolve(orders.testOrder)
|
return Promise.resolve(orders.testOrder)
|
||||||
|
|||||||
@@ -370,6 +370,57 @@ class RegionService extends BaseService {
|
|||||||
const final = await this.runDecorators_(decorated)
|
const final = await this.runDecorators_(decorated)
|
||||||
return final
|
return final
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dedicated method to set metadata for a region.
|
||||||
|
* To ensure that plugins does not overwrite each
|
||||||
|
* others metadata fields, setMetadata is provided.
|
||||||
|
* @param {string} regionId - the region to decorate.
|
||||||
|
* @param {string} key - key for metadata field
|
||||||
|
* @param {string} value - value for metadata field.
|
||||||
|
* @return {Promise} resolves to the updated result.
|
||||||
|
*/
|
||||||
|
async setMetadata(regionId, key, value) {
|
||||||
|
const validatedId = this.validateId_(regionId)
|
||||||
|
|
||||||
|
if (typeof key !== "string") {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_ARGUMENT,
|
||||||
|
"Key type is invalid. Metadata keys must be strings"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyPath = `metadata.${key}`
|
||||||
|
return this.regionModel_
|
||||||
|
.updateOne({ _id: validatedId }, { $set: { [keyPath]: value } })
|
||||||
|
.catch(err => {
|
||||||
|
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dedicated method to delete metadata for an region.
|
||||||
|
* @param {string} regionId - the region to delete metadata from.
|
||||||
|
* @param {string} key - key for metadata field
|
||||||
|
* @return {Promise} resolves to the updated result.
|
||||||
|
*/
|
||||||
|
async deleteMetadata(regionId, key) {
|
||||||
|
const validatedId = this.validateId_(regionId)
|
||||||
|
|
||||||
|
if (typeof key !== "string") {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_ARGUMENT,
|
||||||
|
"Key type is invalid. Metadata keys must be strings"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyPath = `metadata.${key}`
|
||||||
|
return this.regionModel_
|
||||||
|
.updateOne({ _id: validatedId }, { $unset: { [keyPath]: "" } })
|
||||||
|
.catch(err => {
|
||||||
|
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RegionService
|
export default RegionService
|
||||||
|
|||||||
Reference in New Issue
Block a user