diff --git a/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx b/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx index 24866887a09a5..99425e1345275 100644 --- a/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx +++ b/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx @@ -304,3 +304,66 @@ In the test, you use the `api.delete` method to send a `DELETE` request to `/cus - Has a `success` property in its data. - The `success` property's value is true. +--- + +## Pass Headers in Test Requests + +Some requests require passing headers. For example, all routes prefixed with `/store` must pass a publishable API key in the header. + +The `get`, `post`, and `delete` methods accept an optional third parameter that you can pass a `headers` property to, whose value is an object of headers to pass in the request. + +For example, to pass a publishable API key in the header for a request to a `/store` route: + +export const headersHighlights = [ + ["10", "pak", "Create a publishable API key before the tests run."], + ["27", "headers", "Pass the publishable API key in the request's header."] +] + +```ts title="integration-tests/http/custom-routes.spec.ts" highlights={headersHighlights} +import { medusaIntegrationTestRunner } from "@medusajs/test-utils" +import { ApiKeyDTO } from "@medusajs/framework/types" +import { createApiKeysWorkflow } from "@medusajs/medusa/core-flows" + +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + describe("Custom endpoints", () => { + let pak: ApiKeyDTO + beforeAll(async () => { + pak = (await createApiKeysWorkflow(getContainer()).run({ + input: { + api_keys: [ + { + type: "publishable", + title: "Test Key", + created_by: "" + } + ] + } + })).result[0] + }) + describe("GET /custom", () => { + it("returns correct message", async () => { + const response = await api.get( + `/store/custom`, + { + headers: { + "x-publishable-api-key": pak.token + } + } + ) + + expect(response.status).toEqual(200) + expect(response.data).toHaveProperty("message") + expect(response.data.message).toEqual("Hello, World!") + }) + }) + }) + }, +}) + +jest.setTimeout(60 * 1000) +``` + +In your test suit, you add a `beforeAll` hook to create a publishable API key before the tests run. To create the API key, you can use the `createApiKeysWorkflow` or the [API Key Module's service](!resources!/commerce-modules/api-key). + +Then, in the test, you pass an object as the last parameter to `api.get` with a `headers` property. The `headers` property is an object with the key `x-publishable-api-key` and the value of the API key's token. diff --git a/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx b/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx index 05ea2b43dab07..97bc9f29fef2c 100644 --- a/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx +++ b/www/apps/book/app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx @@ -93,3 +93,52 @@ If you don't have a `test:integration` script in `package.json`, refer to the [M This runs your Medusa application and runs the tests available under the `integrations/http` directory. + +--- + +## Test That a Workflow Throws an Error + +You might want to test that a workflow throws an error in certain cases. To test this: + +- Disable the `throwOnError` option when executing the workflow. +- Use the returned `errors` property to check what errors were thrown. + +For example, if you have a step that throws this error: + +```ts title="src/workflows/hello-world.ts" +import { MedusaError } from "@medusajs/framework/utils" +import { createStep } from "@medusajs/framework/workflows-sdk" + +const step1 = createStep("step-1", () => { + throw new MedusaError(MedusaError.Types.NOT_FOUND, "Item doesn't exist") +}) +``` + +You can write the following test to ensure that the workflow throws that error: + +```ts title="integration-tests/http/workflow.spec.ts" +import { medusaIntegrationTestRunner } from "@medusajs/test-utils" +import { helloWorldWorkflow } from "../../src/workflows/hello-world" + +medusaIntegrationTestRunner({ + testSuite: ({ getContainer }) => { + describe("Test hello-world workflow", () => { + it("returns message", async () => { + const { errors } = await helloWorldWorkflow(getContainer()) + .run({ + throwOnError: false + }) + + expect(errors.length).toBeGreaterThan(0) + expect(errors[0].error.message).toBe("Item doesn't exist") + }) + }) + }, +}) + +jest.setTimeout(60 * 1000) +``` + +The `errors` property contains an array of errors thrown during the execution of the workflow. Each error item has an `error` object, being the error thrown. + +If you threw a `MedusaError`, then you can check the error message in `errors[0].error.message`. \ No newline at end of file diff --git a/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx b/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx index ddf07c233f8d6..79b2c1cf0660a 100644 --- a/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx +++ b/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx @@ -58,6 +58,8 @@ moduleIntegrationTestRunner({ }) }, }) + +jest.setTimeout(60 * 1000) ``` You use the `moduleIntegrationTestRunner` function to add tests for the `hello` module. You have one test that passes if the `getMessage` method returns the `"Hello, World!"` string. @@ -69,12 +71,12 @@ You use the `moduleIntegrationTestRunner` function to add tests for the `hello` Run the following command to run your module integration tests: ```bash npm2yarn -npm run test:modules +npm run test:integration:modules ``` -If you don't have a `test:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../../page.mdx#add-test-commands). +If you don't have a `test:integration:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../../page.mdx#add-test-commands). diff --git a/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx b/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx index 8dbedfc2b1e1a..0d1fce9086256 100644 --- a/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx +++ b/www/apps/book/app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx @@ -37,6 +37,8 @@ moduleIntegrationTestRunner({ // TODO write tests }, }) + +jest.setTimeout(60 * 1000) ``` The `moduleIntegrationTestRunner` function accepts as a parameter an object with the following properties: @@ -63,12 +65,12 @@ The tests in the `testSuite` function are written using [Jest](https://jestjs.io Run the following command to run your module integration tests: ```bash npm2yarn -npm run test:modules +npm run test:integration:modules ``` -If you don't have a `test:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../page.mdx#add-test-commands). +If you don't have a `test:integration:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../page.mdx#add-test-commands). @@ -115,6 +117,8 @@ moduleIntegrationTestRunner({ moduleModels: [DummyModel], // ... }) + +jest.setTimeout(60 * 1000) ``` --- diff --git a/www/apps/book/app/learn/debugging-and-testing/testing-tools/page.mdx b/www/apps/book/app/learn/debugging-and-testing/testing-tools/page.mdx index 5ae1a5dbcb8de..8f64553872777 100644 --- a/www/apps/book/app/learn/debugging-and-testing/testing-tools/page.mdx +++ b/www/apps/book/app/learn/debugging-and-testing/testing-tools/page.mdx @@ -22,14 +22,6 @@ npm install --save-dev @medusajs/test-utils@latest Writing tests with `@medusajs/test-utils`'s tools requires installing and configuring Jest in your project. -{/* TODO remove this note at some point in the future */} - - - -If your Medusa project was created after September 3rd, Jest is already installed and configured. - - - Run the following command to install the required Jest dependencies: ```bash npm2yarn @@ -56,6 +48,7 @@ module.exports = { testEnvironment: "node", moduleFileExtensions: ["js", "ts", "json"], modulePathIgnorePatterns: ["dist/"], + setupFiles: ["./integration-tests/setup.js"], } if (process.env.TEST_TYPE === "integration:http") { @@ -67,6 +60,14 @@ if (process.env.TEST_TYPE === "integration:http") { } ``` +Next, create the `integration-tests/setup.js` file with the following content: + +```js title="integration-tests/setup.js" +const { MetadataStorage } = require("@mikro-orm/core") + +MetadataStorage.clear() +``` + --- ## Add Test Commands diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 3e21e9c7f3203..fde77bd7077c0 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -59,10 +59,10 @@ export const generatedEditDates = { "app/learn/fundamentals/data-models/index/page.mdx": "2024-10-21T13:30:21.368Z", "app/learn/fundamentals/custom-cli-scripts/page.mdx": "2024-10-23T07:08:55.898Z", "app/learn/fundamentals/data-models/property-types/page.mdx": "2024-12-12T10:41:32.999Z", - "app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-12-09T15:34:08.049Z", + "app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2025-01-31T13:19:02.586Z", "app/learn/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-12-09T15:52:01.019Z", - "app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-12-09T15:51:15.422Z", - "app/learn/debugging-and-testing/testing-tools/page.mdx": "2024-12-09T15:53:56.878Z", + "app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2025-01-31T13:19:02.586Z", + "app/learn/debugging-and-testing/testing-tools/page.mdx": "2025-01-31T13:19:02.587Z", "app/learn/debugging-and-testing/testing-tools/unit-tests/module-example/page.mdx": "2024-09-02T11:04:27.232Z", "app/learn/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z", "app/learn/fundamentals/modules/service-constraints/page.mdx": "2024-11-19T16:37:47.253Z", @@ -70,8 +70,8 @@ export const generatedEditDates = { "app/learn/fundamentals/api-routes/validation/page.mdx": "2024-12-09T13:04:02.426Z", "app/learn/fundamentals/api-routes/errors/page.mdx": "2024-12-09T16:44:19.781Z", "app/learn/fundamentals/admin/constraints/page.mdx": "2024-10-21T13:30:21.366Z", - "app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2024-12-09T15:52:22.185Z", - "app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2024-12-09T15:52:57.091Z", + "app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2025-01-31T13:19:02.586Z", + "app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-01-31T13:19:02.587Z", "app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-01-06T11:19:13.178Z", "app/learn/fundamentals/module-links/directions/page.mdx": "2024-12-12T15:31:31.555Z", "app/learn/fundamentals/module-links/page.mdx": "2024-12-09T14:39:26.668Z", diff --git a/www/apps/resources/app/troubleshooting/test-errors/page.mdx b/www/apps/resources/app/troubleshooting/test-errors/page.mdx new file mode 100644 index 0000000000000..51100a13ebf51 --- /dev/null +++ b/www/apps/resources/app/troubleshooting/test-errors/page.mdx @@ -0,0 +1,32 @@ +export const metadata = { + title: `Test Errors`, +} + +# {metadata.title} + +## Loaders for module Workflows failed + +If you get the following error when running your tests: + +```bash +Loaders for module Workflows failed: Method Map.prototype.set called on incompatible receiver # +``` + +This may occur if you have multiple test files and you don't configure your Jest environment correctly. To resolve this, add the following configuration to your `jest.config.js` file: + +```js title="jest.config.js" +module.exports = { + // ... + setupFiles: ["./integration-tests/setup.js"], +} +``` + +Then, create the `integration-tests/setup.js` file with the following content: + +```js title="integration-tests/setup.js" +const { MetadataStorage } = require("@mikro-orm/core") + +MetadataStorage.clear() +``` + +Learn more about configuring test tools in [this documentation](!docs!/learn/debugging-and-testing/testing-tools) diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index f475cebc92932..23c1ab24fa866 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -5901,5 +5901,6 @@ export const generatedEditDates = { "references/types/HttpTypes/interfaces/types.HttpTypes.StoreProductTypeParams/page.mdx": "2025-01-27T11:43:54.211Z", "references/types/HttpTypes/interfaces/types.HttpTypes.StoreProductTypeResponse/page.mdx": "2025-01-27T11:43:54.212Z", "references/types/interfaces/types.BaseProductTypeListParams/page.mdx": "2025-01-27T11:43:54.550Z", - "references/core_flows/Order/Steps_Order/variables/core_flows.Order.Steps_Order.updateOrderChangesStepId/page.mdx": "2025-01-27T11:43:49.278Z" + "references/core_flows/Order/Steps_Order/variables/core_flows.Order.Steps_Order.updateOrderChangesStepId/page.mdx": "2025-01-27T11:43:49.278Z", + "app/troubleshooting/test-errors/page.mdx": "2025-01-31T13:08:42.639Z" } \ No newline at end of file diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index f7895d187ff00..e42188a94a6f6 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -1235,6 +1235,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/troubleshooting/s3/page.mdx", "pathname": "/troubleshooting/s3" }, + { + "filePath": "/www/apps/resources/app/troubleshooting/test-errors/page.mdx", + "pathname": "/troubleshooting/test-errors" + }, { "filePath": "/www/apps/resources/app/troubleshooting/workflow-errors/page.mdx", "pathname": "/troubleshooting/workflow-errors" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 5acc1fa870133..b28897ab3075a 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -17293,6 +17293,14 @@ export const generatedSidebar = [ "path": "/troubleshooting/workflow-errors", "title": "Workflow Errors", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/troubleshooting/test-errors", + "title": "Test Errors", + "children": [] } ] }, diff --git a/www/apps/resources/sidebars/troubleshooting.mjs b/www/apps/resources/sidebars/troubleshooting.mjs index 199928aa283d1..b3d7a7554076e 100644 --- a/www/apps/resources/sidebars/troubleshooting.mjs +++ b/www/apps/resources/sidebars/troubleshooting.mjs @@ -45,6 +45,11 @@ export const troubleshootingSidebar = [ path: "/troubleshooting/workflow-errors", title: "Workflow Errors", }, + { + type: "link", + path: "/troubleshooting/test-errors", + title: "Test Errors", + }, ], }, {