diff --git a/README.md b/README.md index 925e608..c61b60e 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ The following set of extra asserts are provided by this package: - [Callback](#callback) (requires `callback`) - [CpfNumber](#cpfnumber) (requires `cpf`) - [CreditCard](#creditcard) (requires `creditcard`) +- [CurpNumber](#curpnumber) (requires `curp`) - [Date](#date) (requires `moment` for format validation only) - [DateDiffGreaterThan](#datediffgreaterthan) (requires `moment`) - [DateDiffGreaterThanOrEqualTo](#datediffgreaterthanorequalto) (requires `moment`) @@ -114,6 +115,9 @@ Tests if the value is valid CPF number. ### CreditCard Tests if the value is a valid credit card number using the Luhn10 algorithm. +### CurpNumber +Tests if the value is valid CURP number. + ### Date Tests if the value is a valid date. diff --git a/package.json b/package.json index 0f59fbd..bc43845 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "bignumber.js": "^9.0.0", "cpf": "^2.0.1", "creditcard": "^0.1.2", + "curp": "^1.2.3", "google-libphonenumber": "^1.0.18", "iban": "0.0.6", "isoc": "0.0.1", @@ -66,6 +67,7 @@ "bignumber.js": ">=7 <=9.0.0", "cpf": "^2.0.1", "creditcard": ">=0.0.1 <1.0.0", + "curp": "^1.2.3", "google-libphonenumber": ">=1 <4", "iban": ">=0.0.6 <1.0.0", "isoc": ">=0.0.1 <1.0.0", diff --git a/src/asserts/curp-number-assert.js b/src/asserts/curp-number-assert.js new file mode 100644 index 0000000..ab4c4c4 --- /dev/null +++ b/src/asserts/curp-number-assert.js @@ -0,0 +1,53 @@ +'use strict'; + +/** + * Module dependencies. + */ + +const _ = require('lodash'); +const { Validator, Violation } = require('validator.js'); +let curp; + +/** + * Optional peer dependencies. + */ + +try { + curp = require('curp'); +} catch (e) { + // eslint-disable-next-line no-empty +} + +/** + * Export `CurpNumber`. + */ + +module.exports = function curpNumberAssert() { + if (!curp) { + throw new Error('curp is not installed'); + } + + /** + * Class name. + */ + + this.__class__ = 'CurpNumber'; + + /** + * Validation algorithm. + */ + + this.validate = function (value) { + if (!_.isString(value)) { + throw new Violation(this, value, { value: Validator.errorCode.must_be_a_string }); + } + + if (!curp.validar(value)) { + throw new Violation(this, value, { value: 'must_be_a_valid_curp_number' }); + } + + return true; + }; + + return this; +}; diff --git a/src/index.js b/src/index.js index 6675139..a212821 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,7 @@ const Boolean = require('./asserts/boolean-assert.js'); const Callback = require('./asserts/callback-assert'); const CpfNumber = require('./asserts/cpf-number-assert'); const CreditCard = require('./asserts/credit-card-assert.js'); +const CurpNumber = require('./asserts/curp-number-assert.js'); const Date = require('./asserts/date-assert.js'); const DateDiffGreaterThan = require('./asserts/date-diff-greater-than-assert.js'); const DateDiffGreaterThanOrEqualTo = require('./asserts/date-diff-greater-than-or-equal-to-assert.js'); @@ -60,6 +61,7 @@ module.exports = { Callback, CpfNumber, CreditCard, + CurpNumber, Date, DateDiffGreaterThan, DateDiffGreaterThanOrEqualTo, diff --git a/test/asserts/curp-number-assert.test.js b/test/asserts/curp-number-assert.test.js new file mode 100644 index 0000000..b070719 --- /dev/null +++ b/test/asserts/curp-number-assert.test.js @@ -0,0 +1,51 @@ +'use strict'; + +/** + * Module dependencies. + */ + +const { Assert: BaseAssert, Violation } = require('validator.js'); +const CurpNumberAssert = require('../../src/asserts/curp-number-assert'); + +/** + * Extend `Assert` with `CurpNumberAssert`. + */ + +const Assert = BaseAssert.extend({ + CurpNumber: CurpNumberAssert +}); + +/** + * Test `CurpNumberAssert`. + */ + +describe('CurpNumberAssert', () => { + it('should throw an error if the input value is not a string', () => { + try { + Assert.curpNumber().validate(); + + fail(); + } catch (e) { + expect(e).toBeInstanceOf(Violation); + expect(e.show().assert).toBe('CurpNumber'); + expect(e.value).toBeUndefined(); + expect(e.violation.value).toBe('must_be_a_string'); + } + }); + + it('should throw an error if `curp` is invalid', () => { + try { + Assert.curpNumber().validate('123'); + + fail(); + } catch (e) { + expect(e).toBeInstanceOf(Violation); + expect(e.value).toBe('123'); + expect(e.violation.value).toBe('must_be_a_valid_curp_number'); + } + }); + + it('should accept a valid `curp`', () => { + Assert.curpNumber().validate('LOOA531113HTCPBN07'); + }); +}); diff --git a/test/index.test.js b/test/index.test.js index 6704d3d..caec9c1 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -14,7 +14,7 @@ describe('validator.js-asserts', () => { it('should export all asserts', () => { const assertNames = Object.keys(asserts); - expect(assertNames).toHaveLength(38); + expect(assertNames).toHaveLength(39); expect(assertNames).toEqual( expect.arrayContaining([ 'AbaRoutingNumber', @@ -29,6 +29,7 @@ describe('validator.js-asserts', () => { 'Callback', 'CpfNumber', 'CreditCard', + 'CurpNumber', 'Date', 'DateDiffGreaterThan', 'DateDiffGreaterThanOrEqualTo', diff --git a/yarn.lock b/yarn.lock index 654f829..e2a680d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1141,6 +1141,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +curp@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/curp/-/curp-1.2.3.tgz#8db13da2d64073df1da9c1f94e673e829df28d32" + integrity sha512-o/NZE+1A1y77orlN8kBRa4+yG4m1owVI9V2KzEpHDV1z2k90rPCHuECYmXLyW4bcYOHdTf36EJuz6KWLn/hyKg== + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz"