From 7418c34d792b16f1028b71d3c9f43707a3826ea1 Mon Sep 17 00:00:00 2001 From: hasezoey Date: Fri, 12 Jul 2019 11:57:58 +0200 Subject: [PATCH] add missing string validation options with tests (#293) adding chai-as-promised --- package-lock.json | 18 ++++++++++++++ package.json | 2 ++ src/prop.ts | 16 ++++++++++-- test/index.test.ts | 43 ++++++++++++++++++++++++++++++++- test/models/stringValidators.ts | 20 +++++++++++++++ 5 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 test/models/stringValidators.ts diff --git a/package-lock.json b/package-lock.json index 6a42781..b0eb61c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -165,6 +165,15 @@ "integrity": "sha512-f5dXGzOJycyzSMdaXVhiBhauL4dYydXwVpavfQ1mVCaGjR56a9QfklXObUxlIY9bGTmCPHEEZ04I16BZ/8w5ww==", "dev": true }, + "@types/chai-as-promised": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", + "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, "@types/mocha": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", @@ -559,6 +568,15 @@ "type-detect": "^4.0.0" } }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", diff --git a/package.json b/package.json index 6674559..9f31ca4 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,9 @@ "@types/mocha": "^5.2.7", "@types/mongoose": "^5.5.0", "@types/node": "8.10.0", + "@types/chai-as-promised": "^7.1.0", "chai": "4.1.2", + "chai-as-promised": "7.1.1", "coveralls": "^3.0.4", "mocha": "^6.1.4", "mongoose": "^5.5.13", diff --git a/src/prop.ts b/src/prop.ts index 49bc5a5..b7bd563 100644 --- a/src/prop.ts +++ b/src/prop.ts @@ -52,9 +52,13 @@ export interface ValidateNumberOptions { } export interface ValidateStringOptions { + lowercase?: boolean; + uppercase?: boolean; + trim?: boolean; + match?: RegExp | [RegExp, string]; + enum?: string[]; minlength?: number | [number, string]; maxlength?: number | [number, string]; - match?: RegExp | [RegExp, string]; } export interface TransformStringOptions { @@ -77,7 +81,15 @@ export type PropOptionsWithStringValidate = PropOptions & TransformStringOptions export type PropOptionsWithValidate = PropOptionsWithNumberValidate | PropOptionsWithStringValidate | VirtualOptions; const isWithStringValidate = (options: PropOptionsWithStringValidate) => - options.minlength || options.maxlength || options.match; + ( + options.lowercase + || options.uppercase + || options.trim + || options.match + || options.enum + || options.minlength + || options.maxlength + ); const isWithStringTransform = (options: PropOptionsWithStringValidate) => options.lowercase || options.uppercase || options.trim; diff --git a/test/index.test.ts b/test/index.test.ts index faf651f..ddd145c 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,7 +1,8 @@ -import { expect } from 'chai'; +import { expect, use } from 'chai'; import * as mongoose from 'mongoose'; import { fail } from 'assert'; +import * as cap from 'chai-as-promised'; import { Ref } from '../src/prop'; import { getClassForDocument } from '../src/utils'; import { Genders } from './enums/genders'; @@ -12,10 +13,13 @@ import { AddressNested, PersonNested, PersonNestedModel } from './models/nested- import { model as Person } from './models/person'; import { model as Rating } from './models/rating'; import { model as Select } from './models/select'; +import { model as StringValidators } from './models/stringValidators'; import { model as User, User as UserType } from './models/user'; import { Virtual, VirtualSub } from './models/virtualprop'; import { connect, disconnect } from './utils/mongooseConnect'; +use(cap); + describe('Typegoose', () => { before(() => connect()); after(() => disconnect()); @@ -260,6 +264,43 @@ describe('Typegoose', () => { // wrong type to make typescript happy expect((items[1].kind as typeof Beverage).isDecaf).to.be.an('undefined'); }); + describe('string validators', () => { + // TODO: Specify an identifier for the error messages, e. g. as a regex to the message content. + // Otherwise we could catch errors that have nothing to do with what is being tested. + + it('should respect maxlength', (done) => { + expect(StringValidators.create({ + maxLength: 'this is too long', + })).to.eventually.rejectedWith(mongoose.Error).and.notify(done); + }); + + it('should trim', async () => { + const trimmed = await StringValidators.create({ + trimmed: 'trim my end ', + }); + expect(trimmed.trimmed).equals('trim my end'); + }); + + it('should uppercase', async () => { + const uppercased = await StringValidators.create({ + uppercased: 'make me uppercase', + }); + expect(uppercased.uppercased).equals('MAKE ME UPPERCASE'); + }); + + it('should lowercase', async () => { + const lowercased = await StringValidators.create({ + lowercased: 'MAKE ME LOWERCASE', + }); + expect(lowercased.lowercased).equals('make me lowercase'); + }); + + it('should respect enum', (done) => { + expect(StringValidators.create({ + enumed: 'i am not valid', + })).to.eventually.rejectedWith(mongoose.Error).and.notify(done); + }); + }); it('should only return selected types', async () => { const selecttest = new Select(); diff --git a/test/models/stringValidators.ts b/test/models/stringValidators.ts new file mode 100644 index 0000000..80ef747 --- /dev/null +++ b/test/models/stringValidators.ts @@ -0,0 +1,20 @@ +import { prop, Typegoose } from '../../src/typegoose'; + +export class StringValidators extends Typegoose { + @prop({ maxlength: 3 }) + public maxLength: string; + + @prop({ trim: true }) + public trimmed: string; + + @prop({ uppercase: true }) + public uppercased: string; + + @prop({ lowercase: true }) + public lowercased: string; + + @prop({ enum: ['one', 'two', 'three'] }) + public enumed: string; +} + +export const model = new StringValidators().getModelForClass(StringValidators);