saleor-app-sdk-REDIS_APL/src/handlers/next/create-app-register-handler.test.ts
2023-02-28 13:54:58 +01:00

264 lines
8.4 KiB
TypeScript

import { createMocks } from "node-mocks-http";
import { describe, expect, it, Mock, vi } from "vitest";
import { APL, AuthData } from "../../APL";
import { createAppRegisterHandler } from "./create-app-register-handler";
const mockJwksValue = "{}";
const mockAppId = "42";
vi.mock("../../get-app-id", () => ({
getAppId: vi.fn().mockResolvedValue("42"), // can't use var reference, due to hoisting
}));
vi.mock("../../fetch-remote-jwks", () => ({
fetchRemoteJwks: vi.fn().mockResolvedValue("{}"), // can't use var reference, due to hoisting
}));
const mockApl: APL = {
get: vi.fn(),
set: vi.fn(),
delete: vi.fn(),
getAll: vi.fn(),
isReady: vi.fn().mockImplementation(async () => ({
ready: true,
})),
isConfigured: vi.fn().mockImplementation(async () => ({
configured: true,
})),
};
describe("create-app-register-handler", () => {
it("Sets auth data for correct request", async () => {
const { res, req } = createMocks({
/**
* Use body, instead of params, otherwise - for some reason - param is not accessible in mock request
* Maybe this is a bug https://github.com/howardabrams/node-mocks-http/blob/master/lib/mockRequest.js
*/
body: {
auth_token: "mock-auth-token",
},
headers: {
host: "some-saleor-host.cloud",
"x-forwarded-proto": "https",
"saleor-api-url": "https://mock-saleor-domain.saleor.cloud/graphql/",
"saleor-domain": "https://mock-saleor-domain.saleor.cloud/",
},
method: "POST",
});
const handler = createAppRegisterHandler({
apl: mockApl,
});
await handler(req, res);
/**
* It fails -> params.auth_token isn't present
*/
expect(mockApl.set).toHaveBeenCalledWith({
saleorApiUrl: "https://mock-saleor-domain.saleor.cloud/graphql/",
domain: "https://mock-saleor-domain.saleor.cloud/",
token: "mock-auth-token",
appId: "42",
jwks: "{}",
});
});
it("Returns 403 if configured to work only for specific saleor URL and try to install on prohibited one", async () => {
const { res, req } = createMocks({
/**
* Use body, instead of params, otherwise - for some reason - param is not accessible in mock request
* Maybe this is a bug https://github.com/howardabrams/node-mocks-http/blob/master/lib/mockRequest.js
*/
body: {
auth_token: "mock-auth-token",
},
headers: {
host: "some-saleor-host.cloud",
"x-forwarded-proto": "https",
"saleor-api-url": "https://wrong-saleor-domain.saleor.cloud/graphql/",
"saleor-domain": "https://wrong-saleor-domain.saleor.cloud/",
},
method: "POST",
});
const handler = createAppRegisterHandler({
apl: mockApl,
allowedSaleorUrls: [(url: string) => url === "https://mock-saleor-domain.saleor.cloud"],
});
await handler(req, res);
expect(res._getStatusCode()).toBe(403);
expect(res._getData().success).toBe(false);
});
describe("Callback hooks", () => {
it("Runs callback hooks - successful saving to APL scenario", async () => {
const mockOnRequestStart = vi.fn();
const mockOnRequestVerified = vi.fn();
const mockOnAuthAplFailed = vi.fn();
const mockOnAuthAplSaved = vi.fn();
const { res, req } = createMocks({
/**
* Use body, instead of params, otherwise - for some reason - param is not accessible in mock request
* Maybe this is a bug https://github.com/howardabrams/node-mocks-http/blob/master/lib/mockRequest.js
*/
body: {
auth_token: "mock-auth-token",
},
headers: {
host: "some-saleor-host.cloud",
"x-forwarded-proto": "https",
"saleor-api-url": "https://mock-saleor-domain.saleor.cloud/graphql/",
"saleor-domain": "https://mock-saleor-domain.saleor.cloud/",
},
method: "POST",
});
const handler = createAppRegisterHandler({
apl: mockApl,
onRequestStart: mockOnRequestStart,
onRequestVerified: mockOnRequestVerified,
onAplSetFailed: mockOnAuthAplFailed,
onAuthAplSaved: mockOnAuthAplSaved,
});
const expectedAuthData: AuthData = {
token: "mock-auth-token",
domain: "https://mock-saleor-domain.saleor.cloud/",
saleorApiUrl: "https://mock-saleor-domain.saleor.cloud/graphql/",
jwks: mockJwksValue,
appId: mockAppId,
};
await handler(req, res);
expect(mockOnRequestStart).toHaveBeenCalledWith(
expect.anything(/* Assume original request */),
expect.objectContaining({
authToken: "mock-auth-token",
saleorDomain: "https://mock-saleor-domain.saleor.cloud/",
saleorApiUrl: "https://mock-saleor-domain.saleor.cloud/graphql/",
})
);
expect(mockOnRequestVerified).toHaveBeenCalledWith(
expect.anything(/* Assume original request */),
expect.objectContaining({
authData: expectedAuthData,
})
);
expect(mockOnAuthAplSaved).toHaveBeenCalledWith(
expect.anything(/* Assume original request */),
expect.objectContaining({
authData: expectedAuthData,
})
);
expect(mockOnAuthAplFailed).not.toHaveBeenCalled();
});
it("Runs callback hooks - failed saving to APL scenario", async () => {
const mockOnAuthAplFailed = vi.fn();
const mockOnAuthAplSaved = vi.fn();
(mockApl.set as Mock).mockImplementationOnce(() => {
throw new Error("test error");
});
const { res, req } = createMocks({
/**
* Use body, instead of params, otherwise - for some reason - param is not accessible in mock request
* Maybe this is a bug https://github.com/howardabrams/node-mocks-http/blob/master/lib/mockRequest.js
*/
body: {
auth_token: "mock-auth-token",
},
headers: {
host: "some-saleor-host.cloud",
"x-forwarded-proto": "https",
"saleor-api-url": "https://mock-saleor-domain.saleor.cloud/graphql/",
"saleor-domain": "https://mock-saleor-domain.saleor.cloud/",
},
method: "POST",
});
const handler = createAppRegisterHandler({
apl: mockApl,
onAplSetFailed: mockOnAuthAplFailed,
onAuthAplSaved: mockOnAuthAplSaved,
});
const expectedAuthData: AuthData = {
token: "mock-auth-token",
domain: "https://mock-saleor-domain.saleor.cloud/",
saleorApiUrl: "https://mock-saleor-domain.saleor.cloud/graphql/",
jwks: mockJwksValue,
appId: mockAppId,
};
await handler(req, res);
expect(mockOnAuthAplSaved).not.toHaveBeenCalled();
expect(mockOnAuthAplFailed).toHaveBeenCalledWith(
expect.anything(/* Assume original request */),
expect.objectContaining({
authData: expectedAuthData,
error: expect.objectContaining({
message: "test error",
}),
})
);
});
it("Allows to send custom error response via callback hook", async () => {
const mockOnRequestStart = vi.fn().mockImplementation(
(
req,
context: {
respondWithError(params: { status: number; body: string; message: string }): Error;
}
) =>
context.respondWithError({
status: 401,
body: "test",
message: "test message",
})
);
const { res, req } = createMocks({
/**
* Use body, instead of params, otherwise - for some reason - param is not accessible in mock request
* Maybe this is a bug https://github.com/howardabrams/node-mocks-http/blob/master/lib/mockRequest.js
*/
body: {
auth_token: "mock-auth-token",
},
headers: {
host: "some-saleor-host.cloud",
"x-forwarded-proto": "https",
"saleor-api-url": "https://mock-saleor-domain.saleor.cloud/graphql/",
"saleor-domain": "https://mock-saleor-domain.saleor.cloud/",
},
method: "POST",
});
const handler = createAppRegisterHandler({
apl: mockApl,
onRequestStart: mockOnRequestStart,
});
await handler(req, res);
expect(res._getStatusCode()).toBe(401);
expect(res._getData()).toEqual({
success: false,
error: {
code: "REGISTER_HANDLER_HOOK_ERROR",
message: "test message",
},
});
});
});
});