@@ -7,7 +7,15 @@ var assert = chai.assert;
77var eventually = assert . eventually ;
88
99describe ( 'Read-only API' , function ( ) {
10- var sequelize , User , UserHistory ;
10+ var sequelize , User , UserHistory , Group , queries = [ ] ;
11+
12+ function logging ( message ) {
13+ if ( process . env . LOGGING === 'true' ) {
14+ console . log ( message ) ;
15+ }
16+
17+ queries . push ( message . substring ( message . indexOf ( ':' ) + 2 ) ) ;
18+ }
1119
1220 function freshDB ( ) {
1321 return freshDBWithOptions ( ) ;
@@ -22,12 +30,21 @@ describe('Read-only API', function(){
2230 sequelize = new Sequelize ( '' , '' , '' , {
2331 dialect : 'sqlite' ,
2432 storage : __dirname + '/.test.sqlite' ,
25- logging : process . env . LOGGING === 'true' ? console . log : false
33+ logging
2634 } ) ;
2735 User = Temporal ( sequelize . define ( 'User' , {
28- name : Sequelize . TEXT
36+ name : Sequelize . TEXT ,
37+ virtual : Sequelize . VIRTUAL ( Sequelize . STRING , [ 'name' ] ) ,
2938 } , modelOptions ) , sequelize , temporalOptions ) ;
3039 UserHistory = sequelize . models . UserHistory ;
40+
41+ Group = sequelize . define ( 'Group' , {
42+ name : Sequelize . TEXT
43+ } ) ;
44+ Group . hasMany ( User ) ;
45+ User . belongsTo ( Group ) ;
46+ User . addScope ( 'withGroup' , { include : [ Group ] } ) ;
47+
3148 return sequelize . sync ( { force : true } ) ;
3249 }
3350
@@ -41,6 +58,10 @@ describe('Read-only API', function(){
4158 }
4259 }
4360
61+ afterEach ( function ( ) {
62+ queries . length = 0 ;
63+ } ) ;
64+
4465 describe ( 'hooks' , function ( ) {
4566 beforeEach ( freshDB ) ;
4667 it ( 'onCreate: should not store the new version in history db' , function ( ) {
@@ -328,7 +349,7 @@ describe('Read-only API', function(){
328349
329350 it ( 'onUpdate: should store the previous version to the historyDB even if entity was partially loaded' , async function ( ) {
330351 const created = await User . create ( { name : 'name' } ) ;
331- const user = await User . findByPk ( created . id , { attributes : [ 'id' , 'name' ] } ) ; // Don't fetch timestamps
352+ const user = await User . scope ( 'withGroup' ) . findByPk ( created . id , { attributes : [ 'id' , 'name' ] } ) ; // Don't fetch timestamps
332353
333354 await user . update ( { name : 'newName' } ) ;
334355 await user . update ( { name : 'thirdName' } ) ;
@@ -348,6 +369,46 @@ describe('Read-only API', function(){
348369 assert . equal ( 'name' , initial . name ) ;
349370 assert . equal ( 'newName' , firstUpdate . name ) ;
350371 assert . equal ( 'thirdName' , secondUpdate . name ) ;
372+
373+ const selects = queries . filter ( query => query . startsWith ( 'SELECT' ) ) ;
374+
375+ assert . deepEqual ( selects , [
376+ "SELECT `User`.`id`, `User`.`name`, `Group`.`id` AS `Group.id`, `Group`.`name` AS `Group.name`, `Group`.`createdAt` AS `Group.createdAt`, `Group`.`updatedAt` AS `Group.updatedAt` FROM `Users` AS `User` LEFT OUTER JOIN `Groups` AS `Group` ON `User`.`GroupId` = `Group`.`id` WHERE (`User`.`deletedAt` IS NULL AND `User`.`id` = 1);" ,
377+ "SELECT `createdAt`, `GroupId` FROM `Users` AS `User` WHERE `User`.`id` = 1;" , // Reload for first update, no includes and only required fields. Second update does not need a reload
378+ "SELECT `id`, `name`, `createdAt`, `updatedAt`, `deletedAt`, `hid`, `archivedAt` FROM `UserHistories` AS `UserHistory`;"
379+ ] )
380+ } ) ;
381+
382+ it ( 'onUpdate: should not reload virtual fields' , async function ( ) {
383+ const created = await User . create ( { name : 'name' } ) ;
384+ const user = await User . findByPk ( created . id , { attributes : [ 'id' , 'name' , 'createdAt' , 'GroupId' ] } ) ; // Don't fetch timestamps
385+
386+ await user . update ( { name : 'newName' } ) ;
387+ await user . update ( { name : 'thirdName' } ) ;
388+
389+ const history = await UserHistory . findAll ( ) ;
390+
391+ assert . equal ( history . length , 3 , 'initial revision and to updates saved' ) ;
392+
393+ const [ initial , firstUpdate , secondUpdate ] = history ;
394+
395+ assert . equal ( + initial . createdAt , + firstUpdate . createdAt , 'createdAt was saved during first update, despite not being eagerly loaded' ) ;
396+ assert . equal ( + initial . createdAt , + secondUpdate . createdAt , 'createdAt was saved during second update, despite not being eagerly loaded' ) ;
397+
398+ assert . isAtLeast ( firstUpdate . updatedAt , initial . createdAt , 'updatedAt was saved during first update' ) ;
399+ assert . isAtLeast ( secondUpdate . updatedAt , firstUpdate . updatedAt , 'updatedAt was saved during second update' ) ;
400+
401+ assert . equal ( 'name' , initial . name ) ;
402+ assert . equal ( 'newName' , firstUpdate . name ) ;
403+ assert . equal ( 'thirdName' , secondUpdate . name ) ;
404+
405+ const selects = queries . filter ( query => query . startsWith ( 'SELECT' ) ) ;
406+
407+ // No reload
408+ assert . deepEqual ( selects , [
409+ "SELECT `id`, `name`, `createdAt`, `GroupId` FROM `Users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND `User`.`id` = 1);" ,
410+ "SELECT `id`, `name`, `createdAt`, `updatedAt`, `deletedAt`, `hid`, `archivedAt` FROM `UserHistories` AS `UserHistory`;"
411+ ] )
351412 } ) ;
352413
353414 } ) ;
0 commit comments