mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
const { generateOTP, getOTPExpiry, isOTPExpired } = require('../../utils/otp.util');
|
||||
|
||||
// ── generateOTP ───────────────────────────────────────────────────────────────
|
||||
|
||||
describe('generateOTP()', () => {
|
||||
test('returns a 6-character string', () => {
|
||||
expect(generateOTP()).toHaveLength(6);
|
||||
});
|
||||
|
||||
test('contains only digits', () => {
|
||||
expect(generateOTP()).toMatch(/^\d{6}$/);
|
||||
});
|
||||
|
||||
test('value is within 000000-999999', () => {
|
||||
const n = Number(generateOTP());
|
||||
expect(n).toBeGreaterThanOrEqual(0);
|
||||
expect(n).toBeLessThanOrEqual(999999);
|
||||
});
|
||||
|
||||
test('zero-pads values under 100000', () => {
|
||||
// Run many samples to catch low values; deterministic check via string length
|
||||
for (let i = 0; i < 50; i++) {
|
||||
expect(generateOTP()).toHaveLength(6);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ── getOTPExpiry ──────────────────────────────────────────────────────────────
|
||||
|
||||
describe('getOTPExpiry()', () => {
|
||||
test('returns a Date instance', () => {
|
||||
expect(getOTPExpiry()).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
test('expiry is in the future', () => {
|
||||
expect(getOTPExpiry().getTime()).toBeGreaterThan(Date.now());
|
||||
});
|
||||
|
||||
test('default offset is approximately 10 minutes', () => {
|
||||
const before = Date.now();
|
||||
const expiry = getOTPExpiry().getTime();
|
||||
const after = Date.now();
|
||||
const tenMin = 10 * 60 * 1000;
|
||||
expect(expiry).toBeGreaterThanOrEqual(before + tenMin - 100);
|
||||
expect(expiry).toBeLessThanOrEqual(after + tenMin + 100);
|
||||
});
|
||||
|
||||
test('custom minutes are respected', () => {
|
||||
const before = Date.now();
|
||||
const expiry = getOTPExpiry(5).getTime();
|
||||
const fiveMin = 5 * 60 * 1000;
|
||||
expect(expiry).toBeGreaterThanOrEqual(before + fiveMin - 100);
|
||||
});
|
||||
});
|
||||
|
||||
// ── isOTPExpired ──────────────────────────────────────────────────────────────
|
||||
|
||||
describe('isOTPExpired()', () => {
|
||||
test('null → expired (true)', () => {
|
||||
expect(isOTPExpired(null)).toBe(true);
|
||||
});
|
||||
|
||||
test('undefined → expired (true)', () => {
|
||||
expect(isOTPExpired(undefined)).toBe(true);
|
||||
});
|
||||
|
||||
test('past date → expired (true)', () => {
|
||||
const past = new Date(Date.now() - 60_000);
|
||||
expect(isOTPExpired(past)).toBe(true);
|
||||
});
|
||||
|
||||
test('future date → not expired (false)', () => {
|
||||
const future = new Date(Date.now() + 60_000);
|
||||
expect(isOTPExpired(future)).toBe(false);
|
||||
});
|
||||
|
||||
test('accepts ISO string as well as Date', () => {
|
||||
const future = new Date(Date.now() + 60_000).toISOString();
|
||||
expect(isOTPExpired(future)).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user