diff --git a/www/apps/book/app/debugging-and-testing/page.mdx b/www/apps/book/app/debugging-and-testing/page.mdx index 45d6d575da..3af9252b31 100644 --- a/www/apps/book/app/debugging-and-testing/page.mdx +++ b/www/apps/book/app/debugging-and-testing/page.mdx @@ -4,10 +4,9 @@ export const metadata = { # {metadata.title} -In the next chapters, you’ll find some tips when debugging and testing your customizations in the Medusa application. +In the next chapters, you’ll learn about the tools Medusa provides for testing and debugging your Medusa application. By the end of this chapter, you’ll learn: +- How to use Medusa's `medusa-test-utils` test to write integration tests. - How to use Medusa’s `Logger` utility to log messages. -- What tools to use for testing and debugging. -- What feature flags are and how to enable them. diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx new file mode 100644 index 0000000000..08cb0f7911 --- /dev/null +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx @@ -0,0 +1,284 @@ +export const metadata = { + title: `${pageNumber} Example: Write Integration Tests for API Routes`, +} + +# {metadata.title} + +In this chapter, you'll learn how to write integration tests for API routes using the [medusaIntegrationTestRunner utility function](../page.mdx). + +## Test a GET API Route + +Consider the following API route created at `src/api/store/custom/route.ts`: + +```ts title="src/api/store/custom/route.ts" +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +){ + res.json({ + message: "Hello, World!" + }) +} +``` + +To write an integration test that tests this API route, create the file `integration-tests/http/custom-routes.spec.ts` with the following content: + +export const getHighlights = [ + ["8", "api.get", "Send a GET request to the `/store/custom` API route."] +] + +```ts title="integration-tests/http/custom-routes.spec.ts" highlights={getHighlights} +import { medusaIntegrationTestRunner } from "medusa-test-utils" + +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + describe("Custom endpoints", () => { + describe("GET /store/custom", () => { + it("returns correct message", async () => { + const response = await api.get( + `/store/custom` + ) + + expect(response.status).toEqual(200) + expect(response.data).toHaveProperty("message") + expect(response.data.message).toEqual("Hello, World!") + }) + }) + }) + } +}) +``` + +You use the `medusaIntegrationTestRunner` to write your tests. + +You add a single test that sends a `GET` request to `/store/custom` using the `api.get` method. For the test to pass, the response is expected to: + +- Have a code status `200`, +- Have a `message` property in the returned data. +- Have the value of the `message` property equal to `Hello, World!`. + +### Run Tests + +Run the following command to run your tests: + +```bash npm2yarn +npm run test:integration +``` + + + +If you don't have a `test:integration` script in `package.json`, refer to the [Medusa Testing Tools chapter](../../page.mdx#add-test-commands). + + + +This runs your Medusa application and runs the tests available under the `src/integrations` directory. + +--- + +## Test a POST API Route + +Suppose you have a `hello` module whose main service extends the service factory, and that has the following model: + +```ts title="src/modules/hello/models/my-custom.ts" +import { model } from "@medusajs/utils" + +const MyCustom = model.define("my_custom", { + id: model.id().primaryKey(), + name: model.text(), +}) + +export default MyCustom +``` + +And consider that the file `src/api/store/custom/route.ts` defines another route handler for `POST` requests: + +```ts title="src/api/store/custom/route.ts" +// other imports... +import HelloModuleService from "../../../modules/hello/service"; + +// ... + +export async function POST( + req: MedusaRequest, + res: MedusaResponse +) { + const helloModuleService: HelloModuleService = req.scope.resolve( + "helloModuleService" + ) + + const myCustom = await helloModuleService.createMyCustoms( + req.body + ) + + res.json({ + my_custom: myCustom + }) +} +``` + +This API route creates a new record of `MyCustom`. + +To write tests for this API route, add the following at the end of the `testSuite` function in `integration-tests/http/custom-routes.spec.ts`: + +export const postHighlights = [ + ["14", "api.post", "Send a POST request to the `/store/custom` API route."] +] + +```ts title="integration-tests/http/custom-routes.spec.ts" highlights={postHighlights} +// other imports... +import HelloModuleService from "../../src/modules/hello/service" + +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + describe("Custom endpoints", () => { + // other tests... + + describe("POST /store/custom", () => { + const id = "1" + + it("Creates my custom", async () => { + + const response = await api.post( + `/store/custom`, + { + id, + name: "Test" + } + ) + + expect(response.status).toEqual(200) + expect(response.data).toHaveProperty("my_custom") + expect(response.data.my_custom).toEqual({ + id, + name: "Test", + created_at: expect.any(String), + updated_at: expect.any(String), + }) + }) + }) + }) + } +}) +``` + +This adds a test for the `POST /store/custom` API route. It uses `api.post` to send the POST request. The `api.post` method accepts as a second parameter the data to pass in the request body. + +The test passes if the response has: + +- Status code `200`. +- A `my_custom` property in its data. +- Its `id` and `name` match the ones provided to the request. + +### Tear Down Created Record + +To ensure consistency in the database for the rest of the tests after the above test is executed, utilize [Jest's setup and teardown hooks](https://jestjs.io/docs/setup-teardown) to delete the created record. + +Use the `getContainer` function passed as a parameter to the `testSuite` function to resolve a service and use it for setup or teardown purposes + +So, add an `afterAll` hook in the `describe` block for `POST /store/custom`: + +```ts title="integration-tests/http/custom-routes.spec.ts" +// other imports... +import HelloModuleService from "../../src/modules/hello/service" + +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + describe("Custom endpoints", () => { + // other tests... + + describe("POST /store/custom", () => { + // ... + afterAll(() => async () => { + const helloModuleService: HelloModuleService = getContainer().resolve( + "helloModuleService" + ) + + await helloModuleService.deleteMyCustoms(id) + }) + }) + }) + } +}) +``` + +The `afterAll` hook resolves the `HelloModuleService` and use its `deleteMyCustoms` to delete the record created by the test. + +--- + +## Test a DELETE API Route + +Consider a `/store/custom/:id` API route created at `src/api/store/custom/[id]/route.ts`: + +```ts title="src/api/store/custom/[id]/route.ts" +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; +import HelloModuleService from "../../../modules/hello/service"; + +export async function DELETE( + req: MedusaRequest, + res: MedusaResponse +) { + const helloModuleService: HelloModuleService = req.scope.resolve( + "helloModuleService" + ) + + await helloModuleService.deleteMyCustoms(req.params.id) + + res.json({ + success: true + }) +} +``` + +This API route accepts an ID path parameter, and uses the `HelloModuleService` to delete a `MyCustom` record by that ID. + +To add tests for this API route, add the following to `integration-tests/http/custom-routes.spec.ts`: + +export const deleteHighlights = [ + ["21", "api.delete", "Send a DELETE request to the `/store/custom/:id` API route."] +] + +```ts title="integration-tests/http/custom-routes.spec.ts" highlights={deleteHighlights} +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + describe("Custom endpoints", () => { + // ... + + describe("DELETE /store/custom/:id", () => { + const id = "1" + + beforeAll(() => async () => { + const helloModuleService: HelloModuleService = getContainer().resolve( + "helloModuleService" + ) + + await helloModuleService.createMyCustoms({ + id, + name: "Test" + }) + }) + + it("Deletes my custom", async () => { + const response = await api.delete( + `/store/custom/${id}` + ) + + expect(response.status).toEqual(200) + expect(response.data).toHaveProperty("success") + expect(response.data.success).toBeTruthy() + }) + }) + }) + } +}) +``` + +This adds a new test for the `DELETE /store/custom/:id` API route. You use the `beforeAll` hook to create a `MyCustom` record using the `HelloModuleService`. + +In the test, you use the `api.delete` method to send a `DELETE` request to `/store/custom/:id`. The test passes if the response: + +- Has a `200` status code. +- Has a `success` property in its data. +- The `success` property's value is true. + diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx new file mode 100644 index 0000000000..0116a1ce34 --- /dev/null +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx @@ -0,0 +1,58 @@ +export const metadata = { + title: `${pageNumber} Write Integration Tests`, +} + +# {metadata.title} + +In this chapter, you'll learn about the `medusaIntegrationTestRunner` utility function used to write integration tests. + +## medusaIntegrationTestRunner Utility + +The `medusaIntegrationTestRunner` utility function is provided by the `medusa-test-utils` package to create integration tests in your Medusa project. It runs a full Medusa application, allowing you test API routes, workflows, or other customizations. + +For example: + +export const highlights = [ + ["4", "api", "A set of utility methods used to send requests to the Medusa application."], + ["4", "getContainer", "A function to retrieve the Medusa container."] +] + +```ts title="integration-tests/http/test.spec.ts" highlights={highlights} +import { medusaIntegrationTestRunner } from "medusa-test-utils" + +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + // TODO write tests... + } +}) +``` + +The `medusaIntegrationTestRunner` function accepts an object as a parameter. The object has a required property `testSuite`. + +`testSuite`'s value is a function that defines the tests to run. The function accepts as a parameter an object that has the following properties: + +- `api`: a set of utility methods used to send requests to the Medusa application. It has the following methods: + - `get`: Send a `GET` request to an API route. + - `post`: Send a `POST` request to an API route. + - `delete`: Send a `DELETE` request to an API route. +- `getContainer`: a function that retrieves the Medusa Container. Use the `getContainer().resolve` method to resolve resources from the Medusa Container. + +The tests in the `testSuite` function are written using [Jest](https://jestjs.io/). + +### Other Options and Inputs + +Refer to [this reference in the Learning Resources documentation](!resources!/test-tools-reference/medusaIntegrationTestRunner) for other available parameter options and inputs of the `testSuite` function. + +--- + +## Database Used in Tests + +The `medusaIntegrationTestRunner` function creates a database with a random name before running the tests. Then, it drops that database after all the tests end. + +To manage that database, such as changing its name or perform operations on it in your tests, refer to the [references in the Learning Resources documentation](!resources!/test-tools-reference/medusaIntegrationTestRunner). + +--- + +## Example Integration Tests + +The next chapters provide examples of writing integration tests for API routes and workflows. diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx new file mode 100644 index 0000000000..905c7797f4 --- /dev/null +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx @@ -0,0 +1,73 @@ +export const metadata = { + title: `${pageNumber} Example: Write Integration Tests for Workflows`, +} + +# {metadata.title} + +In this chapter, you'll learn how to write integration tests for workflows using the [medusaIntegrationTestRunner utility function](../page.mdx). + +## Write Integration Test for Workflow + +Consider you have the following workflow defined at `src/workflows/hello-world.ts`: + +```ts title="src/workflows/hello-world.ts" +import { + createWorkflow, + createStep, + StepResponse, + WorkflowResponse +} from "@medusajs/workflows-sdk" + +const step1 = createStep("step-1", () => { + return new StepResponse("Hello, World!") +}) + +export const helloWorldWorkflow = createWorkflow( + "hello-world-workflow", + () => { + const message = step1() + + return new WorkflowResponse(message) + } +) +``` + +To write a test for this workflow, create the file `integration-tests/http/workflow.spec.ts` with the following content: + +```ts title="integration-tests/http/workflow.spec.ts" +import { medusaIntegrationTestRunner } from "medusa-test-utils" +import { helloWorldWorkflow } from "../../src/workflows/hello-world" + +medusaIntegrationTestRunner({ + testSuite: ({ getContainer }) => { + describe("Test hello-world workflow", () => { + it("returns message", async () => { + const { result } = await helloWorldWorkflow(getContainer()) + .run() + + expect(result).toEqual("Hello, World!") + }) + }) + } +}) +``` + +You use the `medusaIntegrationTestRunner` to write an integration test for the workflow. The test pases if the workflow returns the string `"Hello, World!"`. + +--- + +## Run Test + +Run the following command to run your tests: + +```bash npm2yarn +npm run test:integration +``` + + + +If you don't have a `test:integration` script in `package.json`, refer to the [Medusa Testing Tools chapter](../../page.mdx#add-test-commands). + + + +This runs your Medusa application and runs the tests available under the `integrations/http` directory. diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx new file mode 100644 index 0000000000..606d7f8291 --- /dev/null +++ b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx @@ -0,0 +1,70 @@ +export const metadata = { + title: `${pageNumber} Example: Integration Tests for a Module`, +} + +# {metadata.title} + +In this chapter, find an example of writing an integration test for a module using the [moduleIntegrationTestRunner utility function](../page.mdx). + +## Write Integration Test for Module + +Consider a `hello` module with a `HelloModuleService` that has a `getMessage` method: + +```ts title="src/modules/hello/service.ts" +import { MedusaService } from "@medusajs/utils" +import MyCustom from "./models/my-custom" + +class HelloModuleService extends MedusaService({ + MyCustom, +}){ + getMessage(): string { + return "Hello, World!" + } +} + +export default HelloModuleService +``` + +To create an integration test for the method, create the file `src/modules/hello/__tests__/service.spec.ts` with the following content: + +```ts title="src/modules/hello/__tests__/service.spec.ts" +import { moduleIntegrationTestRunner } from "medusa-test-utils" +import { HELLO_MODULE } from ".." +import HelloModuleService from "../service" +import MyCustom from "../models/my-custom" + +moduleIntegrationTestRunner({ + moduleName: HELLO_MODULE, + moduleModels: [MyCustom], + resolve: "./modules/hello", + testSuite: ({ service }) => { + describe("HelloModuleService", () => { + it("says hello world", () => { + const message = service.getMessage() + + expect(message).toEqual("Hello, World!") + }) + }) + } +}) +``` + +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. + +--- + +## Run Test + +Run the following command to run your module integration tests: + +```bash npm2yarn +npm run test: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). + + + +This runs your Medusa application and runs the tests available in any `__tests__` directory under the `src` directory. diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx new file mode 100644 index 0000000000..9be6ef07fe --- /dev/null +++ b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx @@ -0,0 +1,101 @@ +export const metadata = { + title: `${pageNumber} Write Tests for Modules`, +} + +# {metadata.title} + +In this chapter, you'll learn about the `moduleIntegrationTestRunner` utility function and how to use it to write integration tests for a module's main service. + +## moduleIntegrationTestRunner Utility + +The `moduleIntegrationTestRunner` utility function is provided by the `medusa-test-utils` package to create integration tests for a module. The integration tests run on a test Medusa application with only the specified module enabled. + +For example, assuming you have a `hello` module, create a test file at `src/modules/hello/__tests__/service.spec.ts`: + +```ts title="src/modules/hello/__tests__/service.spec.ts" +import { moduleIntegrationTestRunner } from "medusa-test-utils" +import { HELLO_MODULE } from ".." +import HelloModuleService from "../service" +import MyCustom from "../models/my-custom" + +moduleIntegrationTestRunner({ + moduleName: HELLO_MODULE, + moduleModels: [MyCustom], + resolve: "./modules/hello", + testSuite: ({ service }) => { + // TODO write tests + } +}) +``` + +The `moduleIntegrationTestRunner` function accepts as a parameter an object with the following properties: + +- `moduleName`: The name of the module. +- `moduleModels`: An array of models in the module. Refer to [this section](#write-tests-for-modules-without-data-models) if your module doesn't have data models. +- `resolve`: The path to the model relative to the `src` directory. +- `testSuite`: A function that defines the tests to run. + +The `testSuite` function accepts as a parameter an object having the `service` property, which is an instance of the module's main service. + + + +The type argument provided to the `moduleIntegrationTestRunner` function is used as the type of the `service` property. + + + +The tests in the `testSuite` function are written using [Jest](https://jestjs.io/). + +--- + +## Pass Module Options + +If your module accepts options, you can set them using the `moduleOptions` property of the `moduleIntegrationTestRunner`'s parameter. + +For example: + +```ts +import { moduleIntegrationTestRunner } from "medusa-test-utils" +import HelloModuleService from "../service" + +moduleIntegrationTestRunner({ + moduleOptions: { + apiKey: "123" + }, + // ... +}) +``` + +--- + +## Write Tests for Modules without Data Models + +If your module doesn't have a data model, pass a dummy model in the `moduleModels` property. + +For example: + +```ts +import { moduleIntegrationTestRunner } from "medusa-test-utils" +import HelloModuleService from "../service" +import { model } from "@medusajs/utils" + +const DummyModel = model.define("dummy_model", {}) + +moduleIntegrationTestRunner({ + moduleModels: [DummyModel], + // ... +}) +``` + +--- + +### Other Options and Inputs + +Refer to [this reference in the Learning Resources documentation](!resources!/test-tools-reference/moduleIntegrationTestRunner) for other available parameter options and inputs of the `testSuite` function. + +--- + +## Database Used in Tests + +The `moduleIntegrationTestRunner` function creates a database with a random name before running the tests. Then, it drops that database after all the tests end. + +To manage that database, such as changing its name or perform operations on it in your tests, refer to the [references in the Learning Resources documentation](!resources!/test-tools-reference/moduleIntegrationTestRunner). diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx new file mode 100644 index 0000000000..33594e2a36 --- /dev/null +++ b/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx @@ -0,0 +1,103 @@ +export const metadata = { + title: `${pageNumber} Medusa Testing Tools`, +} + +# {metadata.title} + +In this chapter, you'll learn about Medusa's testing tools and how to install and configure them. + +## medusa-test-utils Package + +Medusa provides a `medusa-test-utils` package with utility tools to create integration tests for your custom API routes, modules, or other Medusa customizations. + +### Install medusa-test-utils + +To use the `medusa-test-utils` package, install it as a `devDependency`: + +```bash npm2yarn +npm install --save-dev medusa-test-utils +``` + +--- + +## Install and Configure Jest + +Writing tests with `medusa-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 +npm install --save-dev jest @types/jest @swc/jest +``` + +Then, create the file `jest.config.js` with the following content: + +```js title="jest.config.js" +const { loadEnv } = require('@medusajs/utils') +loadEnv('test', process.cwd()) + +module.exports = { + transform: { + "^.+\\.[jt]s$": [ + "@swc/jest", + { + jsc: { + parser: { syntax: "typescript", decorators: true }, + }, + }, + ], + }, + testEnvironment: "node", + moduleFileExtensions: ["js", "ts", "json"], + modulePathIgnorePatterns: ["dist/"], +} + +if (process.env.TEST_TYPE === "integration:http") { + module.exports.testMatch = ["**/integration-tests/http/*.spec.[jt]s"] +} else if (process.env.TEST_TYPE === "integration:modules") { + module.exports.testMatch = ["**/src/modules/*/__tests__/**/*.[jt]s"] +} else if (process.env.TEST_TYPE === "unit") { + module.exports.testMatch = ["**/src/**/__tests__/**/*.unit.spec.[jt]s"] +} +``` + +--- + +## Add Test Commands + +Finally, add the following scripts to `package.json`: + +```json title="package.json" +"scripts": { + // ... + "test:integration:http": "TEST_TYPE=integration:http NODE_OPTIONS=--experimental-vm-modules jest --silent=false --runInBand --forceExit", + "test:integration:modules": "TEST_TYPE=integration:modules NODE_OPTIONS=--experimental-vm-modules jest --silent --runInBand --forceExit", + "test:unit": "TEST_TYPE=unit NODE_OPTIONS=--experimental-vm-modules jest --silent --runInBand --forceExit" +}, +``` + +You now have two commands: + +- `test:integration:http` to run integration tests (for example, for API routes and workflows) available under the `integration-tests/http` directory. +- `test:integration:modules` to run integration tests for modules available in any `__tests__` directory under `src/modules`. +- `test:unit` to run unit tests in any `__tests` directory under the `src` directory. + + + +Unit tests aren't covered by Medusa's testing tools. + + + +--- + +## Test Tools and Writing Tests + +The next chapters explain how to use the testing tools provided by `medusa-test-utils` to write tests. diff --git a/www/apps/book/app/debugging-and-testing/tools/page.mdx b/www/apps/book/app/debugging-and-testing/tools/page.mdx deleted file mode 100644 index ac54170415..0000000000 --- a/www/apps/book/app/debugging-and-testing/tools/page.mdx +++ /dev/null @@ -1,66 +0,0 @@ -export const metadata = { - title: `${pageNumber} Debugging and Testing Tools`, -} - -# {metadata.title} - -In this chapter, you’ll learn about debugging and testing tools you can use. - - - -Since the Medusa server is a Node.js server, you can use any Node.js testing tool you prefer, even if it’s not listed here. - - - -## Jest - -[Jest](https://jestjs.io/) is a JavaScript testing framework. Your Medusa project is already configured with Jest; you can use it out-of-the-box. - - - -Refer to [Jest's documentation](https://jestjs.io/docs/getting-started) to learn how to install and configure it. - - - -For example, consider the following service created at `src/modules/hello/service.ts`: - -```ts title="src/modules/hello/service.ts" -class HelloModuleService { - getMessage(): string { - return "Hello, world!" - } -} - -export default HelloModuleService - -``` - -You can write a test for it in the file `src/modules/hello/__tests__/hello-world.spec.ts`: - -```ts title="src/modules/hello/__tests__/hello-world.spec.ts" -import HelloModuleService from "../service" - -describe("HelloModuleService", () => { - const helloModuleService = new HelloModuleService() - - it("should return hello world message", () => { - expect(helloModuleService.getMessage()).toBe("Hello, world!") - }) -}) -``` - ---- - -## IDE Debugging Tools - -Your IDE may provide a debugging tool for Node.js. In that case, you can use that tool to debug your Medusa customizations. - -For example, if you’re using VSCode, refer to [this guide](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) to learn how to configure and use the debugger. - ---- - -## Node.js Debugger - -You can also use Node.js’s Debugger API to debug your Medusa customizations. - -Refer to [Node.js’s documentation](https://nodejs.org/docs/latest-v18.x/api/debugger.html) for more details. diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index c3f02492c5..e143fbe48a 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -9,7 +9,6 @@ export const generatedEditDates = { "app/advanced-development/workflows/workflow-hooks/page.mdx": "2024-08-13T09:55:37+03:00", "app/cheatsheet/page.mdx": "2024-07-11T13:53:40+03:00", "app/debugging-and-testing/logging/page.mdx": "2024-07-04T17:26:03+03:00", - "app/debugging-and-testing/tools/page.mdx": "2024-07-04T17:26:03+03:00", "app/more-resources/page.mdx": "2024-07-04T17:26:03+03:00", "app/storefront-development/page.mdx": "2024-07-04T17:26:03+03:00", "app/storefront-development/nextjs-starter/page.mdx": "2024-07-04T17:26:03+03:00", @@ -19,6 +18,8 @@ export const generatedEditDates = { "app/advanced-development/workflows/parallel-steps/page.mdx": "2024-07-31T17:01:33+03:00", "app/advanced-development/page.mdx": "2024-07-04T17:26:03+03:00", "app/first-customizations/page.mdx": "2024-05-07T18:00:28+02:00", + "app/debugging-and-testing/page.mdx": "2024-09-02T11:06:13.298Z", + "app/basics/medusa-container/page.mdx": "2024-08-05T07:24:27+00:00", "app/debugging-and-testing/page.mdx": "2024-05-03T17:36:38+03:00", "app/basics/medusa-container/page.mdx": "2024-09-03T07:31:40.214Z", "app/architectural-modules/page.mdx": "2024-07-04T17:26:03+03:00", @@ -66,5 +67,11 @@ export const generatedEditDates = { "app/advanced-development/data-models/configure-properties/page.mdx": "2024-07-04T17:26:03+03:00", "app/advanced-development/data-models/index/page.mdx": "2024-07-04T17:26:03+03:00", "app/advanced-development/custom-cli-scripts/page.mdx": "2024-07-04T17:26:03+03:00", - "app/advanced-development/data-models/property-types/page.mdx": "2024-07-04T17:26:03+03:00" + "app/advanced-development/data-models/property-types/page.mdx": "2024-07-04T17:26:03+03:00", + "app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-09-02T10:57:08.040Z", + "app/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-09-02T10:56:09.872Z", + "app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-09-02T10:57:04.202Z", + "app/debugging-and-testing/testing-tools/page.mdx": "2024-09-02T10:08:29.388Z", + "app/debugging-and-testing/testing-tools/unit-tests/module-example/page.mdx": "2024-09-02T11:04:27.232Z", + "app/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z" } \ No newline at end of file diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index 9fb5d2960c..3d82e99d2b 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -370,13 +370,42 @@ export const sidebar = numberSidebarItems( children: [ { type: "link", - path: "/debugging-and-testing/logging", - title: "Logging", + path: "/debugging-and-testing/testing-tools", + title: "Testing Tools", }, { type: "link", - path: "/debugging-and-testing/tools", - title: "Tools", + path: "/debugging-and-testing/testing-tools/integration-tests", + title: "Integration Tests", + children: [ + { + type: "link", + path: "/debugging-and-testing/testing-tools/integration-tests/api-routes", + title: "Example: API Routes Tests", + }, + { + type: "link", + path: "/debugging-and-testing/testing-tools/integration-tests/workflows", + title: "Example: Workflows Tests", + }, + ], + }, + { + type: "link", + path: "/debugging-and-testing/testing-tools/modules-tests", + title: "Modules Tests", + children: [ + { + type: "link", + path: "/debugging-and-testing/testing-tools/unit-tests/module-example", + title: "Example", + }, + ], + }, + { + type: "link", + path: "/debugging-and-testing/logging", + title: "Logging", }, ], }, diff --git a/www/apps/resources/app/test-tools-reference/medusaIntegrationTestRunner/page.mdx b/www/apps/resources/app/test-tools-reference/medusaIntegrationTestRunner/page.mdx new file mode 100644 index 0000000000..d074f76be6 --- /dev/null +++ b/www/apps/resources/app/test-tools-reference/medusaIntegrationTestRunner/page.mdx @@ -0,0 +1,152 @@ +import { TypeList } from "docs-ui" + +export const metadata = { + title: `medusaIntegrationTestRunner Reference`, +} + +# {metadata.title} + +This document provides a reference to the `medusaIntegrationTestRunner` function provided by the `medusa-test-utils` package. + +## Example + +```ts +import { medusaIntegrationTestRunner } from "medusa-test-utils" + +medusaIntegrationTestRunner({ + testSuite: ({ api, getContainer }) => { + // TODO write tests... + } +}) +``` + +## Parameters + + void`", + name: "testSuite", + description: "The Jest tests to run.", + optional: false + }, + { + type: "`string`", + name: "dbName", + description: "A name to use for the database. By default, a random name is generated.", + }, + { + type: "`string`", + name: "schema", + description: "The PostgreSQL schema that the database is created in.", + }, + { + type: "`Record`", + name: "env", + description: "Environment variables to use in the test suite." + }, + { + type: "`boolean`", + name: "debug", + description: "Whether to show database log messages.", + defaultValue: "false" + } + ] + } + ]} + sectionTitle="Parameters" +/> + +## Test Suite Parameters + +The function passed to `testSuite` accepts the following parameters: + +", + name: "api", + description: "A set of methods used to send requests to the Medusa application.", + optional: false, + children: [ + { + type: "(path: string) => Promise", + name: "get", + description: "Send a GET request to the specified path." + }, + { + type: "(path: string, data?: any) => Promise", + name: "post", + description: "Send a POST request to the specified path." + }, + { + type: "(path: string) => Promise", + name: "delete", + description: "Send a DELETE request to the specified path." + }, + ] + }, + { + type: "`() => MedusaContainer`", + name: "getContainer", + description: "A name to use for the database. By default, a random name is generated.", + }, + { + type: "`Record`", + name: "dbConfig", + description: "The created database's configurations", + children: [ + { + type: "`string`", + name: "dbName", + description: "The database's name." + }, + { + type: "`string`", + name: "schema", + description: "The PostgreSQL schema the database is created in." + }, + { + type: "`string`", + name: "clientUrl", + description: "The connection URL to the database." + }, + ] + }, + { + type: "`Record`", + name: "dbUtils", + description: "A set of methods to manage the database", + children: [ + { + type: "`(dbName: string) => Promise`", + name: "create", + description: "Creates a database." + }, + { + type: "`(options: { schema?: string }) => Promise`", + name: "teardown", + description: "Deletes all data in a database's tables." + }, + { + type: "`(dbName: string) => Promise`", + name: "shutdown", + description: "Drops a database." + }, + ] + } + ] + } + ]} + sectionTitle="Test Suite Parameters" +/> diff --git a/www/apps/resources/app/test-tools-reference/moduleIntegrationTestRunner/page.mdx b/www/apps/resources/app/test-tools-reference/moduleIntegrationTestRunner/page.mdx new file mode 100644 index 0000000000..cd3afb3d06 --- /dev/null +++ b/www/apps/resources/app/test-tools-reference/moduleIntegrationTestRunner/page.mdx @@ -0,0 +1,154 @@ +import { TypeList } from "docs-ui" + +export const metadata = { + title: `moduleIntegrationTestRunner Reference`, +} + +# {metadata.title} + +This document provides a reference to the `moduleIntegrationTestRunner` function provided by the `medusa-test-utils` package. + +## Example + +```ts +import { moduleIntegrationTestRunner } from "medusa-test-utils" +import { HELLO_MODULE } from ".." +import HelloModuleService from "../service" +import MyCustom from "../models/my-custom" + +moduleIntegrationTestRunner({ + moduleName: HELLO_MODULE, + moduleModels: [MyCustom], + resolve: "./modules/hello", + testSuite: ({ service }) => { + // TODO write tests + } +}) +``` + +## Parameters + + void`", + name: "testSuite", + description: "The Jest tests to run.", + optional: false + }, + { + type: "`Record`", + name: "moduleOptions", + description: "Options to pass to the module.", + }, + { + type: "`Record`", + name: "injectedDependencies", + description: "Dependencies to inject into the module's container. They key is the registration name, and the value is the instance of the dependency.", + }, + { + type: "`string`", + name: "schema", + description: "The PostgreSQL schema that the database is created in.", + }, + { + type: "`boolean`", + name: "debug", + description: "Whether to show database log messages.", + defaultValue: "false" + } + ] + } + ]} + sectionTitle="Parameters" +/> + +## Test Suite Parameters + +The function passed to `testSuite` accepts the following parameters: + +`", + name: "dbConfig", + description: "The created database's configurations", + children: [ + { + type: "`string`", + name: "schema", + description: "The PostgreSQL schema the database is created in." + }, + { + type: "`string`", + name: "clientUrl", + description: "The connection URL to the database." + }, + ] + }, + { + type: "`TestDatabase`", + name: "MikroOrmWrapper", + description: "Utility functions to query and manage the database.", + children: [ + { + type: `[SqlEntityManager](https://mikro-orm.io/api/5.9/knex/class/EntityManager)`, + name: "manager", + description: "An instance of MikroORM's entity manager, which can be used to run queries and perform other database tasks." + }, + { + type: "`() => Promise`", + name: "setupDatabase", + description: "Creates the database for the test." + }, + { + type: "`() => Promise`", + name: "clearDatabase", + description: "Removes all data in the database's tables." + }, + { + type: "`() => SqlEntityManager`", + name: "forkManager", + description: "Returns a new entity manager." + } + ] + } + ] + } + ]} + sectionTitle="Test Suite Parameters" +/> diff --git a/www/apps/resources/app/test-tools-reference/page.mdx b/www/apps/resources/app/test-tools-reference/page.mdx new file mode 100644 index 0000000000..62068c3a08 --- /dev/null +++ b/www/apps/resources/app/test-tools-reference/page.mdx @@ -0,0 +1,11 @@ +import { ChildDocs } from "docs-ui" + +export const metadata = { + title: `Medusa Test Functions Reference`, +} + +# {metadata.title} + +This section of the documentation provides a reference to the testing functions provided by the `medusa-test-utils` package. + + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index a141e1abc4..7e7de7a858 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -773,6 +773,9 @@ export const generatedEditDates = { "references/types/HttpTypes/interfaces/types.HttpTypes.AdminWorkflowExecution/page.mdx": "2024-08-30T00:11:02.510Z", "references/types/HttpTypes/interfaces/types.HttpTypes.AdminWorkflowExecutionResponse/page.mdx": "2024-08-30T00:11:02.514Z", "references/types/interfaces/types.BaseReturnItem/page.mdx": "2024-08-30T00:11:02.538Z", + "app/test-tools-reference/medusaIntegrationTestRunner/page.mdx": "2024-09-02T12:12:48.492Z", + "app/test-tools-reference/moduleIntegrationTestRunner/page.mdx": "2024-09-02T12:18:33.134Z", + "app/test-tools-reference/page.mdx": "2024-09-02T12:25:44.922Z", "references/types/HttpTypes/interfaces/types.HttpTypes.AdminGetInvitesParams/page.mdx": "2024-09-03T00:10:55.319Z", "references/types/HttpTypes/interfaces/types.HttpTypes.AdminInventoryLevel/page.mdx": "2024-09-03T00:10:55.295Z", "references/types/HttpTypes/interfaces/types.HttpTypes.BaseAddress/page.mdx": "2024-09-03T00:10:55.003Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 70c48d80af..42d3e64f62 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -1011,6 +1011,18 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/storefront-development/tips/page.mdx", "pathname": "/storefront-development/tips" }, + { + "filePath": "/www/apps/resources/app/test-tools-reference/medusaIntegrationTestRunner/page.mdx", + "pathname": "/test-tools-reference/medusaIntegrationTestRunner" + }, + { + "filePath": "/www/apps/resources/app/test-tools-reference/moduleIntegrationTestRunner/page.mdx", + "pathname": "/test-tools-reference/moduleIntegrationTestRunner" + }, + { + "filePath": "/www/apps/resources/app/test-tools-reference/page.mdx", + "pathname": "/test-tools-reference" + }, { "filePath": "/www/apps/resources/app/troubleshooting/cors-errors/page.mdx", "pathname": "/troubleshooting/cors-errors" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 4b20eff7a1..0a2694e4c6 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -13987,6 +13987,40 @@ export const generatedSidebar = [ "initialOpen": false } ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Testing Tools Reference", + "path": "/test-tools-reference", + "isChildSidebar": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Functions", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "medusaIntegrationTestRunner", + "path": "/test-tools-reference/medusaIntegrationTestRunner", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "moduleIntegrationTestRunner", + "path": "/test-tools-reference/moduleIntegrationTestRunner", + "children": [] + } + ] + } + ] } ] }, diff --git a/www/apps/resources/sidebar.mjs b/www/apps/resources/sidebar.mjs index 52ceeb8b17..dd5ed53d11 100644 --- a/www/apps/resources/sidebar.mjs +++ b/www/apps/resources/sidebar.mjs @@ -2343,6 +2343,30 @@ export const sidebar = sidebarAttachHrefCommonOptions([ isChildSidebar: true, custom_autogenerate: "core-flows", }, + { + type: "link", + title: "Testing Tools Reference", + path: "/test-tools-reference", + isChildSidebar: true, + children: [ + { + type: "category", + title: "Functions", + children: [ + { + type: "link", + title: "medusaIntegrationTestRunner", + path: "/test-tools-reference/medusaIntegrationTestRunner", + }, + { + type: "link", + title: "moduleIntegrationTestRunner", + path: "/test-tools-reference/moduleIntegrationTestRunner", + }, + ], + }, + ], + }, ], }, { diff --git a/www/vale/styles/docs/ModuleNames.yml b/www/vale/styles/docs/ModuleNames.yml index 609fef20bd..750a25d20c 100644 --- a/www/vale/styles/docs/ModuleNames.yml +++ b/www/vale/styles/docs/ModuleNames.yml @@ -16,4 +16,5 @@ exceptions: - the link module - the first module - the second module - - the module provider \ No newline at end of file + - the module provider + - the specified module \ No newline at end of file