Browse Source

feat: add credit card validator

pull/4025/head
Arman Ozak 6 years ago
parent
commit
bfe5360656
  1. 39
      npm/ng-packs/packages/core/src/lib/tests/validators.spec.ts
  2. 32
      npm/ng-packs/packages/core/src/lib/validators/credit-card.validator.ts
  3. 3
      npm/ng-packs/packages/core/src/lib/validators/index.ts

39
npm/ng-packs/packages/core/src/lib/tests/validators.spec.ts

@ -1,7 +1,46 @@
import { FormControl } from '@angular/forms';
import { validateCreditCard } from '../validators/credit-card.validator';
import { validateRequired } from '../validators/required.validator';
describe('Validators', () => {
describe('Credit Card Validator', () => {
const error = { creditCardNumber: true };
test.each`
input | expected
${'0'} | ${error}
${'5105105105105100' /* Mastercard */} | ${null}
${'5105105105105101' /* Mastercard */} | ${error}
${'5105 1051 0510 5100'} | ${null}
${'5105-1051-0510-5100'} | ${null}
${'5105 - 1051 - 0510 - 5100'} | ${null}
${'4111111111111111' /*Visa*/} | ${null}
${'4111111111111112' /*Visa*/} | ${error}
${'4012888888881881' /* Visa */} | ${null}
${'4012888888881882' /* Visa */} | ${error}
${'4222222222222' /* Visa */} | ${null}
${'4222222222223' /* Visa */} | ${error}
${'378282246310005' /* American Express */} | ${null}
${'378282246310006' /* American Express */} | ${error}
${'6011111111111117' /* Discover */} | ${null}
${'6011111111111118' /* Discover */} | ${error}
`('should return $expected when input is $input', ({ input, expected }) => {
const control = new FormControl(input, [validateCreditCard()]);
control.markAsDirty({ onlySelf: true });
control.updateValueAndValidity({ onlySelf: true, emitEvent: false });
expect(control.errors).toEqual(expected);
});
it('should return null when control is pristine', () => {
const invalidNumber = '5105105105105101';
const control = new FormControl(invalidNumber, [validateCreditCard()]);
// control is not dirty
expect(control.valid).toBe(true);
});
});
describe('Required Validator', () => {
const error = { required: true };

32
npm/ng-packs/packages/core/src/lib/validators/credit-card.validator.ts

@ -0,0 +1,32 @@
import { AbstractControl, ValidatorFn } from '@angular/forms';
export interface CreditCardError {
creditCardNumber: true;
}
export function validateCreditCard(): ValidatorFn {
return (control: AbstractControl): CreditCardError | null => {
if (control.pristine) return null;
return isValidCreditCard(String(control.value)) ? null : { creditCardNumber: true };
};
}
function isValidCreditCard(value: string): boolean {
value = value.replace(/[ -]/g, '');
if (!/^[0-9]{13,19}$/.test(value)) return false;
let checksum = 0;
let multiplier = 1;
for (let i = value.length; i > 0; i--) {
const digit = Number(value[i - 1]) * multiplier;
/* tslint:disable-next-line:no-bitwise */
checksum += (digit % 10) + ~~(digit / 10);
multiplier = (multiplier * 2) % 3;
}
return checksum % 10 === 0;
}

3
npm/ng-packs/packages/core/src/lib/validators/index.ts

@ -1,8 +1,11 @@
import { Validators } from '@angular/forms';
import { validateCreditCard } from './credit-card.validator';
import { validateRequired } from './required.validator';
export * from './credit-card.validator';
export * from './required.validator';
export const AbpValidators = {
creditCard: validateCreditCard,
email: () => Validators.email,
required: validateRequired,
};

Loading…
Cancel
Save