docs: added authentication in integration tests (#11363)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Prerequisites } from "docs-ui"
|
||||
import { Prerequisites, CodeTabs, CodeTab } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Example: Write Integration Tests for API Routes`,
|
||||
@@ -312,6 +312,8 @@ Some requests require passing headers. For example, all routes prefixed with `/s
|
||||
|
||||
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.
|
||||
|
||||
### Pass Publishable API Key
|
||||
|
||||
For example, to pass a publishable API key in the header for a request to a `/store` route:
|
||||
|
||||
export const headersHighlights = [
|
||||
@@ -367,3 +369,197 @@ 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.
|
||||
|
||||
### Send Authenticated Requests
|
||||
|
||||
If your custom route is accessible by authenticated users only, such as routes prefixed by `/admin` or `/store/customers/me`, you can create a test customer or user, generate a JWT token for them, and pass the token in the request's Authorization header.
|
||||
|
||||
For example:
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
For custom actor types, you only need to change the `actorType` value in the `jwt.sign` method.
|
||||
|
||||
</Note>
|
||||
|
||||
<CodeTabs group="user-type">
|
||||
<CodeTab label="Admin User" value="admin">
|
||||
|
||||
export const adminHighlights = [
|
||||
["8", "headers", "Define the headers that you'll pass in the request."],
|
||||
["10", "beforeEach", "Run before every test."],
|
||||
["16", "user", "Create the admin user."],
|
||||
["20", "authIdentity", "Create the auth identity for the user."],
|
||||
["35", "token", "Generate a JWT token for the user."],
|
||||
["47", "headers", "Set the token in the Authorization header."],
|
||||
["52", "headers", "Pass the headers to the request."]
|
||||
]
|
||||
|
||||
```ts title="integration-tests/http/custom-routes.spec.ts" highlights={adminHighlights}
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import jwt from "jsonwebtoken"
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
testSuite: ({ api, getContainer }) => {
|
||||
describe("Custom endpoints", () => {
|
||||
describe("GET /custom", () => {
|
||||
const headers: Record<string, string> = {
|
||||
}
|
||||
beforeEach(async () => {
|
||||
const container = getContainer()
|
||||
|
||||
const authModuleService = container.resolve("auth")
|
||||
const userModuleService = container.resolve("user")
|
||||
|
||||
const user = await userModuleService.createUsers({
|
||||
email: "admin@medusa.js",
|
||||
|
||||
})
|
||||
const authIdentity = await authModuleService.createAuthIdentities({
|
||||
provider_identities: [
|
||||
{
|
||||
provider: "emailpass",
|
||||
entity_id: "admin@medusa.js",
|
||||
provider_metadata: {
|
||||
password: "supersecret"
|
||||
}
|
||||
}
|
||||
],
|
||||
app_metadata: {
|
||||
user_id: user.id
|
||||
}
|
||||
})
|
||||
|
||||
const token = jwt.sign(
|
||||
{
|
||||
actor_id: user.id,
|
||||
actor_type: "user",
|
||||
auth_identity_id: authIdentity.id,
|
||||
},
|
||||
"supersecret",
|
||||
{
|
||||
expiresIn: "1d",
|
||||
}
|
||||
)
|
||||
|
||||
headers["authorization"] = `Bearer ${token}`
|
||||
})
|
||||
it("returns correct message", async () => {
|
||||
const response = await api.get(
|
||||
`/admin/custom`,
|
||||
{ headers }
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
jest.setTimeout(60 * 1000)
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="Customer User" value="customer">
|
||||
|
||||
export const customerHighlights = [
|
||||
["10", "headers", "Define the headers that you'll pass in the request."],
|
||||
["12", "beforeEach", "Run before every test."],
|
||||
["18", "customer", "Create the customer."],
|
||||
["22", "authIdentity", "Create the auth identity for the customer."],
|
||||
["37", "token", "Generate a JWT token for the customer."],
|
||||
["49", "headers", "Set the token in the Authorization header."],
|
||||
["52", "pak", "Create a publishable API key"],
|
||||
["64", "headers", "Set the publishable API key in the request's header."],
|
||||
["69", "headers", "Pass the headers to the request."]
|
||||
]
|
||||
|
||||
```ts title="integration-tests/http/custom-routes.spec.ts" highlights={customerHighlights}
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { ApiKeyDTO } from "@medusajs/framework/types"
|
||||
import jwt from "jsonwebtoken"
|
||||
import { createApiKeysWorkflow } from "@medusajs/medusa/core-flows"
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
testSuite: ({ api, getContainer }) => {
|
||||
describe("Custom endpoints", () => {
|
||||
describe("GET /custom", () => {
|
||||
const headers: Record<string, string> = {
|
||||
}
|
||||
beforeEach(async () => {
|
||||
const container = getContainer()
|
||||
|
||||
const authModuleService = container.resolve("auth")
|
||||
const customerModuleService = container.resolve("customer")
|
||||
|
||||
const customer = await customerModuleService.createCustomers({
|
||||
email: "admin@medusa.js",
|
||||
|
||||
})
|
||||
const authIdentity = await authModuleService.createAuthIdentities({
|
||||
provider_identities: [
|
||||
{
|
||||
provider: "emailpass",
|
||||
entity_id: "customer@medusa.js",
|
||||
provider_metadata: {
|
||||
password: "supersecret"
|
||||
}
|
||||
}
|
||||
],
|
||||
app_metadata: {
|
||||
user_id: customer.id
|
||||
}
|
||||
})
|
||||
|
||||
const token = jwt.sign(
|
||||
{
|
||||
actor_id: customer.id,
|
||||
actor_type: "customer",
|
||||
auth_identity_id: authIdentity.id,
|
||||
},
|
||||
"supersecret",
|
||||
{
|
||||
expiresIn: "1d",
|
||||
}
|
||||
)
|
||||
|
||||
headers["authorization"] = `Bearer ${token}`
|
||||
|
||||
|
||||
const pak = (await createApiKeysWorkflow(getContainer()).run({
|
||||
input: {
|
||||
api_keys: [
|
||||
{
|
||||
type: "publishable",
|
||||
title: "Test Key",
|
||||
created_by: ""
|
||||
}
|
||||
]
|
||||
}
|
||||
})).result[0]
|
||||
|
||||
headers["x-publishable-api-key"] = pak.token
|
||||
})
|
||||
it("returns correct message", async () => {
|
||||
const response = await api.get(
|
||||
`/store/customers/me/custom`,
|
||||
{ headers }
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
jest.setTimeout(60 * 1000)
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
In the test suite, you add a `beforeEach` hook that creates a user or customer, an auth identity, and generates a JWT token for them. The JWT token is then set in the `Authorization` header of the request.
|
||||
|
||||
You also create and pass a publishable API key in the header for the customer as it's required for requests to `/store` routes. Learn more in [this section](#pass-publishable-api-key).
|
||||
|
||||
Reference in New Issue
Block a user