Adds ProductVariant endpoints (#59)
Adds endpoints for product variants with tests. Closes #58
This commit is contained in:
1 parent
809133fa2a
commit
420c1d8cdb
24 files changed
+732
-3
No files matched your search
@@ -36,7 +36,7 @@ export default (app, container) => {
|
|||||||
shippingProfileRoutes(route)
|
shippingProfileRoutes(route)
|
||||||
discountRoutes(route)
|
discountRoutes(route)
|
||||||
orderRoutes(route)
|
orderRoutes(route)
|
||||||
// productVariantRoutes(route)
|
productVariantRoutes(route)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("POST /admin/product-variants/:id/options", () => {
|
||||||
|
describe("successful add option value", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}/options`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
optionId: IdMap.getId("testOption"),
|
||||||
|
optionValue: "test",
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls service addOption", () => {
|
||||||
|
expect(ProductVariantServiceMock.addOptionValue).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.addOptionValue).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant"),
|
||||||
|
IdMap.getId("testOption"),
|
||||||
|
"test"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("POST /admin/product-variants", () => {
|
||||||
|
describe("successful creation", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request("POST", "/admin/product-variants", {
|
||||||
|
payload: {
|
||||||
|
title: "Test Product Variant",
|
||||||
|
prices: [{}],
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns created product draft", () => {
|
||||||
|
expect(subject.body._id).toEqual(IdMap.getId("testVariant"))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls service createDraft", () => {
|
||||||
|
expect(ProductVariantServiceMock.createDraft).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.createDraft).toHaveBeenCalledWith({
|
||||||
|
title: "Test Product Variant",
|
||||||
|
prices: [{}],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("invalid data returns error details", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request("POST", "/admin/products", {
|
||||||
|
payload: {
|
||||||
|
image: "image",
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 400", () => {
|
||||||
|
expect(subject.status).toEqual(400)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns error details", () => {
|
||||||
|
expect(subject.body.name).toEqual("invalid_data")
|
||||||
|
expect(subject.body.message[0].message).toEqual(`"title" is required`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("DELETE /admin/product-variants/:id/options", () => {
|
||||||
|
describe("successfully deletes option value", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"DELETE",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}/options`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
optionId: IdMap.getId("testOption"),
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
it("calls service deleteOptionValue", () => {
|
||||||
|
expect(ProductVariantServiceMock.deleteOptionValue).toHaveBeenCalledTimes(
|
||||||
|
1
|
||||||
|
)
|
||||||
|
expect(ProductVariantServiceMock.deleteOptionValue).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant"),
|
||||||
|
IdMap.getId("testOption")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("DELETE /admin/product-variants/:id", () => {
|
||||||
|
describe("successfully deletes a product variant", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"DELETE",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}`,
|
||||||
|
{
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls ProductVariantService delete", () => {
|
||||||
|
expect(ProductVariantServiceMock.delete).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.delete).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns correct delete data", () => {
|
||||||
|
expect(subject.body).toEqual({
|
||||||
|
id: IdMap.getId("testVariant"),
|
||||||
|
object: "productVariant",
|
||||||
|
deleted: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("GET /admin/product-variants/:id", () => {
|
||||||
|
describe("successfully gets a product variant", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"GET",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}`,
|
||||||
|
{
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls productVariantService retrieve", () => {
|
||||||
|
expect(ProductVariantServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.retrieve).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns product", () => {
|
||||||
|
expect(subject.body._id).toEqual(IdMap.getId("testVariant"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("GET /admin/product-variants", () => {
|
||||||
|
describe("successfully lists product variants", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request("GET", `/admin/product-variants`, {
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls ProductVariantService list", () => {
|
||||||
|
expect(ProductVariantServiceMock.list).toHaveBeenCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200 and product variants", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
expect(subject.body[0]._id).toEqual(IdMap.getId("testVariant"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("POST /admin/product-variants/:id/publish", () => {
|
||||||
|
describe("successful publish", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/product-variants/${IdMap.getId("publish")}/publish`,
|
||||||
|
{
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns product with published flag true", () => {
|
||||||
|
expect(subject.body.published).toEqual(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls service publish", () => {
|
||||||
|
expect(ProductVariantServiceMock.publish).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.publish).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("publish")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("POST /admin/product-variants/:id/currency-price", () => {
|
||||||
|
describe("successful sets currency price", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}/currency-price`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
currencyCode: "DKK",
|
||||||
|
amount: 100,
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls service setCurrencyPrice", () => {
|
||||||
|
expect(ProductVariantServiceMock.setCurrencyPrice).toHaveBeenCalledTimes(
|
||||||
|
1
|
||||||
|
)
|
||||||
|
expect(ProductVariantServiceMock.setCurrencyPrice).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant"),
|
||||||
|
"DKK",
|
||||||
|
100
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("POST /admin/product-variants/:id/region-price", () => {
|
||||||
|
describe("successfully sets region price", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}/region-price`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
regionId: IdMap.getId("region-fr"),
|
||||||
|
amount: 100,
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls service setCurrencyPrice", () => {
|
||||||
|
expect(ProductVariantServiceMock.setRegionPrice).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.setRegionPrice).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant"),
|
||||||
|
IdMap.getId("region-fr"),
|
||||||
|
100
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
|
|
||||||
|
describe("POST /admin/product-variants/:id", () => {
|
||||||
|
describe("successful update", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
title: "Test Product Variant Updated",
|
||||||
|
prices: [{}],
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls service update", () => {
|
||||||
|
expect(ProductVariantServiceMock.update).toHaveBeenCalledTimes(1)
|
||||||
|
expect(ProductVariantServiceMock.update).toHaveBeenCalledWith(
|
||||||
|
IdMap.getId("testVariant"),
|
||||||
|
{
|
||||||
|
title: "Test Product Variant Updated",
|
||||||
|
prices: [{}],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("handles failed update operation", () => {
|
||||||
|
it("throws if metadata is to be updated", async () => {
|
||||||
|
try {
|
||||||
|
await request(
|
||||||
|
"POST",
|
||||||
|
`/admin/product-variants/${IdMap.getId("testVariant")}`,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
_id: IdMap.getId("testVariant"),
|
||||||
|
title: "Product 1",
|
||||||
|
metadata: "Test Description",
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.status).toEqual(400)
|
||||||
|
expect(error.message).toEqual(
|
||||||
|
"Use setMetadata to update metadata fields"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
optionId: Validator.objectId().required(),
|
||||||
|
optionValue: Validator.string().required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.addOptionValue(
|
||||||
|
id,
|
||||||
|
value.optionId,
|
||||||
|
value.optionValue
|
||||||
|
)
|
||||||
|
|
||||||
|
res.status(200).json(productVariant)
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
title: Validator.string().required(),
|
||||||
|
prices: Validator.array()
|
||||||
|
.items({})
|
||||||
|
.required(),
|
||||||
|
options: Validator.array().items({}),
|
||||||
|
image: Validator.string().optional(),
|
||||||
|
inventory_quantity: Validator.number().optional(),
|
||||||
|
allow_backorder: Validator.boolean().optional(),
|
||||||
|
manage_inventory: Validator.boolean().optional(),
|
||||||
|
metadata: Validator.object().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.createDraft(value)
|
||||||
|
|
||||||
|
res.status(200).json(productVariant)
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
optionId: Validator.objectId().required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.deleteOptionValue(
|
||||||
|
id,
|
||||||
|
value.optionId
|
||||||
|
)
|
||||||
|
|
||||||
|
res.status(200).json(productVariant)
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
await productVariantService.delete(id)
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
id: id,
|
||||||
|
object: "productVariant",
|
||||||
|
deleted: true,
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.retrieve(id)
|
||||||
|
|
||||||
|
res.json(productVariant)
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,5 +4,46 @@ import middlewares from "../../../middlewares"
|
|||||||
const route = Router()
|
const route = Router()
|
||||||
|
|
||||||
export default app => {
|
export default app => {
|
||||||
|
app.use("/product-variants", route)
|
||||||
|
|
||||||
|
route.post("/", middlewares.wrap(require("./create-product-variant").default))
|
||||||
|
route.post(
|
||||||
|
"/:id",
|
||||||
|
middlewares.wrap(require("./update-product-variant").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.post(
|
||||||
|
"/:id/publish",
|
||||||
|
middlewares.wrap(require("./publish-product-variant").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.post(
|
||||||
|
"/:id/currency-price",
|
||||||
|
middlewares.wrap(require("./set-currency-price").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.post(
|
||||||
|
"/:id/region-price",
|
||||||
|
middlewares.wrap(require("./set-region-price").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.post(
|
||||||
|
"/:id/options",
|
||||||
|
middlewares.wrap(require("./add-option-value").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.delete(
|
||||||
|
"/:id/options",
|
||||||
|
middlewares.wrap(require("./delete-option-value").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.delete(
|
||||||
|
"/:id",
|
||||||
|
middlewares.wrap(require("./delete-product-variant").default)
|
||||||
|
)
|
||||||
|
|
||||||
|
route.get("/:id", middlewares.wrap(require("./get-product-variant").default))
|
||||||
|
route.get("/", middlewares.wrap(require("./list-product-variants").default))
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export default async (req, res) => {
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariants = await productVariantService.list({})
|
||||||
|
|
||||||
|
res.json(productVariants)
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.publish(id)
|
||||||
|
|
||||||
|
res.json(productVariant)
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
currencyCode: Validator.string().required(),
|
||||||
|
amount: Validator.number().required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.setCurrencyPrice(
|
||||||
|
id,
|
||||||
|
value.currencyCode,
|
||||||
|
value.amount
|
||||||
|
)
|
||||||
|
|
||||||
|
res.status(200).json(productVariant)
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
regionId: Validator.objectId().required(),
|
||||||
|
amount: Validator.number().required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.setRegionPrice(
|
||||||
|
id,
|
||||||
|
value.regionId,
|
||||||
|
value.amount
|
||||||
|
)
|
||||||
|
|
||||||
|
res.status(200).json(productVariant)
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
title: Validator.string().optional(),
|
||||||
|
prices: Validator.array()
|
||||||
|
.items({})
|
||||||
|
.optional(),
|
||||||
|
options: Validator.array()
|
||||||
|
.items({})
|
||||||
|
.optional(),
|
||||||
|
image: Validator.string().optional(),
|
||||||
|
inventory_quantity: Validator.number().optional(),
|
||||||
|
allow_backorder: Validator.boolean().optional(),
|
||||||
|
manage_inventory: Validator.boolean().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productVariantService = req.scope.resolve("productVariantService")
|
||||||
|
const productVariant = await productVariantService.update(id, value)
|
||||||
|
|
||||||
|
res.status(200).json(productVariant)
|
||||||
|
} catch (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -117,6 +117,16 @@ export const variants = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ProductVariantServiceMock = {
|
export const ProductVariantServiceMock = {
|
||||||
|
createDraft: jest.fn().mockImplementation(data => {
|
||||||
|
return Promise.resolve(testVariant)
|
||||||
|
}),
|
||||||
|
publish: jest.fn().mockImplementation(_ => {
|
||||||
|
return Promise.resolve({
|
||||||
|
_id: IdMap.getId("publish"),
|
||||||
|
name: "Product Variant",
|
||||||
|
published: true,
|
||||||
|
})
|
||||||
|
}),
|
||||||
retrieve: jest.fn().mockImplementation(variantId => {
|
retrieve: jest.fn().mockImplementation(variantId => {
|
||||||
if (variantId === "1") {
|
if (variantId === "1") {
|
||||||
return Promise.resolve(variant1)
|
return Promise.resolve(variant1)
|
||||||
@@ -133,6 +143,9 @@ export const ProductVariantServiceMock = {
|
|||||||
if (variantId === IdMap.getId("validId")) {
|
if (variantId === IdMap.getId("validId")) {
|
||||||
return Promise.resolve(variant5)
|
return Promise.resolve(variant5)
|
||||||
}
|
}
|
||||||
|
if (variantId === IdMap.getId("testVariant")) {
|
||||||
|
return Promise.resolve(testVariant)
|
||||||
|
}
|
||||||
if (variantId === "invalid_option") {
|
if (variantId === "invalid_option") {
|
||||||
return Promise.resolve(invalidVariant)
|
return Promise.resolve(invalidVariant)
|
||||||
}
|
}
|
||||||
@@ -177,9 +190,15 @@ export const ProductVariantServiceMock = {
|
|||||||
return Promise.reject(new Error("Not found"))
|
return Promise.reject(new Error("Not found"))
|
||||||
}),
|
}),
|
||||||
delete: jest.fn().mockReturnValue(Promise.resolve()),
|
delete: jest.fn().mockReturnValue(Promise.resolve()),
|
||||||
|
update: jest.fn().mockReturnValue(Promise.resolve()),
|
||||||
|
setCurrencyPrice: jest.fn().mockReturnValue(Promise.resolve()),
|
||||||
|
setRegionPrice: jest.fn().mockReturnValue(Promise.resolve()),
|
||||||
addOptionValue: jest.fn().mockImplementation((variantId, optionId, value) => {
|
addOptionValue: jest.fn().mockImplementation((variantId, optionId, value) => {
|
||||||
return Promise.resolve({})
|
return Promise.resolve({})
|
||||||
}),
|
}),
|
||||||
|
list: jest.fn().mockImplementation(data => {
|
||||||
|
return Promise.resolve([testVariant])
|
||||||
|
}),
|
||||||
deleteOptionValue: jest.fn().mockImplementation((variantId, optionId) => {
|
deleteOptionValue: jest.fn().mockImplementation((variantId, optionId) => {
|
||||||
return Promise.resolve({})
|
return Promise.resolve({})
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class ProductVariantService extends BaseService {
|
|||||||
* @param {object} variant - the variant to create
|
* @param {object} variant - the variant to create
|
||||||
* @return {Promise} resolves to the creation result.
|
* @return {Promise} resolves to the creation result.
|
||||||
*/
|
*/
|
||||||
createDraft(productVariant) {
|
async createDraft(productVariant) {
|
||||||
return this.productVariantModel_
|
return this.productVariantModel_
|
||||||
.create({
|
.create({
|
||||||
...productVariant,
|
...productVariant,
|
||||||
@@ -99,7 +99,7 @@ class ProductVariantService extends BaseService {
|
|||||||
* @param {object} update - an object with the update values.
|
* @param {object} update - an object with the update values.
|
||||||
* @return {Promise} resolves to the update result.
|
* @return {Promise} resolves to the update result.
|
||||||
*/
|
*/
|
||||||
update(variantId, update) {
|
async update(variantId, update) {
|
||||||
const validatedId = this.validateId_(variantId)
|
const validatedId = this.validateId_(variantId)
|
||||||
|
|
||||||
if (update.prices) {
|
if (update.prices) {
|
||||||
|
|||||||
Reference in new issue
Block a user