From 4d1c747504dfc8bcf30560c69dd394f60fb789c8 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Tue, 15 Jul 2025 23:32:10 +0200 Subject: [PATCH 1/8] test(finance): add case for credit card issuer pattern validation --- test/modules/finance.spec.ts | 57 +++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/test/modules/finance.spec.ts b/test/modules/finance.spec.ts index d325f1b7813..94b4dc9fbcb 100644 --- a/test/modules/finance.spec.ts +++ b/test/modules/finance.spec.ts @@ -1,6 +1,6 @@ import isCreditCard from 'validator/lib/isCreditCard'; import { describe, expect, it } from 'vitest'; -import { faker, fakerZH_CN } from '../../src'; +import { allLocales, faker, fakerZH_CN } from '../../src'; import { FakerError } from '../../src/errors/faker-error'; import { BitcoinAddressFamily, @@ -597,3 +597,58 @@ describe('finance', () => { } ); }); + +describe('finance locale data', () => { + describe.each(Object.entries(allLocales))(`%s`, (_localeName, localeData) => { + describe('credit cards', () => { + describe('issuer', () => { + describe.each(Object.entries(localeData.finance?.credit_card ?? {}))( + '%s', + (issuerName, issuerPatterns) => { + // Dedicated type for readability purposes + type KnownProvider = Exclude< + Parameters[1], + undefined + >['provider']; + + function isKnownProvider( + value: string | undefined + ): value is KnownProvider { + // taken from type definitions of validatorjs: + // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/be7c952a562aa9a55f06058187ece41fcb173b17/types/validator/index.d.ts#L268 + return ( + value === undefined || + [ + 'amex', + 'dinersclub', + 'discover', + 'jcb', + 'mastercard', + 'unionpay', + 'visa', + ].includes(value) + ); + } + + function isCreditCardFromIsser(value: string) { + if (!isKnownProvider(value)) { + // best we can do is retun false, so that the test fails + return false; + } + + return isCreditCard(value, { provider: value }); + } + + it.each(issuerPatterns)( + 'patter "%s" should generate a valid credit card number', + (pattern) => { + const result = faker.finance.creditCardNumber(pattern); + expect(result).toSatisfy(isCreditCardFromIsser); + } + ); + } + ); + }); + }); + }); +}); From d64050e4e4c95b9589b9227259423cfb3a05227f Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 16 Jul 2025 19:31:35 +0200 Subject: [PATCH 2/8] test: fix incorrect provider parameter --- test/modules/finance.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/modules/finance.spec.ts b/test/modules/finance.spec.ts index 94b4dc9fbcb..cdec4fe7b77 100644 --- a/test/modules/finance.spec.ts +++ b/test/modules/finance.spec.ts @@ -631,12 +631,12 @@ describe('finance locale data', () => { } function isCreditCardFromIsser(value: string) { - if (!isKnownProvider(value)) { + if (!isKnownProvider(issuerName)) { // best we can do is retun false, so that the test fails return false; } - return isCreditCard(value, { provider: value }); + return isCreditCard(value, { provider: issuerName }); } it.each(issuerPatterns)( From 890fa34b0c0955b3635fc645ff5af39348fa7a81 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 16 Jul 2025 19:32:03 +0200 Subject: [PATCH 3/8] test: add luhn check for better error evaluation --- test/modules/finance.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/modules/finance.spec.ts b/test/modules/finance.spec.ts index cdec4fe7b77..b17f003de10 100644 --- a/test/modules/finance.spec.ts +++ b/test/modules/finance.spec.ts @@ -1,4 +1,5 @@ import isCreditCard from 'validator/lib/isCreditCard'; +import isLuhnNumber from 'validator/lib/isLuhnNumber'; import { describe, expect, it } from 'vitest'; import { allLocales, faker, fakerZH_CN } from '../../src'; import { FakerError } from '../../src/errors/faker-error'; @@ -643,6 +644,7 @@ describe('finance locale data', () => { 'patter "%s" should generate a valid credit card number', (pattern) => { const result = faker.finance.creditCardNumber(pattern); + expect(result).toSatisfy(isLuhnNumber); expect(result).toSatisfy(isCreditCardFromIsser); } ); From 84868c2e45e5553a9e42aa27703ff4c7e13bc5a9 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 16 Jul 2025 19:32:38 +0200 Subject: [PATCH 4/8] refactor: remove invalid "discover" patterns --- src/locales/el/finance/credit_card/discover.ts | 6 +----- src/locales/en/finance/credit_card/discover.ts | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/locales/el/finance/credit_card/discover.ts b/src/locales/el/finance/credit_card/discover.ts index 1010fae7e49..6b7bbb482ea 100644 --- a/src/locales/el/finance/credit_card/discover.ts +++ b/src/locales/el/finance/credit_card/discover.ts @@ -1,5 +1 @@ -export default [ - '/6011-####-####-###L/', - '/64[4-9]#-####-####-###L/', - '/65##-####-####-###L/', -]; +export default ['/6011-####-####-###L/', '/65##-####-####-###L/']; diff --git a/src/locales/en/finance/credit_card/discover.ts b/src/locales/en/finance/credit_card/discover.ts index d2b3ac18dbb..734723f8929 100644 --- a/src/locales/en/finance/credit_card/discover.ts +++ b/src/locales/en/finance/credit_card/discover.ts @@ -1,5 +1 @@ -export default [ - '6011-####-####-###L', - '64[4-9]#-####-####-###L', - '65##-####-####-###L', -]; +export default ['6011-####-####-###L', '65##-####-####-###L']; From a3fddc6c98770dc74feba955c10bc216b38816fd Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 16 Jul 2025 20:08:54 +0200 Subject: [PATCH 5/8] refactor: remove invalid "diners_club" patterns --- src/locales/en/finance/credit_card/diners_club.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/locales/en/finance/credit_card/diners_club.ts b/src/locales/en/finance/credit_card/diners_club.ts index b372913b820..b5eb693355b 100644 --- a/src/locales/en/finance/credit_card/diners_club.ts +++ b/src/locales/en/finance/credit_card/diners_club.ts @@ -1,5 +1 @@ -export default [ - '30[0-5]#-######-###L', - '36##-######-###L', - '54##-####-####-###L', -]; +export default ['30[0-5]#-######-###L', '36##-######-###L']; From 517fb09809c6499cb0656ca043e645ccc846cac4 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 16 Jul 2025 20:09:47 +0200 Subject: [PATCH 6/8] test: refine provider mapping --- test/modules/finance.spec.ts | 47 +++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/test/modules/finance.spec.ts b/test/modules/finance.spec.ts index b17f003de10..316cb15b872 100644 --- a/test/modules/finance.spec.ts +++ b/test/modules/finance.spec.ts @@ -612,32 +612,35 @@ describe('finance locale data', () => { undefined >['provider']; - function isKnownProvider( + function getKnownProvider( value: string | undefined - ): value is KnownProvider { - // taken from type definitions of validatorjs: - // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/be7c952a562aa9a55f06058187ece41fcb173b17/types/validator/index.d.ts#L268 - return ( - value === undefined || - [ - 'amex', - 'dinersclub', - 'discover', - 'jcb', - 'mastercard', - 'unionpay', - 'visa', - ].includes(value) - ); + ): KnownProvider { + // taken from definitions of validatorjs: + // https://github.com/validatorjs/validator.js/blob/72573b3d1d8ab2e6575e6bba1cbe2b01f95f4935/src/lib/isCreditCard.js#L4-L12 + const providers: Record = { + american_express: 'amex', + diners_club: 'dinersclub', + discover: 'discover', + jcb: 'jcb', + mastercard: 'mastercard', + unionpay: 'unionpay', + visa: 'visa', + }; + + const knownProvider = providers[value ?? '']; + if (knownProvider == null) { + throw new Error( + `Issuer "${value}" is not a known provider for validatorjs. Because of that the validity of it's patterns can not be verified.` + ); + } + + return knownProvider; } function isCreditCardFromIsser(value: string) { - if (!isKnownProvider(issuerName)) { - // best we can do is retun false, so that the test fails - return false; - } - - return isCreditCard(value, { provider: issuerName }); + return isCreditCard(value, { + provider: getKnownProvider(issuerName), + }); } it.each(issuerPatterns)( From 0f1d1117fc7d0dc7619e0c937402986b71570947 Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Wed, 16 Jul 2025 20:10:13 +0200 Subject: [PATCH 7/8] test: filter out locale entries without finance data --- test/modules/finance.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/modules/finance.spec.ts b/test/modules/finance.spec.ts index 316cb15b872..ab2dd074fc6 100644 --- a/test/modules/finance.spec.ts +++ b/test/modules/finance.spec.ts @@ -600,7 +600,10 @@ describe('finance', () => { }); describe('finance locale data', () => { - describe.each(Object.entries(allLocales))(`%s`, (_localeName, localeData) => { + const localesWithData = Object.entries(allLocales).filter( + ([, data]) => Object.keys(data.finance?.credit_card ?? {}).length > 0 + ); + describe.each(localesWithData)(`%s`, (_localeName, localeData) => { describe('credit cards', () => { describe('issuer', () => { describe.each(Object.entries(localeData.finance?.credit_card ?? {}))( From 17ba487aea09ac332b08c985c642cc038a1489ba Mon Sep 17 00:00:00 2001 From: xDivisionByZerox Date: Mon, 11 Aug 2025 22:49:58 +0200 Subject: [PATCH 8/8] test(finance): move function definition to prevent constant recreation --- test/modules/finance.spec.ts | 66 +++++++++++++++++------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/test/modules/finance.spec.ts b/test/modules/finance.spec.ts index ab2dd074fc6..d79bc79a060 100644 --- a/test/modules/finance.spec.ts +++ b/test/modules/finance.spec.ts @@ -600,6 +600,35 @@ describe('finance', () => { }); describe('finance locale data', () => { + // Dedicated type for readability purposes + type KnownProvider = Exclude< + Parameters[1], + undefined + >['provider']; + + function getKnownProvider(value: string | undefined): KnownProvider { + // taken from definitions of validatorjs: + // https://github.com/validatorjs/validator.js/blob/72573b3d1d8ab2e6575e6bba1cbe2b01f95f4935/src/lib/isCreditCard.js#L4-L12 + const providers: Record = { + american_express: 'amex', + diners_club: 'dinersclub', + discover: 'discover', + jcb: 'jcb', + mastercard: 'mastercard', + unionpay: 'unionpay', + visa: 'visa', + }; + + const knownProvider = providers[value ?? '']; + if (knownProvider == null) { + throw new Error( + `Issuer "${value}" is not a known provider for validatorjs. Because of that the validity of it's patterns can not be verified.` + ); + } + + return knownProvider; + } + const localesWithData = Object.entries(allLocales).filter( ([, data]) => Object.keys(data.finance?.credit_card ?? {}).length > 0 ); @@ -609,49 +638,18 @@ describe('finance locale data', () => { describe.each(Object.entries(localeData.finance?.credit_card ?? {}))( '%s', (issuerName, issuerPatterns) => { - // Dedicated type for readability purposes - type KnownProvider = Exclude< - Parameters[1], - undefined - >['provider']; - - function getKnownProvider( - value: string | undefined - ): KnownProvider { - // taken from definitions of validatorjs: - // https://github.com/validatorjs/validator.js/blob/72573b3d1d8ab2e6575e6bba1cbe2b01f95f4935/src/lib/isCreditCard.js#L4-L12 - const providers: Record = { - american_express: 'amex', - diners_club: 'dinersclub', - discover: 'discover', - jcb: 'jcb', - mastercard: 'mastercard', - unionpay: 'unionpay', - visa: 'visa', - }; - - const knownProvider = providers[value ?? '']; - if (knownProvider == null) { - throw new Error( - `Issuer "${value}" is not a known provider for validatorjs. Because of that the validity of it's patterns can not be verified.` - ); - } - - return knownProvider; - } - - function isCreditCardFromIsser(value: string) { + function isCreditCardFromIssuer(value: string) { return isCreditCard(value, { provider: getKnownProvider(issuerName), }); } it.each(issuerPatterns)( - 'patter "%s" should generate a valid credit card number', + 'pattern "%s" should generate a valid credit card number', (pattern) => { const result = faker.finance.creditCardNumber(pattern); expect(result).toSatisfy(isLuhnNumber); - expect(result).toSatisfy(isCreditCardFromIsser); + expect(result).toSatisfy(isCreditCardFromIssuer); } ); }