2022-02-21 10:45:31 +08:00
|
|
|
import { CreateUser, User } from '@logto/schemas';
|
|
|
|
|
|
|
|
import { hasUser, findUserById } from '@/queries/user';
|
2022-02-21 16:42:48 +08:00
|
|
|
import { mockUser, mockUserResponse } from '@/utils/mock';
|
|
|
|
import { createRequester } from '@/utils/test-utils';
|
2022-02-21 10:45:31 +08:00
|
|
|
|
|
|
|
import adminUserRoutes from './admin-user';
|
|
|
|
|
|
|
|
jest.mock('@/queries/user', () => ({
|
|
|
|
findTotalNumberOfUsers: jest.fn(async () => ({ count: 10 })),
|
|
|
|
findAllUsers: jest.fn(async (): Promise<User[]> => [mockUser]),
|
|
|
|
findUserById: jest.fn(async (): Promise<User> => mockUser),
|
|
|
|
hasUser: jest.fn(async () => false),
|
|
|
|
updateUserById: jest.fn(
|
|
|
|
async (_, data: Partial<CreateUser>): Promise<User> => ({
|
|
|
|
...mockUser,
|
|
|
|
...data,
|
|
|
|
})
|
|
|
|
),
|
|
|
|
insertUser: jest.fn(
|
|
|
|
async (user: CreateUser): Promise<User> => ({
|
|
|
|
...mockUser,
|
|
|
|
...user,
|
|
|
|
})
|
|
|
|
),
|
|
|
|
}));
|
|
|
|
|
|
|
|
jest.mock('@/lib/user', () => ({
|
|
|
|
generateUserId: jest.fn(() => 'fooId'),
|
|
|
|
encryptUserPassword: jest.fn(() => ({
|
|
|
|
passwordEncryptionSalt: 'salt',
|
|
|
|
passwordEncrypted: 'password',
|
|
|
|
passwordEncryptionMethod: 'saltAndPepper',
|
|
|
|
})),
|
|
|
|
}));
|
|
|
|
|
|
|
|
describe('adminUserRoutes', () => {
|
2022-02-23 11:09:26 +08:00
|
|
|
const userRequest = createRequester({ authedRoutes: adminUserRoutes });
|
2022-02-21 10:45:31 +08:00
|
|
|
|
|
|
|
it('GET /users', async () => {
|
|
|
|
const response = await userRequest.get('/users');
|
|
|
|
expect(response.status).toEqual(200);
|
|
|
|
expect(response.body).toEqual([mockUserResponse]);
|
2022-02-21 16:42:48 +08:00
|
|
|
expect(response.header).toHaveProperty('total-number', '10');
|
2022-02-21 10:45:31 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
it('GET /users/:userId', async () => {
|
|
|
|
const response = await userRequest.get('/users/foo');
|
|
|
|
expect(response.status).toEqual(200);
|
|
|
|
expect(response.body).toEqual(mockUserResponse);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('POST /users', async () => {
|
|
|
|
const username = 'MJ@logto.io';
|
|
|
|
const password = 'PASSWORD';
|
|
|
|
const name = 'Micheal';
|
|
|
|
|
|
|
|
const response = await userRequest.post('/users').send({ username, password, name });
|
|
|
|
expect(response.status).toEqual(200);
|
|
|
|
expect(response.body).toEqual({
|
|
|
|
...mockUserResponse,
|
|
|
|
id: 'fooId',
|
|
|
|
username,
|
|
|
|
name,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('POST /users should throw with invalid input params', async () => {
|
|
|
|
const username = 'MJ@logto.io';
|
|
|
|
const password = 'PASSWORD';
|
|
|
|
const name = 'Micheal';
|
|
|
|
|
|
|
|
// Missing input
|
|
|
|
await expect(userRequest.post('/users').send({})).resolves.toHaveProperty('status', 400);
|
|
|
|
await expect(userRequest.post('/users').send({ username, password })).resolves.toHaveProperty(
|
|
|
|
'status',
|
|
|
|
400
|
|
|
|
);
|
|
|
|
await expect(userRequest.post('/users').send({ username, name })).resolves.toHaveProperty(
|
|
|
|
'status',
|
|
|
|
400
|
|
|
|
);
|
|
|
|
await expect(userRequest.post('/users').send({ password, name })).resolves.toHaveProperty(
|
|
|
|
'status',
|
|
|
|
400
|
|
|
|
);
|
|
|
|
|
|
|
|
// Invalid input format
|
|
|
|
await expect(
|
|
|
|
userRequest.post('/users').send({ username: 'xy', password, name })
|
|
|
|
).resolves.toHaveProperty('status', 400);
|
|
|
|
await expect(
|
|
|
|
userRequest.post('/users').send({ username, password: 'abc', name })
|
|
|
|
).resolves.toHaveProperty('status', 400);
|
|
|
|
await expect(
|
|
|
|
userRequest.post('/users').send({ username, password, name: 'xy' })
|
|
|
|
).resolves.toHaveProperty('status', 400);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('POST /users should throw if username exist', async () => {
|
|
|
|
const mockHasUser = hasUser as jest.Mock;
|
|
|
|
mockHasUser.mockImplementationOnce(async () => Promise.resolve(true));
|
|
|
|
|
|
|
|
const username = 'MJ@logto.io';
|
|
|
|
const password = 'PASSWORD';
|
|
|
|
const name = 'Micheal';
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
userRequest.post('/users').send({ username, password, name })
|
|
|
|
).resolves.toHaveProperty('status', 422);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('PATCH /users/:userId', async () => {
|
|
|
|
const name = 'Micheal';
|
|
|
|
const avatar = 'http://www.micheal.png';
|
|
|
|
|
|
|
|
const response = await userRequest.patch('/users/foo').send({ name, avatar });
|
|
|
|
expect(response.status).toEqual(200);
|
|
|
|
expect(response.body).toEqual({
|
|
|
|
...mockUserResponse,
|
|
|
|
name,
|
|
|
|
avatar,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('PATCH /users/:userId throw with invalid input params', async () => {
|
|
|
|
const name = 'Micheal';
|
|
|
|
const avatar = 'http://www.micheal.png';
|
|
|
|
|
|
|
|
await expect(userRequest.patch('/users/foo').send({ avatar })).resolves.toHaveProperty(
|
|
|
|
'status',
|
|
|
|
200
|
|
|
|
);
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
userRequest.patch('/users/foo').send({ name, avatar: 'non url' })
|
|
|
|
).resolves.toHaveProperty('status', 400);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('PATCH /users/:userId throw if user not found', async () => {
|
|
|
|
const name = 'Micheal';
|
|
|
|
const avatar = 'http://www.micheal.png';
|
|
|
|
|
|
|
|
const mockFindUserById = findUserById as jest.Mock;
|
|
|
|
mockFindUserById.mockImplementationOnce(() => {
|
|
|
|
throw new Error(' ');
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(userRequest.patch('/users/foo').send({ name, avatar })).resolves.toHaveProperty(
|
|
|
|
'status',
|
|
|
|
500
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|