mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-21 15:56:10 +08:00
More database-related spec fixes
This commit is contained in:
parent
a2c901559e
commit
2bb9ce3591
|
@ -244,7 +244,7 @@ class MessageList extends React.Component
|
|||
</div>
|
||||
|
||||
_renderLabels: =>
|
||||
labels = @state.currentThread.sortedLabels()
|
||||
labels = @state.currentThread.sortedCategories()
|
||||
labels = _.reject labels, (l) -> l.name is 'important'
|
||||
labels.map (label) =>
|
||||
<MailLabel label={label} key={label.id} onRemove={ => @_onRemoveLabel(label) }/>
|
||||
|
|
|
@ -70,7 +70,7 @@ c3 = new ListTabular.Column
|
|||
ignoredIds = _.pluck(currentCategories, 'id')
|
||||
ignoredIds.push(cat.id) for cat in CategoryStore.hiddenCategories(account)
|
||||
|
||||
for label in (thread.sortedLabels())
|
||||
for label in (thread.sortedCategories())
|
||||
continue if label.id in ignoredIds
|
||||
c3LabelComponentCache[label.id] ?= <MailLabel label={label} key={label.id} />
|
||||
labels.push c3LabelComponentCache[label.id]
|
||||
|
|
|
@ -2,7 +2,7 @@ _ = require 'underscore'
|
|||
Contact = require '../../../src/flux/models/contact'
|
||||
Message = require '../../../src/flux/models/message'
|
||||
Thread = require '../../../src/flux/models/thread'
|
||||
Label = require '../../../src/flux/models/label'
|
||||
Category = require '../../../src/flux/models/category'
|
||||
CategoryStore = require '../../../src/flux/stores/category-store'
|
||||
DatabaseStore = require '../../../src/flux/stores/database-store'
|
||||
AccountStore = require '../../../src/flux/stores/account-store'
|
||||
|
@ -14,17 +14,17 @@ describe "UnreadNotifications", ->
|
|||
beforeEach ->
|
||||
Main.activate()
|
||||
|
||||
inbox = new Label(id: "l1", name: "inbox", displayName: "Inbox")
|
||||
archive = new Label(id: "l2", name: "archive", displayName: "Archive")
|
||||
inbox = new Category(id: "l1", name: "inbox", displayName: "Inbox")
|
||||
archive = new Category(id: "l2", name: "archive", displayName: "Archive")
|
||||
|
||||
spyOn(CategoryStore, "getStandardCategory").andReturn inbox
|
||||
|
||||
account = AccountStore.accounts()[0]
|
||||
|
||||
@threadA = new Thread
|
||||
labels: [inbox]
|
||||
categories: [inbox]
|
||||
@threadB = new Thread
|
||||
labels: [archive]
|
||||
categories: [archive]
|
||||
|
||||
@msg1 = new Message
|
||||
unread: true
|
||||
|
|
|
@ -12,7 +12,7 @@ describe "ModelQuery", ->
|
|||
beforeEach ->
|
||||
@q = new ModelQuery(Thread, @db)
|
||||
@m1 = Thread.attributes.id.equal(4)
|
||||
@m2 = Thread.attributes.labels.contains('label-id')
|
||||
@m2 = Thread.attributes.categories.contains('category-id')
|
||||
|
||||
it "should accept an array of Matcher objects", ->
|
||||
@q.where([@m1,@m2])
|
||||
|
@ -148,17 +148,17 @@ describe "ModelQuery", ->
|
|||
|
||||
it "should correctly generate `contains` queries using JOINS", ->
|
||||
@runScenario Thread,
|
||||
builder: (q) -> q.where(Thread.attributes.labels.contains('label-id')).where({id: '1234'})
|
||||
builder: (q) -> q.where(Thread.attributes.categories.contains('category-id')).where({id: '1234'})
|
||||
sql: "SELECT `Thread`.`data` FROM `Thread` \
|
||||
INNER JOIN `Thread-Label` AS `M1` ON `M1`.`id` = `Thread`.`id` \
|
||||
WHERE `M1`.`value` = 'label-id' AND `Thread`.`id` = '1234' \
|
||||
INNER JOIN `Thread-Category` AS `M1` ON `M1`.`id` = `Thread`.`id` \
|
||||
WHERE `M1`.`value` = 'category-id' AND `Thread`.`id` = '1234' \
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC"
|
||||
|
||||
@runScenario Thread,
|
||||
builder: (q) -> q.where([Thread.attributes.labels.contains('l-1'), Thread.attributes.labels.contains('l-2')])
|
||||
builder: (q) -> q.where([Thread.attributes.categories.contains('l-1'), Thread.attributes.categories.contains('l-2')])
|
||||
sql: "SELECT `Thread`.`data` FROM `Thread` \
|
||||
INNER JOIN `Thread-Label` AS `M1` ON `M1`.`id` = `Thread`.`id` \
|
||||
INNER JOIN `Thread-Label` AS `M2` ON `M2`.`id` = `Thread`.`id` \
|
||||
INNER JOIN `Thread-Category` AS `M1` ON `M1`.`id` = `Thread`.`id` \
|
||||
INNER JOIN `Thread-Category` AS `M2` ON `M2`.`id` = `Thread`.`id` \
|
||||
WHERE `M1`.`value` = 'l-1' AND `M2`.`value` = 'l-2' \
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC"
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ describe "QuerySubscription", ->
|
|||
subscription = new QuerySubscription(DatabaseStore.findAll(Thread))
|
||||
subscription.update()
|
||||
advanceClock()
|
||||
expect(subscription._fetchRange).toHaveBeenCalledWith(QueryRange.infinite(), {entireModels: true})
|
||||
expect(subscription._fetchRange).toHaveBeenCalledWith(QueryRange.infinite(), {entireModels: true, version: 2})
|
||||
|
||||
it "should fetch full full models only when the previous set is empty", ->
|
||||
subscription = new QuerySubscription(DatabaseStore.findAll(Thread))
|
||||
|
@ -224,7 +224,7 @@ describe "QuerySubscription", ->
|
|||
subscription._set.addModelsInRange([new Thread()], new QueryRange(start: 0, end: 1))
|
||||
subscription.update()
|
||||
advanceClock()
|
||||
expect(subscription._fetchRange).toHaveBeenCalledWith(QueryRange.infinite(), {entireModels: false})
|
||||
expect(subscription._fetchRange).toHaveBeenCalledWith(QueryRange.infinite(), {entireModels: false, version: 2})
|
||||
|
||||
describe "when the query has a range", ->
|
||||
beforeEach ->
|
||||
|
@ -236,7 +236,7 @@ describe "QuerySubscription", ->
|
|||
subscription._set = null
|
||||
subscription.update()
|
||||
advanceClock()
|
||||
expect(subscription._fetchRange).toHaveBeenCalledWith(@query.range(), {entireModels: true})
|
||||
expect(subscription._fetchRange).toHaveBeenCalledWith(@query.range(), {entireModels: true, version: 2})
|
||||
|
||||
describe "when we have a previous range", ->
|
||||
it "should call _fetchRange for the ranges representing the difference", ->
|
||||
|
@ -250,5 +250,5 @@ describe "QuerySubscription", ->
|
|||
subscription.update()
|
||||
advanceClock()
|
||||
expect(subscription._fetchRange.callCount).toBe(2)
|
||||
expect(subscription._fetchRange.calls[0].args).toEqual([customRange1, {entireModels: true}])
|
||||
expect(subscription._fetchRange.calls[1].args).toEqual([customRange2, {entireModels: true}])
|
||||
expect(subscription._fetchRange.calls[0].args).toEqual([customRange1, {entireModels: true, version: 2}])
|
||||
expect(subscription._fetchRange.calls[1].args).toEqual([customRange2, {entireModels: true, version: 2}])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Message = require '../../src/flux/models/message'
|
||||
Thread = require '../../src/flux/models/thread'
|
||||
Label = require '../../src/flux/models/label'
|
||||
Category = require '../../src/flux/models/category'
|
||||
{Utils} = require 'nylas-exports'
|
||||
_ = require 'underscore'
|
||||
|
||||
|
@ -20,49 +20,49 @@ describe 'Thread', ->
|
|||
iterations += 1
|
||||
console.log((Date.now() - start) / 1000.0 + "ms per 1000")
|
||||
|
||||
describe '.sortLabels()', ->
|
||||
getSortedLabels = (inputs) ->
|
||||
labels = _.map inputs, (i) ->
|
||||
new Label(name: i, displayName: i)
|
||||
thread = new Thread(labels: labels)
|
||||
return thread.sortedLabels()
|
||||
describe 'sortedCategories', ->
|
||||
sortedForCategoryNames = (inputs) ->
|
||||
categories = _.map inputs, (i) ->
|
||||
new Category(name: i, displayName: i)
|
||||
thread = new Thread(categories: categories)
|
||||
return thread.sortedCategories()
|
||||
|
||||
it "puts 'important' label first, if it's present", ->
|
||||
inputs = ['alphabetically before important', 'important']
|
||||
actualOut = getSortedLabels inputs
|
||||
actualOut = sortedForCategoryNames inputs
|
||||
expect(actualOut[0].displayName).toBe 'important'
|
||||
|
||||
it "ignores 'important' label if not present", ->
|
||||
inputs = ['not important']
|
||||
actualOut = getSortedLabels inputs
|
||||
actualOut = sortedForCategoryNames inputs
|
||||
expect(actualOut.length).toBe 1
|
||||
expect(actualOut[0].displayName).toBe 'not important'
|
||||
|
||||
it "doesn't display 'sent', 'all', 'archive', or 'drafts'", ->
|
||||
inputs = ['sent', 'all', 'archive', 'drafts']
|
||||
actualOut = getSortedLabels inputs
|
||||
actualOut = sortedForCategoryNames inputs
|
||||
expect(actualOut.length).toBe 0
|
||||
|
||||
it "displays standard category names which aren't hidden next, if they're present", ->
|
||||
inputs = ['inbox', 'important', 'social']
|
||||
actualOut = _.pluck getSortedLabels(inputs), 'displayName'
|
||||
actualOut = _.pluck sortedForCategoryNames(inputs), 'displayName'
|
||||
expectedOut = ['important', 'inbox', 'social']
|
||||
expect(actualOut).toEqual expectedOut
|
||||
|
||||
it "ignores standard category names if they aren't present", ->
|
||||
inputs = ['social', 'work', 'important']
|
||||
actualOut = _.pluck getSortedLabels(inputs), 'displayName'
|
||||
actualOut = _.pluck sortedForCategoryNames(inputs), 'displayName'
|
||||
expectedOut = ['important', 'social', 'work']
|
||||
expect(actualOut).toEqual expectedOut
|
||||
|
||||
it "puts user-added categories at the end", ->
|
||||
inputs = ['food', 'inbox']
|
||||
actualOut = _.pluck getSortedLabels(inputs), 'displayName'
|
||||
actualOut = _.pluck sortedForCategoryNames(inputs), 'displayName'
|
||||
expectedOut = ['inbox', 'food']
|
||||
expect(actualOut).toEqual expectedOut
|
||||
|
||||
it "sorts user-added categories by displayName", ->
|
||||
inputs = ['work', 'social', 'receipts', 'important', 'inbox']
|
||||
actualOut = _.pluck getSortedLabels(inputs), 'displayName'
|
||||
actualOut = _.pluck sortedForCategoryNames(inputs), 'displayName'
|
||||
expectedOut = ['important', 'inbox', 'receipts', 'social', 'work']
|
||||
expect(actualOut).toEqual expectedOut
|
||||
|
|
|
@ -3,8 +3,7 @@ DatabaseStore = require '../../src/flux/stores/database-store'
|
|||
DatabaseTransaction = require '../../src/flux/stores/database-transaction'
|
||||
ThreadCountsStore = require '../../src/flux/stores/thread-counts-store'
|
||||
Thread = require '../../src/flux/models/thread'
|
||||
Folder = require '../../src/flux/models/folder'
|
||||
Label = require '../../src/flux/models/label'
|
||||
Category = require '../../src/flux/models/category'
|
||||
Matcher = require '../../src/flux/attributes/matcher'
|
||||
WindowBridge = require '../../src/window-bridge'
|
||||
|
||||
|
@ -66,10 +65,10 @@ describe "ThreadCountsStore", ->
|
|||
describe "_fetchCountsMissing", ->
|
||||
beforeEach ->
|
||||
ThreadCountsStore._categories = [
|
||||
new Label(id: "l1", name: "inbox", displayName: "Inbox", accountId: 'a1'),
|
||||
new Label(id: "l2", name: "archive", displayName: "Archive", accountId: 'a1'),
|
||||
new Label(id: "l3", displayName: "Happy Days", accountId: 'a1'),
|
||||
new Label(id: "l4", displayName: "Sad Days", accountId: 'a1')
|
||||
new Category(id: "l1", name: "inbox", displayName: "Inbox", accountId: 'a1'),
|
||||
new Category(id: "l2", name: "archive", displayName: "Archive", accountId: 'a1'),
|
||||
new Category(id: "l3", displayName: "Happy Days", accountId: 'a1'),
|
||||
new Category(id: "l4", displayName: "Sad Days", accountId: 'a1')
|
||||
]
|
||||
ThreadCountsStore._deltas =
|
||||
l1: 10
|
||||
|
@ -138,23 +137,15 @@ describe "ThreadCountsStore", ->
|
|||
expect(ThreadCountsStore._fetchCountsMissing).not.toHaveBeenCalled()
|
||||
|
||||
describe "_fetchCountForCategory", ->
|
||||
it "should make the appropriate label or folder database query", ->
|
||||
it "should make the appropriate category database query", ->
|
||||
spyOn(DatabaseStore, 'count')
|
||||
Matcher.muid = 0
|
||||
ThreadCountsStore._fetchCountForCategory(new Label(id: 'l1', accountId: 'a1'))
|
||||
ThreadCountsStore._fetchCountForCategory(new Category(id: 'l1', accountId: 'a1'))
|
||||
Matcher.muid = 0
|
||||
expect(DatabaseStore.count).toHaveBeenCalledWith(Thread, [
|
||||
Thread.attributes.categories.contains('l1'),
|
||||
Thread.attributes.accountId.equal('a1'),
|
||||
Thread.attributes.unread.equal(true),
|
||||
Thread.attributes.labels.contains('l1')
|
||||
])
|
||||
Matcher.muid = 0
|
||||
ThreadCountsStore._fetchCountForCategory(new Folder(id: 'l1', accountId: 'a1'))
|
||||
Matcher.muid = 0
|
||||
expect(DatabaseStore.count).toHaveBeenCalledWith(Thread, [
|
||||
Thread.attributes.accountId.equal('a1'),
|
||||
Thread.attributes.unread.equal(true),
|
||||
Thread.attributes.folders.contains('l1')
|
||||
])
|
||||
|
||||
describe "_saveCounts", ->
|
||||
|
@ -185,23 +176,25 @@ describe "ThreadCountsStore", ->
|
|||
|
||||
describe "CategoryDatabaseMutationObserver", ->
|
||||
beforeEach ->
|
||||
@label1 = new Label(id: "l1", name: "inbox", displayName: "Inbox")
|
||||
@label2 = new Label(id: "l2", name: "archive", displayName: "Archive")
|
||||
@label3 = new Label(id: "l3", displayName: "Happy Days")
|
||||
@label4 = new Label(id: "l4", displayName: "Sad Days")
|
||||
@category1 = new Category(id: "l1", name: "inbox", displayName: "Inbox")
|
||||
@category2 = new Category(id: "l2", name: "archive", displayName: "Archive")
|
||||
@category3 = new Category(id: "l3", displayName: "Happy Days")
|
||||
@category4 = new Category(id: "l4", displayName: "Sad Days")
|
||||
|
||||
# Values here are the "after" state. Below, the spy on the query returns the
|
||||
# "current" state.
|
||||
@threadA = new Thread
|
||||
id: "A"
|
||||
unread: true
|
||||
labels: [@label1, @label4]
|
||||
categories: [@category1, @category4]
|
||||
@threadB = new Thread
|
||||
id: "B"
|
||||
unread: true
|
||||
labels: [@label3]
|
||||
categories: [@category3]
|
||||
@threadC = new Thread
|
||||
id: "C"
|
||||
unread: false
|
||||
labels: [@label1, @label3]
|
||||
categories: [@category1, @category3]
|
||||
|
||||
describe "given a set of modifying models", ->
|
||||
scenarios = [{
|
||||
|
@ -220,7 +213,7 @@ describe "CategoryDatabaseMutationObserver", ->
|
|||
}
|
||||
}]
|
||||
scenarios.forEach ({type, expected}) ->
|
||||
it "should call countsDidChange with the folder / label membership deltas (#{type})", ->
|
||||
it "should call countsDidChange with the category membership deltas (#{type})", ->
|
||||
queryResolves = []
|
||||
query = jasmine.createSpy('query').andCallFake =>
|
||||
new Promise (resolve, reject) ->
|
||||
|
@ -235,16 +228,14 @@ describe "CategoryDatabaseMutationObserver", ->
|
|||
objectIds: [@threadA.id, @threadB.id, @threadC.id]
|
||||
objectClass: Thread.name
|
||||
})
|
||||
expect(query.callCount).toBe(2)
|
||||
expect(query.calls[0].args[0]).toEqual("SELECT `Thread`.id as id, `Thread-Label`.`value` as catId FROM `Thread` INNER JOIN `Thread-Label` ON `Thread`.`id` = `Thread-Label`.`id` WHERE `Thread`.id IN ('A','B','C') AND `Thread`.unread = 1")
|
||||
expect(query.calls[1].args[0]).toEqual("SELECT `Thread`.id as id, `Thread-Folder`.`value` as catId FROM `Thread` INNER JOIN `Thread-Folder` ON `Thread`.`id` = `Thread-Folder`.`id` WHERE `Thread`.id IN ('A','B','C') AND `Thread`.unread = 1")
|
||||
expect(query.callCount).toBe(1)
|
||||
expect(query.calls[0].args[0]).toEqual("SELECT `Thread`.id as id, `Thread-Category`.`value` as catId FROM `Thread` INNER JOIN `Thread-Category` ON `Thread`.`id` = `Thread-Category`.`id` WHERE `Thread`.id IN ('A','B','C') AND `Thread`.unread = 1")
|
||||
queryResolves[0]([
|
||||
{id: @threadA.id, catId: @label1.id},
|
||||
{id: @threadA.id, catId: @label3.id},
|
||||
{id: @threadB.id, catId: @label2.id},
|
||||
{id: @threadB.id, catId: @label3.id},
|
||||
{id: @threadA.id, catId: @category1.id},
|
||||
{id: @threadA.id, catId: @category3.id},
|
||||
{id: @threadB.id, catId: @category2.id},
|
||||
{id: @threadB.id, catId: @category3.id},
|
||||
])
|
||||
queryResolves[1]([])
|
||||
|
||||
waitsForPromise =>
|
||||
beforePromise.then (result) =>
|
||||
|
|
|
@ -119,7 +119,7 @@ class Thread extends Model
|
|||
#
|
||||
categoryNamed: (name) -> return _.findWhere(@categories, {name})
|
||||
|
||||
sortedLabels: ->
|
||||
sortedCategories: ->
|
||||
return [] unless @labels
|
||||
out = []
|
||||
|
||||
|
|
|
@ -35,11 +35,9 @@ class CategoryDatabaseMutationObserver
|
|||
if type is 'persist'
|
||||
for thread in objects
|
||||
continue unless thread.unread
|
||||
for collection in ['labels', 'folders']
|
||||
if thread[collection]
|
||||
for cat in thread[collection]
|
||||
categories[cat.id] ?= 0
|
||||
categories[cat.id] += 1
|
||||
for cat in thread.categories
|
||||
categories[cat.id] ?= 0
|
||||
categories[cat.id] += 1
|
||||
|
||||
for key, val of categories
|
||||
delete categories[key] if val is 0
|
||||
|
|
Loading…
Reference in a new issue