feat: Add unit tests for backend validators and configure Jest.
This commit is contained in:
parent
ebcae0b3e7
commit
9bb941b45e
16 changed files with 2071 additions and 381 deletions
246
Backend/tests/unit/validators/auth.validator.test.ts
Normal file
246
Backend/tests/unit/validators/auth.validator.test.ts
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
import {
|
||||
loginSchema,
|
||||
registerSchema,
|
||||
refreshTokenSchema,
|
||||
resetPasswordSchema,
|
||||
changePasswordSchema,
|
||||
resetRequestSchema,
|
||||
} from '@/validators/auth.validator';
|
||||
|
||||
// ============================================================
|
||||
// loginSchema
|
||||
// ============================================================
|
||||
|
||||
describe('loginSchema', () => {
|
||||
it('should pass with valid email and password', () => {
|
||||
const { error } = loginSchema.validate({
|
||||
email: 'user@example.com',
|
||||
password: 'password123',
|
||||
});
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail with invalid email format', () => {
|
||||
const { error } = loginSchema.validate({
|
||||
email: 'not-an-email',
|
||||
password: 'password123',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/valid email/i);
|
||||
});
|
||||
|
||||
it('should fail without email', () => {
|
||||
const { error } = loginSchema.validate({ password: 'password123' });
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Email is required/i);
|
||||
});
|
||||
|
||||
it('should fail without password', () => {
|
||||
const { error } = loginSchema.validate({ email: 'user@example.com' });
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Password is required/i);
|
||||
});
|
||||
|
||||
it('should fail with password shorter than 6 characters', () => {
|
||||
const { error } = loginSchema.validate({
|
||||
email: 'user@example.com',
|
||||
password: '12345',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/at least 6 characters/i);
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// registerSchema
|
||||
// ============================================================
|
||||
|
||||
describe('registerSchema', () => {
|
||||
const validPayload = {
|
||||
username: 'john_doe',
|
||||
email: 'john@example.com',
|
||||
password: 'securepass',
|
||||
first_name: 'John',
|
||||
last_name: 'Doe',
|
||||
phone: '0812345678',
|
||||
};
|
||||
|
||||
it('should pass with all required fields', () => {
|
||||
const { error } = registerSchema.validate(validPayload);
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should pass with optional prefix', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
prefix: { th: 'นาย', en: 'Mr.' },
|
||||
});
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail if username has invalid characters', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
username: 'john doe!',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/letters, numbers, and underscores/i);
|
||||
});
|
||||
|
||||
it('should fail if username is too short (< 3 chars)', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
username: 'ab',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/at least 3 characters/i);
|
||||
});
|
||||
|
||||
it('should fail if username is too long (> 50 chars)', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
username: 'a'.repeat(51),
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/not exceed 50 characters/i);
|
||||
});
|
||||
|
||||
it('should fail with invalid email', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
email: 'bad-email',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
});
|
||||
|
||||
it('should fail if phone is too short (< 10 chars)', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
phone: '081234',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
});
|
||||
|
||||
it('should fail without first_name', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
first_name: undefined,
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/First name is required/i);
|
||||
});
|
||||
|
||||
it('should fail without last_name', () => {
|
||||
const { error } = registerSchema.validate({
|
||||
...validPayload,
|
||||
last_name: undefined,
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Last name is required/i);
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// refreshTokenSchema
|
||||
// ============================================================
|
||||
|
||||
describe('refreshTokenSchema', () => {
|
||||
it('should pass with a valid refreshToken', () => {
|
||||
const { error } = refreshTokenSchema.validate({
|
||||
refreshToken: 'some-refresh-token-string',
|
||||
});
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail without refreshToken', () => {
|
||||
const { error } = refreshTokenSchema.validate({});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Refresh token is required/i);
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// resetPasswordSchema
|
||||
// ============================================================
|
||||
|
||||
describe('resetPasswordSchema', () => {
|
||||
it('should pass with valid token and password', () => {
|
||||
const { error } = resetPasswordSchema.validate({
|
||||
token: 'reset-token-abc',
|
||||
password: 'newpassword',
|
||||
});
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail without token', () => {
|
||||
const { error } = resetPasswordSchema.validate({ password: 'newpassword' });
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Reset token is required/i);
|
||||
});
|
||||
|
||||
it('should fail with password too short', () => {
|
||||
const { error } = resetPasswordSchema.validate({
|
||||
token: 'abc',
|
||||
password: '12345',
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/at least 6 characters/i);
|
||||
});
|
||||
|
||||
it('should fail with password too long (> 100 chars)', () => {
|
||||
const { error } = resetPasswordSchema.validate({
|
||||
token: 'abc',
|
||||
password: 'a'.repeat(101),
|
||||
});
|
||||
expect(error).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// changePasswordSchema (auth)
|
||||
// ============================================================
|
||||
|
||||
describe('changePasswordSchema (auth.validator)', () => {
|
||||
it('should pass with valid old and new passwords', () => {
|
||||
const { error } = changePasswordSchema.validate({
|
||||
oldPassword: 'oldpass123',
|
||||
newPassword: 'newpass456',
|
||||
});
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail without oldPassword', () => {
|
||||
const { error } = changePasswordSchema.validate({ newPassword: 'newpass456' });
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Password is required/i);
|
||||
});
|
||||
|
||||
it('should fail without newPassword', () => {
|
||||
const { error } = changePasswordSchema.validate({ oldPassword: 'oldpass123' });
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Password is required/i);
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// resetRequestSchema
|
||||
// ============================================================
|
||||
|
||||
describe('resetRequestSchema', () => {
|
||||
it('should pass with valid email', () => {
|
||||
const { error } = resetRequestSchema.validate({ email: 'user@example.com' });
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail without email', () => {
|
||||
const { error } = resetRequestSchema.validate({});
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/Email is required/i);
|
||||
});
|
||||
|
||||
it('should fail with invalid email', () => {
|
||||
const { error } = resetRequestSchema.validate({ email: 'not-email' });
|
||||
expect(error).toBeDefined();
|
||||
expect(error?.details[0].message).toMatch(/valid email/i);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue