// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Node module: loopback-datasource-juggler // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT // This test written in mocha+should.js var should = require('./init.js'); var db, User, options, whereCount = 0; var j = require('../'); var ValidationError = j.ValidationError; var INITIAL_NAME = 'Bert'; var NEW_NAME = 'Ernie'; var INVALID_DATA = {name: null}; var VALID_DATA = {name: INITIAL_NAME}; describe('optional-validation', function () { before(function (done) { db = getSchema(); User = db.define('User', { seq: {type: Number, index: true}, name: {type: String, index: true, sort: true}, email: {type: String, index: true}, birthday: {type: Date, index: true}, role: {type: String, index: true}, order: {type: Number, index: true, sort: true}, vip: {type: Boolean} }, { forceId: true, strict: true }); db.automigrate(['User'], done); }); beforeEach(function (done) { User.destroyAll(function () { delete User.validations; User.validatesPresenceOf('name'); done(); }); }); function expectValidationError(done) { return function (err, result) { should.exist(err); err.should.be.instanceOf(Error); err.should.be.instanceOf(ValidationError); done(); }; } function expectCreateSuccess(data, done) { if (done === undefined && typeof data === 'function') { done = data; data = { name: INITIAL_NAME }; } return function(err, instance) { if (err) return done(err); instance.should.be.instanceOf(User); if (data.name) { instance.name.should.eql(data.name || INITIAL_NAME); } else { should.not.exist(instance.name); } done(); }; } function expectChangeSuccess(data, done) { if (done === undefined && typeof data === 'function') { done = data; data = { name: NEW_NAME }; } return function(err, instance) { if (err) return done(err); instance.should.be.instanceOf(User); if (data.name) { instance.name.should.eql(data.name || NEW_NAME); } else { should.not.exist(instance.name); } done(); }; } function createUserAndChangeName(name, cb) { User.create(VALID_DATA, {validate: true}, function (err, d) { d.name = name; cb(err, d); }); } function createUser(cb) { User.create(VALID_DATA, {validate: true}, cb); } function callUpdateOrCreateWithExistingUserId(name, options, cb){ User.create({'name': 'Groover'}, function(err, user){ if (err) return cb(err); var data = {name: name}; data.id = user.id; User.updateOrCreate(data, options, cb); }); } function getNewWhere() { return {name: 'DoesNotExist' + (whereCount++)}; } describe('no model setting', function () { describe('method create', function() { it('should throw on create with validate:true with invalid data', function (done) { User.create(INVALID_DATA, {validate: true}, expectValidationError(done)); }); it('should NOT throw on create with validate:false with invalid data', function (done) { User.create(INVALID_DATA, {validate: false}, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on create with validate:true with valid data', function (done) { User.create(VALID_DATA, {validate: true}, expectCreateSuccess(done)); }); it('should NOT throw on create with validate:false with valid data', function (done) { User.create(VALID_DATA, {validate: false}, expectCreateSuccess(done)); }); it('should throw on create with invalid data', function (done) { User.create(INVALID_DATA, expectValidationError(done)); }); it('should NOT throw on create with valid data', function (done) { User.create(VALID_DATA, expectCreateSuccess(done)); }); }); describe('method findOrCreate', function() { it('should throw on findOrCreate with validate:true with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true}, expectValidationError(done)); }); it('should NOT throw on findOrCreate with validate:false with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false}, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on findOrCreate with validate:true with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true}, expectCreateSuccess(done)); }); it('should NOT throw on findOrCreate with validate:false with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false}, expectCreateSuccess(done)); }); it('should throw on findOrCreate with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done)); }); it('should NOT throw on findOrCreate with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, expectCreateSuccess(done)); }); }); describe('method updateOrCreate on existing data', function() { it('should throw on updateOrCreate(id) with validate:true with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, {validate: true}, expectValidationError(done)); }); it('should NOT throw on updateOrCreate(id) with validate:false with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, {validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); it('should NOT throw on updateOrCreate(id) with validate:true with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true}, expectChangeSuccess(done)); }); it('should NOT throw on updateOrCreate(id) with validate:false with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false}, expectChangeSuccess(done)); }); // backwards compatible with validateUpsert it('should NOT throw on updateOrCreate(id) with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, expectChangeSuccess(INVALID_DATA, done)); }); it('should NOT throw on updateOrCreate(id) with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, expectChangeSuccess(done)); }); }); describe('method save', function() { it('should throw on save with {validate:true} with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save({validate: true}, expectValidationError(done)); }); }); it('should NOT throw on save with {validate:false} with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save({validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); }); it('should NOT throw on save with {validate:true} with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save({validate: true}, expectChangeSuccess(done)); }); }); it('should NOT throw on save with {validate:false} with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save({validate: false}, expectChangeSuccess(done)); }); }); it('should throw on save(cb) with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save(expectValidationError(done)); }); }); it('should NOT throw on save(cb) with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save(expectChangeSuccess(done)); }); }); }); describe('method updateAttributes', function() { it('should throw on updateAttributes with {validate:true} with invalid data', function (done) { createUser(function (err, d) { d.updateAttributes(INVALID_DATA, {validate: true}, expectValidationError(done)); }); }); it('should NOT throw on updateAttributes with {validate:false} with invalid data', function (done) { createUser(function (err, d) { d.updateAttributes(INVALID_DATA, {validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); }); it('should NOT throw on updateAttributes with {validate:true} with valid data', function (done) { createUser(function (err, d) { d.updateAttributes({'name': NEW_NAME}, {validate: true}, expectChangeSuccess(done)); }); }); it('should NOT throw on updateAttributes with {validate:false} with valid data', function (done) { createUser(function (err, d) { d.updateAttributes({'name': NEW_NAME}, {validate: false}, expectChangeSuccess(done)); }); }); it('should throw on updateAttributes(cb) with invalid data', function (done) { createUser(function (err, d) { d.updateAttributes(INVALID_DATA, expectValidationError(done)); }); }); it('should NOT throw on updateAttributes(cb) with valid data', function (done) { createUser(function (err, d) { d.updateAttributes({'name': NEW_NAME}, expectChangeSuccess(done)); }); }); }); }); describe('model setting: automaticValidation: false', function () { before(function (done) { User.settings.automaticValidation = false; done(); }); describe('method create', function() { it('should throw on create with validate:true with invalid data', function (done) { User.create(INVALID_DATA, {validate: true}, expectValidationError(done)); }); it('should NOT throw on create with validate:false with invalid data', function (done) { User.create(INVALID_DATA, {validate: false}, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on create with validate:true with valid data', function (done) { User.create(VALID_DATA, {validate: true}, expectCreateSuccess(done)); }); it('should NOT throw on create with validate:false with valid data', function (done) { User.create(VALID_DATA, {validate: false}, expectCreateSuccess(done)); }); it('should NOT throw on create with invalid data', function (done) { User.create(INVALID_DATA, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on create with valid data', function (done) { User.create(VALID_DATA, expectCreateSuccess(done)); }); }); describe('method findOrCreate', function() { it('should throw on findOrCreate with validate:true with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true}, expectValidationError(done)); }); it('should NOT throw on findOrCreate with validate:false with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false}, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on findOrCreate with validate:true with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true}, expectCreateSuccess(done)); }); it('should NOT throw on findOrCreate with validate:false with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false}, expectCreateSuccess(done)); }); it('should NOT throw on findOrCreate with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on findOrCreate with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, expectCreateSuccess(done)); }); }); describe('method updateOrCreate on existing data', function() { it('should throw on updateOrCreate(id) with validate:true with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, {validate: true}, expectValidationError(done)); }); it('should NOT throw on updateOrCreate(id) with validate:false with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, {validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); it('should NOT throw on updateOrCreate(id) with validate:true with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true}, expectChangeSuccess(done)); }); it('should NOT throw on updateOrCreate(id) with validate:false with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false}, expectChangeSuccess(done)); }); it('should NOT throw on updateOrCreate(id) with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, expectChangeSuccess(INVALID_DATA, done)); }); it('should NOT throw on updateOrCreate(id) with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, expectChangeSuccess(done)); }); }); describe('method save', function() { it('should throw on save with {validate:true} with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save({validate: true}, expectValidationError(done)); }); }); it('should NOT throw on save with {validate:false} with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save({validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); }); it('should NOT throw on save with {validate:true} with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save({validate: true}, expectChangeSuccess(done)); }); }); it('should NOT throw on save with {validate:false} with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save({validate: false}, expectChangeSuccess(done)); }); }); it('should NOT throw on save(cb) with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save(expectChangeSuccess(INVALID_DATA, done)); }); }); it('should NOT throw on save(cb) with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save(expectChangeSuccess(done)); }); }); }); }); describe('model setting: automaticValidation: true', function () { before(function (done) { User.settings.automaticValidation = true; done(); }); describe('method create', function() { it('should throw on create with validate:true with invalid data', function (done) { User.create(INVALID_DATA, {validate: true}, expectValidationError(done)); }); it('should NOT throw on create with validate:false with invalid data', function (done) { User.create(INVALID_DATA, {validate: false}, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on create with validate:true with valid data', function (done) { User.create(VALID_DATA, {validate: true}, expectCreateSuccess(done)); }); it('should NOT throw on create with validate:false with valid data', function (done) { User.create(VALID_DATA, {validate: false}, expectCreateSuccess(done)); }); it('should throw on create with invalid data', function (done) { User.create(INVALID_DATA, expectValidationError(done)); }); it('should NOT throw on create with valid data', function (done) { User.create(VALID_DATA, expectCreateSuccess(done)); }); }); describe('method findOrCreate', function() { it('should throw on findOrCreate with validate:true with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true}, expectValidationError(done)); }); it('should NOT throw on findOrCreate with validate:false with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false}, expectCreateSuccess(INVALID_DATA, done)); }); it('should NOT throw on findOrCreate with validate:true with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true}, expectCreateSuccess(done)); }); it('should NOT throw on findOrCreate with validate:false with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false}, expectCreateSuccess(done)); }); it('should throw on findOrCreate with invalid data', function (done) { User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done)); }); it('should NOT throw on findOrCreate with valid data', function (done) { User.findOrCreate(getNewWhere(), VALID_DATA, expectCreateSuccess(done)); }); }); describe('method updateOrCreate on existing data', function() { it('should throw on updateOrCreate(id) with validate:true with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, {validate: true}, expectValidationError(done)); }); it('should NOT throw on updateOrCreate(id) with validate:false with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, {validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); it('should NOT throw on updateOrCreate(id) with validate:true with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true}, expectChangeSuccess(done)); }); it('should NOT throw on updateOrCreate(id) with validate:false with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false}, expectChangeSuccess(done)); }); it('should throw on updateOrCreate(id) with invalid data', function (done) { callUpdateOrCreateWithExistingUserId(null, expectValidationError(done)); }); it('should NOT throw on updateOrCreate(id) with valid data', function (done) { callUpdateOrCreateWithExistingUserId(NEW_NAME, expectChangeSuccess(done)); }); }); describe('method save', function() { it('should throw on save with {validate:true} with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save(options, expectValidationError(done)); }); }); it('should NOT throw on save with {validate:false} with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save({validate: false}, expectChangeSuccess(INVALID_DATA, done)); }); }); it('should NOT throw on save with {validate:true} with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save({validate: true}, expectChangeSuccess(done)); }); }); it('should NOT throw on save with {validate:false} with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save({validate: false}, expectChangeSuccess(done)); }); }); it('should throw on save(cb) with invalid data', function (done) { createUserAndChangeName(null, function (err, d) { d.save(expectValidationError(done)); }); }); it('should NOT throw on save(cb) with valid data', function (done) { createUserAndChangeName(NEW_NAME, function (err, d) { d.save(expectChangeSuccess(done)); }); }); }); }); });