validate.test.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. 'use strict';
  2. const chai = require('chai');
  3. const sinon = require('sinon');
  4. const expect = chai.expect;
  5. const Support = require('../support');
  6. const { DataTypes } = require('@sequelize/core');
  7. describe(Support.getTestDialectTeaser('Hooks'), () => {
  8. beforeEach(async function () {
  9. this.User = this.sequelize.define('User', {
  10. username: {
  11. type: DataTypes.STRING,
  12. allowNull: false,
  13. },
  14. mood: {
  15. type: DataTypes.ENUM(['happy', 'sad', 'neutral']),
  16. },
  17. });
  18. await this.sequelize.sync({ force: true });
  19. });
  20. describe('#validate', () => {
  21. describe('#create', () => {
  22. it('should return the user', async function () {
  23. this.User.beforeValidate(user => {
  24. user.username = 'Bob';
  25. user.mood = 'happy';
  26. });
  27. this.User.afterValidate(user => {
  28. user.username = 'Toni';
  29. });
  30. const user = await this.User.create({ mood: 'ecstatic' });
  31. expect(user.mood).to.equal('happy');
  32. expect(user.username).to.equal('Toni');
  33. });
  34. });
  35. describe('#3534, hooks modifications', () => {
  36. it('fields modified in hooks are saved', async function () {
  37. this.User.afterValidate(user => {
  38. // if username is defined and has more than 5 char
  39. user.username = user.username ? (user.username.length < 5 ? null : user.username) : null;
  40. user.username = user.username || 'Samorost 3';
  41. });
  42. this.User.beforeValidate(user => {
  43. user.mood = user.mood || 'neutral';
  44. });
  45. const user = await this.User.create({ username: 'T', mood: 'neutral' });
  46. expect(user.mood).to.equal('neutral');
  47. expect(user.username).to.equal('Samorost 3');
  48. // change attributes
  49. user.mood = 'sad';
  50. user.username = 'Samorost Good One';
  51. const uSaved0 = await user.save();
  52. expect(uSaved0.mood).to.equal('sad');
  53. expect(uSaved0.username).to.equal('Samorost Good One');
  54. // change attributes, expect to be replaced by hooks
  55. uSaved0.username = 'One';
  56. const uSaved = await uSaved0.save();
  57. // attributes were replaced by hooks ?
  58. expect(uSaved.mood).to.equal('sad');
  59. expect(uSaved.username).to.equal('Samorost 3');
  60. const uFetched0 = await this.User.findByPk(uSaved.id);
  61. expect(uFetched0.mood).to.equal('sad');
  62. expect(uFetched0.username).to.equal('Samorost 3');
  63. uFetched0.mood = null;
  64. uFetched0.username = 'New Game is Needed';
  65. const uFetchedSaved0 = await uFetched0.save();
  66. expect(uFetchedSaved0.mood).to.equal('neutral');
  67. expect(uFetchedSaved0.username).to.equal('New Game is Needed');
  68. const uFetched = await this.User.findByPk(uFetchedSaved0.id);
  69. expect(uFetched.mood).to.equal('neutral');
  70. expect(uFetched.username).to.equal('New Game is Needed');
  71. // expect to be replaced by hooks
  72. uFetched.username = 'New';
  73. uFetched.mood = 'happy';
  74. const uFetchedSaved = await uFetched.save();
  75. expect(uFetchedSaved.mood).to.equal('happy');
  76. expect(uFetchedSaved.username).to.equal('Samorost 3');
  77. });
  78. });
  79. describe('on error', () => {
  80. it('should emit an error from after hook', async function () {
  81. this.User.afterValidate(user => {
  82. user.mood = 'ecstatic';
  83. throw new Error('Whoops! Changed user.mood!');
  84. });
  85. await expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejectedWith(
  86. 'Whoops! Changed user.mood!',
  87. );
  88. });
  89. it('should call validationFailed hook', async function () {
  90. const validationFailedHook = sinon.spy();
  91. this.User.validationFailed(validationFailedHook);
  92. await expect(this.User.create({ mood: 'happy' })).to.be.rejected;
  93. expect(validationFailedHook).to.have.been.calledOnce;
  94. });
  95. it('should not replace the validation error in validationFailed hook by default', async function () {
  96. const validationFailedHook = sinon.stub();
  97. this.User.validationFailed(validationFailedHook);
  98. const err = await expect(this.User.create({ mood: 'happy' })).to.be.rejected;
  99. expect(err.name).to.equal('SequelizeValidationError');
  100. });
  101. it('should replace the validation error if validationFailed hook creates a new error', async function () {
  102. const validationFailedHook = sinon.stub().throws(new Error('Whoops!'));
  103. this.User.validationFailed(validationFailedHook);
  104. const err = await expect(this.User.create({ mood: 'happy' })).to.be.rejected;
  105. expect(err.message).to.equal('Whoops!');
  106. });
  107. });
  108. });
  109. });