feat(dashboard, core-flows, js-sdk, types, medusa): listing order's shipping options (#13242)
* feat(dashboard, core-flows,js-sdk,types,medusa): listing order's shipping option * fix: typo * chore: migrate claim form * fix: cleanup rule logic * feat: add test case, rm params * fix: expand location name
This commit is contained in:
119
integration-tests/http/__tests__/fixtures/shipping.ts
Normal file
119
integration-tests/http/__tests__/fixtures/shipping.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import {
|
||||
AdminShippingProfile,
|
||||
AdminStockLocation,
|
||||
AdminSalesChannel,
|
||||
MedusaContainer,
|
||||
} from "@medusajs/types"
|
||||
import { adminHeaders } from "../../../helpers/create-admin-user"
|
||||
|
||||
export async function createShippingOptionSeeder({
|
||||
api,
|
||||
container,
|
||||
salesChannelOverride,
|
||||
stockLocationOverride,
|
||||
shippingProfileOverride,
|
||||
countries = ["us"],
|
||||
}: {
|
||||
api: any
|
||||
container: MedusaContainer
|
||||
salesChannelOverride?: AdminSalesChannel
|
||||
stockLocationOverride?: AdminStockLocation
|
||||
shippingProfileOverride?: AdminShippingProfile
|
||||
countries?: string[]
|
||||
}) {
|
||||
const salesChannel =
|
||||
salesChannelOverride ??
|
||||
(
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "first channel", description: "channel" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.sales_channel
|
||||
|
||||
const stockLocation =
|
||||
stockLocationOverride ??
|
||||
(
|
||||
await api.post(
|
||||
`/admin/stock-locations`,
|
||||
{ name: "test location" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.stock_location
|
||||
|
||||
await api.post(
|
||||
`/admin/stock-locations/${stockLocation.id}/sales-channels`,
|
||||
{ add: [salesChannel.id] },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const shippingProfile =
|
||||
shippingProfileOverride ??
|
||||
(
|
||||
await api.post(
|
||||
`/admin/shipping-profiles`,
|
||||
{ name: `test-${stockLocation.id}`, type: "default" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.shipping_profile
|
||||
|
||||
const fulfillmentSets = (
|
||||
await api.post(
|
||||
`/admin/stock-locations/${stockLocation.id}/fulfillment-sets?fields=*fulfillment_sets`,
|
||||
{
|
||||
name: `Test-${shippingProfile.id}`,
|
||||
type: "test-type",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.stock_location.fulfillment_sets
|
||||
|
||||
const fulfillmentSet = (
|
||||
await api.post(
|
||||
`/admin/fulfillment-sets/${fulfillmentSets[0].id}/service-zones`,
|
||||
{
|
||||
name: `Test-${shippingProfile.id}`,
|
||||
geo_zones: countries.map((country) => ({
|
||||
type: "country",
|
||||
country_code: country,
|
||||
})),
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.fulfillment_set
|
||||
|
||||
await api.post(
|
||||
`/admin/stock-locations/${stockLocation.id}/fulfillment-providers`,
|
||||
{ add: ["manual_test-provider"] },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const shippingOption = (
|
||||
await api.post(
|
||||
`/admin/shipping-options?fields=+service_zone.fulfillment_set.*,service_zone.geo_zones.*,service_zone.fulfillment_set.location*`,
|
||||
{
|
||||
name: `Test shipping option ${fulfillmentSet.id}`,
|
||||
service_zone_id: fulfillmentSet.service_zones[0].id,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
provider_id: "manual_test-provider",
|
||||
price_type: "flat",
|
||||
type: {
|
||||
label: "Test type",
|
||||
description: "Test description",
|
||||
code: "test-code",
|
||||
},
|
||||
prices: [{ currency_code: "usd", amount: 1000 }],
|
||||
rules: [],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.shipping_option
|
||||
|
||||
return {
|
||||
salesChannel,
|
||||
stockLocation,
|
||||
shippingProfile,
|
||||
fulfillmentSet,
|
||||
shippingOption,
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
} from "../../../../helpers/create-admin-user"
|
||||
import { setupTaxStructure } from "../../../../modules/__tests__/fixtures"
|
||||
import { createOrderSeeder } from "../../fixtures/order"
|
||||
import { createShippingOptionSeeder } from "../../fixtures/shipping"
|
||||
import { AdminShippingOption } from "@medusajs/types"
|
||||
|
||||
jest.setTimeout(300000)
|
||||
|
||||
@@ -73,7 +75,10 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
|
||||
it("should search orders by shipping address", async () => {
|
||||
let response = await api.get(`/admin/orders?fields=+shipping_address.address_1,+shipping_address.address_2`, adminHeaders)
|
||||
let response = await api.get(
|
||||
`/admin/orders?fields=+shipping_address.address_1,+shipping_address.address_2`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
@@ -82,7 +87,10 @@ medusaIntegrationTestRunner({
|
||||
}),
|
||||
])
|
||||
|
||||
response = await api.get(`/admin/orders?fields=+shipping_address.address_1,+shipping_address.address_2&q=${order.shipping_address.address_1}`, adminHeaders)
|
||||
response = await api.get(
|
||||
`/admin/orders?fields=+shipping_address.address_1,+shipping_address.address_2&q=${order.shipping_address.address_1}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
@@ -91,7 +99,10 @@ medusaIntegrationTestRunner({
|
||||
}),
|
||||
])
|
||||
|
||||
response = await api.get(`/admin/orders?q=${order.shipping_address.address_2}`, adminHeaders)
|
||||
response = await api.get(
|
||||
`/admin/orders?q=${order.shipping_address.address_2}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
@@ -107,16 +118,10 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
|
||||
it("should search orders by billing address", async () => {
|
||||
let response = await api.get(`/admin/orders?fields=+billing_address.address_1,+billing_address.address_2`, adminHeaders)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: order.id,
|
||||
}),
|
||||
])
|
||||
|
||||
response = await api.get(`/admin/orders?fields=+billing_address.address_1,+billing_address.address_2&q=${order.billing_address.address_1}`, adminHeaders)
|
||||
let response = await api.get(
|
||||
`/admin/orders?fields=+billing_address.address_1,+billing_address.address_2`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
@@ -125,12 +130,27 @@ medusaIntegrationTestRunner({
|
||||
}),
|
||||
])
|
||||
|
||||
response = await api.get(`/admin/orders?q=${order.billing_address.address_2}`, adminHeaders)
|
||||
response = await api.get(
|
||||
`/admin/orders?fields=+billing_address.address_1,+billing_address.address_2&q=${order.billing_address.address_1}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: order.id,
|
||||
id: order.id,
|
||||
}),
|
||||
])
|
||||
|
||||
response = await api.get(
|
||||
`/admin/orders?q=${order.billing_address.address_2}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.orders).toHaveLength(1)
|
||||
expect(response.data.orders).toEqual([
|
||||
expect.objectContaining({
|
||||
id: order.id,
|
||||
}),
|
||||
])
|
||||
})
|
||||
@@ -2471,6 +2491,76 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
})
|
||||
|
||||
describe("GET /orders/:id/shipping-options", () => {
|
||||
let so1: AdminShippingOption
|
||||
let so2: AdminShippingOption
|
||||
let so3: AdminShippingOption
|
||||
|
||||
beforeEach(async () => {
|
||||
seeder = await createOrderSeeder({ api, container: getContainer() })
|
||||
order = seeder.order
|
||||
order = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
|
||||
.order
|
||||
|
||||
so1 = (
|
||||
await createShippingOptionSeeder({
|
||||
api,
|
||||
container: getContainer(),
|
||||
salesChannelOverride: seeder.salesChannel,
|
||||
countries: ["us"],
|
||||
})
|
||||
).shippingOption
|
||||
|
||||
so2 = (
|
||||
await createShippingOptionSeeder({
|
||||
api,
|
||||
container: getContainer(),
|
||||
salesChannelOverride: seeder.salesChannel,
|
||||
countries: ["us", "ca"],
|
||||
})
|
||||
).shippingOption
|
||||
|
||||
so3 = (
|
||||
await createShippingOptionSeeder({
|
||||
api,
|
||||
container: getContainer(),
|
||||
salesChannelOverride: seeder.salesChannel,
|
||||
countries: ["de"],
|
||||
})
|
||||
).shippingOption
|
||||
})
|
||||
|
||||
it("should return the shipping options applicable for the order", async () => {
|
||||
const { data } = await api.get(
|
||||
`/admin/orders/${order.id}/shipping-options`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const originalShippingOptionId =
|
||||
order.shipping_methods[0].shipping_option_id
|
||||
|
||||
expect(order.shipping_address.country_code).toEqual("us")
|
||||
|
||||
expect(data.shipping_options.length).toEqual(3)
|
||||
expect(data.shipping_options).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: so1.id,
|
||||
insufficient_inventory: true,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: so2.id,
|
||||
insufficient_inventory: true, // new SO without location levels for the order item, should have insufficient inventory
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: originalShippingOptionId,
|
||||
insufficient_inventory: false, // order is created with this SO, location has to have enough inventory
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /orders/:id/fulfillments/:id/mark-as-delivered", () => {
|
||||
beforeEach(async () => {
|
||||
seeder = await createOrderSeeder({ api, container: getContainer() })
|
||||
|
||||
Reference in New Issue
Block a user