From 022367a9d8bed3542982a8466188605606b6f826 Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Wed, 27 May 2020 20:03:21 +0200 Subject: [PATCH] Adds store/regions endpoints; fixes payment provider service --- packages/medusa/src/api/routes/store/index.js | 2 ++ .../api/routes/store/regions/get-region.js | 26 ++++++++++++++++ .../src/api/routes/store/regions/index.js | 13 ++++++++ .../api/routes/store/regions/list-regions.js | 23 ++++++++++++++ .../medusa/src/services/__tests__/cart.js | 31 ++++++++++++++----- .../services/__tests__/payment-provider.js | 9 ++---- packages/medusa/src/services/cart.js | 9 ++++++ .../medusa/src/services/payment-provider.js | 2 +- packages/medusa/src/services/region.js | 13 ++++++++ 9 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 packages/medusa/src/api/routes/store/regions/get-region.js create mode 100644 packages/medusa/src/api/routes/store/regions/index.js create mode 100644 packages/medusa/src/api/routes/store/regions/list-regions.js diff --git a/packages/medusa/src/api/routes/store/index.js b/packages/medusa/src/api/routes/store/index.js index a81c02c9bf..db737588ee 100644 --- a/packages/medusa/src/api/routes/store/index.js +++ b/packages/medusa/src/api/routes/store/index.js @@ -5,6 +5,7 @@ import cartRoutes from "./carts" import orderRoutes from "./orders" import customerRoutes from "./customers" import shippingOptionRoutes from "./shipping-options" +import regionRoutes from "./regions" const route = Router() @@ -16,6 +17,7 @@ export default app => { orderRoutes(route) cartRoutes(route) shippingOptionRoutes(route) + regionRoutes(route) return app } diff --git a/packages/medusa/src/api/routes/store/regions/get-region.js b/packages/medusa/src/api/routes/store/regions/get-region.js new file mode 100644 index 0000000000..95acc61dec --- /dev/null +++ b/packages/medusa/src/api/routes/store/regions/get-region.js @@ -0,0 +1,26 @@ +import { Validator } from "medusa-core-utils" + +export default async (req, res) => { + const { region_id } = req.params + + const schema = Validator.objectId() + const { value, error } = schema.validate(region_id) + + if (error) { + throw error + } + + const productService = req.scope.resolve("regionService") + const region = await regionService.retrieve(value) + + const data = await regionService.decorate(region, [ + "name", + "currency_code", + "tax_rate", + "countries", + "payment_providers", + "fulfillment_providers", + ]) + + res.json({ region }) +} diff --git a/packages/medusa/src/api/routes/store/regions/index.js b/packages/medusa/src/api/routes/store/regions/index.js new file mode 100644 index 0000000000..b41ced688f --- /dev/null +++ b/packages/medusa/src/api/routes/store/regions/index.js @@ -0,0 +1,13 @@ +import { Router } from "express" +import middlewares from "../../../middlewares" + +const route = Router() + +export default app => { + app.use("/regions", route) + + route.get("/", middlewares.wrap(require("./list-regions").default)) + route.get("/:region_id", middlewares.wrap(require("./get-region").default)) + + return app +} diff --git a/packages/medusa/src/api/routes/store/regions/list-regions.js b/packages/medusa/src/api/routes/store/regions/list-regions.js new file mode 100644 index 0000000000..5a3c12ee39 --- /dev/null +++ b/packages/medusa/src/api/routes/store/regions/list-regions.js @@ -0,0 +1,23 @@ +import { Validator } from "medusa-core-utils" + +export default async (req, res) => { + const selector = {} + + const regionService = req.scope.resolve("regionService") + const regions = await regionService.list(selector) + + const data = await Promise.all( + regions.map(r => + regionService.decorate(r, [ + "name", + "currency_code", + "tax_rate", + "countries", + "payment_providers", + "fulfillment_providers", + ]) + ) + ) + + res.json({ regions: data }) +} diff --git a/packages/medusa/src/services/__tests__/cart.js b/packages/medusa/src/services/__tests__/cart.js index a1bedb8ef0..26eae60d26 100644 --- a/packages/medusa/src/services/__tests__/cart.js +++ b/packages/medusa/src/services/__tests__/cart.js @@ -494,6 +494,7 @@ describe("CartService", () => { const cartService = new CartService({ cartModel: CartModelMock, eventBusService: EventBusServiceMock, + regionService: RegionServiceMock, }) beforeEach(() => { @@ -530,8 +531,27 @@ describe("CartService", () => { ) }) + it("throws if country not in region", async () => { + const address = { + first_name: "LeBron", + last_name: "James", + address_1: "24 Dunks Drive", + city: "Los Angeles", + country_code: "ru", + province: "CA", + postal_code: "93011", + } + + await expect( + cartService.updateShippingAddress(IdMap.getId("emptyCart"), address) + ).rejects.toThrow("Shipping country must be in the cart region") + + expect(CartModelMock.updateOne).toHaveBeenCalledTimes(0) + }) + it("throws on invalid address", async () => { const address = { + // Missing first_name last_name: "James", address_1: "24 Dunks Drive", city: "Los Angeles", @@ -540,14 +560,9 @@ describe("CartService", () => { postal_code: "93011", } - try { - await cartService.updateShippingAddress( - IdMap.getId("emptyCart"), - address - ) - } catch (err) { - expect(err.message).toEqual("The address is not valid") - } + await expect( + cartService.updateShippingAddress(IdMap.getId("emptyCart"), address) + ).rejects.toThrow("The address is not valid") expect(CartModelMock.updateOne).toHaveBeenCalledTimes(0) }) diff --git a/packages/medusa/src/services/__tests__/payment-provider.js b/packages/medusa/src/services/__tests__/payment-provider.js index e1fb0a6bac..9fbfcf374d 100644 --- a/packages/medusa/src/services/__tests__/payment-provider.js +++ b/packages/medusa/src/services/__tests__/payment-provider.js @@ -1,13 +1,10 @@ -import { createContainer, asValue } from "awilix" import PaymentProviderService from "../payment-provider" describe("ProductService", () => { describe("retrieveProvider", () => { - const container = createContainer() - - container.register({ - pp_default_provider: asValue("good"), - }) + const container = { + pp_default_provider: "good", + } const providerService = new PaymentProviderService(container) diff --git a/packages/medusa/src/services/cart.js b/packages/medusa/src/services/cart.js index ec39c9710d..3d8d072c88 100644 --- a/packages/medusa/src/services/cart.js +++ b/packages/medusa/src/services/cart.js @@ -448,12 +448,21 @@ class CartService extends BaseService { const cart = await this.retrieve(cartId) const { value, error } = Validator.address().validate(address) if (error) { + console.log(error) throw new MedusaError( MedusaError.Types.INVALID_DATA, "The address is not valid" ) } + const region = await this.regionService_.retrieve(cart.region_id) + if (!region.countries.includes(address.country_code.toUpperCase())) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "Shipping country must be in the cart region" + ) + } + return this.cartModel_ .updateOne( { diff --git a/packages/medusa/src/services/payment-provider.js b/packages/medusa/src/services/payment-provider.js index 5e58221dbf..a539b75d4e 100644 --- a/packages/medusa/src/services/payment-provider.js +++ b/packages/medusa/src/services/payment-provider.js @@ -19,7 +19,7 @@ class PaymentProviderService { */ retrieveProvider(provider_id) { try { - const provider = this.container_.resolve(`pp_${provider_id}`) + const provider = this.container_[`pp_${provider_id}`] return provider } catch (err) { throw new MedusaError( diff --git a/packages/medusa/src/services/region.js b/packages/medusa/src/services/region.js index ba9a5661e4..6ae729d0bd 100644 --- a/packages/medusa/src/services/region.js +++ b/packages/medusa/src/services/region.js @@ -351,6 +351,19 @@ class RegionService extends BaseService { } ) } + + /** + * Decorates a region + * @param {object} region - the region to decorate + * @param {[string]} fields - the fields to include + * @param {[string]} expandFields - the fields to expand + * @return {Region} the region + */ + async decorate(region, fields, expandFields = []) { + const requiredFields = ["_id", "metadata"] + const decorated = _.pick(region, fields.concat(requiredFields)) + return decorated + } } export default RegionService