mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-11 18:32:20 +08:00
257 lines
11 KiB
CoffeeScript
257 lines
11 KiB
CoffeeScript
|
DatabaseStore = require '../../src/flux/stores/database-store'
|
||
|
QuerySubscription = require '../../src/flux/models/query-subscription'
|
||
|
Thread = require '../../src/flux/models/thread'
|
||
|
Label = require '../../src/flux/models/label'
|
||
|
Utils = require '../../src/flux/models/utils'
|
||
|
|
||
|
describe "QuerySubscription", ->
|
||
|
describe "constructor", ->
|
||
|
it "should throw an error if the query is a count query", ->
|
||
|
query = DatabaseStore.findAll(Label).count()
|
||
|
expect( => new QuerySubscription(query)).toThrow()
|
||
|
|
||
|
it "should throw an error if a query is not provided", ->
|
||
|
expect( => new QuerySubscription({})).toThrow()
|
||
|
|
||
|
it "should fetch an initial result set", ->
|
||
|
spyOn(QuerySubscription.prototype, '_refetchResultSet')
|
||
|
sub = new QuerySubscription(DatabaseStore.findAll(Label))
|
||
|
expect(QuerySubscription.prototype._refetchResultSet).toHaveBeenCalled()
|
||
|
|
||
|
describe "applyChangeRecord", ->
|
||
|
spyOn(Utils, 'generateTempId').andCallFake => ""
|
||
|
|
||
|
scenarios = [{
|
||
|
name: "query with full set of objects (4)"
|
||
|
query: DatabaseStore.findAll(Thread)
|
||
|
.where(Thread.attributes.accountId.equal('a'))
|
||
|
.limit(4)
|
||
|
.offset(2)
|
||
|
lastResultSet: [
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4)
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1),
|
||
|
]
|
||
|
tests: [{
|
||
|
name: 'Item saved which belongs in the set'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '5', lastMessageReceivedTimestamp: 3.5)]
|
||
|
type: 'persist'
|
||
|
newResultSet:[
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4),
|
||
|
new Thread(accountId: 'a', id: '5', lastMessageReceivedTimestamp: 3.5),
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
},{
|
||
|
name: 'Item saved which does not match query clauses'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'b', id: '5', lastMessageReceivedTimestamp: 5)]
|
||
|
type: 'persist'
|
||
|
newResultSet: 'unchanged'
|
||
|
refetchRequired: false
|
||
|
},{
|
||
|
name: 'Item saved which does not lie in the range after sorting'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'b', id: '5', lastMessageReceivedTimestamp: -2)]
|
||
|
type: 'persist'
|
||
|
newResultSet: 'unchanged'
|
||
|
refetchRequired: false
|
||
|
},{
|
||
|
name: 'Item in set saved'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4, subject: 'hello')]
|
||
|
type: 'persist'
|
||
|
newResultSet:[
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4, subject: 'hello')
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1),
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
},{
|
||
|
name: 'Item in set saved, sort order changed (within range only)'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1.5)]
|
||
|
type: 'persist'
|
||
|
newResultSet:[
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1.5),
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1),
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
},{
|
||
|
name: 'Item in set saved, sort order changed and sorted to edge of set (impacting last)'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 6)]
|
||
|
type: 'persist'
|
||
|
refetchRequired: true
|
||
|
},{
|
||
|
name: 'Item in set saved, sort order changed and sorted to edge of set (impacting first)'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: -1)]
|
||
|
type: 'persist'
|
||
|
refetchRequired: true
|
||
|
},{
|
||
|
name: 'Item in set saved, no longer matches query clauses'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'b', id: '4', lastMessageReceivedTimestamp: 4)]
|
||
|
type: 'persist'
|
||
|
newResultSet: [
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1),
|
||
|
]
|
||
|
refetchRequired: true
|
||
|
},{
|
||
|
name: 'Item in set deleted'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '4')]
|
||
|
type: 'unpersist'
|
||
|
newResultSet: [
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1),
|
||
|
]
|
||
|
refetchRequired: true
|
||
|
},{
|
||
|
name: 'Item not in set deleted'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '5')]
|
||
|
type: 'unpersist'
|
||
|
newResultSet: 'unchanged'
|
||
|
refetchRequired: false
|
||
|
}]
|
||
|
|
||
|
},{
|
||
|
name: "query with fewer than LIMIT objects"
|
||
|
query: DatabaseStore.findAll(Thread)
|
||
|
.where(Thread.attributes.accountId.equal('a'))
|
||
|
.limit(4)
|
||
|
.offset(2)
|
||
|
lastResultSet: [
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4)
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2)
|
||
|
]
|
||
|
tests: [{
|
||
|
name: 'Item in set saved, no longer matches query clauses'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'b', id: '4', lastMessageReceivedTimestamp: 4)]
|
||
|
type: 'persist'
|
||
|
newResultSet: [
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
},{
|
||
|
name: 'Item in set deleted'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '4')]
|
||
|
type: 'unpersist'
|
||
|
newResultSet: [
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3),
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2),
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
}]
|
||
|
},{
|
||
|
name: "query with ASC sort order"
|
||
|
query: DatabaseStore.findAll(Thread)
|
||
|
.where(Thread.attributes.accountId.equal('a'))
|
||
|
.limit(4)
|
||
|
.offset(2)
|
||
|
.order(Thread.attributes.lastMessageReceivedTimestamp.ascending())
|
||
|
lastResultSet: [
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1)
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2)
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 3)
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4)
|
||
|
]
|
||
|
tests: [{
|
||
|
name: 'Item in set saved, sort order changed'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1.5)]
|
||
|
type: 'persist'
|
||
|
newResultSet:[
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1)
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1.5)
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 2)
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 4)
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
}]
|
||
|
|
||
|
},{
|
||
|
name: "query with multiple sort orders"
|
||
|
query: DatabaseStore.findAll(Thread)
|
||
|
.where(Thread.attributes.accountId.equal('a'))
|
||
|
.limit(4)
|
||
|
.offset(2)
|
||
|
.order([
|
||
|
Thread.attributes.lastMessageReceivedTimestamp.ascending(),
|
||
|
Thread.attributes.unread.descending()
|
||
|
])
|
||
|
lastResultSet: [
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1, unread: true)
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 1, unread: false)
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1, unread: false)
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 2, unread: true)
|
||
|
]
|
||
|
tests: [{
|
||
|
name: 'Item in set saved, secondary sort order changed'
|
||
|
change:
|
||
|
objectClass: Thread.name
|
||
|
objects: [new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1, unread: true)]
|
||
|
type: 'persist'
|
||
|
newResultSet:[
|
||
|
new Thread(accountId: 'a', id: '1', lastMessageReceivedTimestamp: 1, unread: true)
|
||
|
new Thread(accountId: 'a', id: '3', lastMessageReceivedTimestamp: 1, unread: true)
|
||
|
new Thread(accountId: 'a', id: '2', lastMessageReceivedTimestamp: 1, unread: false)
|
||
|
new Thread(accountId: 'a', id: '4', lastMessageReceivedTimestamp: 2, unread: true)
|
||
|
]
|
||
|
refetchRequired: false
|
||
|
}]
|
||
|
}]
|
||
|
|
||
|
jasmine.unspy(Utils, 'generateTempId')
|
||
|
|
||
|
describe "scenarios", ->
|
||
|
scenarios.forEach (scenario) =>
|
||
|
scenario.tests.forEach (test) =>
|
||
|
it "with #{scenario.name}, should correctly apply #{test.name}", ->
|
||
|
@q = new QuerySubscription(scenario.query, -> )
|
||
|
@q._lastResultSet = scenario.lastResultSet
|
||
|
spyOn(@q, '_invokeCallbacks')
|
||
|
spyOn(@q, '_refetchResultSet')
|
||
|
@q.applyChangeRecord(test.change)
|
||
|
|
||
|
if test.newResultSet is 'unchanged'
|
||
|
expect(@q._invokeCallbacks).not.toHaveBeenCalled()
|
||
|
expect(@q._lastResultSet).toEqual(scenario.lastResultSet)
|
||
|
|
||
|
else if test.newResultSet
|
||
|
expect(@q._invokeCallbacks).toHaveBeenCalled()
|
||
|
expect(@q._lastResultSet).toEqual(test.newResultSet)
|
||
|
|
||
|
if test.refetchRequired
|
||
|
expect(@q._refetchResultSet).toHaveBeenCalled()
|
||
|
else
|
||
|
expect(@q._refetchResultSet).not.toHaveBeenCalled()
|