Adds store/regions endpoints; fixes payment provider service
This commit is contained in:
@@ -5,6 +5,7 @@ import cartRoutes from "./carts"
|
|||||||
import orderRoutes from "./orders"
|
import orderRoutes from "./orders"
|
||||||
import customerRoutes from "./customers"
|
import customerRoutes from "./customers"
|
||||||
import shippingOptionRoutes from "./shipping-options"
|
import shippingOptionRoutes from "./shipping-options"
|
||||||
|
import regionRoutes from "./regions"
|
||||||
|
|
||||||
const route = Router()
|
const route = Router()
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ export default app => {
|
|||||||
orderRoutes(route)
|
orderRoutes(route)
|
||||||
cartRoutes(route)
|
cartRoutes(route)
|
||||||
shippingOptionRoutes(route)
|
shippingOptionRoutes(route)
|
||||||
|
regionRoutes(route)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 })
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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 })
|
||||||
|
}
|
||||||
@@ -494,6 +494,7 @@ describe("CartService", () => {
|
|||||||
const cartService = new CartService({
|
const cartService = new CartService({
|
||||||
cartModel: CartModelMock,
|
cartModel: CartModelMock,
|
||||||
eventBusService: EventBusServiceMock,
|
eventBusService: EventBusServiceMock,
|
||||||
|
regionService: RegionServiceMock,
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(() => {
|
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 () => {
|
it("throws on invalid address", async () => {
|
||||||
const address = {
|
const address = {
|
||||||
|
// Missing first_name
|
||||||
last_name: "James",
|
last_name: "James",
|
||||||
address_1: "24 Dunks Drive",
|
address_1: "24 Dunks Drive",
|
||||||
city: "Los Angeles",
|
city: "Los Angeles",
|
||||||
@@ -540,14 +560,9 @@ describe("CartService", () => {
|
|||||||
postal_code: "93011",
|
postal_code: "93011",
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await expect(
|
||||||
await cartService.updateShippingAddress(
|
cartService.updateShippingAddress(IdMap.getId("emptyCart"), address)
|
||||||
IdMap.getId("emptyCart"),
|
).rejects.toThrow("The address is not valid")
|
||||||
address
|
|
||||||
)
|
|
||||||
} catch (err) {
|
|
||||||
expect(err.message).toEqual("The address is not valid")
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(CartModelMock.updateOne).toHaveBeenCalledTimes(0)
|
expect(CartModelMock.updateOne).toHaveBeenCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import { createContainer, asValue } from "awilix"
|
|
||||||
import PaymentProviderService from "../payment-provider"
|
import PaymentProviderService from "../payment-provider"
|
||||||
|
|
||||||
describe("ProductService", () => {
|
describe("ProductService", () => {
|
||||||
describe("retrieveProvider", () => {
|
describe("retrieveProvider", () => {
|
||||||
const container = createContainer()
|
const container = {
|
||||||
|
pp_default_provider: "good",
|
||||||
container.register({
|
}
|
||||||
pp_default_provider: asValue("good"),
|
|
||||||
})
|
|
||||||
|
|
||||||
const providerService = new PaymentProviderService(container)
|
const providerService = new PaymentProviderService(container)
|
||||||
|
|
||||||
|
|||||||
@@ -448,12 +448,21 @@ class CartService extends BaseService {
|
|||||||
const cart = await this.retrieve(cartId)
|
const cart = await this.retrieve(cartId)
|
||||||
const { value, error } = Validator.address().validate(address)
|
const { value, error } = Validator.address().validate(address)
|
||||||
if (error) {
|
if (error) {
|
||||||
|
console.log(error)
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.INVALID_DATA,
|
MedusaError.Types.INVALID_DATA,
|
||||||
"The address is not valid"
|
"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_
|
return this.cartModel_
|
||||||
.updateOne(
|
.updateOne(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class PaymentProviderService {
|
|||||||
*/
|
*/
|
||||||
retrieveProvider(provider_id) {
|
retrieveProvider(provider_id) {
|
||||||
try {
|
try {
|
||||||
const provider = this.container_.resolve(`pp_${provider_id}`)
|
const provider = this.container_[`pp_${provider_id}`]
|
||||||
return provider
|
return provider
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
|
|||||||
@@ -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
|
export default RegionService
|
||||||
|
|||||||
Reference in New Issue
Block a user