mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-23 08:46:07 +08:00
559ecb1cda
Summary: Renamed in prep for next few diffs Test Plan: manual Reviewers: juan, mark, spang, halla Reviewed By: halla Differential Revision: https://phab.nylas.com/D4302
232 lines
8.8 KiB
CoffeeScript
232 lines
8.8 KiB
CoffeeScript
_ = require 'underscore'
|
|
fs = require 'fs'
|
|
path = require 'path'
|
|
{NylasAPIHelpers,
|
|
Thread,
|
|
DatabaseWriter,
|
|
Actions,
|
|
Message,
|
|
Thread} = require 'nylas-exports'
|
|
|
|
DeltaProcessor = require('../../src/services/delta-processor').default
|
|
|
|
fixturesPath = path.resolve(__dirname, '..', 'fixtures')
|
|
|
|
describe "DeltaProcessor", ->
|
|
|
|
describe "handleDeltas", ->
|
|
beforeEach ->
|
|
@sampleDeltas = JSON.parse(fs.readFileSync("#{fixturesPath}/sample-deltas.json"))
|
|
@sampleClustered = JSON.parse(fs.readFileSync("#{fixturesPath}/sample-deltas-clustered.json"))
|
|
|
|
it "should immediately fire the received raw deltas event", ->
|
|
spyOn(Actions, 'longPollReceivedRawDeltas')
|
|
spyOn(DeltaProcessor, '_clusterDeltas').andReturn({create: {}, modify: {}, destroy: []})
|
|
waitsForPromise ->
|
|
DeltaProcessor.process(@sampleDeltas, {source: 'n1Cloud'})
|
|
runs ->
|
|
expect(Actions.longPollReceivedRawDeltas).toHaveBeenCalled()
|
|
|
|
xit "should call helper methods for all creates first, then modifications, then destroys", ->
|
|
spyOn(Actions, 'longPollProcessedDeltas')
|
|
|
|
handleDeltaDeletionPromises = []
|
|
resolveDeltaDeletionPromises = ->
|
|
fn() for fn in handleDeltaDeletionPromises
|
|
handleDeltaDeletionPromises = []
|
|
|
|
spyOn(DeltaProcessor, '_handleDestroyDelta').andCallFake ->
|
|
new Promise (resolve, reject) ->
|
|
handleDeltaDeletionPromises.push(resolve)
|
|
|
|
handleModelResponsePromises = []
|
|
resolveModelResponsePromises = ->
|
|
fn() for fn in handleModelResponsePromises
|
|
handleModelResponsePromises = []
|
|
|
|
spyOn(NylasAPIHelpers, 'handleModelResponse').andCallFake ->
|
|
new Promise (resolve, reject) ->
|
|
handleModelResponsePromises.push(resolve)
|
|
|
|
spyOn(DeltaProcessor, '_clusterDeltas').andReturn(JSON.parse(JSON.stringify(@sampleClustered)))
|
|
DeltaProcessor.process(@sampleDeltas)
|
|
|
|
createTypes = Object.keys(@sampleClustered['create'])
|
|
expect(NylasAPIHelpers.handleModelResponse.calls.length).toEqual(createTypes.length)
|
|
expect(NylasAPIHelpers.handleModelResponse.calls[0].args[0]).toEqual(_.values(@sampleClustered['create'][createTypes[0]]))
|
|
expect(DeltaProcessor._handleDestroyDelta.calls.length).toEqual(0)
|
|
|
|
NylasAPIHelpers.handleModelResponse.reset()
|
|
resolveModelResponsePromises()
|
|
advanceClock()
|
|
|
|
modifyTypes = Object.keys(@sampleClustered['modify'])
|
|
expect(NylasAPIHelpers.handleModelResponse.calls.length).toEqual(modifyTypes.length)
|
|
expect(NylasAPIHelpers.handleModelResponse.calls[0].args[0]).toEqual(_.values(@sampleClustered['modify'][modifyTypes[0]]))
|
|
expect(DeltaProcessor._handleDestroyDelta.calls.length).toEqual(0)
|
|
|
|
NylasAPIHelpers.handleModelResponse.reset()
|
|
resolveModelResponsePromises()
|
|
advanceClock()
|
|
|
|
destroyCount = @sampleClustered['destroy'].length
|
|
expect(DeltaProcessor._handleDestroyDelta.calls.length).toEqual(destroyCount)
|
|
expect(DeltaProcessor._handleDestroyDelta.calls[0].args[0]).toEqual(@sampleClustered['destroy'][0])
|
|
|
|
expect(Actions.longPollProcessedDeltas).not.toHaveBeenCalled()
|
|
|
|
resolveDeltaDeletionPromises()
|
|
advanceClock()
|
|
|
|
expect(Actions.longPollProcessedDeltas).toHaveBeenCalled()
|
|
|
|
describe "clusterDeltas", ->
|
|
beforeEach ->
|
|
@sampleDeltas = JSON.parse(fs.readFileSync("#{fixturesPath}/sample-deltas.json"))
|
|
@expectedClustered = JSON.parse(fs.readFileSync("#{fixturesPath}/sample-deltas-clustered.json"))
|
|
|
|
it "should collect create/modify events into a hash by model type", ->
|
|
{create, modify} = DeltaProcessor._clusterDeltas(@sampleDeltas)
|
|
expect(create).toEqual(@expectedClustered.create)
|
|
expect(modify).toEqual(@expectedClustered.modify)
|
|
|
|
it "should collect destroys into an array", ->
|
|
{destroy} = DeltaProcessor._clusterDeltas(@sampleDeltas)
|
|
expect(destroy).toEqual(@expectedClustered.destroy)
|
|
|
|
describe "handleDeltaDeletion", ->
|
|
beforeEach ->
|
|
@thread = new Thread(id: 'idhere')
|
|
@delta =
|
|
"cursor": "bb95ddzqtr2gpmvgrng73t6ih",
|
|
"object": "thread",
|
|
"event": "delete",
|
|
"objectId": @thread.id,
|
|
"timestamp": "2015-08-26T17:36:45.297Z"
|
|
|
|
spyOn(DatabaseWriter.prototype, 'unpersistModel')
|
|
|
|
it "should resolve if the object cannot be found", ->
|
|
spyOn(DatabaseWriter.prototype, 'find').andCallFake (klass, id) =>
|
|
return Promise.resolve(null)
|
|
waitsForPromise =>
|
|
DeltaProcessor._handleDestroyDelta(@delta)
|
|
runs =>
|
|
expect(DatabaseWriter.prototype.find).toHaveBeenCalledWith(Thread, 'idhere')
|
|
expect(DatabaseWriter.prototype.unpersistModel).not.toHaveBeenCalled()
|
|
|
|
it "should call unpersistModel if the object exists", ->
|
|
spyOn(DatabaseWriter.prototype, 'find').andCallFake (klass, id) =>
|
|
return Promise.resolve(@thread)
|
|
waitsForPromise =>
|
|
DeltaProcessor._handleDestroyDelta(@delta)
|
|
runs =>
|
|
expect(DatabaseWriter.prototype.find).toHaveBeenCalledWith(Thread, 'idhere')
|
|
expect(DatabaseWriter.prototype.unpersistModel).toHaveBeenCalledWith(@thread)
|
|
|
|
describe "handleModelResponse", ->
|
|
# SEE spec/nylas-api-spec.coffee
|
|
|
|
describe "receives metadata deltas", ->
|
|
beforeEach ->
|
|
@stubDB = {}
|
|
spyOn(DatabaseWriter.prototype, 'find').andCallFake (klass, id) =>
|
|
return @stubDB[id]
|
|
spyOn(DatabaseWriter.prototype, 'findAll').andCallFake (klass, where) =>
|
|
ids = where.id
|
|
models = []
|
|
ids.forEach (id) =>
|
|
model = @stubDB[id]
|
|
if model
|
|
models.push(model)
|
|
return models
|
|
spyOn(DatabaseWriter.prototype, 'persistModels').andCallFake (models) =>
|
|
models.forEach (model) =>
|
|
@stubDB[model.id] = model
|
|
return Promise.resolve()
|
|
|
|
@messageMetadataDelta =
|
|
id: 519,
|
|
event: "create",
|
|
object: "metadata",
|
|
objectId: 8876,
|
|
changedFields: ["version", "object"],
|
|
attributes:
|
|
id: 8876,
|
|
value: {link_clicks: 1},
|
|
object: "metadata",
|
|
version: 2,
|
|
plugin_id: "link-tracking",
|
|
object_id: '2887',
|
|
object_type: "message",
|
|
account_id: 2
|
|
|
|
@threadMetadataDelta =
|
|
id: 392,
|
|
event: "create",
|
|
object: "metadata",
|
|
objectId: 3845,
|
|
changedFields: ["version", "object"],
|
|
attributes:
|
|
id: 3845,
|
|
value: {shouldNotify: true},
|
|
object: "metadata",
|
|
version: 2,
|
|
plugin_id: "send-reminders",
|
|
object_id: 't:3984',
|
|
object_type: "thread"
|
|
account_id: 2,
|
|
|
|
it "saves metadata to existing Messages", ->
|
|
message = new Message({serverId: @messageMetadataDelta.attributes.object_id})
|
|
@stubDB[message.id] = message
|
|
waitsForPromise =>
|
|
DeltaProcessor.process([@messageMetadataDelta])
|
|
runs ->
|
|
message = @stubDB[message.id] # refresh reference
|
|
expect(message.pluginMetadata.length).toEqual(1)
|
|
expect(message.metadataForPluginId('link-tracking')).toEqual({link_clicks: 1})
|
|
|
|
it "saves metadata to existing Threads", ->
|
|
thread = new Thread({serverId: @threadMetadataDelta.attributes.object_id})
|
|
@stubDB[thread.id] = thread
|
|
waitsForPromise =>
|
|
DeltaProcessor.process([@threadMetadataDelta])
|
|
runs ->
|
|
thread = @stubDB[thread.id] # refresh reference
|
|
expect(thread.pluginMetadata.length).toEqual(1)
|
|
expect(thread.metadataForPluginId('send-reminders')).toEqual({shouldNotify: true})
|
|
|
|
it "knows how to reconcile different thread ids", ->
|
|
thread = new Thread({serverId: 't:1948'})
|
|
@stubDB[thread.id] = thread
|
|
message = new Message({
|
|
serverId: @threadMetadataDelta.attributes.object_id.substring(2),
|
|
threadId: thread.id
|
|
})
|
|
@stubDB[message.id] = message
|
|
waitsForPromise =>
|
|
DeltaProcessor.process([@threadMetadataDelta])
|
|
runs ->
|
|
thread = @stubDB[thread.id] # refresh reference
|
|
expect(thread.pluginMetadata.length).toEqual(1)
|
|
expect(thread.metadataForPluginId('send-reminders')).toEqual({shouldNotify: true})
|
|
|
|
it "creates ghost Messages if necessary", ->
|
|
waitsForPromise =>
|
|
DeltaProcessor.process([@messageMetadataDelta])
|
|
runs ->
|
|
message = @stubDB[@messageMetadataDelta.attributes.object_id]
|
|
expect(message).toBeDefined()
|
|
expect(message.pluginMetadata.length).toEqual(1)
|
|
expect(message.metadataForPluginId('link-tracking')).toEqual({link_clicks: 1})
|
|
|
|
it "creates ghost Threads if necessary", ->
|
|
waitsForPromise =>
|
|
DeltaProcessor.process([@threadMetadataDelta])
|
|
runs ->
|
|
thread = @stubDB[@threadMetadataDelta.attributes.object_id]
|
|
expect(thread.pluginMetadata.length).toEqual(1)
|
|
expect(thread.metadataForPluginId('send-reminders')).toEqual({shouldNotify: true})
|
|
|