Skip to content

Commit

Permalink
feat: add isISSN validator (#450)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiliandeca authored and vlapo committed Nov 1, 2019
1 parent 79dccff commit 4bd586e
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -860,6 +860,7 @@ validator.maxLength(str, max); // Checks if the string's length is not more than
validator.matches(str, pattern, modifiers); // Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
validator.isMilitaryTime(str); // Checks if the string is a valid representation of military time in the format HH:MM.
validator.isHash(str, algorithm); // Checks if the string is a hash of type algorithm.
validator.isISSN(str, options); // Checks if the string is a ISSN.

// array validation methods
validator.arrayContains(array, values); // Checks if array contains all values from the given array of values.
Expand Down Expand Up @@ -955,6 +956,7 @@ validator.isInstance(value, target); // Checks value is an instance of the targe
| `@Matches(pattern: RegExp, modifiers?: string)` | Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
| `@IsMilitaryTime()` | Checks if the string is a valid representation of military time in the format HH:MM. |
| `@IsHash(algorithm: string)` | Checks if the string is a hash of type algorithm. <br/><br/>Algorithm is one of `['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']` |
| `@IsISSN(options?: IsISSNOptions)` | Checks if the string is a ISSN. |
| **Array validation decorators** |
| `@ArrayContains(values: any[])` | Checks if array contains all values from the given array of values. |
| `@ArrayNotContains(values: any[])` | Checks if array does not contain any of the given values. |
Expand Down
17 changes: 17 additions & 0 deletions src/decorator/decorators.ts
Expand Up @@ -1250,6 +1250,23 @@ export function IsHash(algorithm: string, validationOptions?: ValidationOptions)
};
}


/**
* Checks if the string is a valid ISSN.
*/
export function IsISSN(options?: ValidatorJS.IsISSNOptions, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
const args: ValidationMetadataArgs = {
type: ValidationTypes.IS_ISSN,
target: object.constructor,
propertyName: propertyName,
constraints: [options],
validationOptions: validationOptions
};
getFromContainer(MetadataStorage).addValidationMetadata(new ValidationMetadata(args));
};
}

// -------------------------------------------------------------------------
// Array checkers
// -------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions src/validation/ValidationTypes.ts
Expand Up @@ -93,6 +93,7 @@ export class ValidationTypes {
static MATCHES = "matches";
static IS_MILITARY_TIME = "isMilitaryTime";
static IS_HASH = "isHash";
static IS_ISSN = "isISSN";

/* array checkers */
static ARRAY_CONTAINS = "arrayContains";
Expand Down Expand Up @@ -284,6 +285,8 @@ export class ValidationTypes {
return eachPrefix + "$property must be a valid representation of military time in the format HH:MM";
case this.IS_HASH:
return eachPrefix + "$property must be a hash of type $constraint1";
case this.IS_ISSN:
return eachPrefix + "$property must be a ISSN";

/* array checkers */
case this.ARRAY_CONTAINS:
Expand Down
12 changes: 11 additions & 1 deletion src/validation/Validator.ts
Expand Up @@ -270,7 +270,9 @@ export class Validator {
return this.isMilitaryTime(value);
case ValidationTypes.IS_HASH:
return this.isHash(value, metadata.constraints[0]);

case ValidationTypes.IS_ISSN:
return this.isISSN(value, metadata.constraints[0]);

/* array checkers */
case ValidationTypes.ARRAY_CONTAINS:
return this.arrayContains(value, metadata.constraints[0]);
Expand Down Expand Up @@ -877,6 +879,14 @@ export class Validator {
return typeof value === "string" && this.validatorJs.isHash(value, algorithm);
}

/**
* Checks if the string is a ISSN.
* If given value is not a string, then it returns false.
*/
isISSN(value: unknown, options?: ValidatorJS.IsISSNOptions): boolean {
return typeof value === "string" && this.validatorJs.isISSN(value, options);
}

// -------------------------------------------------------------------------
// Validation Methods: array checkers
// -------------------------------------------------------------------------
Expand Down
100 changes: 100 additions & 0 deletions test/functional/validation-functions-and-decorators.spec.ts
Expand Up @@ -75,6 +75,7 @@ import {
IsISO31661Alpha2,
IsISO31661Alpha3,
IsHash,
IsISSN,
} from "../../src/decorator/decorators";
import {Validator} from "../../src/validation/Validator";
import {ValidatorOptions} from "../../src/validation/ValidatorOptions";
Expand Down Expand Up @@ -3371,6 +3372,105 @@ describe("isHash", function() {
});
});

describe("IsISSN", function() {

const validValues = [
"0378-5955",
"0000-0000",
"2434-561X",
"2434-561x",
"01896016",
"20905076",
];
const invalidValues = [
null,
undefined,
"0378-5954",
"0000-0001",
"0378-123",
"037-1234",
"0",
"2434-561c",
"1684-5370",
"19960791",
"",
];

class MyClass {
@IsISSN()
someProperty: string;
}

it("should not fail if validator.validate said that its valid", function(done) {
checkValidValues(new MyClass(), validValues, done);
});

it("should fail if validator.validate said that its invalid", function(done) {
checkInvalidValues(new MyClass(), invalidValues, done);
});

it("should not fail if method in validator said that its valid", function() {
validValues.forEach(value => validator.isISSN(value).should.be.true);
});

it("should fail if method in validator said that its invalid", function() {
invalidValues.forEach(value => validator.isISSN(value).should.be.false);
});

it("should return error object with proper data", function(done) {
const validationType = "isISSN";
const message = "someProperty must be a ISSN";
checkReturnedError(new MyClass(), invalidValues, validationType, message, done);
});

});

describe("IsISSN with options", function() {

const options = {case_sensitive: true, require_hyphen: true};

const validValues = [
"2434-561X",
"0378-5955",
];
const invalidValues = [
null,
undefined,
"2434-561x",
"2434561X",
"2434561x",
"03785955",
];

class MyClass {
@IsISSN(options)
someProperty: string;
}

it("should not fail if validator.validate said that its valid", function(done) {
checkValidValues(new MyClass(), validValues, done);
});

it("should fail if validator.validate said that its invalid", function(done) {
checkInvalidValues(new MyClass(), invalidValues, done);
});

it("should not fail if method in validator said that its valid", function() {
validValues.forEach(value => validator.isISSN(value, options).should.be.true);
});

it("should fail if method in validator said that its invalid", function() {
invalidValues.forEach(value => validator.isISSN(value, options).should.be.false);
});

it("should return error object with proper data", function(done) {
const validationType = "isISSN";
const message = "someProperty must be a ISSN";
checkReturnedError(new MyClass(), invalidValues, validationType, message, done);
});

});




Expand Down

0 comments on commit 4bd586e

Please sign in to comment.