2020-05-06 06:10:51 -04:00
/ *
* decaffeinate suggestions :
* DS101 : Remove unnecessary use of Array . from
* DS102 : Remove unnecessary code created because of implicit returns
* Full docs : https : //github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
* /
const sinon = require ( 'sinon' ) ;
const chai = require ( 'chai' ) ;
const should = chai . should ( ) ;
const {
expect
} = chai ;
const modulePath = "../../../../app/js/RangesManager.js" ;
const SandboxedModule = require ( 'sandboxed-module' ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "RangesManager" , function ( ) {
beforeEach ( function ( ) {
this . RangesManager = SandboxedModule . require ( modulePath , {
requires : {
"logger-sharelatex" : ( this . logger = { error : sinon . stub ( ) , log : sinon . stub ( ) , warn : sinon . stub ( ) } )
}
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
this . doc _id = "doc-id-123" ;
this . project _id = "project-id-123" ;
this . user _id = "user-id-123" ;
return this . callback = sinon . stub ( ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "applyUpdate" , function ( ) {
beforeEach ( function ( ) {
this . updates = [ {
meta : {
user _id : this . user _id
} ,
2017-03-15 10:12:06 -04:00
op : [ {
2020-05-06 06:10:51 -04:00
i : "two " ,
2017-03-15 10:12:06 -04:00
p : 4
} ]
2020-05-06 06:10:51 -04:00
} ] ;
this . entries = {
2017-03-15 10:12:06 -04:00
comments : [ {
2020-05-06 06:10:51 -04:00
op : {
c : "three " ,
2017-03-15 10:12:06 -04:00
p : 4
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
} ] ,
2017-03-15 10:12:06 -04:00
changes : [ {
2020-05-06 06:10:51 -04:00
op : {
i : "five" ,
2017-03-15 10:12:06 -04:00
p : 15
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
2017-03-15 10:12:06 -04:00
} ]
2020-05-06 06:10:51 -04:00
} ;
return this . newDocLines = [ "one two three four five" ] ; } ) ; // old is "one three four five"
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "successfully" , function ( ) {
beforeEach ( function ( ) {
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return the modified the comments and changes" , function ( ) {
this . callback . called . should . equal ( true ) ;
const [ error , entries , ranges _were _collapsed ] = Array . from ( this . callback . args [ 0 ] ) ;
expect ( error ) . to . be . null ;
expect ( ranges _were _collapsed ) . to . equal ( false ) ;
entries . comments [ 0 ] . op . should . deep . equal ( {
c : "three " ,
2017-03-15 10:12:06 -04:00
p : 8
2020-05-06 06:10:51 -04:00
} ) ;
return entries . changes [ 0 ] . op . should . deep . equal ( {
i : "five" ,
2017-03-15 10:12:06 -04:00
p : 19
2020-05-06 06:10:51 -04:00
} ) ;
} ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "with empty comments" , function ( ) {
beforeEach ( function ( ) {
this . entries . comments = [ ] ;
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return an object with no comments" , function ( ) {
// Save space in redis and don't store just {}
this . callback . called . should . equal ( true ) ;
const [ error , entries ] = Array . from ( this . callback . args [ 0 ] ) ;
expect ( error ) . to . be . null ;
return expect ( entries . comments ) . to . be . undefined ;
} ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "with empty changes" , function ( ) {
beforeEach ( function ( ) {
this . entries . changes = [ ] ;
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return an object with no changes" , function ( ) {
// Save space in redis and don't store just {}
this . callback . called . should . equal ( true ) ;
const [ error , entries ] = Array . from ( this . callback . args [ 0 ] ) ;
expect ( error ) . to . be . null ;
return expect ( entries . changes ) . to . be . undefined ;
} ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "with too many comments" , function ( ) {
beforeEach ( function ( ) {
this . RangesManager . MAX _COMMENTS = 2 ;
this . updates = [ {
meta : {
user _id : this . user _id
} ,
2017-03-15 10:12:06 -04:00
op : [ {
2020-05-06 06:10:51 -04:00
c : "one" ,
p : 0 ,
2017-03-20 06:37:02 -04:00
t : "thread-id-1"
2017-03-15 10:12:06 -04:00
} ]
2020-05-06 06:10:51 -04:00
} ] ;
this . entries = {
2017-03-15 10:12:06 -04:00
comments : [ {
2020-05-06 06:10:51 -04:00
op : {
c : "three " ,
p : 4 ,
2017-03-20 06:37:02 -04:00
t : "thread-id-2"
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
2017-03-15 10:12:06 -04:00
} , {
2020-05-06 06:10:51 -04:00
op : {
c : "four " ,
p : 10 ,
2017-03-20 06:37:02 -04:00
t : "thread-id-3"
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
} ] ,
2017-03-15 10:12:06 -04:00
changes : [ ]
2020-05-06 06:10:51 -04:00
} ;
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return an error" , function ( ) {
this . callback . called . should . equal ( true ) ;
const [ error , entries ] = Array . from ( this . callback . args [ 0 ] ) ;
expect ( error ) . to . not . be . null ;
return expect ( error . message ) . to . equal ( "too many comments or tracked changes" ) ;
} ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "with too many changes" , function ( ) {
beforeEach ( function ( ) {
this . RangesManager . MAX _CHANGES = 2 ;
this . updates = [ {
meta : {
user _id : this . user _id ,
2017-03-15 10:12:06 -04:00
tc : "track-changes-id-yes"
2020-05-06 06:10:51 -04:00
} ,
2017-03-15 10:12:06 -04:00
op : [ {
2020-05-06 06:10:51 -04:00
i : "one " ,
2017-03-15 10:12:06 -04:00
p : 0
} ]
2020-05-06 06:10:51 -04:00
} ] ;
this . entries = {
2017-03-15 10:12:06 -04:00
changes : [ {
2020-05-06 06:10:51 -04:00
op : {
i : "three" ,
2017-03-15 10:12:06 -04:00
p : 4
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
2017-03-15 10:12:06 -04:00
} , {
2020-05-06 06:10:51 -04:00
op : {
i : "four" ,
2017-03-15 10:12:06 -04:00
p : 10
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
} ] ,
2017-03-15 10:12:06 -04:00
comments : [ ]
2020-05-06 06:10:51 -04:00
} ;
this . newDocLines = [ "one two three four" ] ;
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return an error" , function ( ) {
// Save space in redis and don't store just {}
this . callback . called . should . equal ( true ) ;
const [ error , entries ] = Array . from ( this . callback . args [ 0 ] ) ;
expect ( error ) . to . not . be . null ;
return expect ( error . message ) . to . equal ( "too many comments or tracked changes" ) ;
} ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
describe ( "inconsistent changes" , function ( ) {
beforeEach ( function ( ) {
this . updates = [ {
meta : {
user _id : this . user _id
} ,
2017-03-15 10:12:06 -04:00
op : [ {
2020-05-06 06:10:51 -04:00
c : "doesn't match" ,
2017-03-15 10:12:06 -04:00
p : 0
} ]
2020-05-06 06:10:51 -04:00
} ] ;
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2017-03-15 10:12:06 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return an error" , function ( ) {
// Save space in redis and don't store just {}
this . callback . called . should . equal ( true ) ;
const [ error , entries ] = Array . from ( this . callback . args [ 0 ] ) ;
expect ( error ) . to . not . be . null ;
return expect ( error . message ) . to . equal ( "Change ({\"op\":{\"i\":\"five\",\"p\":15},\"metadata\":{\"user_id\":\"user-id-123\"}}) doesn't match text (\"our \")" ) ;
} ) ;
} ) ;
2017-05-09 11:16:25 -04:00
2019-04-11 08:25:03 -04:00
2020-05-06 06:10:51 -04:00
return describe ( "with an update that collapses a range" , function ( ) {
beforeEach ( function ( ) {
this . updates = [ {
meta : {
user _id : this . user _id
} ,
2019-04-11 08:25:03 -04:00
op : [ {
2020-05-06 06:10:51 -04:00
d : "one" ,
p : 0 ,
2019-04-11 08:25:03 -04:00
t : "thread-id-1"
} ]
2020-05-06 06:10:51 -04:00
} ] ;
this . entries = {
2019-04-11 08:25:03 -04:00
comments : [ {
2020-05-06 06:10:51 -04:00
op : {
c : "n" ,
p : 1 ,
2019-04-11 08:25:03 -04:00
t : "thread-id-2"
2020-05-06 06:10:51 -04:00
} ,
metadata : {
user _id : this . user _id
}
} ] ,
2019-04-11 08:25:03 -04:00
changes : [ ]
2020-05-06 06:10:51 -04:00
} ;
return this . RangesManager . applyUpdate ( this . project _id , this . doc _id , this . entries , this . updates , this . newDocLines , this . callback ) ;
} ) ;
2019-04-11 08:25:03 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should return ranges_were_collapsed == true" , function ( ) {
this . callback . called . should . equal ( true ) ;
const [ error , entries , ranges _were _collapsed ] = Array . from ( this . callback . args [ 0 ] ) ;
return expect ( ranges _were _collapsed ) . to . equal ( true ) ;
} ) ;
} ) ;
} ) ;
2019-04-11 08:25:03 -04:00
2020-05-06 06:10:51 -04:00
return describe ( "acceptChanges" , function ( ) {
beforeEach ( function ( ) {
this . RangesManager = SandboxedModule . require ( modulePath , {
requires : {
"logger-sharelatex" : ( this . logger = { error : sinon . stub ( ) , log : sinon . stub ( ) , warn : sinon . stub ( ) } ) ,
"./RangesTracker" : ( this . RangesTracker = SandboxedModule . require ( "../../../../app/js/RangesTracker.js" ) )
}
}
) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
this . ranges = {
comments : [ ] ,
2017-05-12 09:42:40 -04:00
changes : [ {
2020-05-06 06:10:51 -04:00
id : "a1" ,
op : {
i : "lorem" ,
2017-05-12 09:42:40 -04:00
p : 0
2020-05-06 06:10:51 -04:00
}
2017-05-12 09:42:40 -04:00
} , {
2020-05-06 06:10:51 -04:00
id : "a2" ,
op : {
i : "ipsum" ,
2017-05-12 09:42:40 -04:00
p : 10
2020-05-06 06:10:51 -04:00
}
2017-05-12 09:42:40 -04:00
} , {
2020-05-06 06:10:51 -04:00
id : "a3" ,
op : {
i : "dolor" ,
2017-05-12 09:42:40 -04:00
p : 20
2020-05-06 06:10:51 -04:00
}
2017-05-12 09:42:40 -04:00
} , {
2020-05-06 06:10:51 -04:00
id : "a4" ,
op : {
i : "sit" ,
2017-05-12 09:42:40 -04:00
p : 30
2020-05-06 06:10:51 -04:00
}
2017-05-12 09:42:40 -04:00
} , {
2020-05-06 06:10:51 -04:00
id : "a5" ,
op : {
i : "amet" ,
2017-05-12 09:42:40 -04:00
p : 40
2020-05-06 06:10:51 -04:00
}
2017-05-12 09:42:40 -04:00
} ]
2020-05-06 06:10:51 -04:00
} ;
return this . removeChangeIdsSpy = sinon . spy ( this . RangesTracker . prototype , "removeChangeIds" ) ;
} ) ;
2017-05-09 11:16:25 -04:00
2020-05-06 06:10:51 -04:00
describe ( "successfully with a single change" , function ( ) {
beforeEach ( function ( done ) {
this . change _ids = [ this . ranges . changes [ 1 ] . id ] ;
return this . RangesManager . acceptChanges ( this . change _ids , this . ranges , ( err , ranges ) => {
this . rangesResponse = ranges ;
return done ( ) ;
} ) ;
} ) ;
2017-05-09 11:16:25 -04:00
2020-05-06 06:10:51 -04:00
it ( "should log the call with the correct number of changes" , function ( ) {
return this . logger . log
2017-05-09 11:16:25 -04:00
. calledWith ( "accepting 1 changes in ranges" )
2020-05-06 06:10:51 -04:00
. should . equal ( true ) ;
} ) ;
2017-05-09 11:16:25 -04:00
2020-05-06 06:10:51 -04:00
it ( "should delegate the change removal to the ranges tracker" , function ( ) {
return this . removeChangeIdsSpy
. calledWith ( this . change _ids )
. should . equal ( true ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
it ( "should remove the change" , function ( ) {
return expect ( this . rangesResponse . changes
. find ( change => change . id === this . ranges . changes [ 1 ] . id ) )
. to . be . undefined ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
it ( "should return the original number of changes minus 1" , function ( ) {
return this . rangesResponse . changes . length
. should . equal ( this . ranges . changes . length - 1 ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should not touch other changes" , function ( ) {
return [ 0 , 2 , 3 , 4 ] . map ( ( i ) =>
expect ( this . rangesResponse . changes
. find ( change => change . id === this . ranges . changes [ i ] . id ) )
. to . deep . equal ( this . ranges . changes [ i ] ) ) ;
} ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
return describe ( "successfully with multiple changes" , function ( ) {
beforeEach ( function ( done ) {
this . change _ids = [ this . ranges . changes [ 1 ] . id , this . ranges . changes [ 3 ] . id , this . ranges . changes [ 4 ] . id ] ;
return this . RangesManager . acceptChanges ( this . change _ids , this . ranges , ( err , ranges ) => {
this . rangesResponse = ranges ;
return done ( ) ;
} ) ;
} ) ;
2017-05-09 11:16:25 -04:00
2020-05-06 06:10:51 -04:00
it ( "should log the call with the correct number of changes" , function ( ) {
return this . logger . log
. calledWith ( ` accepting ${ this . change _ids . length } changes in ranges ` )
. should . equal ( true ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
it ( "should delegate the change removal to the ranges tracker" , function ( ) {
return this . removeChangeIdsSpy
. calledWith ( this . change _ids )
. should . equal ( true ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
it ( "should remove the changes" , function ( ) {
return [ 1 , 3 , 4 ] . map ( ( i ) =>
expect ( this . rangesResponse . changes
. find ( change => change . id === this . ranges . changes [ 1 ] . id ) )
. to . be . undefined ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
it ( "should return the original number of changes minus the number of accepted changes" , function ( ) {
return this . rangesResponse . changes . length
. should . equal ( this . ranges . changes . length - 3 ) ;
} ) ;
2017-05-12 09:42:40 -04:00
2020-05-06 06:10:51 -04:00
return it ( "should not touch other changes" , function ( ) {
return [ 0 , 2 ] . map ( ( i ) =>
expect ( this . rangesResponse . changes
. find ( change => change . id === this . ranges . changes [ i ] . id ) )
. to . deep . equal ( this . ranges . changes [ i ] ) ) ;
} ) ;
} ) ;
} ) ;
} ) ;
2017-05-12 09:42:40 -04:00