Gift cards are automatically added to gift card profile

This commit is contained in:
Sebastian Rindom
2020-07-20 15:54:14 +02:00
parent 0b8f1a5c31
commit df47da50fa
10 changed files with 124 additions and 4 deletions
@@ -1,6 +1,7 @@
import { IdMap } from "medusa-test-utils" import { IdMap } from "medusa-test-utils"
import { request } from "../../../../../helpers/test-request" import { request } from "../../../../../helpers/test-request"
import { ProductServiceMock } from "../../../../../services/__mocks__/product" import { ProductServiceMock } from "../../../../../services/__mocks__/product"
import { ShippingProfileServiceMock } from "../../../../../services/__mocks__/shipping-profile"
describe("POST /admin/products", () => { describe("POST /admin/products", () => {
describe("successful creation", () => { describe("successful creation", () => {
@@ -38,8 +39,80 @@ describe("POST /admin/products", () => {
description: "Test Description", description: "Test Description",
tags: "hi,med,dig", tags: "hi,med,dig",
handle: "test-product", handle: "test-product",
is_giftcard: false,
}) })
}) })
it("calls shipping profile default", () => {
expect(ShippingProfileServiceMock.retrieveDefault).toHaveBeenCalledTimes(
1
)
expect(ShippingProfileServiceMock.retrieveDefault).toHaveBeenCalledWith()
})
})
describe("successful creation of gift card product", () => {
let subject
beforeAll(async () => {
jest.clearAllMocks()
subject = await request("POST", "/admin/products", {
payload: {
title: "Gift Card",
description: "make someone happy",
handle: "test-gift-card",
is_giftcard: true,
options: [{ title: "Denominations" }],
variants: [
{
title: "100 USD",
prices: [
{
currency_code: "USD",
amount: 100,
},
],
options: [
{
value: "100",
},
],
},
],
},
adminSession: {
jwt: {
userId: IdMap.getId("admin_user"),
},
},
})
})
it("calls service createDraft", () => {
expect(ProductServiceMock.createDraft).toHaveBeenCalledTimes(1)
expect(ProductServiceMock.createDraft).toHaveBeenCalledWith({
title: "Gift Card",
description: "make someone happy",
options: [{ title: "Denominations" }],
handle: "test-gift-card",
is_giftcard: true,
})
})
it("calls profile service", () => {
expect(
ShippingProfileServiceMock.retrieveGiftCardDefault
).toHaveBeenCalledTimes(1)
expect(
ShippingProfileServiceMock.retrieveGiftCardDefault
).toHaveBeenCalledWith()
expect(ShippingProfileServiceMock.addProduct).toHaveBeenCalledTimes(1)
expect(ShippingProfileServiceMock.addProduct).toHaveBeenCalledWith(
IdMap.getId("giftCardProfile"),
undefined
)
})
}) })
describe("invalid data returns error details", () => { describe("invalid data returns error details", () => {
@@ -5,6 +5,7 @@ export default async (req, res) => {
title: Validator.string().required(), title: Validator.string().required(),
description: Validator.string(), description: Validator.string(),
tags: Validator.string(), tags: Validator.string(),
is_giftcard: Validator.boolean().default(false),
options: Validator.array().items({ options: Validator.array().items({
title: Validator.string().required(), title: Validator.string().required(),
}), }),
@@ -71,8 +72,13 @@ export default async (req, res) => {
} }
// Add to default shipping profile // Add to default shipping profile
const { _id } = await shippingProfileService.retrieveDefault() if (value.is_giftcard) {
await shippingProfileService.addProduct(_id, newProduct._id) const { _id } = await shippingProfileService.retrieveGiftCardDefault()
await shippingProfileService.addProduct(_id, newProduct._id)
} else {
const { _id } = await shippingProfileService.retrieveDefault()
await shippingProfileService.addProduct(_id, newProduct._id)
}
newProduct = await productService.decorate( newProduct = await productService.decorate(
newProduct, newProduct,
@@ -90,6 +96,7 @@ export default async (req, res) => {
) )
res.json({ product: newProduct }) res.json({ product: newProduct })
} catch (err) { } catch (err) {
console.log(err)
throw err throw err
} }
} }
@@ -6,6 +6,7 @@ export default async (req, res) => {
const schema = Validator.object().keys({ const schema = Validator.object().keys({
variant_id: Validator.string().required(), variant_id: Validator.string().required(),
quantity: Validator.number().required(), quantity: Validator.number().required(),
metadata: Validator.object().optional(),
}) })
const { value, error } = schema.validate(req.body) const { value, error } = schema.validate(req.body)
@@ -21,7 +22,8 @@ export default async (req, res) => {
const lineItem = await lineItemService.generate( const lineItem = await lineItemService.generate(
value.variant_id, value.variant_id,
cart.region_id, cart.region_id,
value.quantity value.quantity,
value.metadata
) )
await cartService.addLineItem(cart._id, lineItem) await cartService.addLineItem(cart._id, lineItem)
+2
View File
@@ -22,5 +22,7 @@ export default async ({ container }) => {
fulfillment_providers: fulfilIds, fulfillment_providers: fulfilIds,
payment_providers: payIds, payment_providers: payIds,
}) })
await profileService.createDefault() await profileService.createDefault()
await profileService.createGiftCardDefault()
} }
+1
View File
@@ -8,6 +8,7 @@ class DiscountModel extends BaseModel {
static schema = { static schema = {
code: { type: String, required: true, unique: true }, code: { type: String, required: true, unique: true },
is_dynamic: { type: Boolean, default: false }, is_dynamic: { type: Boolean, default: false },
is_giftcard: { type: Boolean, default: false },
discount_rule: { type: DiscountRule, required: true }, discount_rule: { type: DiscountRule, required: true },
usage_count: { type: Number, default: 0 }, usage_count: { type: Number, default: 0 },
disabled: { type: Boolean, default: false }, disabled: { type: Boolean, default: false },
+1
View File
@@ -14,6 +14,7 @@ class ProductModel extends BaseModel {
description: { type: String, default: "" }, description: { type: String, default: "" },
tags: { type: String, default: "" }, tags: { type: String, default: "" },
handle: { type: String, unique: true, sparse: true }, handle: { type: String, unique: true, sparse: true },
is_giftcard: { type: Boolean, default: false },
images: { type: [String], default: [] }, images: { type: [String], default: [] },
thumbnail: { type: String, default: "" }, thumbnail: { type: String, default: "" },
options: { type: [OptionSchema], default: [] }, options: { type: [OptionSchema], default: [] },
@@ -1,6 +1,7 @@
export const MiddlewareServiceMock = { export const MiddlewareServiceMock = {
usePostAuthentication: jest.fn(), usePostAuthentication: jest.fn(),
usePreAuthentication: jest.fn(), usePreAuthentication: jest.fn(),
getRouters: jest.fn().mockReturnValue([]),
} }
const mock = jest.fn().mockImplementation(() => { const mock = jest.fn().mockImplementation(() => {
@@ -31,7 +31,11 @@ export const products = {
export const ProductServiceMock = { export const ProductServiceMock = {
createDraft: jest.fn().mockImplementation(data => { createDraft: jest.fn().mockImplementation(data => {
return Promise.resolve(products.product1) if (data.title === "Test Product") {
return Promise.resolve(products.product1)
}
return Promise.resolve({ ...data })
}), }),
publish: jest.fn().mockImplementation(_ => { publish: jest.fn().mockImplementation(_ => {
return Promise.resolve({ return Promise.resolve({
@@ -31,6 +31,9 @@ export const ShippingProfileServiceMock = {
} }
return Promise.resolve() return Promise.resolve()
}), }),
retrieveGiftCardDefault: jest.fn().mockImplementation(data => {
return Promise.resolve({ _id: IdMap.getId("giftCardProfile") })
}),
retrieveDefault: jest.fn().mockImplementation(data => { retrieveDefault: jest.fn().mockImplementation(data => {
return Promise.resolve({ _id: IdMap.getId("default_shipping_profile") }) return Promise.resolve({ _id: IdMap.getId("default_shipping_profile") })
}), }),
@@ -97,6 +97,32 @@ class ShippingProfileService extends BaseService {
return profile return profile
} }
/**
* Retrieves the default gift card profile
* @return the shipping profile for gift cards
*/
async retrieveGiftCardProfile() {
return await this.profileModel_
.findOne({ name: "default_gift_card_profile" })
.catch(err => {
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
})
}
/**
* Creates a default shipping profile, for gift cards if unless it already
* exists.
* @return {Promise<ShippingProfile>} the shipping profile
*/
async createGiftCardDefault() {
const profile = await this.retrieveGiftCardProfile()
if (!profile) {
return this.profileModel_.create({ name: "default_gift_card_profile" })
}
return profile
}
/** /**
* Creates a new shipping profile. * Creates a new shipping profile.
* @param {ShippingProfile} profile - the shipping profile to create from * @param {ShippingProfile} profile - the shipping profile to create from