Mailspring/spec/tasks/destroy-category-task-spec.coffee
Evan Morikawa 6695de4187 feat(tasks): add Create, Update, Destroy tasks plus spec & lint fixes
Summary:
1. **Generic CUD Tasks**: There is now a generic `CreateModelTask`,
`UpdateModelTask`, and `DestroyModelTask`. These can either be used as-is
or trivially overridden to easily update simple objects. Hopefully all of
the boilerplate rollback, error handling, and undo logic won't have to be
re-duplicated on every task. There are also tests for these tasks. We use
them to perform mutating actions on `Metadata` objects.

1. **Failing on Promise Rejects**: Turns out that if a Promise rejected
due to an error or `Promise.reject` we were ignoring it and letting tests
pass. Now, tests will Fail if any unhandled promise rejects. This
uncovered a variety of errors throughout the test suite that had to be
fixed. The most significant one was during the `theme-manager` tests when
all packages (and their stores with async DB requests) was loaded. Long
after the `theme-manager` specs finished, those DB requests were
(somtimes) silently failing.

1. **Globally stub `DatabaseStore._query`**: All tests shouldn't actually
make queries on the database. Furthremore, the `inTransaction` block
doesn't resolve at all unless `_query` is stubbed. Instead of manually
remembering to do this in every test that touches the DB, it's now mocked
in `spec_helper`. This broke a handful of tests that needed to be manually
fixed.

1. **ESLint Fixes**: Some minor fixes to the linter config to prevent
yelling about minor ES6 things and ensuring we have the correct parser.

Test Plan: new tests

Reviewers: bengotow, juan, drew

Differential Revision: https://phab.nylas.com/D2419

Remove cloudState and N1-Send-Later
2016-01-15 15:16:21 -05:00

110 lines
3.5 KiB
CoffeeScript

{DestroyCategoryTask,
NylasAPI,
Task,
APIError,
Label,
Folder,
DatabaseStore,
DatabaseTransaction} = require "nylas-exports"
describe "DestroyCategoryTask", ->
pathOf = (fn) ->
fn.calls[0].args[0].path
methodOf = (fn) ->
fn.calls[0].args[0].method
accountIdOf = (fn) ->
fn.calls[0].args[0].accountId
nameOf = (fn) ->
fn.calls[0].args[0].body.display_name
makeTask = (CategoryClass) ->
category = new CategoryClass
displayName: "important emails"
accountId: "account 123"
serverId: "server-444"
new DestroyCategoryTask
category: category
beforeEach ->
spyOn(DatabaseTransaction.prototype, 'persistModel').andCallFake -> Promise.resolve()
describe "performLocal", ->
it "sets an `isDeleted` flag and persists the category", ->
task = makeTask(Folder)
runs =>
task.performLocal()
waitsFor =>
DatabaseTransaction.prototype.persistModel.callCount > 0
runs =>
model = DatabaseTransaction.prototype.persistModel.calls[0].args[0]
expect(model.serverId).toEqual "server-444"
expect(model.isDeleted).toBe true
describe "performRemote", ->
it "throws error when no category present", ->
waitsForPromise ->
task = makeTask(Label)
task.category = null
task.performRemote()
.then ->
throw new Error('The promise should reject')
.catch Error, (err) ->
expect(err).toBeDefined()
it "throws error when category does not have a serverId", ->
waitsForPromise ->
task = makeTask(Label)
task.category.serverId = undefined
task.performRemote()
.then ->
throw new Error('The promise should reject')
.catch Error, (err) ->
expect(err).toBeDefined()
describe "when request succeeds", ->
beforeEach ->
spyOn(NylasAPI, "makeRequest").andCallFake -> Promise.resolve("null")
it "sends API req to /labels if user uses labels", ->
task = makeTask(Label)
task.performRemote()
expect(pathOf(NylasAPI.makeRequest)).toBe "/labels/server-444"
it "sends API req to /folders if user uses folders", ->
task = makeTask(Folder)
task.performRemote()
expect(pathOf(NylasAPI.makeRequest)).toBe "/folders/server-444"
it "sends DELETE request", ->
task = makeTask(Folder)
task.performRemote()
expect(methodOf(NylasAPI.makeRequest)).toBe "DELETE"
it "sends the account id", ->
task = makeTask(Label)
task.performRemote()
expect(accountIdOf(NylasAPI.makeRequest)).toBe "account 123"
describe "when request fails", ->
beforeEach ->
spyOn(NylasEnv, 'emitError')
spyOn(NylasAPI, 'makeRequest').andCallFake ->
Promise.reject(new APIError({statusCode: 403}))
it "updates the isDeleted flag for the category and notifies error", ->
waitsForPromise ->
task = makeTask(Folder)
spyOn(task, "_notifyUserOfError")
task.performRemote().then (status) ->
expect(status).toEqual Task.Status.Failed
expect(task._notifyUserOfError).toHaveBeenCalled()
expect(NylasEnv.emitError).toHaveBeenCalled()
expect(DatabaseTransaction.prototype.persistModel).toHaveBeenCalled()
model = DatabaseTransaction.prototype.persistModel.calls[0].args[0]
expect(model.serverId).toEqual "server-444"
expect(model.isDeleted).toBe false