Skip to content

Commit

Permalink
chore(utils): add joi extensions tests [#52]
Browse files Browse the repository at this point in the history
  • Loading branch information
Drapegnik committed Aug 31, 2019
1 parent 2202b46 commit 7d0774a
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 82 deletions.
7 changes: 1 addition & 6 deletions src/utils/joi/colloquialDateHash.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ const isValid = v => {
export default joi => ({
name: 'colloquialDateHash',
base: joi.number().meta({ type: Number }),
// v16
// coerce: {
// from: 'string',
// method: (_, v) => parseInt(v, 10),
// },
// eslint-disable-next-line no-unused-vars
coerce: (v, state, options) => parseInt(v, 10),
coerce: (v, state, options) => v && +v,
pre(v, state, options) {
if (!isValid(v)) {
return this.createError('number.colloquialDateHash', { v }, state, options);
Expand Down
87 changes: 87 additions & 0 deletions src/utils/joi/joiExtensions.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { expect } from 'utils/testing';

import Joi from './index';

const getValidator = joiModel => v => {
const { error } = Joi.validate(v, joiModel);
return !error;
};

describe('Joi.slug', () => {
const validate = getValidator(Joi.slug());

it('should not accept empty strings', () => expect(validate('')).to.be.false());
it('should not accept some special characters', () =>
expect(validate('hello$world?f')).to.be.false());
it('should accept alphnumeric', () => expect(validate('regular-slug_01')).to.be.true());
it('should not accept cyrillic slug', () => expect(validate('прывітанне-слаг-05')).to.be.false());
});

describe('Joi.iamge', () => {
const validate = getValidator(Joi.image());

it('should not accept empty strings', () => expect(validate('')).to.be.false());
it('should not accept filename', () => expect(validate('lol-kek.jpg')).to.be.false());
it('should accept valid url', () => expect(validate('http://wir.by/kino.jpg')).to.be.true());
});

describe('Joi.locale', () => {
const validate = getValidator(Joi.locale());

it('should not accept empty strings', () => expect(validate('')).to.be.false());
it('should not accept unknown locale', () => expect(validate('fr')).to.be.false());
it('should accept be', () => expect(validate('be')).to.be.true());
it('should accept ru', () => expect(validate('ru')).to.be.true());
it('should accept en', () => expect(validate('en')).to.be.true());
});

describe('Joi.colloquialDateHash', () => {
const validate = getValidator(Joi.colloquialDateHash());

it('should not accept empty strings', () => expect(validate('')).to.be.false());
it('should not accept wrong format', () => expect(validate('11/01/1997')).to.be.false());
it('should not accept 111111', () => expect(validate(111111)).to.be.false());
it('should not accept 1984', () => expect(validate('1984')).to.be.false());
it('should accept valid date/month', () => expect(validate('0101')).to.be.true());
it('should accept valid date/month as number', () => expect(validate(1001)).to.be.true());
});

describe('Joi.color', () => {
const validate = getValidator(Joi.color());

it('should not accept color without hash', () => expect(validate('000000')).to.be.false());
it('should not accept short strings', () => expect(validate('#abf6')).to.be.false());
it('should not accept long strings', () => expect(validate('#12345678')).to.be.false());
it('should not accept forbidden symbols', () => expect(validate('#12zfab')).to.be.false());
it('should accept valid hex color', () => expect(validate('#a8a8ff')).to.be.true());
});

describe('Joi.localizedText', () => {
const validate = getValidator(Joi.localizedText());

it('should not accept empty object', () => expect(validate({})).to.be.false());
it('should not accept string', () => expect(validate('some text')).to.be.false());
it('should not accept without be', () => expect(validate({ en: 'en', ru: 'ru' })).to.be.false());
it('should not accept non string value', () => expect(validate({ be: true })).to.be.false());
it('should not accept unknown locale', () =>
expect(validate({ be: 'be', fr: 'fr' })).to.be.false());
it('should accept valid object', () =>
expect(validate({ be: 'be', ru: 'ru', en: 'en' })).to.be.true());
});

describe('Joi.userPermissions', () => {
const validate = getValidator(Joi.userPermissions());

it('should not accept empty array', () => expect(validate([])).to.be.false());
it('should not accept non-empty array', () =>
expect(validate(['canCreateArticle'])).to.be.false());
it('should not accept non-object', () => expect(validate('canCreateArticle')).to.be.false());
it('should have default', () => expect(validate()).to.be.true());
it('should accept empty object', () => expect(validate({})).to.be.true());
it('should accept object with one permission', () =>
expect(validate({ canCreateArticle: true })).to.be.true());
it('should accept object with multiple permissions', () =>
expect(validate({ canCreateArticle: true, canManageArticles: false })).to.be.true());
it('should not accept object with non-boolean value of permission', () =>
expect(validate({ canCreateArticle: 'no' })).to.be.false());
});
2 changes: 1 addition & 1 deletion src/utils/joi/userPermissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export default joi => ({
name: 'userPermissions',
base: joi
.object()
.pattern(joi.string(), joi.boolean())
.default({})
.meta({ type: Object }),
// TODO: to apply permission validator.
});
22 changes: 0 additions & 22 deletions src/utils/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,25 +147,3 @@ export const checkIsFound = (object, code = HttpStatus.NOT_FOUND) => {
};

export const isValidId = id => mongoose.Types.ObjectId.isValid(id);

// TODO: replace all validator with Joi extensions

export const slugValidator = {
validator: v => /^[a-zA-Z0-9_-]+$/.test(v),
message: 'errors.failedMatchRegex',
};

export const permissionsObjectValidator = {
validator: v => {
if (v instanceof Array || typeof v !== 'object') {
return false;
}
return Object.values(v).every(val => typeof val === 'boolean');
},
message: 'errors.badPermissions',
};

export const colorValidator = {
validator: v => /^[0-9a-fA-F]{6}$/.test(v),
message: 'errors.failedMatchRegex',
};
54 changes: 1 addition & 53 deletions src/utils/validation.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,7 @@ import mongoose from 'mongoose';

import { expect } from 'utils/testing';

import {
slugValidator,
permissionsObjectValidator,
checkMainPageEntitiesFormat,
colorValidator,
} from './validation';

describe('Slug Validation Tests', () => {
const validate = slugValidator.validator;

it('should not accept empty strings', () => expect(validate('')).to.be.false());

it('should not accept some special characters', () =>
expect(validate('hello$world?f')).to.be.false());

it('should accept alphnumeric', () => expect(validate('regular-slug_01')).to.be.true());

it('should not accept cyrillic slug', () => expect(validate('прывітанне-слаг-05')).to.be.false());
});

describe('Permissions Object Validation Tests', () => {
const validate = permissionsObjectValidator.validator;

it('should not accept empty array', () => expect(validate([])).to.be.false());

it('should not accept non-empty array', () =>
expect(validate(['canCreateArticle'])).to.be.false());

it('should not accept non-object', () => expect(validate('canCreateArticle')).to.be.false());

it('should accept empty object', () => expect(validate({})).to.be.true());

it('should accept object with one permission', () =>
expect(validate({ canCreateArticle: true })).to.be.true());

it('should accept object with multiple permissions', () =>
expect(validate({ canCreateArticle: true, canManageArticles: false })).to.be.true());

it('should not accept object with non-boolean value of permission', () =>
expect(validate({ canCreateArticle: 'no' })).to.be.false());
});
import { checkMainPageEntitiesFormat } from './validation';

describe('Main Page State Validation Tests', () => {
const sampleObjectId = mongoose.Types.ObjectId().toString();
Expand All @@ -70,15 +30,3 @@ describe('Main Page State Validation Tests', () => {
})
).to.be.true());
});

describe('Color Validation Tests', () => {
const validate = colorValidator.validator;

it('should not accept short strings', () => expect(validate('abf6')).to.be.false());

it('should not accept long strings', () => expect(validate('12345678')).to.be.false());

it('should not accept forbidden symbols', () => expect(validate('12zfab')).to.be.false());

it('should accept valid hex color', () => expect(validate('a8a8ff')).to.be.true());
});

0 comments on commit 7d0774a

Please sign in to comment.