Mailspring/spec/tasks/change-labels-task-spec.coffee
Ben Gotow 60ce0b53ba es6(tasks): Convert all remaining tasks to ES6
Summary: after refactoring some things last week and spending time futsing with coffeescript, I’m pretty convinced it’s worth moving important parts of the app to ES6 to be able to use ESLint as part of our dev workflow

Test Plan: Run existing tests, tested manually. Did not convert the tests in this diff, breaking one part at a time!

Reviewers: evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D2768
2016-03-21 16:50:10 -07:00

227 lines
10 KiB
CoffeeScript

_ = require 'underscore'
Label = require '../../src/flux/models/label'
Thread = require '../../src/flux/models/thread'
Message = require '../../src/flux/models/message'
Actions = require '../../src/flux/actions'
NylasAPI = require '../../src/flux/nylas-api'
DatabaseStore = require '../../src/flux/stores/database-store'
ChangeLabelsTask = require '../../src/flux/tasks/change-labels-task'
ChangeMailTask = require '../../src/flux/tasks/change-mail-task'
{AccountStore, CategoryStore} = require 'nylas-exports'
{APIError} = require '../../src/flux/errors'
{Utils} = require '../../src/flux/models/utils'
testLabels = {}
testThreads = {}
describe "ChangeLabelsTask", ->
beforeEach ->
# IMPORTANT: These specs do not run the performLocal logic of their superclass!
# Tests for that logic are in change-mail-task-spec.
spyOn(ChangeMailTask.prototype, 'performLocal').andCallFake =>
Promise.resolve()
spyOn(AccountStore, 'accountForItems').andReturn({id: 'a1'})
spyOn(CategoryStore, 'getTrashCategory').andReturn name: 'trash'
spyOn(CategoryStore, 'getInboxCategory').andReturn name: 'inbox'
spyOn(CategoryStore, 'getSpamCategory').andReturn name: 'spam'
spyOn(CategoryStore, 'getAllMailCategory').andReturn name: 'all'
spyOn(DatabaseStore, 'modelify').andCallFake (klass, items) =>
Promise.resolve items.map (item) =>
return testLabels[item] if testLabels[item]
return testThreads[item] if testThreads[item]
item
testLabels = @testLabels =
"l1": new Label({name: 'inbox', id: 'l1', displayName: "INBOX"}),
"l2": new Label({name: 'drafts', id: 'l2', displayName: "MyDrafts"})
"l3": new Label({name: null, id: 'l3', displayName: "My Label"})
testThreads = @testThreads =
't1': new Thread(id: 't1', categories: [@testLabels['l1']])
't2': new Thread(id: 't2', categories: _.values(@testLabels))
't3': new Thread(id: 't3', categories: [@testLabels['l2'], @testLabels['l3']])
@basicThreadTask = new ChangeLabelsTask
labelsToAdd: ["l1", "l2"]
labelsToRemove: ["l3"]
threads: ['t1']
describe "description", ->
it "should include the name of the added label if it's the only mutation and it was provided as an object", ->
task = new ChangeLabelsTask(labelsToAdd: ["l1"], labelsToRemove: [], threads: ['t1'])
expect(task.description()).toEqual("Changed labels on 1 thread")
task = new ChangeLabelsTask(labelsToAdd: [new Label(id: 'l1', displayName: 'LABEL')], labelsToRemove: [], threads: ['t1'])
expect(task.description()).toEqual("Added LABEL to 1 thread")
task = new ChangeLabelsTask(labelsToAdd: [new Label(id: 'l1', displayName: 'LABEL')], labelsToRemove: ['l2'], threads: ['t1'])
expect(task.description()).toEqual("Changed labels on 1 thread")
it "should include the name of the removed label if it's the only mutation and it was provided as an object", ->
task = new ChangeLabelsTask(labelsToAdd: [], labelsToRemove: ["l1"], threads: ['t1'])
expect(task.description()).toEqual("Changed labels on 1 thread")
task = new ChangeLabelsTask(labelsToAdd: [], labelsToRemove: [new Label(id: 'l1', displayName: 'LABEL')], threads: ['t1'])
expect(task.description()).toEqual("Removed LABEL from 1 thread")
task = new ChangeLabelsTask(labelsToAdd: ['l2'], labelsToRemove: [new Label(id: 'l1', displayName: 'LABEL')], threads: ['t1'])
expect(task.description()).toEqual("Changed labels on 1 thread")
it "should pluralize properly", ->
task = new ChangeLabelsTask(labelsToAdd: ["l2"], labelsToRemove: ["l1"], threads: ['t1', 't2', 't3'])
expect(task.description()).toEqual("Changed labels on 3 threads")
describe "_ensureAndUpdateLabels", ->
beforeEach ->
@task = new ChangeLabelsTask()
@account = {}
it "does not remove `all` if attempting to remove `all` without adding `trash` or `spam`", ->
toAdd = []
toRemove = [{name: 'all'}]
{labelsToAdd, labelsToRemove} = @task._ensureAndUpdateLabels(@account, toAdd, toRemove)
expect(labelsToRemove).toEqual([])
it "removes `trash` and `spam` if attempting to add `all` and not already removing them", ->
toRemove = []
toAdd = [{name: 'all'}]
{labelsToAdd, labelsToRemove} = @task._ensureAndUpdateLabels(@account, toAdd, toRemove)
expect(labelsToRemove).toEqual([{name: 'trash'}, {name: 'spam'}])
it "adds `all` if removing `trash` and not adding to `all` or `spam`", ->
toRemove = [{name: 'trash'}]
toAdd = []
{labelsToAdd, labelsToRemove} = @task._ensureAndUpdateLabels(@account, toAdd, toRemove)
expect(labelsToAdd).toEqual([{name: 'all'}])
it "removes `all` and `spam` if attempting to add `trash` and not already removing it", ->
toRemove = []
toAdd = [{name: 'trash'}]
{labelsToAdd, labelsToRemove} = @task._ensureAndUpdateLabels(@account, toAdd, toRemove)
expect(labelsToRemove).toEqual([{name: 'all'}, {name: 'spam'}])
it "adds `all` if removing `spam` and not adding to `all` or `trash`", ->
toRemove = [{name: 'spam'}]
toAdd = []
{labelsToAdd, labelsToRemove} = @task._ensureAndUpdateLabels(@account, toAdd, toRemove)
expect(labelsToAdd).toEqual([{name: 'all'}])
it "removes `all` and `trash` if attempting to add `spam` and not already removing it", ->
toRemove = []
toAdd = [{name: 'spam'}]
{labelsToAdd, labelsToRemove} = @task._ensureAndUpdateLabels(@account, toAdd, toRemove)
expect(labelsToRemove).toEqual([{name: 'all'}, {name: 'trash'}])
describe "performLocal", ->
it "should throw an exception if task has not been given a label, has been given messages, or no threads", ->
badTasks = [
new ChangeLabelsTask(),
new ChangeLabelsTask(threads: [123]),
new ChangeLabelsTask(threads: [123], messages: ["foo"]),
new ChangeLabelsTask(labelsToAdd: ['l2'], labelsToRemove: ['l1'], messages: [123]),
new ChangeLabelsTask(threads: "Thread"),
]
goodTasks = [
new ChangeLabelsTask(
labelsToAdd: ['l2']
labelsToRemove: ['l1']
threads: ['t1']
)
]
caught = []
succeeded = []
runs ->
[].concat(badTasks, goodTasks).forEach (task) ->
task.performLocal()
.then -> succeeded.push(task)
.catch (err) -> caught.push(task)
waitsFor ->
succeeded.length + caught.length == 6
runs ->
expect(caught.length).toEqual(badTasks.length)
expect(succeeded.length).toEqual(goodTasks.length)
it 'calls through to super performLocal', ->
task = new ChangeLabelsTask
labelsToAdd: ['l2']
labelsToRemove: ['l1']
threads: ['t1']
waitsForPromise =>
task.performLocal().then =>
expect(task.__proto__.__proto__.performLocal).toHaveBeenCalled()
describe "when object IDs are provided", ->
beforeEach ->
@task = new ChangeLabelsTask
labelsToAdd: ['l2']
labelsToRemove: ['l1']
threads: ['t1']
it 'resolves the objects before calling super', ->
waitsForPromise =>
@task.performLocal().then =>
expect(@task.labelsToAdd).toEqual([testLabels['l2']])
expect(@task.labelsToRemove).toEqual([testLabels['l1']])
expect(@task.threads).toEqual([testThreads['t1']])
describe "when objects are provided", ->
beforeEach ->
@task = new ChangeLabelsTask
labelsToAdd: [testLabels['l2']]
labelsToRemove: [testLabels['l1']]
threads: [testThreads['t1']]
it 'still has the objects when calling super', ->
waitsForPromise =>
@task.performLocal().then =>
expect(@task.labelsToAdd).toEqual([testLabels['l2']])
expect(@task.labelsToRemove).toEqual([testLabels['l1']])
expect(@task.threads).toEqual([testThreads['t1']])
describe 'change methods', ->
describe "changesToModel", ->
it 'properly adds labels', ->
task = new ChangeLabelsTask
labelsToAdd: [testLabels['l1'], testLabels['l2']]
labelsToRemove: []
out = task.changesToModel(testThreads['t1'])
expect(out).toEqual(labels: [testLabels['l1'], testLabels['l2']])
it 'properly removes labels', ->
task = new ChangeLabelsTask
labelsToAdd: []
labelsToRemove: [testLabels['l1'], testLabels['l2']]
out = task.changesToModel(testThreads['t3'])
expect(out).toEqual(labels: [testLabels['l3']])
it 'properly adds and removes labels, ignoring labels that are both added and removed', ->
task = new ChangeLabelsTask
labelsToAdd: [testLabels['l1'], testLabels['l2']]
labelsToRemove: [testLabels['l2'], testLabels['l3']]
out = task.changesToModel(testThreads['t1'])
expect(out).toEqual(labels: [testLabels['l1'], testLabels['l2']])
it 'should return an == array of labels when no changes have occurred', ->
thread = new Thread(id: '1', categories: [testLabels['l2'], testLabels['l3'], testLabels['l1']])
task = new ChangeLabelsTask
labelsToAdd: [testLabels['l3'], testLabels['l1'], testLabels['l2']]
labelsToRemove: []
out = task.changesToModel(thread)
expect(_.isEqual(thread.labels, out.labels)).toBe(true)
it 'should not modify the input thread in any way', ->
thread = new Thread(id: '1', categories: [testLabels['l2'], testLabels['l1']])
task = new ChangeLabelsTask
labelsToAdd: []
labelsToRemove: [testLabels['l2']]
out = task.changesToModel(thread)
expect(thread.labels.length).toBe(2)
expect(out.labels.length).toBe(1)
describe "requestBodyForModel", ->
it 'returns labels:<ids> for both threads and messages', ->
task = new ChangeLabelsTask()
out = task.requestBodyForModel(testThreads['t3'])
expect(out).toEqual(labels: ['l2', 'l3'])