diff --git a/integration-tests/http/__tests__/fixtures/order.ts b/integration-tests/http/__tests__/fixtures/order.ts index c88614e43656c..f2e00df7b6aa3 100644 --- a/integration-tests/http/__tests__/fixtures/order.ts +++ b/integration-tests/http/__tests__/fixtures/order.ts @@ -13,6 +13,7 @@ import { export async function createOrderSeeder({ api, container, + storeHeaderOverride, productOverride, additionalProducts, stockChannelOverride, @@ -20,13 +21,19 @@ export async function createOrderSeeder({ }: { api: any container: MedusaContainer + storeHeaderOverride?: any productOverride?: AdminProduct stockChannelOverride?: AdminStockLocation additionalProducts?: { variant_id: string; quantity: number }[] inventoryItemOverride?: AdminInventoryItem }) { const publishableKey = await generatePublishableKey(container) - const storeHeaders = generateStoreHeaders({ publishableKey }) + + const storeHeaders = + storeHeaderOverride ?? + generateStoreHeaders({ + publishableKey, + }) const region = ( await api.post( diff --git a/integration-tests/http/__tests__/order/store/order.spec.ts b/integration-tests/http/__tests__/order/store/order.spec.ts new file mode 100644 index 0000000000000..473a4242049a1 --- /dev/null +++ b/integration-tests/http/__tests__/order/store/order.spec.ts @@ -0,0 +1,138 @@ +import { medusaIntegrationTestRunner } from "@medusajs/test-utils" +import { ModuleRegistrationName } from "@medusajs/utils" +import { + adminHeaders, + createAdminUser, + generatePublishableKey, + generateStoreHeaders, +} from "../../../../helpers/create-admin-user" +import { setupTaxStructure } from "../../../../modules/__tests__/fixtures" +import { createAuthenticatedCustomer } from "../../../../modules/helpers/create-authenticated-customer" +import { createOrderSeeder } from "../../fixtures/order" + +jest.setTimeout(300000) + +medusaIntegrationTestRunner({ + testSuite: ({ dbConnection, getContainer, api }) => { + let order, + draftOrder, + seeder, + storeHeaders, + customer, + storeHeadersWithCustomer + + beforeEach(async () => { + const container = getContainer() + + await setupTaxStructure(container.resolve(ModuleRegistrationName.TAX)) + await createAdminUser(dbConnection, adminHeaders, container) + const publishableKey = await generatePublishableKey(container) + storeHeaders = generateStoreHeaders({ publishableKey }) + + const result = await createAuthenticatedCustomer(api, storeHeaders, { + first_name: "tony", + last_name: "stark", + email: "tony@stark-industries.com", + }) + + customer = result.customer + storeHeadersWithCustomer = { + headers: { + ...storeHeaders.headers, + authorization: `Bearer ${result.jwt}`, + }, + } + + seeder = await createOrderSeeder({ + api, + container: getContainer(), + storeHeaderOverride: storeHeadersWithCustomer, + }) + order = seeder.order + order = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data + .order + + const payload = { + email: "test@test.test", + region_id: seeder.region.id, + status: "completed", + shipping_methods: [ + { + shipping_option_id: seeder.shippingOption.id, + amount: 10, + name: "test", + }, + ], + } + + const draftOrderResposne = await api.post( + "/admin/draft-orders?fields=+is_draft_order", + payload, + adminHeaders + ) + + await api.post( + `/admin/orders/${draftOrderResposne.data.draft_order.id}/complete`, + {}, + adminHeaders + ) + + draftOrder = draftOrderResposne.data.draft_order + }) + + describe("GET /store/orders", () => { + it("should successfully list non draft orders", async () => { + const response = await api.get( + `/store/orders`, + storeHeadersWithCustomer + ) + + expect(response.data.orders).toHaveLength(1) + expect(response.data.orders).toEqual([ + expect.objectContaining({ + id: order.id, + }), + ]) + }) + + it("should throw an error when customer isn't authenticated", async () => { + const { response } = await api + .get(`/store/orders`, storeHeaders) + .catch((e) => e) + + expect(response.status).toEqual(401) + expect(response.data.message).toEqual("Unauthorized") + }) + }) + + describe("GET /store/orders/:id", () => { + it("should successfully fetch non draft order", async () => { + const response = await api.get( + `/store/orders/${order.id}`, + storeHeadersWithCustomer + ) + + expect(response.data.order).toEqual( + expect.objectContaining({ + id: order.id, + }) + ) + }) + + // TODO: This should have thrown an error, but doesn't seem to. + it.skip("should throw an error when fetching draft order", async () => { + const response = await api + .get( + `/store/orders/${draftOrder.id}?fields=+is_draft_order`, + storeHeaders + ) + .catch((e) => e) + + expect(response.status).toEqual(404) + expect(response.data.message).toEqual( + `Order with id: ${draftOrder.id} was not found` + ) + }) + }) + }, +}) diff --git a/packages/core/core-flows/src/order/workflows/get-order-detail.ts b/packages/core/core-flows/src/order/workflows/get-order-detail.ts index 1c9d4368cafa3..1833fac19b340 100644 --- a/packages/core/core-flows/src/order/workflows/get-order-detail.ts +++ b/packages/core/core-flows/src/order/workflows/get-order-detail.ts @@ -20,6 +20,7 @@ export const getOrderDetailWorkflow = createWorkflow( getOrderDetailWorkflowId, ( input: WorkflowData<{ + filters?: { is_draft_order?: boolean; customer_id?: string } fields: string[] order_id: string version?: number @@ -36,13 +37,14 @@ export const getOrderDetailWorkflow = createWorkflow( ]) }) + const variables = transform({ input }, ({ input }) => { + return { ...input.filters, id: input.order_id, version: input.version } + }) + const order: OrderDTO = useRemoteQueryStep({ entry_point: "orders", fields, - variables: { - id: input.order_id, - version: input.version, - }, + variables, list: false, throw_if_key_not_found: true, }) diff --git a/packages/medusa/src/api/store/orders/[id]/route.ts b/packages/medusa/src/api/store/orders/[id]/route.ts index a1f8e12d0585c..f814de1b4dea0 100644 --- a/packages/medusa/src/api/store/orders/[id]/route.ts +++ b/packages/medusa/src/api/store/orders/[id]/route.ts @@ -12,6 +12,9 @@ export const GET = async ( input: { fields: req.remoteQueryConfig.fields, order_id: req.params.id, + filters: { + is_draft_order: false, + }, }, }) diff --git a/packages/medusa/src/api/store/orders/middlewares.ts b/packages/medusa/src/api/store/orders/middlewares.ts index a79dd7a71d225..beeeaeddb5452 100644 --- a/packages/medusa/src/api/store/orders/middlewares.ts +++ b/packages/medusa/src/api/store/orders/middlewares.ts @@ -1,14 +1,14 @@ +import { validateAndTransformQuery } from "@medusajs/framework" import { MiddlewareRoute, validateAndTransformBody, } from "@medusajs/framework/http" import { authenticate } from "../../../utils/middlewares/authenticate-middleware" -import { validateAndTransformQuery } from "@medusajs/framework" import * as QueryConfig from "./query-config" import { + StoreAcceptOrderTransfer, StoreGetOrderParams, StoreGetOrdersParams, - StoreAcceptOrderTransfer, StoreRequestOrderTransfer, } from "./validators" diff --git a/packages/medusa/src/api/store/orders/route.ts b/packages/medusa/src/api/store/orders/route.ts index 02eace8e8ffb3..2c6e690273b23 100644 --- a/packages/medusa/src/api/store/orders/route.ts +++ b/packages/medusa/src/api/store/orders/route.ts @@ -12,6 +12,7 @@ export const GET = async ( const variables = { filters: { ...req.filterableFields, + is_draft_order: false, customer_id: req.auth_context.actor_id, }, ...req.remoteQueryConfig.pagination,