/test/browser/schema.validation.test_.js

http://github.com/LearnBoost/mongoose · JavaScript · 941 lines · 727 code · 205 blank · 9 comment · 12 complexity · ed3d446fa30152026cdb65341fe9307e MD5 · raw file

  1. /**
  2. * Module dependencies.
  3. */
  4. var Schema = mongoose.Schema,
  5. ValidatorError = mongoose.Error.ValidatorError,
  6. SchemaTypes = Schema.Types,
  7. ObjectId = SchemaTypes.ObjectId,
  8. Mixed = SchemaTypes.Mixed,
  9. DocumentObjectId = mongoose.Types.ObjectId;
  10. describe('schema', function() {
  11. describe('validation', function() {
  12. it('invalid arguments are rejected (1044)', function(done) {
  13. assert.throws(function() {
  14. new Schema({
  15. simple: {type: String, validate: 'nope'}
  16. });
  17. }, /Invalid validator/);
  18. assert.throws(function() {
  19. new Schema({
  20. simple: {type: String, validate: ['nope']}
  21. });
  22. }, /Invalid validator/);
  23. assert.throws(function() {
  24. new Schema({
  25. simple: {type: String, validate: {nope: 1, msg: 'nope'}}
  26. });
  27. }, /Invalid validator/);
  28. assert.throws(function() {
  29. new Schema({
  30. simple: {type: String, validate: [{nope: 1, msg: 'nope'}, 'nope']}
  31. });
  32. }, /Invalid validator/);
  33. done();
  34. });
  35. it('string enum', function(done) {
  36. var Test = new Schema({
  37. complex: {type: String, enum: ['a', 'b', undefined, 'c', null]},
  38. state: {type: String}
  39. });
  40. assert.ok(Test.path('complex') instanceof SchemaTypes.String);
  41. assert.deepEqual(Test.path('complex').enumValues, ['a', 'b', 'c', null]);
  42. assert.equal(Test.path('complex').validators.length, 1);
  43. Test.path('complex').enum('d', 'e');
  44. assert.deepEqual(Test.path('complex').enumValues, ['a', 'b', 'c', null, 'd', 'e']);
  45. // with SchemaTypes validate method
  46. Test.path('state').enum({
  47. values: 'opening open closing closed'.split(' '),
  48. message: 'enum validator failed for path `{PATH}` with value `{VALUE}`'
  49. });
  50. assert.equal(Test.path('state').validators.length, 1);
  51. assert.deepEqual(Test.path('state').enumValues, ['opening', 'open', 'closing', 'closed']);
  52. Test.path('complex').doValidate('x', function(err) {
  53. assert.ok(err instanceof ValidatorError);
  54. });
  55. // allow unsetting enums
  56. Test.path('complex').doValidate(undefined, function(err) {
  57. assert.ifError(err);
  58. });
  59. Test.path('complex').doValidate(null, function(err) {
  60. assert.ifError(err);
  61. });
  62. Test.path('complex').doValidate('da', function(err) {
  63. assert.ok(err instanceof ValidatorError);
  64. });
  65. Test.path('state').doValidate('x', function(err) {
  66. assert.ok(err instanceof ValidatorError);
  67. });
  68. Test.path('state').doValidate('opening', function(err) {
  69. assert.ifError(err);
  70. });
  71. Test.path('state').doValidate('open', function(err) {
  72. assert.ifError(err);
  73. });
  74. done();
  75. });
  76. it('string regexp', function(done) {
  77. var Test = new Schema({
  78. simple: {type: String, match: /[a-z]/}
  79. });
  80. assert.equal(1, Test.path('simple').validators.length);
  81. Test.path('simple').doValidate('az', function(err) {
  82. assert.ifError(err);
  83. });
  84. Test.path('simple').match(/[0-9]/);
  85. assert.equal(2, Test.path('simple').validators.length);
  86. Test.path('simple').doValidate('12', function(err) {
  87. assert.ok(err instanceof ValidatorError);
  88. });
  89. Test.path('simple').doValidate('a12', function(err) {
  90. assert.ifError(err);
  91. });
  92. Test.path('simple').doValidate('', function(err) {
  93. assert.ifError(err);
  94. });
  95. Test.path('simple').doValidate(null, function(err) {
  96. assert.ifError(err);
  97. });
  98. Test.path('simple').doValidate(undefined, function(err) {
  99. assert.ifError(err);
  100. });
  101. Test.path('simple').validators = [];
  102. Test.path('simple').match(/[1-9]/);
  103. Test.path('simple').doValidate(0, function(err) {
  104. assert.ok(err instanceof ValidatorError);
  105. });
  106. done();
  107. });
  108. it('number min and max', function(done) {
  109. var Tobi = new Schema({
  110. friends: {type: Number, max: 15, min: 5}
  111. });
  112. assert.equal(Tobi.path('friends').validators.length, 2);
  113. Tobi.path('friends').doValidate(10, function(err) {
  114. assert.ifError(err);
  115. });
  116. Tobi.path('friends').doValidate(100, function(err) {
  117. assert.ok(err instanceof ValidatorError);
  118. assert.equal('friends', err.path);
  119. assert.equal('max', err.kind);
  120. assert.equal(100, err.value);
  121. });
  122. Tobi.path('friends').doValidate(1, function(err) {
  123. assert.ok(err instanceof ValidatorError);
  124. });
  125. // null is allowed
  126. Tobi.path('friends').doValidate(null, function(err) {
  127. assert.ifError(err);
  128. });
  129. Tobi.path('friends').min();
  130. Tobi.path('friends').max();
  131. assert.equal(Tobi.path('friends').validators.length, 0);
  132. done();
  133. });
  134. describe('required', function() {
  135. it('string required', function(done) {
  136. var Test = new Schema({
  137. simple: String
  138. });
  139. Test.path('simple').required(true);
  140. assert.equal(Test.path('simple').validators.length, 1);
  141. Test.path('simple').doValidate(null, function(err) {
  142. assert.ok(err instanceof ValidatorError);
  143. });
  144. Test.path('simple').doValidate(undefined, function(err) {
  145. assert.ok(err instanceof ValidatorError);
  146. });
  147. Test.path('simple').doValidate('', function(err) {
  148. assert.ok(err instanceof ValidatorError);
  149. });
  150. Test.path('simple').doValidate('woot', function(err) {
  151. assert.ifError(err);
  152. });
  153. done();
  154. });
  155. it('string conditional required', function(done) {
  156. var Test = new Schema({
  157. simple: String
  158. });
  159. var required = true,
  160. isRequired = function() {
  161. return required;
  162. };
  163. Test.path('simple').required(isRequired);
  164. assert.equal(Test.path('simple').validators.length, 1);
  165. Test.path('simple').doValidate(null, function(err) {
  166. assert.ok(err instanceof ValidatorError);
  167. });
  168. Test.path('simple').doValidate(undefined, function(err) {
  169. assert.ok(err instanceof ValidatorError);
  170. });
  171. Test.path('simple').doValidate('', function(err) {
  172. assert.ok(err instanceof ValidatorError);
  173. });
  174. Test.path('simple').doValidate('woot', function(err) {
  175. assert.ifError(err);
  176. });
  177. required = false;
  178. Test.path('simple').doValidate(null, function(err) {
  179. assert.ifError(err);
  180. });
  181. Test.path('simple').doValidate(undefined, function(err) {
  182. assert.ifError(err);
  183. });
  184. Test.path('simple').doValidate('', function(err) {
  185. assert.ifError(err);
  186. });
  187. Test.path('simple').doValidate('woot', function(err) {
  188. assert.ifError(err);
  189. });
  190. done();
  191. });
  192. it('number required', function(done) {
  193. var Edwald = new Schema({
  194. friends: {type: Number, required: true}
  195. });
  196. Edwald.path('friends').doValidate(null, function(err) {
  197. assert.ok(err instanceof ValidatorError);
  198. });
  199. Edwald.path('friends').doValidate(undefined, function(err) {
  200. assert.ok(err instanceof ValidatorError);
  201. });
  202. Edwald.path('friends').doValidate(0, function(err) {
  203. assert.ifError(err);
  204. });
  205. done();
  206. });
  207. it('date required', function(done) {
  208. var Loki = new Schema({
  209. birth_date: {type: Date, required: true}
  210. });
  211. Loki.path('birth_date').doValidate(null, function(err) {
  212. assert.ok(err instanceof ValidatorError);
  213. });
  214. Loki.path('birth_date').doValidate(undefined, function(err) {
  215. assert.ok(err instanceof ValidatorError);
  216. });
  217. Loki.path('birth_date').doValidate(new Date(), function(err) {
  218. assert.ifError(err);
  219. });
  220. done();
  221. });
  222. it('objectid required', function(done) {
  223. var Loki = new Schema({
  224. owner: {type: ObjectId, required: true}
  225. });
  226. Loki.path('owner').doValidate(new DocumentObjectId(), function(err) {
  227. assert.ifError(err);
  228. });
  229. Loki.path('owner').doValidate(null, function(err) {
  230. assert.ok(err instanceof ValidatorError);
  231. });
  232. Loki.path('owner').doValidate(undefined, function(err) {
  233. assert.ok(err instanceof ValidatorError);
  234. });
  235. done();
  236. });
  237. it('array required', function(done) {
  238. var Loki = new Schema({
  239. likes: {type: Array, required: true}
  240. });
  241. Loki.path('likes').doValidate(null, function(err) {
  242. assert.ok(err instanceof ValidatorError);
  243. });
  244. Loki.path('likes').doValidate(undefined, function(err) {
  245. assert.ok(err instanceof ValidatorError);
  246. });
  247. Loki.path('likes').doValidate([], function(err) {
  248. assert.ok(err instanceof ValidatorError);
  249. });
  250. done();
  251. });
  252. it('boolean required', function(done) {
  253. var Animal = new Schema({
  254. isFerret: {type: Boolean, required: true}
  255. });
  256. Animal.path('isFerret').doValidate(null, function(err) {
  257. assert.ok(err instanceof ValidatorError);
  258. });
  259. Animal.path('isFerret').doValidate(undefined, function(err) {
  260. assert.ok(err instanceof ValidatorError);
  261. });
  262. Animal.path('isFerret').doValidate(true, function(err) {
  263. assert.ifError(err);
  264. });
  265. Animal.path('isFerret').doValidate(false, function(err) {
  266. assert.ifError(err);
  267. });
  268. done();
  269. });
  270. it('mixed required', function(done) {
  271. var Animal = new Schema({
  272. characteristics: {type: Mixed, required: true}
  273. });
  274. Animal.path('characteristics').doValidate(null, function(err) {
  275. assert.ok(err instanceof ValidatorError);
  276. });
  277. Animal.path('characteristics').doValidate(undefined, function(err) {
  278. assert.ok(err instanceof ValidatorError);
  279. });
  280. Animal.path('characteristics').doValidate({
  281. aggresive: true
  282. }, function(err) {
  283. assert.ifError(err);
  284. });
  285. Animal.path('characteristics').doValidate('none available', function(err) {
  286. assert.ifError(err);
  287. });
  288. done();
  289. });
  290. });
  291. describe('async', function() {
  292. it('works', function(done) {
  293. var executed = 0;
  294. function validator(value, fn) {
  295. setTimeout(function() {
  296. executed++;
  297. fn(value === true);
  298. if (executed === 2) {
  299. done();
  300. }
  301. }, 5);
  302. }
  303. var Animal = new Schema({
  304. ferret: {type: Boolean, validate: validator}
  305. });
  306. Animal.path('ferret').doValidate(true, function(err) {
  307. assert.ifError(err);
  308. });
  309. Animal.path('ferret').doValidate(false, function(err) {
  310. assert.ok(err instanceof Error);
  311. });
  312. });
  313. it('multiple', function(done) {
  314. var executed = 0;
  315. function validator(value, fn) {
  316. setTimeout(function() {
  317. executed++;
  318. fn(value === true);
  319. if (executed === 2) {
  320. done();
  321. }
  322. }, 5);
  323. }
  324. var Animal = new Schema({
  325. ferret: {
  326. type: Boolean,
  327. validate: [{
  328. validator: validator,
  329. msg: 'validator1'
  330. }, {
  331. validator: validator,
  332. msg: 'validator2'
  333. }]
  334. }
  335. });
  336. Animal.path('ferret').doValidate(true, function(err) {
  337. assert.ifError(err);
  338. });
  339. });
  340. it('scope', function(done) {
  341. var called = false;
  342. function validator(value, fn) {
  343. assert.equal('b', this.a);
  344. setTimeout(function() {
  345. called = true;
  346. fn(true);
  347. }, 5);
  348. }
  349. var Animal = new Schema({
  350. ferret: {type: Boolean, validate: validator}
  351. });
  352. Animal.path('ferret').doValidate(true, function(err) {
  353. assert.ifError(err);
  354. assert.equal(true, called);
  355. done();
  356. }, {a: 'b'});
  357. });
  358. });
  359. describe('messages', function() {
  360. describe('are customizable', function() {
  361. it('within schema definitions', function(done) {
  362. var schema = new Schema({
  363. name: {type: String, enum: ['one', 'two']},
  364. myenum: {type: String, enum: {values: ['x'], message: 'enum validator failed for path: {PATH} with {VALUE}'}},
  365. requiredString1: {type: String, required: true},
  366. requiredString2: {type: String, required: 'oops, {PATH} is missing. {TYPE}'},
  367. matchString0: {type: String, match: /bryancranston/},
  368. matchString1: {type: String, match: [/bryancranston/, 'invalid string for {PATH} with value: {VALUE}']},
  369. numMin0: {type: Number, min: 10},
  370. numMin1: {type: Number, min: [10, 'hey, {PATH} is too small']},
  371. numMax0: {type: Number, max: 20},
  372. numMax1: {type: Number, max: [20, 'hey, {PATH} ({VALUE}) is greater than {MAX}']}
  373. });
  374. var a = new mongoose.Document({}, schema);
  375. a.validate(function(err) {
  376. assert.equal('Path `requiredString1` is required.', err.errors.requiredString1);
  377. assert.equal('oops, requiredString2 is missing. required', err.errors.requiredString2);
  378. a.requiredString1 = a.requiredString2 = 'hi';
  379. a.name = 'three';
  380. a.myenum = 'y';
  381. a.matchString0 = a.matchString1 = 'no match';
  382. a.numMin0 = a.numMin1 = 2;
  383. a.numMax0 = a.numMax1 = 30;
  384. a.validate(function(err) {
  385. assert.equal('`three` is not a valid enum value for path `name`.', err.errors.name);
  386. assert.equal('enum validator failed for path: myenum with y', err.errors.myenum);
  387. assert.equal('Path `matchString0` is invalid (no match).', err.errors.matchString0);
  388. assert.equal('invalid string for matchString1 with value: no match', err.errors.matchString1);
  389. assert.equal('Path `numMin0` (2) is less than minimum allowed value (10).', String(err.errors.numMin0));
  390. assert.equal('hey, numMin1 is too small', String(err.errors.numMin1));
  391. assert.equal('Path `numMax0` (30) is more than maximum allowed value (20).', err.errors.numMax0);
  392. assert.equal('hey, numMax1 (30) is greater than 20', String(err.errors.numMax1));
  393. a.name = 'one';
  394. a.myenum = 'x';
  395. a.requiredString1 = 'fixed';
  396. a.matchString1 = a.matchString0 = 'bryancranston is an actor';
  397. a.numMin0 = a.numMax0 = a.numMin1 = a.numMax1 = 15;
  398. a.validate(done);
  399. });
  400. });
  401. });
  402. it('for custom validators', function(done) {
  403. function validate() {
  404. return false;
  405. }
  406. var validator = [validate, '{PATH} failed validation ({VALUE})'];
  407. var schema = new Schema({x: {type: [], validate: validator}});
  408. var doc = new mongoose.Document({x: [3, 4, 5, 6]}, schema);
  409. doc.validate(function(err) {
  410. assert.equal('x failed validation (3,4,5,6)', String(err.errors.x));
  411. assert.equal('user defined', err.errors.x.kind);
  412. done();
  413. });
  414. });
  415. });
  416. });
  417. describe('types', function() {
  418. describe('are customizable', function() {
  419. it('for single custom validators', function(done) {
  420. function validate() {
  421. return false;
  422. }
  423. var validator = [validate, '{PATH} failed validation ({VALUE})', 'customType'];
  424. var schema = new Schema({x: {type: [], validate: validator}});
  425. var doc = new mongoose.Document({x: [3, 4, 5, 6]}, schema);
  426. doc.validate(function(err) {
  427. assert.equal('x failed validation (3,4,5,6)', String(err.errors.x));
  428. assert.equal('customType', err.errors.x.kind);
  429. done();
  430. });
  431. });
  432. it('for many custom validators', function(done) {
  433. function validate() {
  434. return false;
  435. }
  436. var validator = [
  437. {validator: validate, msg: '{PATH} failed validation ({VALUE})', type: 'customType'}
  438. ];
  439. var schema = new Schema({x: {type: [], validate: validator}});
  440. var doc = new mongoose.Document({x: [3, 4, 5, 6]}, schema);
  441. doc.validate(function(err) {
  442. assert.equal('x failed validation (3,4,5,6)', String(err.errors.x));
  443. assert.equal('customType', err.errors.x.kind);
  444. done();
  445. });
  446. });
  447. });
  448. });
  449. describe('sync', function() {
  450. it('works', function(done) {
  451. var executed = 0;
  452. function validator(value) {
  453. executed++;
  454. return value === true;
  455. }
  456. var Animal = new Schema({
  457. ferret: {type: Boolean, validate: validator}
  458. });
  459. assert.ifError(Animal.path('ferret').doValidateSync(true));
  460. assert.ok(Animal.path('ferret').doValidateSync(false) instanceof Error);
  461. if (executed === 2) {
  462. done();
  463. }
  464. });
  465. it('multiple', function(done) {
  466. var executed = 0;
  467. function validator(value) {
  468. executed++;
  469. return value === true;
  470. }
  471. var Animal = new Schema({
  472. ferret: {
  473. type: Boolean,
  474. validate: [{
  475. validator: validator,
  476. msg: 'validator1'
  477. }, {
  478. validator: validator,
  479. msg: 'validator2'
  480. }]
  481. }
  482. });
  483. assert.ifError(Animal.path('ferret').doValidateSync(true));
  484. if (executed === 2) {
  485. done();
  486. }
  487. });
  488. it('scope', function(done) {
  489. var called = false;
  490. function validator() {
  491. assert.equal('b', this.a);
  492. called = true;
  493. return true;
  494. }
  495. var Animal = new Schema({
  496. ferret: {type: Boolean, validate: validator}
  497. });
  498. var err = Animal.path('ferret').doValidateSync(true, {a: 'b'});
  499. assert.ifError(err);
  500. assert.equal(true, called);
  501. done();
  502. });
  503. it('ingore async', function(done) {
  504. function syncValidator(val) {
  505. return val === 'sync';
  506. }
  507. var called = false;
  508. function asyncValidator(val, respond) {
  509. called = true;
  510. setTimeout(function() {
  511. respond(val === 'async');
  512. }, 0);
  513. }
  514. var Animal = new Schema({
  515. simple: {type: Boolean, validate: [syncValidator, asyncValidator]},
  516. simpleAsync: {type: Boolean, validate: asyncValidator}
  517. });
  518. assert.ifError(Animal.path('simple').doValidateSync('sync'));
  519. assert.ok(Animal.path('simple').doValidateSync('sync123') instanceof ValidatorError);
  520. assert.equal(false, called);
  521. done();
  522. });
  523. it('subdoc', function(done) {
  524. function syncValidator(val) {
  525. return val === 'sync';
  526. }
  527. var called = false;
  528. function asyncValidator(val, respond) {
  529. called = true;
  530. setTimeout(function() {
  531. respond(val === 'async');
  532. }, 0);
  533. }
  534. var Sub = new mongoose.Schema({
  535. title: {type: String, required: true},
  536. sync: {type: String, validate: [syncValidator, asyncValidator]},
  537. async: {type: String, validate: asyncValidator}
  538. });
  539. var SubsSchema = new mongoose.Schema({
  540. subs: [Sub]
  541. });
  542. var doc = new mongoose.Document({
  543. subs: [{}, {}]
  544. }, SubsSchema);
  545. var err = doc.validateSync();
  546. assert.ok(err instanceof mongoose.Error.ValidationError);
  547. assert.equal('title', err.errors['subs.0.title'].path);
  548. var doc1 = new mongoose.Document({
  549. subs: [{
  550. title: 'title1'
  551. }, {}]
  552. }, SubsSchema);
  553. var err1 = doc1.validateSync();
  554. assert.ok(err1 instanceof mongoose.Error.ValidationError);
  555. assert.equal('title', err1.errors['subs.1.title'].path);
  556. var doc2 = new mongoose.Document({
  557. subs: [{
  558. title: 'title0'
  559. }, {
  560. title: 'title2'
  561. }]
  562. }, SubsSchema);
  563. assert.ifError(doc2.validateSync());
  564. var doc3 = new mongoose.Document({
  565. subs: [{
  566. title: 'title0',
  567. sync: 'fail'
  568. }, {
  569. title: 'title2'
  570. }]
  571. }, SubsSchema);
  572. var err3 = doc3.validateSync();
  573. assert.ok(err3 instanceof mongoose.Error.ValidationError);
  574. assert.equal('Validator failed for path `sync` with value `fail`', err3.errors['subs.0.sync'].message);
  575. var doc4 = new mongoose.Document({
  576. subs: [{
  577. title: 'title0',
  578. sync: 'sync',
  579. async: 'fail'
  580. }, {
  581. title: 'title2',
  582. sync: 'fail',
  583. async: 'async'
  584. }]
  585. }, SubsSchema);
  586. var err4 = doc4.validateSync();
  587. assert.ok(err4 instanceof mongoose.Error.ValidationError);
  588. assert.equal(err4.errors['subs.0.sync'], undefined);
  589. assert.ok(err4.errors['subs.1.sync']);
  590. assert.equal(false, called);
  591. done();
  592. });
  593. it('string enum', function(done) {
  594. var Test = new Schema({
  595. complex: {type: String, enum: ['a', 'b', undefined, 'c', null]},
  596. state: {type: String}
  597. });
  598. // with SchemaTypes validate method
  599. Test.path('state').enum({
  600. values: 'opening open closing closed'.split(' '),
  601. message: 'enum validator failed for path `{PATH}` with value `{VALUE}`'
  602. });
  603. assert.ok(Test.path('complex').doValidateSync('x') instanceof ValidatorError);
  604. // allow unsetting enums
  605. assert.ifError(Test.path('complex').doValidateSync(undefined));
  606. assert.ifError(Test.path('complex').doValidateSync(null));
  607. assert.ok(Test.path('complex').doValidateSync('da') instanceof ValidatorError);
  608. assert.ok(Test.path('state').doValidateSync('x') instanceof ValidatorError);
  609. assert.ifError(Test.path('state').doValidateSync('opening'));
  610. assert.ifError(Test.path('state').doValidateSync('open'));
  611. done();
  612. });
  613. it('string regexp', function(done) {
  614. var Test = new Schema({
  615. simple: {type: String, match: /[a-z]/}
  616. });
  617. assert.ifError(Test.path('simple').doValidateSync('az'));
  618. Test.path('simple').match(/[0-9]/);
  619. assert.equal(2, Test.path('simple').validators.length);
  620. assert.ok(Test.path('simple').doValidateSync('12') instanceof ValidatorError);
  621. assert.ifError(Test.path('simple').doValidateSync('a12'));
  622. assert.ifError(Test.path('simple').doValidateSync(''));
  623. assert.ifError(Test.path('simple').doValidateSync(null));
  624. assert.ifError(Test.path('simple').doValidateSync(undefined));
  625. Test.path('simple').validators = [];
  626. Test.path('simple').match(/[1-9]/);
  627. assert.ok(Test.path('simple').doValidateSync(0) instanceof ValidatorError);
  628. done();
  629. });
  630. it('number min and max', function(done) {
  631. var Tobi = new Schema({
  632. friends: {type: Number, max: 15, min: 5}
  633. });
  634. assert.ifError(Tobi.path('friends').doValidateSync(10));
  635. var err = Tobi.path('friends').doValidateSync(100);
  636. assert.ok(err instanceof ValidatorError);
  637. assert.equal('friends', err.path);
  638. assert.equal('max', err.kind);
  639. assert.equal(100, err.value);
  640. assert.ok(Tobi.path('friends').doValidateSync(1) instanceof ValidatorError);
  641. // null is allowed
  642. assert.ifError(Tobi.path('friends').doValidateSync(null));
  643. done();
  644. });
  645. describe('required', function() {
  646. it('string required', function(done) {
  647. var Test = new Schema({
  648. simple: String
  649. });
  650. Test.path('simple').required(true);
  651. assert.ok(Test.path('simple').doValidateSync(null) instanceof ValidatorError);
  652. assert.ok(Test.path('simple').doValidateSync(undefined) instanceof ValidatorError);
  653. assert.ok(Test.path('simple').doValidateSync('') instanceof ValidatorError);
  654. assert.ifError(Test.path('simple').doValidateSync('woot'));
  655. done();
  656. });
  657. it('string conditional required', function(done) {
  658. var Test = new Schema({
  659. simple: String
  660. });
  661. var required = true,
  662. isRequired = function() {
  663. return required;
  664. };
  665. Test.path('simple').required(isRequired);
  666. assert.ok(Test.path('simple').doValidateSync(null) instanceof ValidatorError);
  667. assert.ok(Test.path('simple').doValidateSync(undefined) instanceof ValidatorError);
  668. assert.ok(Test.path('simple').doValidateSync('') instanceof ValidatorError);
  669. assert.ifError(Test.path('simple').doValidateSync('woot'));
  670. required = false;
  671. assert.ifError(Test.path('simple').doValidateSync(null));
  672. assert.ifError(Test.path('simple').doValidateSync(undefined));
  673. assert.ifError(Test.path('simple').doValidateSync(''));
  674. assert.ifError(Test.path('simple').doValidateSync('woot'));
  675. done();
  676. });
  677. it('number required', function(done) {
  678. var Edwald = new Schema({
  679. friends: {type: Number, required: true}
  680. });
  681. assert.ok(Edwald.path('friends').doValidateSync(null) instanceof ValidatorError);
  682. assert.ok(Edwald.path('friends').doValidateSync(undefined) instanceof ValidatorError);
  683. assert.ifError(Edwald.path('friends').doValidateSync(0));
  684. done();
  685. });
  686. it('date required', function(done) {
  687. var Loki = new Schema({
  688. birth_date: {type: Date, required: true}
  689. });
  690. assert.ok(Loki.path('birth_date').doValidateSync(null) instanceof ValidatorError);
  691. assert.ok(Loki.path('birth_date').doValidateSync(undefined) instanceof ValidatorError);
  692. assert.ifError(Loki.path('birth_date').doValidateSync(new Date()));
  693. done();
  694. });
  695. it('objectid required', function(done) {
  696. var Loki = new Schema({
  697. owner: {type: ObjectId, required: true}
  698. });
  699. assert.ifError(Loki.path('owner').doValidateSync(new DocumentObjectId()));
  700. assert.ok(Loki.path('owner').doValidateSync(null) instanceof ValidatorError);
  701. assert.ok(Loki.path('owner').doValidateSync(undefined) instanceof ValidatorError);
  702. done();
  703. });
  704. it('array required', function(done) {
  705. var Loki = new Schema({
  706. likes: {type: Array, required: true}
  707. });
  708. assert.ok(Loki.path('likes').doValidateSync(null) instanceof ValidatorError);
  709. assert.ok(Loki.path('likes').doValidateSync(undefined) instanceof ValidatorError);
  710. assert.ok(Loki.path('likes').doValidateSync([]) instanceof ValidatorError);
  711. done();
  712. });
  713. it('boolean required', function(done) {
  714. var Animal = new Schema({
  715. isFerret: {type: Boolean, required: true}
  716. });
  717. assert.ok(Animal.path('isFerret').doValidateSync(null) instanceof ValidatorError);
  718. assert.ok(Animal.path('isFerret').doValidateSync(undefined) instanceof ValidatorError);
  719. assert.ifError(Animal.path('isFerret').doValidateSync(true));
  720. assert.ifError(Animal.path('isFerret').doValidateSync(false));
  721. done();
  722. });
  723. it('mixed required', function(done) {
  724. var Animal = new Schema({
  725. characteristics: {type: Mixed, required: true}
  726. });
  727. assert.ok(Animal.path('characteristics').doValidateSync(null) instanceof ValidatorError);
  728. assert.ok(Animal.path('characteristics').doValidateSync(undefined) instanceof ValidatorError);
  729. assert.ifError(Animal.path('characteristics').doValidateSync({aggresive: true}));
  730. assert.ifError(Animal.path('characteristics').doValidateSync('none available'));
  731. done();
  732. });
  733. });
  734. });
  735. });
  736. });