mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
test(core): add unit tests for generateUserId()
(#113)
This commit is contained in:
parent
7ae7912642
commit
8e291b51bf
3 changed files with 73 additions and 20 deletions
50
packages/core/src/lib/user.test.ts
Normal file
50
packages/core/src/lib/user.test.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { hasUserWithId } from '@/queries/user';
|
||||
|
||||
import { generateUserId } from './user';
|
||||
|
||||
jest.mock('@/queries/user');
|
||||
|
||||
describe('generateUserId()', () => {
|
||||
afterEach(() => {
|
||||
(hasUserWithId as jest.MockedFunction<typeof hasUserWithId>).mockClear();
|
||||
});
|
||||
|
||||
it('generates user ID with correct length when no conflict found', async () => {
|
||||
const mockedHasUserWithId = (
|
||||
hasUserWithId as jest.MockedFunction<typeof hasUserWithId>
|
||||
).mockImplementationOnce(async () => false);
|
||||
|
||||
await expect(generateUserId()).resolves.toHaveLength(12);
|
||||
expect(mockedHasUserWithId).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('generates user ID with correct length when retry limit is not reached', async () => {
|
||||
// eslint-disable-next-line @silverhand/fp/no-let
|
||||
let tried = 0;
|
||||
const mockedHasUserWithId = (
|
||||
hasUserWithId as jest.MockedFunction<typeof hasUserWithId>
|
||||
).mockImplementation(async () => {
|
||||
if (tried) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @silverhand/fp/no-mutation
|
||||
tried++;
|
||||
return true;
|
||||
});
|
||||
|
||||
await expect(generateUserId(2)).resolves.toHaveLength(12);
|
||||
expect(mockedHasUserWithId).toBeCalledTimes(2);
|
||||
});
|
||||
|
||||
it('rejects with correct error message when retry limit is reached', async () => {
|
||||
const mockedHasUserWithId = (
|
||||
hasUserWithId as jest.MockedFunction<typeof hasUserWithId>
|
||||
).mockImplementation(async () => true);
|
||||
|
||||
await expect(generateUserId(10)).rejects.toThrow(
|
||||
'Cannot generate user ID in reasonable retries'
|
||||
);
|
||||
expect(mockedHasUserWithId).toBeCalledTimes(11);
|
||||
});
|
||||
});
|
21
packages/core/src/lib/user.ts
Normal file
21
packages/core/src/lib/user.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import pRetry from 'p-retry';
|
||||
|
||||
import { hasUserWithId } from '@/queries/user';
|
||||
import { buildIdGenerator } from '@/utils/id';
|
||||
|
||||
const userId = buildIdGenerator(12);
|
||||
|
||||
// LOG-89: Add unit tests
|
||||
export const generateUserId = async (retries = 500) =>
|
||||
pRetry(
|
||||
async () => {
|
||||
const id = userId();
|
||||
|
||||
if (!(await hasUserWithId(id))) {
|
||||
return id;
|
||||
}
|
||||
|
||||
throw new Error('Cannot generate user ID in reasonable retries');
|
||||
},
|
||||
{ retries, factor: 0 } // No need for exponential backoff
|
||||
);
|
|
@ -1,33 +1,15 @@
|
|||
import { PasswordEncryptionMethod } from '@logto/schemas';
|
||||
import { nanoid } from 'nanoid';
|
||||
import pRetry from 'p-retry';
|
||||
import { object, string } from 'zod';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { generateUserId } from '@/lib/user';
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
import { hasUser, hasUserWithId, insertUser } from '@/queries/user';
|
||||
import { buildIdGenerator } from '@/utils/id';
|
||||
import { hasUser, insertUser } from '@/queries/user';
|
||||
import { encryptPassword } from '@/utils/password';
|
||||
|
||||
import { AnonymousRouter } from './types';
|
||||
|
||||
const userId = buildIdGenerator(12);
|
||||
|
||||
// LOG-89: Add unit tests
|
||||
const generateUserId = async (retries = 500) =>
|
||||
pRetry(
|
||||
async () => {
|
||||
const id = userId();
|
||||
|
||||
if (!(await hasUserWithId(id))) {
|
||||
return id;
|
||||
}
|
||||
|
||||
throw new Error('Cannot generate user ID in reasonable retries');
|
||||
},
|
||||
{ retries }
|
||||
);
|
||||
|
||||
export default function userRoutes<T extends AnonymousRouter>(router: T) {
|
||||
router.post(
|
||||
'/user',
|
||||
|
|
Loading…
Reference in a new issue