aggregate.test.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. 'use strict';
  2. const chai = require('chai');
  3. const { DataTypes, Op } = require('@sequelize/core');
  4. const expect = chai.expect;
  5. const Support = require('../../support');
  6. describe(Support.getTestDialectTeaser('Model'), () => {
  7. describe('scope', () => {
  8. describe('aggregate', () => {
  9. beforeEach(async function () {
  10. this.Child = this.sequelize.define('Child', {
  11. priority: DataTypes.INTEGER,
  12. });
  13. this.ScopeMe = this.sequelize.define(
  14. 'ScopeMe',
  15. {
  16. username: DataTypes.STRING,
  17. email: DataTypes.STRING,
  18. access_level: DataTypes.INTEGER,
  19. other_value: DataTypes.INTEGER,
  20. },
  21. {
  22. defaultScope: {
  23. where: {
  24. access_level: {
  25. [Op.gte]: 5,
  26. },
  27. },
  28. },
  29. scopes: {
  30. lowAccess: {
  31. where: {
  32. access_level: {
  33. [Op.lte]: 5,
  34. },
  35. },
  36. },
  37. withOrder: {
  38. order: ['username'],
  39. },
  40. withInclude: {
  41. include: [
  42. {
  43. model: this.Child,
  44. where: {
  45. priority: 1,
  46. },
  47. },
  48. ],
  49. },
  50. },
  51. },
  52. );
  53. this.Child.belongsTo(this.ScopeMe);
  54. this.ScopeMe.hasMany(this.Child);
  55. await this.sequelize.sync({ force: true });
  56. const records0 = [
  57. { username: 'tony', email: 'tony@sequelizejs.com', access_level: 3, other_value: 7 },
  58. { username: 'tobi', email: 'tobi@fakeemail.com', access_level: 10, other_value: 11 },
  59. { username: 'dan', email: 'dan@sequelizejs.com', access_level: 5, other_value: 10 },
  60. { username: 'fred', email: 'fred@foobar.com', access_level: 3, other_value: 7 },
  61. ];
  62. await this.ScopeMe.bulkCreate(records0);
  63. const records = await this.ScopeMe.findAll();
  64. await Promise.all([
  65. records[0].createChild({
  66. priority: 1,
  67. }),
  68. records[1].createChild({
  69. priority: 2,
  70. }),
  71. ]);
  72. });
  73. it('should apply defaultScope', async function () {
  74. await expect(this.ScopeMe.aggregate('*', 'count')).to.eventually.equal(2);
  75. });
  76. it('should be able to override default scope', async function () {
  77. await expect(
  78. this.ScopeMe.aggregate('*', 'count', { where: { access_level: { [Op.gt]: 5 } } }),
  79. ).to.eventually.equal(1);
  80. });
  81. it('returns null when calling sum on an empty result set', async function () {
  82. await expect(
  83. this.ScopeMe.aggregate('access_level', 'sum', {
  84. where: { access_level: { [Op.gt]: 42 } },
  85. }),
  86. ).to.eventually.equal(null);
  87. });
  88. it('returns null when calling min on an empty result set', async function () {
  89. await expect(
  90. this.ScopeMe.aggregate('access_level', 'min', {
  91. where: { access_level: { [Op.gt]: 42 } },
  92. }),
  93. ).to.eventually.equal(null);
  94. });
  95. it('returns null when calling max on an empty result set', async function () {
  96. await expect(
  97. this.ScopeMe.aggregate('access_level', 'max', {
  98. where: { access_level: { [Op.gt]: 42 } },
  99. }),
  100. ).to.eventually.equal(null);
  101. });
  102. it('should be able to unscope', async function () {
  103. await expect(this.ScopeMe.withoutScope().aggregate('*', 'count')).to.eventually.equal(4);
  104. });
  105. it('should be able to apply other scopes', async function () {
  106. await expect(
  107. this.ScopeMe.withScope('lowAccess').aggregate('*', 'count'),
  108. ).to.eventually.equal(3);
  109. });
  110. it('should be able to merge scopes with where', async function () {
  111. await expect(
  112. this.ScopeMe.withScope('lowAccess').aggregate('*', 'count', {
  113. where: { username: 'dan' },
  114. }),
  115. ).to.eventually.equal(1);
  116. });
  117. it('should be able to use where on include', async function () {
  118. await expect(
  119. this.ScopeMe.withScope('withInclude').aggregate('ScopeMe.id', 'count', {
  120. plain: true,
  121. dataType: new DataTypes.INTEGER(),
  122. includeIgnoreAttributes: false,
  123. limit: null,
  124. offset: null,
  125. order: null,
  126. attributes: [],
  127. }),
  128. ).to.eventually.equal(1);
  129. });
  130. if (Support.sequelize.dialect.supports.schemas) {
  131. it('aggregate with schema', async function () {
  132. this.Hero = this.sequelize.define(
  133. 'Hero',
  134. {
  135. codename: DataTypes.STRING,
  136. },
  137. { schema: 'heroschema' },
  138. );
  139. await this.sequelize.createSchema('heroschema');
  140. await this.sequelize.sync({ force: true });
  141. const records = [{ codename: 'hulk' }, { codename: 'rantanplan' }];
  142. await this.Hero.bulkCreate(records);
  143. await expect(
  144. this.Hero.withoutScope().aggregate('*', 'count', { schema: 'heroschema' }),
  145. ).to.eventually.equal(2);
  146. });
  147. }
  148. });
  149. });
  150. });