diff --git a/__tests__/core-utils/element-validations.test.js b/__tests__/core-utils/element-validations.test.js index b9960f6..9f46068 100644 --- a/__tests__/core-utils/element-validations.test.js +++ b/__tests__/core-utils/element-validations.test.js @@ -8,6 +8,7 @@ import { validatePin, validateRevealElementRecords, validateGetInput, + validateExpiryDate, } from '../../src/core-utils/element-validations'; import SKYFLOW_ERROR_CODE from '../../src/utils/skyflow-error-code'; import { parameterizedString } from '../../src/utils/logs-helper'; @@ -186,6 +187,41 @@ describe('test validatePin function', () => { }); }); +describe('test validateExpiryDate function with various format', () => { + it('should return true for current month/year', () => { + const today = new Date(); + const month = (today.getMonth() + 1).toString().padStart(2, '0'); + const year = today.getFullYear(); + expect(validateExpiryDate(`${month}/${year}`, 'MM/YYYY')).toBe(true); + expect(validateExpiryDate(`${year}/${month}`, 'YYYY/MM')).toBe(true); + + const yearTwoDigit = year % 100; + expect(validateExpiryDate(`${month}/${yearTwoDigit}`, 'MM/YY')).toBe(true); + expect(validateExpiryDate(`${yearTwoDigit}/${month}`, 'YY/MM')).toBe(true); + }); + + it('should return true for valid future date', () => { + expect(validateExpiryDate('07/2074', 'MM/YYYY')).toBe(true); + expect(validateExpiryDate('2074/04', 'YYYY/MM')).toBe(true); + expect(validateExpiryDate('01/35', 'MM/YY')).toBe(true); + expect(validateExpiryDate('35/04', 'YY/MM')).toBe(true); + }); + + it('should return false for expired dates', () => { + expect(validateExpiryDate('01/2020', 'MM/YYYY')).toBe(false); + expect(validateExpiryDate('2000/04', 'YYYY/MM')).toBe(false); + expect(validateExpiryDate('04/20', 'MM/YY')).toBe(false); + expect(validateExpiryDate('20/04', 'YY/MM')).toBe(false); + }); + + it('should return false for invalid month for expired date', () => { + expect(validateExpiryDate('15/2040', 'MM/YYYY')).toBe(false); + expect(validateExpiryDate('2040/16', 'YYYY/MM')).toBe(false); + expect(validateExpiryDate('14/20', 'MM/YY')).toBe(false); + expect(validateExpiryDate('40/14', 'YY/MM')).toBe(false); + }); +}); + describe('test validateRevealElementRecords', () => { it('should throw error when invalid redaction type is passed', (done) => { try { diff --git a/src/core-utils/element-validations/index.ts b/src/core-utils/element-validations/index.ts index b9491bf..9f20042 100644 --- a/src/core-utils/element-validations/index.ts +++ b/src/core-utils/element-validations/index.ts @@ -58,13 +58,20 @@ export const validateExpiryDate = (date: string, format: string) => { if (date.trim().length === 0) return true; if (!date.includes('/')) return false; const { month, year } = getYearAndMonthBasedOnFormat(date, format); - const expiryDate = new Date(`${year}-${month}-01`); + + if (month < 1 || month > 12) return false; + + const expiryDate = new Date(Number(year), Number(month) - 1, 1); const today = new Date(); + today.setDate(1); + today.setHours(0, 0, 0, 0); const maxDate = new Date(); maxDate.setFullYear(today.getFullYear() + 50); + maxDate.setDate(1); + maxDate.setHours(0, 0, 0, 0); - return expiryDate > today && expiryDate <= maxDate; + return expiryDate >= today && expiryDate <= maxDate; }; export const validateCreditCardNumber = (cardNumber: string) => {