0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

refactor(core): add test cases

This commit is contained in:
Gao Sun 2022-11-12 15:43:51 +08:00
parent 3a3952ae0a
commit 34bb0de7a9
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
6 changed files with 119 additions and 6 deletions

View file

@ -1,5 +1,5 @@
import type { Application, Passcode, Resource, Role, Setting } from '@logto/schemas';
import { ApplicationType, PasscodeType } from '@logto/schemas';
import type { Application, Hook, Passcode, Resource, Role, Setting } from '@logto/schemas';
import { HookEvent, ApplicationType, PasscodeType } from '@logto/schemas';
export * from './connector';
export * from './sign-in-experience';
@ -36,6 +36,19 @@ export const mockRole: Role = {
description: 'admin',
};
export const mockHook: Readonly<Hook> = Object.freeze({
id: 'logto_hook',
event: HookEvent.PostSignIn,
config: {
url: 'https://foo.bar',
headers: {
'User-Agent': 'Logto Core',
},
retries: 3,
},
createdAt: 1_645_334_775_356,
});
export const mockSetting: Setting = {
id: 'foo setting',
adminConsole: {

View file

@ -0,0 +1,95 @@
import type { Hook, CreateHook, HookConfig } from '@logto/schemas';
import { HookEvent } from '@logto/schemas';
import { mockHook } from '@/__mocks__';
import { createRequester } from '@/utils/test-utils';
import hookRoutes from './hook';
jest.mock('@/queries/hook', () => ({
findTotalNumberOfHooks: jest.fn(async () => ({ count: 10 })),
findAllHooks: jest.fn(async (): Promise<Hook[]> => [mockHook]),
findHookById: jest.fn(async (): Promise<Hook> => mockHook),
insertHook: jest.fn(
async (body: CreateHook): Promise<Hook> => ({
...mockHook,
...body,
})
),
updateHookById: jest.fn(
async (_, data: Partial<CreateHook>): Promise<Hook> => ({
...mockHook,
...data,
config: { ...mockHook.config, ...data.config },
})
),
deleteHookById: jest.fn(),
}));
jest.mock('@logto/shared', () => ({
generateStandardId: jest.fn(() => mockHook.id),
}));
describe('hook routes', () => {
const hookRequest = createRequester({ authedRoutes: hookRoutes });
it('GET /hooks', async () => {
const response = await hookRequest.get('/hooks');
expect(response.status).toEqual(200);
expect(response.body).toEqual([mockHook]);
expect(response.header).toHaveProperty('total-number', '10');
});
it('POST /hooks', async () => {
const event = HookEvent.PostChangePassword;
const response = await hookRequest.post('/hooks').send({ event, config: mockHook.config });
console.log();
expect(response.status).toEqual(200);
expect(response.body).toEqual({
...mockHook,
event,
});
});
it('POST /hooks should throw with invalid input body', async () => {
const id = 'a_good_hook';
const event = HookEvent.PostChangePassword;
await expect(hookRequest.post('/hooks')).resolves.toHaveProperty('status', 400);
await expect(hookRequest.post('/hooks').send({ id })).resolves.toHaveProperty('status', 400);
await expect(hookRequest.post('/hooks').send({ event })).resolves.toHaveProperty('status', 400);
});
it('GET /hooks/:id', async () => {
const response = await hookRequest.get('/hooks/foo');
expect(response.status).toEqual(200);
expect(response.body).toEqual(mockHook);
});
it('PATCH /hooks/:id', async () => {
const event = HookEvent.PostChangePassword;
const config: Partial<HookConfig> = { url: 'https://bar.baz' };
const response = await hookRequest.patch('/hooks/foo').send({ event, config });
expect(response.status).toEqual(200);
expect(response.body).toEqual({
...mockHook,
event,
config: { ...mockHook.config, url: config.url },
});
});
it('PATCH /hooks/:id should throw with invalid properties', async () => {
const response = await hookRequest.patch('/hooks/foo').send({ event: 12 });
expect(response.status).toEqual(400);
});
it('DELETE /hooks/:id', async () => {
await expect(hookRequest.delete('/hooks/foo')).resolves.toHaveProperty('status', 204);
});
});

View file

@ -64,7 +64,7 @@ afterEach(() => {
jest.clearAllMocks();
});
describe('when the application is admin-console', () => {
describe('when application is admin-console', () => {
beforeEach(() => {
interactionDetails.mockResolvedValueOnce({
params: { client_id: adminConsoleApplicationId },
@ -100,7 +100,7 @@ describe('when the application is admin-console', () => {
});
});
describe('when the application is not admin-console', () => {
describe('when application is not admin-console', () => {
it('should call interactionDetails', async () => {
await expect(phraseRequest.get('/phrase')).resolves.toHaveProperty('status', 200);
expect(interactionDetails).toBeCalledTimes(1);

View file

@ -25,8 +25,7 @@ jest.mock('@/queries/resource', () => ({
}));
jest.mock('@logto/shared', () => ({
// eslint-disable-next-line unicorn/consistent-function-scoping
buildIdGenerator: jest.fn(() => () => 'randomId'),
generateStandardId: jest.fn(() => 'randomId'),
}));
describe('resource routes', () => {

View file

@ -0,0 +1,5 @@
export enum HookEvent {
PostSignIn = 'PostSignIn',
PostSignOut = 'PostSignOut',
PostChangePassword = 'PostChangePassword',
}

View file

@ -3,3 +3,4 @@ export * from './log';
export * from './oidc-config';
export * from './user';
export * from './logto-config';
export * from './hook';