mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
refactor(test): refactor expectRejects
helper method to support status code checking (#4292)
* refactor(test): refactor `expectRejects` helper method to support status code checking * refactor(test): replace `createResponseWithCode` with `expectRejects`
This commit is contained in:
parent
65803deaf4
commit
ae0322621f
20 changed files with 318 additions and 176 deletions
|
@ -27,10 +27,6 @@ import { generatePassword, generateUsername } from '#src/utils.js';
|
|||
export const resourceDefault = getManagementApiResourceIndicator(defaultTenantId);
|
||||
export const resourceMe = getManagementApiResourceIndicator(adminTenantId, 'me');
|
||||
|
||||
export const createResponseWithCode = (statusCode: number) => ({
|
||||
response: { statusCode },
|
||||
});
|
||||
|
||||
const createUserWithRoles = async (roleNames: string[]) => {
|
||||
const username = generateUsername();
|
||||
const password = generatePassword();
|
||||
|
|
|
@ -52,15 +52,17 @@ export const removeVerificationCode = async (): Promise<void> => {
|
|||
}
|
||||
};
|
||||
|
||||
export const expectRejects = async (
|
||||
promise: Promise<unknown>,
|
||||
code: string,
|
||||
messageIncludes?: string
|
||||
) => {
|
||||
type ExpectedErrorInfo = {
|
||||
code: string;
|
||||
statusCode: number;
|
||||
messageIncludes?: string;
|
||||
};
|
||||
|
||||
export const expectRejects = async (promise: Promise<unknown>, expected: ExpectedErrorInfo) => {
|
||||
try {
|
||||
await promise;
|
||||
} catch (error: unknown) {
|
||||
expectRequestError(error, code, messageIncludes);
|
||||
expectRequestError(error, expected);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -68,7 +70,9 @@ export const expectRejects = async (
|
|||
fail();
|
||||
};
|
||||
|
||||
export const expectRequestError = (error: unknown, code: string, messageIncludes?: string) => {
|
||||
export const expectRequestError = (error: unknown, expected: ExpectedErrorInfo) => {
|
||||
const { code, statusCode, messageIncludes } = expected;
|
||||
|
||||
if (!(error instanceof RequestError)) {
|
||||
fail('Error should be an instance of RequestError');
|
||||
}
|
||||
|
@ -82,6 +86,8 @@ export const expectRequestError = (error: unknown, code: string, messageIncludes
|
|||
|
||||
expect(body.code).toEqual(code);
|
||||
|
||||
expect(error.response?.statusCode).toEqual(statusCode);
|
||||
|
||||
if (messageIncludes) {
|
||||
expect(body.message.includes(messageIncludes)).toBeTruthy();
|
||||
}
|
||||
|
|
|
@ -78,7 +78,10 @@ export const createNewSocialUserWithUsernameAndPassword = async (connectorId: st
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
await client.successSend(patchInteractionIdentifiers, { username, password });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import { HTTPError } from 'got';
|
|||
|
||||
import { assignRolesToUser, getUserRoles, deleteRoleFromUser } from '#src/api/index.js';
|
||||
import { createRole } from '#src/api/role.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { createUserByAdmin } from '#src/helpers/index.js';
|
||||
import { createUserByAdmin, expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
describe('admin console user management (roles)', () => {
|
||||
it('should get empty list successfully', async () => {
|
||||
|
@ -27,9 +26,10 @@ describe('admin console user management (roles)', () => {
|
|||
const role = await createRole();
|
||||
|
||||
await assignRolesToUser(user.id, [role.id]);
|
||||
await expect(assignRolesToUser(user.id, [role.id])).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expectRejects(assignRolesToUser(user.id, [role.id]), {
|
||||
code: 'user.role_exists',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
it('should delete role from user successfully', async () => {
|
||||
|
|
|
@ -178,8 +178,7 @@ describe('admin console user search params', () => {
|
|||
['search.primaryEmail', 'jerry_swift_jr_2@geek.best'],
|
||||
['search.primaryEmail', 'jerry_swift_jr_jr@gmail.com'],
|
||||
]),
|
||||
'request.invalid_input',
|
||||
'`exact`'
|
||||
{ code: 'request.invalid_input', statusCode: 400, messageIncludes: '`exact`' }
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -189,8 +188,11 @@ describe('admin console user search params', () => {
|
|||
['search.primaryEmail', ''],
|
||||
['search', 'tom'],
|
||||
]),
|
||||
'request.invalid_input',
|
||||
'cannot be empty'
|
||||
{
|
||||
code: 'request.invalid_input',
|
||||
statusCode: 400,
|
||||
messageIncludes: 'cannot be empty',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -200,8 +202,11 @@ describe('admin console user search params', () => {
|
|||
['search.primaryEmail', '%gmail%'],
|
||||
['mode.primaryEmail', 'similar_to'],
|
||||
]),
|
||||
'request.invalid_input',
|
||||
'case-insensitive'
|
||||
{
|
||||
code: 'request.invalid_input',
|
||||
statusCode: 400,
|
||||
messageIncludes: 'case-insensitive',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -212,21 +217,27 @@ describe('admin console user search params', () => {
|
|||
['search.primaryEmail', '%gmail%'],
|
||||
['mode.primaryEmail', 'similar to'],
|
||||
]),
|
||||
'request.invalid_input',
|
||||
'is not valid'
|
||||
),
|
||||
expectRejects(
|
||||
getUsers<User[]>([['search.email', '%gmail%']]),
|
||||
'request.invalid_input',
|
||||
'is not valid'
|
||||
{
|
||||
code: 'request.invalid_input',
|
||||
statusCode: 400,
|
||||
messageIncludes: 'is not valid',
|
||||
}
|
||||
),
|
||||
expectRejects(getUsers<User[]>([['search.email', '%gmail%']]), {
|
||||
code: 'request.invalid_input',
|
||||
statusCode: 400,
|
||||
messageIncludes: 'is not valid',
|
||||
}),
|
||||
expectRejects(
|
||||
getUsers<User[]>([
|
||||
['search.primaryEmail', '%gmail%'],
|
||||
['joint', 'and1'],
|
||||
]),
|
||||
'request.invalid_input',
|
||||
'is not valid'
|
||||
{
|
||||
code: 'request.invalid_input',
|
||||
statusCode: 400,
|
||||
messageIncludes: 'is not valid',
|
||||
}
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -17,8 +17,7 @@ import {
|
|||
postUserIdentity,
|
||||
verifyUserPassword,
|
||||
} from '#src/api/index.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { createUserByAdmin } from '#src/helpers/index.js';
|
||||
import { createUserByAdmin, expectRejects } from '#src/helpers/index.js';
|
||||
import { createNewSocialUserWithUsernameAndPassword } from '#src/helpers/interactions.js';
|
||||
import { generateUsername, generateEmail, generatePhone, generatePassword } from '#src/utils.js';
|
||||
|
||||
|
@ -38,19 +37,25 @@ describe('admin console user management', () => {
|
|||
generatePhone(),
|
||||
];
|
||||
await createUserByAdmin(username, password, email, phone);
|
||||
await expect(createUserByAdmin(username, password)).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expect(createUserByAdmin(undefined, undefined, email)).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expect(createUserByAdmin(undefined, undefined, undefined, phone)).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expectRejects(createUserByAdmin(username, password), {
|
||||
code: 'user.username_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
await expectRejects(createUserByAdmin(undefined, undefined, email), {
|
||||
code: 'user.email_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
await expectRejects(createUserByAdmin(undefined, undefined, undefined, phone), {
|
||||
code: 'user.phone_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail when get user by invalid id', async () => {
|
||||
await expect(getUser('invalid-user-id')).rejects.toMatchObject(createResponseWithCode(404));
|
||||
await expectRejects(getUser('invalid-user-id'), {
|
||||
code: 'entity.not_found',
|
||||
statusCode: 404,
|
||||
});
|
||||
});
|
||||
|
||||
it('should update userinfo successfully', async () => {
|
||||
|
@ -74,7 +79,10 @@ describe('admin console user management', () => {
|
|||
|
||||
it('should respond 422 when no update data provided', async () => {
|
||||
const user = await createUserByAdmin();
|
||||
await expect(updateUser(user.id, {})).rejects.toMatchObject(createResponseWithCode(422));
|
||||
await expectRejects(updateUser(user.id, {}), {
|
||||
code: 'entity.invalid_input',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail when update userinfo with conflict identifiers', async () => {
|
||||
|
@ -82,15 +90,20 @@ describe('admin console user management', () => {
|
|||
await createUserByAdmin(username, undefined, email, phone);
|
||||
const anotherUser = await createUserByAdmin();
|
||||
|
||||
await expect(updateUser(anotherUser.id, { username })).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expect(updateUser(anotherUser.id, { primaryEmail: email })).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expect(updateUser(anotherUser.id, { primaryPhone: phone })).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expectRejects(updateUser(anotherUser.id, { username }), {
|
||||
code: 'user.username_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await expectRejects(updateUser(anotherUser.id, { primaryEmail: email }), {
|
||||
code: 'user.email_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await expectRejects(updateUser(anotherUser.id, { primaryPhone: phone }), {
|
||||
code: 'user.phone_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
it('should delete user successfully', async () => {
|
||||
|
@ -171,22 +184,23 @@ describe('admin console user management', () => {
|
|||
it('should return 204 if password is correct', async () => {
|
||||
const user = await createUserByAdmin(undefined, 'new_password');
|
||||
expect(await verifyUserPassword(user.id, 'new_password')).toHaveProperty('statusCode', 204);
|
||||
void deleteUser(user.id);
|
||||
await deleteUser(user.id);
|
||||
});
|
||||
|
||||
it('should return 422 if password is incorrect', async () => {
|
||||
const user = await createUserByAdmin(undefined, 'new_password');
|
||||
await expect(verifyUserPassword(user.id, 'wrong_password')).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
void deleteUser(user.id);
|
||||
await expectRejects(verifyUserPassword(user.id, 'wrong_password'), {
|
||||
code: 'session.invalid_credentials',
|
||||
statusCode: 422,
|
||||
});
|
||||
await deleteUser(user.id);
|
||||
});
|
||||
|
||||
it('should return 400 if password is empty', async () => {
|
||||
const user = await createUserByAdmin();
|
||||
await expect(verifyUserPassword(user.id, '')).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
void deleteUser(user.id);
|
||||
await expectRejects(verifyUserPassword(user.id, ''), {
|
||||
code: 'guard.invalid_input',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
listConnectorFactories,
|
||||
getConnectorFactory,
|
||||
} from '#src/api/connector.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
const connectorIdMap = new Map<string, string>();
|
||||
|
||||
|
@ -158,32 +158,39 @@ test('connector set-up flow', async () => {
|
|||
|
||||
test('create connector with non-exist connectorId', async () => {
|
||||
await cleanUpConnectorTable();
|
||||
await expect(postConnector({ connectorId: 'non-exist-id' })).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expectRejects(postConnector({ connectorId: 'non-exist-id' }), {
|
||||
code: 'connector.not_found_with_connector_id',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
test('create non standard social connector with target', async () => {
|
||||
await cleanUpConnectorTable();
|
||||
await expect(
|
||||
postConnector({ connectorId: mockSocialConnectorId, metadata: { target: 'target' } })
|
||||
).rejects.toMatchObject(createResponseWithCode(400));
|
||||
await expectRejects(
|
||||
postConnector({ connectorId: mockSocialConnectorId, metadata: { target: 'target' } }),
|
||||
{
|
||||
code: 'connector.cannot_overwrite_metadata_for_non_standard_connector',
|
||||
statusCode: 400,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('create duplicated social connector', async () => {
|
||||
await cleanUpConnectorTable();
|
||||
await postConnector({ connectorId: mockSocialConnectorId });
|
||||
await expect(postConnector({ connectorId: mockSocialConnectorId })).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expectRejects(postConnector({ connectorId: mockSocialConnectorId }), {
|
||||
code: 'connector.multiple_instances_not_supported',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
test('override metadata for non-standard social connector', async () => {
|
||||
await cleanUpConnectorTable();
|
||||
const { id } = await postConnector({ connectorId: mockSocialConnectorId });
|
||||
await expect(updateConnectorConfig(id, {}, { target: 'target' })).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(updateConnectorConfig(id, {}, { target: 'target' }), {
|
||||
code: 'connector.cannot_overwrite_metadata_for_non_standard_connector',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
|
||||
test('send SMS/email test message', async () => {
|
||||
|
|
|
@ -2,8 +2,7 @@ import { SignInIdentifier } from '@logto/schemas';
|
|||
|
||||
import type { StatisticsData } from '#src/api/index.js';
|
||||
import { api, getTotalUsersCount, getNewUsersData, getActiveUsersData } from '#src/api/index.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { createUserByAdmin } from '#src/helpers/index.js';
|
||||
import { createUserByAdmin, expectRejects } from '#src/helpers/index.js';
|
||||
import { registerNewUser, signInWithPassword } from '#src/helpers/interactions.js';
|
||||
import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js';
|
||||
import { generateUsername, generatePassword } from '#src/utils.js';
|
||||
|
@ -18,13 +17,18 @@ describe('admin console dashboard', () => {
|
|||
});
|
||||
|
||||
it('non authorized request should return 401', async () => {
|
||||
await expect(api.get('dashboard/users/total')).rejects.toMatchObject(
|
||||
createResponseWithCode(401)
|
||||
);
|
||||
await expect(api.get('dashboard/users/new')).rejects.toMatchObject(createResponseWithCode(401));
|
||||
await expect(api.get('dashboard/users/active')).rejects.toMatchObject(
|
||||
createResponseWithCode(401)
|
||||
);
|
||||
await expectRejects(api.get('dashboard/users/total'), {
|
||||
code: 'auth.authorization_header_missing',
|
||||
statusCode: 401,
|
||||
});
|
||||
await expectRejects(api.get('dashboard/users/new'), {
|
||||
code: 'auth.authorization_header_missing',
|
||||
statusCode: 401,
|
||||
});
|
||||
await expectRejects(api.get('dashboard/users/active'), {
|
||||
code: 'auth.authorization_header_missing',
|
||||
statusCode: 401,
|
||||
});
|
||||
});
|
||||
|
||||
it('should get total user count successfully', async () => {
|
||||
|
|
|
@ -2,8 +2,8 @@ import type { Hook } from '@logto/schemas';
|
|||
import { HookEvent } from '@logto/schemas';
|
||||
|
||||
import { authedAdminApi } from '#src/api/index.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { getHookCreationPayload } from '#src/helpers/hook.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
describe('hooks', () => {
|
||||
it('should be able to create, query, update, and delete a hook', async () => {
|
||||
|
@ -20,10 +20,10 @@ describe('hooks', () => {
|
|||
.json<Hook>()
|
||||
).toMatchObject({ ...created, events: [HookEvent.PostSignIn] });
|
||||
expect(await authedAdminApi.delete(`hooks/${created.id}`)).toHaveProperty('statusCode', 204);
|
||||
await expect(authedAdminApi.get(`hooks/${created.id}`)).rejects.toHaveProperty(
|
||||
'response.statusCode',
|
||||
404
|
||||
);
|
||||
await expectRejects(authedAdminApi.get(`hooks/${created.id}`), {
|
||||
code: 'entity.not_exists_with_id',
|
||||
statusCode: 404,
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to create, query, update, and delete a hook by the original API', async () => {
|
||||
|
@ -49,10 +49,10 @@ describe('hooks', () => {
|
|||
event: HookEvent.PostSignIn,
|
||||
});
|
||||
expect(await authedAdminApi.delete(`hooks/${created.id}`)).toHaveProperty('statusCode', 204);
|
||||
await expect(authedAdminApi.get(`hooks/${created.id}`)).rejects.toHaveProperty(
|
||||
'response.statusCode',
|
||||
404
|
||||
);
|
||||
await expectRejects(authedAdminApi.get(`hooks/${created.id}`), {
|
||||
code: 'entity.not_exists_with_id',
|
||||
statusCode: 404,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return hooks with pagination if pagination-related query params are provided', async () => {
|
||||
|
@ -76,9 +76,10 @@ describe('hooks', () => {
|
|||
url: 'not_work_url',
|
||||
},
|
||||
};
|
||||
await expect(authedAdminApi.post('hooks', { json: payload })).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(authedAdminApi.post('hooks', { json: payload }), {
|
||||
code: 'guard.invalid_input',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error when no event is provided when creating a hook', async () => {
|
||||
|
@ -88,9 +89,10 @@ describe('hooks', () => {
|
|||
url: 'not_work_url',
|
||||
},
|
||||
};
|
||||
await expect(authedAdminApi.post('hooks', { json: payload })).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(authedAdminApi.post('hooks', { json: payload }), {
|
||||
code: 'hook.missing_events',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error if update a hook with a invalid hook id', async () => {
|
||||
|
@ -98,14 +100,16 @@ describe('hooks', () => {
|
|||
name: 'new_hook_name',
|
||||
};
|
||||
|
||||
await expect(authedAdminApi.patch('hooks/invalid_id', { json: payload })).rejects.toMatchObject(
|
||||
createResponseWithCode(404)
|
||||
);
|
||||
await expectRejects(authedAdminApi.patch('hooks/invalid_id', { json: payload }), {
|
||||
code: 'entity.not_exists',
|
||||
statusCode: 404,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error if regenerate a hook signing key with a invalid hook id', async () => {
|
||||
await expect(authedAdminApi.patch('hooks/invalid_id/signing-key')).rejects.toMatchObject(
|
||||
createResponseWithCode(404)
|
||||
);
|
||||
await expectRejects(authedAdminApi.patch('hooks/invalid_id/signing-key'), {
|
||||
code: 'entity.not_exists',
|
||||
statusCode: 404,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { HookEvent, type Hook } from '@logto/schemas';
|
||||
|
||||
import { authedAdminApi } from '#src/api/api.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { getHookCreationPayload } from '#src/helpers/hook.js';
|
||||
import { createMockServer } from '#src/helpers/index.js';
|
||||
import { createMockServer, expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
const responseSuccessPort = 9999;
|
||||
const responseSuccessEndpoint = `http://localhost:${responseSuccessPort}`;
|
||||
|
@ -46,21 +45,29 @@ describe('hook testing', () => {
|
|||
|
||||
it('should return 404 if the hook to test does not exist', async () => {
|
||||
const invalidHookId = 'invalid_id';
|
||||
await expect(
|
||||
await expectRejects(
|
||||
authedAdminApi.post(`hooks/${invalidHookId}/test`, {
|
||||
json: { events: [HookEvent.PostSignIn], config: { url: responseSuccessEndpoint } },
|
||||
})
|
||||
).rejects.toMatchObject(createResponseWithCode(404));
|
||||
}),
|
||||
{
|
||||
code: 'entity.not_exists_with_id',
|
||||
statusCode: 404,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should return 422 if the hook endpoint is not working', async () => {
|
||||
const payload = getHookCreationPayload(HookEvent.PostRegister);
|
||||
const created = await authedAdminApi.post('hooks', { json: payload }).json<Hook>();
|
||||
await expect(
|
||||
await expectRejects(
|
||||
authedAdminApi.post(`hooks/${created.id}/test`, {
|
||||
json: { events: [HookEvent.PostSignIn], config: { url: 'not_work_url' } },
|
||||
})
|
||||
).rejects.toMatchObject(createResponseWithCode(422));
|
||||
}),
|
||||
{
|
||||
code: 'hook.send_test_payload_failed',
|
||||
statusCode: 422,
|
||||
}
|
||||
);
|
||||
|
||||
// Clean Up
|
||||
await authedAdminApi.delete(`hooks/${created.id}`);
|
||||
|
|
|
@ -62,11 +62,17 @@ describe('reset password', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.new_password_required_in_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.new_password_required_in_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionProfile, { password: userProfile.password });
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.same_password');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.same_password',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
const newPasswordRecord = generatePassword();
|
||||
|
||||
|
@ -115,11 +121,17 @@ describe('reset password', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.new_password_required_in_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.new_password_required_in_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionProfile, { password: userProfile.password });
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.same_password');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.same_password',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
const newPasswordRecord = generatePassword();
|
||||
|
||||
|
|
|
@ -138,7 +138,10 @@ describe('Register with passwordless identifier', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(patchInteractionProfile, {
|
||||
password,
|
||||
|
@ -240,7 +243,10 @@ describe('Register with passwordless identifier', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(patchInteractionProfile, {
|
||||
password,
|
||||
|
@ -308,7 +314,10 @@ describe('Register with passwordless identifier', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.email_already_in_use');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.email_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(deleteInteractionProfile);
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.SignIn });
|
||||
|
@ -360,7 +369,10 @@ describe('Register with passwordless identifier', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.phone_already_in_use');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.phone_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(deleteInteractionProfile);
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.SignIn });
|
||||
|
|
|
@ -124,7 +124,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.user_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.user_not_exist',
|
||||
statusCode: 404,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { email: newEmail });
|
||||
|
@ -163,7 +166,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.user_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.user_not_exist',
|
||||
statusCode: 404,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { phone: newPhone });
|
||||
|
@ -205,7 +211,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
// Fulfill user profile
|
||||
await client.successSend(putInteractionProfile, {
|
||||
|
@ -264,7 +273,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
// Fulfill user profile with existing password
|
||||
await client.successSend(putInteractionProfile, {
|
||||
|
@ -272,7 +284,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
password,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.password_exists_in_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.password_exists_in_profile',
|
||||
statusCode: 400,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionProfile, {
|
||||
username,
|
||||
|
@ -315,7 +330,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
verificationCode: code,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
// Fulfill user profile with existing password
|
||||
await client.successSend(putInteractionProfile, {
|
||||
|
@ -323,7 +341,10 @@ describe('Sign-In flow using verification-code identifiers', () => {
|
|||
password,
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.username_already_in_use');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.username_already_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionProfile, {
|
||||
username,
|
||||
|
|
|
@ -112,7 +112,10 @@ describe('Sign-In flow using password identifiers', () => {
|
|||
},
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(sendVerificationCode, {
|
||||
email: primaryEmail,
|
||||
|
@ -171,7 +174,10 @@ describe('Sign-In flow using password identifiers', () => {
|
|||
},
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(sendVerificationCode, {
|
||||
phone: primaryPhone,
|
||||
|
|
|
@ -63,7 +63,10 @@ describe('Social Identifier Interactions', () => {
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
@ -116,7 +119,10 @@ describe('Social Identifier Interactions', () => {
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId, email: socialEmail },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
@ -149,7 +155,10 @@ describe('Social Identifier Interactions', () => {
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId, phone: socialPhone },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
@ -192,7 +201,10 @@ describe('Social Identifier Interactions', () => {
|
|||
},
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
connectorId,
|
||||
|
@ -253,12 +265,18 @@ describe('Social Identifier Interactions', () => {
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.missing_profile',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(patchInteractionProfile, { username: generateUsername() });
|
||||
|
||||
|
@ -291,7 +309,10 @@ describe('Social Identifier Interactions', () => {
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId, email: generateEmail() },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
@ -325,7 +346,10 @@ describe('Social Identifier Interactions', () => {
|
|||
connectorData: { state, redirectUri, code, userId: socialUserId, phone: generatePhone() },
|
||||
});
|
||||
|
||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||
await expectRejects(client.submitInteraction(), {
|
||||
code: 'user.identity_not_exist',
|
||||
statusCode: 422,
|
||||
});
|
||||
|
||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||
await client.successSend(putInteractionProfile, { connectorId });
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { getLog, getAuditLogs } from '#src/api/index.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
describe('logs', () => {
|
||||
it('should get logs successfully', async () => {
|
||||
|
@ -20,6 +20,9 @@ describe('logs', () => {
|
|||
});
|
||||
|
||||
it('should throw on getting non-exist log detail', async () => {
|
||||
await expect(getLog('non-exist-log-id')).rejects.toMatchObject(createResponseWithCode(404));
|
||||
await expectRejects(getLog('non-exist-log-id'), {
|
||||
code: 'entity.not_exists_with_id',
|
||||
statusCode: 404,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,18 +2,19 @@ import { got } from 'got';
|
|||
|
||||
import { logtoConsoleUrl, logtoUrl } from '#src/constants.js';
|
||||
import {
|
||||
createResponseWithCode,
|
||||
createUserWithAllRolesAndSignInToClient,
|
||||
deleteUser,
|
||||
resourceDefault,
|
||||
resourceMe,
|
||||
} from '#src/helpers/admin-tenant.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
describe('me', () => {
|
||||
it('should only be available in admin tenant', async () => {
|
||||
await expect(got.get(new URL('/me/custom-data', logtoConsoleUrl))).rejects.toMatchObject(
|
||||
createResponseWithCode(401)
|
||||
);
|
||||
await expectRejects(got.get(new URL('/me/custom-data', logtoConsoleUrl)), {
|
||||
code: 'auth.authorization_header_missing',
|
||||
statusCode: 401,
|
||||
});
|
||||
|
||||
// Redirect to UI
|
||||
const response = await got.get(new URL('/me/custom-data', logtoUrl));
|
||||
|
@ -24,11 +25,15 @@ describe('me', () => {
|
|||
it('should only recognize the access token with correct resource and scope', async () => {
|
||||
const { id, client } = await createUserWithAllRolesAndSignInToClient();
|
||||
|
||||
await expect(
|
||||
await expectRejects(
|
||||
got.get(logtoConsoleUrl + '/me/custom-data', {
|
||||
headers: { authorization: `Bearer ${await client.getAccessToken(resourceDefault)}` },
|
||||
})
|
||||
).rejects.toMatchObject(createResponseWithCode(401));
|
||||
}),
|
||||
{
|
||||
code: 'auth.unauthorized',
|
||||
statusCode: 401,
|
||||
}
|
||||
);
|
||||
|
||||
await expect(
|
||||
got.get(logtoConsoleUrl + '/me/custom-data', {
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
deleteResource,
|
||||
setDefaultResource,
|
||||
} from '#src/api/index.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
import { generateResourceIndicator, generateResourceName } from '#src/utils.js';
|
||||
|
||||
describe('admin console api resources', () => {
|
||||
|
@ -47,9 +47,10 @@ describe('admin console api resources', () => {
|
|||
|
||||
// Create second resource with same indicator should throw
|
||||
const resourceName2 = generateResourceName();
|
||||
await expect(createResource(resourceName2, resourceIndicator)).rejects.toMatchObject(
|
||||
createResponseWithCode(422)
|
||||
);
|
||||
await expectRejects(createResource(resourceName2, resourceIndicator), {
|
||||
code: 'resource.resource_identifier_in_use',
|
||||
statusCode: 422,
|
||||
});
|
||||
});
|
||||
|
||||
it('should get resource list successfully', async () => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { SignInIdentifier } from '@logto/schemas';
|
||||
|
||||
import { getSignInExperience, updateSignInExperience } from '#src/api/index.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
describe('admin console sign-in experience', () => {
|
||||
it('should get sign-in experience successfully', async () => {
|
||||
|
@ -38,8 +38,9 @@ describe('admin console sign-in experience', () => {
|
|||
},
|
||||
};
|
||||
|
||||
await expect(updateSignInExperience(newSignInExperience)).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(updateSignInExperience(newSignInExperience), {
|
||||
code: 'sign_in_experiences.username_requires_password',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,13 +2,12 @@ import { VerificationCodeType } from '@logto/connector-kit';
|
|||
import { ConnectorType, type RequestVerificationCodePayload } from '@logto/schemas';
|
||||
|
||||
import { requestVerificationCode, verifyVerificationCode } from '#src/api/verification-code.js';
|
||||
import { createResponseWithCode } from '#src/helpers/admin-tenant.js';
|
||||
import {
|
||||
clearConnectorsByTypes,
|
||||
setEmailConnector,
|
||||
setSmsConnector,
|
||||
} from '#src/helpers/connector.js';
|
||||
import { readVerificationCode, removeVerificationCode } from '#src/helpers/index.js';
|
||||
import { expectRejects, readVerificationCode, removeVerificationCode } from '#src/helpers/index.js';
|
||||
import { enableAllVerificationCodeSignInMethods } from '#src/helpers/sign-in-experience.js';
|
||||
|
||||
describe('Generic verification code through management API', () => {
|
||||
|
@ -55,9 +54,10 @@ describe('Generic verification code through management API', () => {
|
|||
});
|
||||
|
||||
it('should fail to create a verification code on server side when the email and phone are not provided', async () => {
|
||||
await expect(requestVerificationCode({ username: 'any_string' })).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(requestVerificationCode({ username: 'any_string' }), {
|
||||
code: 'guard.invalid_input',
|
||||
statusCode: 400,
|
||||
});
|
||||
|
||||
await expect(readVerificationCode()).rejects.toThrow();
|
||||
});
|
||||
|
@ -65,9 +65,10 @@ describe('Generic verification code through management API', () => {
|
|||
it('should fail to send a verification code on server side when no email connector has been set', async () => {
|
||||
const emailForTestSendCode = 'test_send@email.com';
|
||||
await clearConnectorsByTypes([ConnectorType.Email]);
|
||||
await expect(requestVerificationCode({ email: emailForTestSendCode })).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(requestVerificationCode({ email: emailForTestSendCode }), {
|
||||
code: 'connector.not_found',
|
||||
statusCode: 400,
|
||||
});
|
||||
|
||||
await expect(
|
||||
verifyVerificationCode({ email: emailForTestSendCode, verificationCode: 'any_string' })
|
||||
|
@ -88,9 +89,10 @@ describe('Generic verification code through management API', () => {
|
|||
it('should fail to send a verification code on server side when no SMS connector has not been set', async () => {
|
||||
const phoneForTestSendCode = '1233212321';
|
||||
await clearConnectorsByTypes([ConnectorType.Sms]);
|
||||
await expect(requestVerificationCode({ phone: phoneForTestSendCode })).rejects.toMatchObject(
|
||||
createResponseWithCode(400)
|
||||
);
|
||||
await expectRejects(requestVerificationCode({ phone: phoneForTestSendCode }), {
|
||||
code: 'connector.not_found',
|
||||
statusCode: 400,
|
||||
});
|
||||
|
||||
await expect(
|
||||
verifyVerificationCode({ phone: phoneForTestSendCode, verificationCode: 'any_string' })
|
||||
|
@ -131,9 +133,10 @@ describe('Generic verification code through management API', () => {
|
|||
it('should throw when the code is not valid', async () => {
|
||||
await requestVerificationCode({ phone: mockPhone });
|
||||
await readVerificationCode();
|
||||
await expect(
|
||||
verifyVerificationCode({ phone: mockPhone, verificationCode: '666' })
|
||||
).rejects.toMatchObject(createResponseWithCode(400));
|
||||
await expectRejects(verifyVerificationCode({ phone: mockPhone, verificationCode: '666' }), {
|
||||
code: 'verification_code.code_mismatch',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when the phone number is not matched', async () => {
|
||||
|
@ -142,9 +145,10 @@ describe('Generic verification code through management API', () => {
|
|||
await requestVerificationCode({ phone: phoneToGetCode });
|
||||
const { code, phone } = await readVerificationCode();
|
||||
expect(phoneToGetCode).toEqual(phone);
|
||||
await expect(
|
||||
verifyVerificationCode({ phone: phoneToVerify, verificationCode: code })
|
||||
).rejects.toMatchObject(createResponseWithCode(400));
|
||||
await expectRejects(verifyVerificationCode({ phone: phoneToVerify, verificationCode: code }), {
|
||||
code: 'verification_code.not_found',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when the email is not matched', async () => {
|
||||
|
@ -153,8 +157,9 @@ describe('Generic verification code through management API', () => {
|
|||
await requestVerificationCode({ email: emailToGetCode });
|
||||
const { code, address } = await readVerificationCode();
|
||||
expect(emailToGetCode).toEqual(address);
|
||||
await expect(
|
||||
verifyVerificationCode({ email: emailToVerify, verificationCode: code })
|
||||
).rejects.toMatchObject(createResponseWithCode(400));
|
||||
await expectRejects(verifyVerificationCode({ email: emailToVerify, verificationCode: code }), {
|
||||
code: 'verification_code.not_found',
|
||||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue