mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-14 21:57:55 +08:00
be7b52cb98
Summary: write tests for adding/removing existing labels and popover closing add more tests address code review comments fix the tests add test for creating label add test for creating label and queueing change label task add test for creating a folder add syncback category task spec make the rest of the tests pass remove unnecessary parens add a few more tests add last test Test Plan: added some tests. all tests green Reviewers: bengotow, evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D2010
283 lines
10 KiB
CoffeeScript
283 lines
10 KiB
CoffeeScript
_ = require 'underscore'
|
|
React = require "react/addons"
|
|
ReactTestUtils = React.addons.TestUtils
|
|
CategoryPicker = require '../lib/category-picker'
|
|
{Popover} = require 'nylas-component-kit'
|
|
|
|
{Utils,
|
|
Label,
|
|
Folder,
|
|
Thread,
|
|
Actions,
|
|
CategoryStore,
|
|
DatabaseStore,
|
|
ChangeLabelsTask,
|
|
ChangeFolderTask,
|
|
SyncbackCategoryTask,
|
|
FocusedMailViewStore,
|
|
TaskQueueStatusStore} = require 'nylas-exports'
|
|
|
|
describe 'CategoryPicker', ->
|
|
beforeEach ->
|
|
CategoryStore._categoryCache = {}
|
|
|
|
afterEach ->
|
|
atom.testOrganizationUnit = null
|
|
|
|
setupFor = (organizationUnit) ->
|
|
atom.testOrganizationUnit = organizationUnit
|
|
klass = if organizationUnit is "label" then Label else Folder
|
|
|
|
@inboxCategory = new klass(id: 'id-123', name: 'inbox', displayName: "INBOX")
|
|
@archiveCategory = new klass(id: 'id-456', name: 'archive', displayName: "ArCHIVe")
|
|
@userCategory = new klass(id: 'id-789', name: null, displayName: "MyCategory")
|
|
|
|
spyOn(CategoryStore, "getStandardCategories").andReturn [ @inboxCategory, @archiveCategory ]
|
|
spyOn(CategoryStore, "getUserCategories").andReturn [ @userCategory ]
|
|
spyOn(CategoryStore, "getStandardCategory").andReturn @inboxCategory
|
|
|
|
# By default we're going to set to "inbox". This has implications for
|
|
# what categories get filtered out of the list.
|
|
f = FocusedMailViewStore
|
|
f._setMailView f._defaultMailView()
|
|
|
|
setupForCreateNew = (orgUnit = "folder") ->
|
|
setupFor.call(@, orgUnit)
|
|
|
|
@testThread = new Thread(id: 't1', subject: "fake")
|
|
@picker = ReactTestUtils.renderIntoDocument(
|
|
<CategoryPicker thread={@testThread} />
|
|
)
|
|
|
|
@popover = ReactTestUtils.findRenderedComponentWithType @picker, Popover
|
|
@popover.open()
|
|
|
|
describe 'when using labels', ->
|
|
beforeEach ->
|
|
setupFor.call(@, "label")
|
|
|
|
describe 'when using folders', ->
|
|
beforeEach ->
|
|
setupFor.call(@, "folder")
|
|
|
|
@testThread = new Thread(id: 't1', subject: "fake")
|
|
@picker = ReactTestUtils.renderIntoDocument(
|
|
<CategoryPicker thread={@testThread} />
|
|
)
|
|
|
|
it 'lists the desired categories', ->
|
|
data = @picker.state.categoryData
|
|
# NOTE: The inbox category is not included here because it's the
|
|
# currently focused category, which gets filtered out of the list.
|
|
expect(data[0].id).toBe "id-456"
|
|
expect(data[0].name).toBe "archive"
|
|
expect(data[0].category).toBe @archiveCategory
|
|
expect(data[1].divider).toBe true
|
|
expect(data[1].id).toBe "category-divider"
|
|
expect(data[2].id).toBe "id-789"
|
|
expect(data[2].name).toBeUndefined()
|
|
expect(data[2].category).toBe @userCategory
|
|
|
|
xdescribe 'when picking for a single Thread', ->
|
|
it 'renders a picker', ->
|
|
expect(ReactTestUtils.isCompositeComponentWithType @picker, CategoryPicker).toBe true
|
|
|
|
it "does not include a newItem prompt if there's no search", ->
|
|
outData = @picker._recalculateState().categoryData
|
|
newItem = _.findWhere(outData, newCategoryItem: true)
|
|
l1 = _.findWhere(outData, id: 'id-123')
|
|
expect(newItem).toBeUndefined()
|
|
expect(l1.name).toBe "inbox"
|
|
|
|
it "includes a newItem selector with the current search term", ->
|
|
|
|
xdescribe 'when picking labels for a single Thread', ->
|
|
beforeEach ->
|
|
atom.testOrganizationUnit = "label"
|
|
|
|
describe "'create new' item", ->
|
|
beforeEach ->
|
|
setupForCreateNew.call @
|
|
|
|
afterEach -> atom.testOrganizationUnit = null
|
|
|
|
it "is not visible when the search box is empty", ->
|
|
count = ReactTestUtils.scryRenderedDOMComponentsWithClass(@picker, 'category-create-new').length
|
|
expect(count).toBe 0
|
|
|
|
it "is visible when the search box has text", ->
|
|
inputNode = React.findDOMNode(ReactTestUtils.scryRenderedDOMComponentsWithTag(@picker, "input")[0])
|
|
ReactTestUtils.Simulate.change inputNode, target: { value: "calendar" }
|
|
count = ReactTestUtils.scryRenderedDOMComponentsWithClass(@picker, 'category-create-new').length
|
|
expect(count).toBe 1
|
|
|
|
it "shows folder icon if we're using exchange", ->
|
|
inputNode = React.findDOMNode(ReactTestUtils.scryRenderedDOMComponentsWithTag(@picker, "input")[0])
|
|
ReactTestUtils.Simulate.change inputNode, target: { value: "calendar" }
|
|
count = ReactTestUtils.scryRenderedDOMComponentsWithClass(@picker, 'category-create-new-folder').length
|
|
expect(count).toBe 1
|
|
|
|
describe "'create new' item with labels", ->
|
|
beforeEach ->
|
|
setupForCreateNew.call @, "label"
|
|
|
|
it "shows label icon if we're using gmail", ->
|
|
inputNode = React.findDOMNode(ReactTestUtils.scryRenderedDOMComponentsWithTag(@picker, "input")[0])
|
|
ReactTestUtils.Simulate.change inputNode, target: { value: "calendar" }
|
|
count = ReactTestUtils.scryRenderedDOMComponentsWithClass(@picker, 'category-create-new-tag').length
|
|
expect(count).toBe 1
|
|
|
|
describe "_onSelectCategory()", ->
|
|
describe "using labels", ->
|
|
beforeEach ->
|
|
setupForCreateNew.call @, "label"
|
|
spyOn Actions, "queueTask"
|
|
|
|
it "adds a label if it was previously unused", ->
|
|
input = { usage: 0, newCategoryItem: undefined, category: "asdf" }
|
|
|
|
@picker._onSelectCategory input
|
|
|
|
expect(Actions.queueTask).toHaveBeenCalled()
|
|
|
|
labelsToAdd = Actions.queueTask.calls[0].args[0].labelsToAdd
|
|
expect(labelsToAdd.length).toBe 1
|
|
expect(labelsToAdd[0]).toEqual input.category
|
|
|
|
threadsToUpdate = Actions.queueTask.calls[0].args[0].threads
|
|
expect(threadsToUpdate).toEqual [ @testThread ]
|
|
|
|
it "removes a label if it was previously used", ->
|
|
input = { usage: 1, newCategoryItem: undefined, category: "asdf" }
|
|
|
|
@picker._onSelectCategory input
|
|
|
|
expect(Actions.queueTask).toHaveBeenCalled()
|
|
|
|
labelsToRemove = Actions.queueTask.calls[0].args[0].labelsToRemove
|
|
expect(labelsToRemove.length).toBe 1
|
|
expect(labelsToRemove[0]).toEqual input.category
|
|
|
|
threadsToUpdate = Actions.queueTask.calls[0].args[0].threads
|
|
expect(threadsToUpdate).toEqual [ @testThread ]
|
|
|
|
it "creates a new label task", ->
|
|
input = { newCategoryItem: true }
|
|
|
|
@picker.setState searchValue: "teSTing!"
|
|
|
|
@picker._onSelectCategory input
|
|
|
|
expect(Actions.queueTask).toHaveBeenCalled()
|
|
|
|
syncbackTask = Actions.queueTask.calls[0].args[0]
|
|
newCategory = syncbackTask.category
|
|
expect(syncbackTask.organizationUnit).toBe "label"
|
|
expect(newCategory.displayName).toBe "teSTing!"
|
|
expect(newCategory.accountId).toBe TEST_ACCOUNT_ID
|
|
|
|
it "queues a change label task after performRemote for creating it", ->
|
|
input = { newCategoryItem: true }
|
|
label = new Label(clientId: "local-123")
|
|
|
|
spyOn(TaskQueueStatusStore, "waitForPerformRemote").andCallFake (task) ->
|
|
expect(task instanceof SyncbackCategoryTask).toBe true
|
|
Promise.resolve()
|
|
spyOn(DatabaseStore, "findBy").andCallFake (klass, {clientId}) ->
|
|
expect(klass).toBe Label
|
|
expect(typeof clientId).toBe "string"
|
|
Promise.resolve label
|
|
|
|
runs ->
|
|
@picker.setState searchValue: "teSTing!"
|
|
@picker._onSelectCategory input
|
|
|
|
waitsFor -> Actions.queueTask.calls.length > 1
|
|
|
|
runs ->
|
|
changeLabelsTask = Actions.queueTask.calls[1].args[0]
|
|
expect(changeLabelsTask instanceof ChangeLabelsTask).toBe true
|
|
expect(changeLabelsTask.labelsToAdd).toEqual [ label ]
|
|
expect(changeLabelsTask.threads).toEqual [ @testThread ]
|
|
|
|
it "doesn't queue any duplicate syncback tasks", ->
|
|
input = { newCategoryItem: true }
|
|
label = new Label(clientId: "local-123")
|
|
|
|
spyOn(TaskQueueStatusStore, "waitForPerformRemote").andCallFake (task) ->
|
|
expect(task instanceof SyncbackCategoryTask).toBe true
|
|
Promise.resolve()
|
|
spyOn(DatabaseStore, "findBy").andCallFake (klass, {clientId}) ->
|
|
expect(klass).toBe Label
|
|
expect(typeof clientId).toBe "string"
|
|
Promise.resolve label
|
|
|
|
runs ->
|
|
@picker.setState searchValue: "teSTing!"
|
|
@picker._onSelectCategory input
|
|
|
|
waitsFor -> Actions.queueTask.calls.length > 1
|
|
|
|
runs ->
|
|
allInputs = Actions.queueTask.calls.map (c) -> c.args[0]
|
|
syncbackTasks = allInputs.filter (i) -> i instanceof SyncbackCategoryTask
|
|
expect(syncbackTasks.length).toBe 1
|
|
|
|
describe "using folders", ->
|
|
beforeEach ->
|
|
setupForCreateNew.call @, "folder"
|
|
spyOn Actions, "queueTask"
|
|
spyOn Actions, "moveThread"
|
|
spyOn Actions, "moveThreads"
|
|
|
|
it "moves a thread if the component has one", ->
|
|
input = { category: "blah" }
|
|
@picker._onSelectCategory input
|
|
expect(Actions.moveThread).toHaveBeenCalled()
|
|
|
|
args = Actions.moveThread.calls[0].args
|
|
expect(args[0]).toEqual @testThread
|
|
expect(args[1].folder).toEqual input.category
|
|
expect(args[1].threads).toEqual [ @testThread ]
|
|
|
|
it "moves threads if the component has no thread but has items", ->
|
|
@picker = ReactTestUtils.renderIntoDocument(
|
|
<CategoryPicker items={[@testThread]} />
|
|
)
|
|
@popover = ReactTestUtils.findRenderedComponentWithType @picker, Popover
|
|
@popover.open()
|
|
|
|
input = { category: "blah" }
|
|
@picker._onSelectCategory input
|
|
expect(Actions.moveThreads).toHaveBeenCalled()
|
|
|
|
it "creates a new folder task", ->
|
|
input = { newCategoryItem: true }
|
|
folder = new Folder(clientId: "local-456", serverId: "yes.")
|
|
|
|
spyOn(TaskQueueStatusStore, "waitForPerformRemote").andCallFake (task) ->
|
|
expect(task instanceof SyncbackCategoryTask).toBe true
|
|
Promise.resolve()
|
|
spyOn(DatabaseStore, "findBy").andCallFake (klass, {clientId}) ->
|
|
expect(klass).toBe Folder
|
|
expect(typeof clientId).toBe "string"
|
|
Promise.resolve folder
|
|
|
|
runs ->
|
|
@picker.setState searchValue: "teSTing!"
|
|
@picker._onSelectCategory input
|
|
|
|
waitsFor -> Actions.moveThread.calls.length > 0
|
|
|
|
runs ->
|
|
changeFoldersTask = Actions.moveThread.calls[0].args[1]
|
|
expect(changeFoldersTask instanceof ChangeFolderTask).toBe true
|
|
expect(changeFoldersTask.folder).toEqual folder
|
|
expect(changeFoldersTask.threads).toEqual [ @testThread ]
|
|
|
|
it "closes the popover", ->
|
|
setupForCreateNew.call @, "folder"
|
|
spyOn @popover, "close"
|
|
spyOn Actions, "moveThread"
|
|
@picker._onSelectCategory { usage: 0, category: "asdf" }
|
|
expect(@popover.close).toHaveBeenCalled()
|