Skip to content

[NoQA] Refactored ValidationUtils files with date-fns. #24061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ const CONST = {
DATE: {
MOMENT_FORMAT_STRING: 'YYYY-MM-DD',
SQL_DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
FNS_FORMAT_STRING: 'yyyy-MM-dd',
Comment on lines 176 to +178
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this different than the moment format? @waterim

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because moment is using its own formatting, and date-fns using ECMAScript Internationalization API, thats why its different

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying 🙇

UNIX_EPOCH: '1970-01-01 00:00:00.000',
MAX_DATE: '9999-12-31',
MIN_DATE: '0001-01-01',
Expand Down
49 changes: 25 additions & 24 deletions src/libs/ValidationUtils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import moment from 'moment';
import {subYears, addYears, startOfDay, endOfMonth, isAfter, isBefore, isValid, isWithinInterval, isSameDay, format} from 'date-fns';
import _ from 'underscore';
import {URL_REGEX_WITH_REQUIRED_PROTOCOL} from 'expensify-common/lib/Url';
import {parsePhoneNumber} from 'awesome-phonenumber';
Expand Down Expand Up @@ -53,10 +53,10 @@ function isValidDate(date) {
return false;
}

const pastDate = moment().subtract(1000, 'years');
const futureDate = moment().add(1000, 'years');
const testDate = moment(date);
return testDate.isValid() && testDate.isBetween(pastDate, futureDate);
const pastDate = subYears(new Date(), 1000);
const futureDate = addYears(new Date(), 1000);
const testDate = new Date(date);
return isValid(testDate) && isAfter(testDate, pastDate) && isBefore(testDate, futureDate);
}

/**
Expand All @@ -70,10 +70,10 @@ function isValidPastDate(date) {
return false;
}

const pastDate = moment().subtract(1000, 'years');
const currentDate = moment();
const testDate = moment(date).startOf('day');
return testDate.isValid() && testDate.isBetween(pastDate, currentDate);
const pastDate = subYears(new Date(), 1000);
const currentDate = new Date();
const testDate = startOfDay(new Date(date));
return isValid(testDate) && isAfter(testDate, pastDate) && isBefore(testDate, currentDate);
}

/**
Expand Down Expand Up @@ -112,7 +112,7 @@ function isValidExpirationDate(string) {

// Use the last of the month to check if the expiration date is in the future or not
const expirationDate = `${CardUtils.getYearFromExpirationDateString(string)}-${CardUtils.getMonthFromExpirationDateString(string)}-01`;
return moment(expirationDate).endOf('month').isAfter(moment());
return isAfter(new Date(expirationDate), endOfMonth(new Date()));
}

/**
Expand Down Expand Up @@ -188,9 +188,9 @@ function isValidPaypalUsername(paypalUsername) {
* @returns {Boolean}
*/
function meetsMinimumAgeRequirement(date) {
const testDate = moment(date);
const minDate = moment().subtract(CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT, 'years');
return testDate.isValid() && testDate.isSameOrBefore(minDate, 'day');
const testDate = new Date(date);
const minDate = subYears(new Date(), CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT);
return isValid(testDate) && (isSameDay(testDate, minDate) || isBefore(testDate, minDate));
}

/**
Expand All @@ -200,9 +200,9 @@ function meetsMinimumAgeRequirement(date) {
* @returns {Boolean}
*/
function meetsMaximumAgeRequirement(date) {
const testDate = moment(date);
const maxDate = moment().subtract(CONST.DATE_BIRTH.MAX_AGE, 'years');
return testDate.isValid() && testDate.isSameOrAfter(maxDate, 'day');
const testDate = new Date(date);
const maxDate = subYears(new Date(), CONST.DATE_BIRTH.MAX_AGE);
return isValid(testDate) && (isSameDay(testDate, maxDate) || isAfter(testDate, maxDate));
}

/**
Expand All @@ -214,19 +214,20 @@ function meetsMaximumAgeRequirement(date) {
* @returns {String|Array}
*/
function getAgeRequirementError(date, minimumAge, maximumAge) {
const recentDate = moment().startOf('day').subtract(minimumAge, 'years');
const longAgoDate = moment().startOf('day').subtract(maximumAge, 'years');
const testDate = moment(date);
if (!testDate.isValid()) {
const currentDate = startOfDay(new Date());
const recentDate = subYears(currentDate, minimumAge);
const longAgoDate = subYears(currentDate, maximumAge);
const testDate = new Date(date);
if (!isValid(testDate)) {
return 'common.error.dateInvalid';
}
if (testDate.isBetween(longAgoDate, recentDate, undefined, '[]')) {
if (isWithinInterval(testDate, {start: longAgoDate, end: recentDate})) {
return '';
}
if (testDate.isSameOrAfter(recentDate)) {
return ['privatePersonalDetails.error.dateShouldBeBefore', {dateString: recentDate.format(CONST.DATE.MOMENT_FORMAT_STRING)}];
if (isSameDay(testDate, recentDate) || isAfter(testDate, recentDate)) {
return ['privatePersonalDetails.error.dateShouldBeBefore', {dateString: format(recentDate, CONST.DATE.FNS_FORMAT_STRING)}];
}
return ['privatePersonalDetails.error.dateShouldBeAfter', {dateString: longAgoDate.format(CONST.DATE.MOMENT_FORMAT_STRING)}];
return ['privatePersonalDetails.error.dateShouldBeAfter', {dateString: format(longAgoDate, CONST.DATE.FNS_FORMAT_STRING)}];
}

/**
Expand Down
24 changes: 12 additions & 12 deletions tests/unit/ValidationUtilsTest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {addDays, format, subYears, startOfDay} from 'date-fns';
import CONST from '../../src/CONST';

const moment = require('moment');
const ValidationUtils = require('../../src/libs/ValidationUtils');

describe('ValidationUtils', () => {
Expand Down Expand Up @@ -50,7 +50,7 @@ describe('ValidationUtils', () => {
});

test('Should return false for a future date', () => {
const futureDate = moment().add(1, 'day').format(CONST.DATE.MOMENT_FORMAT_STRING);
const futureDate = format(addDays(new Date(), 1), CONST.DATE.FNS_FORMAT_STRING);
const isValid = ValidationUtils.isValidPastDate(futureDate);
expect(isValid).toBe(false);
});
Expand All @@ -76,7 +76,7 @@ describe('ValidationUtils', () => {
});

test('Should return true for a valid date value', () => {
const dateValue = moment();
const dateValue = new Date();
const isFulfilled = ValidationUtils.isRequiredFulfilled(dateValue);
expect(isFulfilled).toBe(true);
});
Expand Down Expand Up @@ -139,13 +139,13 @@ describe('ValidationUtils', () => {

describe('meetsMinimumAgeRequirement', () => {
test('Should return true for a date that meets the minimum age requirement', () => {
const validDate = moment().subtract(18, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 18 years ago
const validDate = format(subYears(new Date(), 18), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 18 years ago
const meetsRequirement = ValidationUtils.meetsMinimumAgeRequirement(validDate);
expect(meetsRequirement).toBe(true);
});

test('Should return false for a date that does not meet the minimum age requirement', () => {
const invalidDate = moment().subtract(17, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 17 years ago
const invalidDate = format(subYears(new Date(), 17), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 17 years ago
const meetsRequirement = ValidationUtils.meetsMinimumAgeRequirement(invalidDate);
expect(meetsRequirement).toBe(false);
});
Expand All @@ -159,13 +159,13 @@ describe('ValidationUtils', () => {

describe('meetsMaximumAgeRequirement', () => {
test('Should return true for a date that meets the maximum age requirement', () => {
const validDate = moment().subtract(65, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 65 years ago
const validDate = format(subYears(new Date(), 65), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 65 years ago
const meetsRequirement = ValidationUtils.meetsMaximumAgeRequirement(validDate);
expect(meetsRequirement).toBe(true);
});

test('Should return false for a date that does not meet the maximum age requirement', () => {
const invalidDate = moment().subtract(151, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 151 years ago
const invalidDate = format(subYears(new Date(), 151), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 151 years ago
const meetsRequirement = ValidationUtils.meetsMaximumAgeRequirement(invalidDate);
expect(meetsRequirement).toBe(false);
});
Expand All @@ -179,21 +179,21 @@ describe('ValidationUtils', () => {

describe('getAgeRequirementError', () => {
test('Should return an empty string for a date within the specified range', () => {
const validDate = moment().subtract(30, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 30 years ago
const validDate = format(subYears(new Date(), 30), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 30 years ago
const error = ValidationUtils.getAgeRequirementError(validDate, 18, 150);
expect(error).toBe('');
});

test('Should return an error message for a date before the minimum age requirement', () => {
const invalidDate = moment().subtract(17, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 17 years ago
const invalidDate = format(subYears(new Date(), 17), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 17 years ago
const error = ValidationUtils.getAgeRequirementError(invalidDate, 18, 150);
expect(error).toEqual(['privatePersonalDetails.error.dateShouldBeBefore', {dateString: moment().subtract(18, 'years').startOf('day').format(CONST.DATE.MOMENT_FORMAT_STRING)}]);
expect(error).toEqual(['privatePersonalDetails.error.dateShouldBeBefore', {dateString: format(startOfDay(subYears(new Date(), 18)), CONST.DATE.FNS_FORMAT_STRING)}]);
});

test('Should return an error message for a date after the maximum age requirement', () => {
const invalidDate = moment().subtract(160, 'years').format(CONST.DATE.MOMENT_FORMAT_STRING); // Date of birth 160 years ago
const invalidDate = format(subYears(new Date(), 160), CONST.DATE.FNS_FORMAT_STRING); // Date of birth 160 years ago
const error = ValidationUtils.getAgeRequirementError(invalidDate, 18, 150);
expect(error).toEqual(['privatePersonalDetails.error.dateShouldBeAfter', {dateString: moment().subtract(150, 'years').startOf('day').format(CONST.DATE.MOMENT_FORMAT_STRING)}]);
expect(error).toEqual(['privatePersonalDetails.error.dateShouldBeAfter', {dateString: format(startOfDay(subYears(new Date(), 150)), CONST.DATE.FNS_FORMAT_STRING)}]);
});

test('Should return an error message for an invalid date', () => {
Expand Down