0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-17 22:04:19 -05:00

test(core): add api response guard and error case tests for verification code (#3825)

This commit is contained in:
Xiao Yijun 2023-05-12 17:17:51 +08:00 committed by GitHub
parent 124e0bca0d
commit 59a6ad3b7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 6 deletions

View file

@ -21,6 +21,7 @@ export default function verificationCodeRoutes<T extends AuthedRouter>(
'/verification-codes',
koaGuard({
body: requestVerificationCodePayloadGuard,
status: [204, 400],
}),
async (ctx, next) => {
const code = await createPasscode(undefined, codeType, ctx.guard.body);
@ -36,6 +37,7 @@ export default function verificationCodeRoutes<T extends AuthedRouter>(
'/verification-codes/verify',
koaGuard({
body: verifyVerificationCodePayloadGuard,
status: [204, 400],
}),
async (ctx, next) => {
const { verificationCode, ...identifier } = ctx.guard.body;

View file

@ -1,8 +1,8 @@
import type { RequestVerificationCodePayload, VerifyVerificationCodePayload } from '@logto/schemas';
import type { VerifyVerificationCodePayload } from '@logto/schemas';
import { authedAdminApi } from './api.js';
export const requestVerificationCode = async (payload: RequestVerificationCodePayload) =>
export const requestVerificationCode = async (payload: unknown) =>
authedAdminApi.post('verification-codes', { json: payload });
export const verifyVerificationCode = async (payload: VerifyVerificationCodePayload) =>

View file

@ -1,7 +1,8 @@
import { VerificationCodeType } from '@logto/connector-kit';
import { ConnectorType } from '@logto/schemas';
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,
@ -30,7 +31,9 @@ describe('Generic verification code through management API', () => {
});
it('should create an email verification code on server side', async () => {
await requestVerificationCode({ email: mockEmail });
const payload: RequestVerificationCodePayload = { email: mockEmail };
const response = await requestVerificationCode(payload);
expect(response.statusCode).toBe(204);
const { code, type, address } = await readVerificationCode();
@ -40,7 +43,9 @@ describe('Generic verification code through management API', () => {
});
it('should create an SMS verification code on server side', async () => {
await requestVerificationCode({ phone: mockPhone });
const payload: RequestVerificationCodePayload = { phone: mockPhone };
const response = await requestVerificationCode(payload);
expect(response.statusCode).toBe(204);
const { code, type, phone } = await readVerificationCode();
@ -49,6 +54,60 @@ describe('Generic verification code through management API', () => {
expect(code).not.toBeNull();
});
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 expect(readVerificationCode()).rejects.toThrow();
});
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 expect(
verifyVerificationCode({ email: emailForTestSendCode, verificationCode: 'any_string' })
).rejects.toMatchObject({
response: {
statusCode: 400,
body: JSON.stringify({
message: 'Invalid verification code.',
code: 'verification_code.code_mismatch',
}),
},
});
// Restore the email connector
await setEmailConnector();
});
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 expect(
verifyVerificationCode({ phone: phoneForTestSendCode, verificationCode: 'any_string' })
).rejects.toMatchObject({
response: {
statusCode: 400,
body: JSON.stringify({
message: 'Invalid verification code.',
code: 'verification_code.code_mismatch',
}),
},
});
// Restore the SMS connector
await setSmsConnector();
});
it('should be able to verify the email verification code', async () => {
await requestVerificationCode({ email: mockEmail });
@ -74,6 +133,28 @@ describe('Generic verification code through management API', () => {
await readVerificationCode();
await expect(
verifyVerificationCode({ phone: mockPhone, verificationCode: '666' })
).rejects.toThrow();
).rejects.toMatchObject(createResponseWithCode(400));
});
it('should throw when the phone number is not matched', async () => {
const phoneToVerify = '666';
const phoneToGetCode = mockPhone;
await requestVerificationCode({ phone: phoneToGetCode });
const { code, phone } = await readVerificationCode();
expect(phoneToGetCode).toEqual(phone);
await expect(
verifyVerificationCode({ phone: phoneToVerify, verificationCode: code })
).rejects.toMatchObject(createResponseWithCode(400));
});
it('should throw when the email is not matched', async () => {
const emailToVerify = 'verify_email@mail.com';
const emailToGetCode = mockEmail;
await requestVerificationCode({ email: emailToGetCode });
const { code, address } = await readVerificationCode();
expect(emailToGetCode).toEqual(address);
await expect(
verifyVerificationCode({ email: emailToVerify, verificationCode: code })
).rejects.toMatchObject(createResponseWithCode(400));
});
});