Commit 3c7e9ddd authored by Robert Knight's avatar Robert Knight

Fix selection of annotations when bucket bar indicators are clicked

A typo, `annotator` instead of `@annotator`, caused this functionality
to break when `window.annotator` (which was the same object as
`@annotator`) was removed in 0033f774.

Correct the typo and add tests. The tests operate at the DOM level so
they should be easy to adapt if the BucketBar implementation is
rewritten or changed substantially in future.

Fixes https://github.com/hypothesis/product-backlog/issues/704
parent 5d68724e
......@@ -76,6 +76,8 @@ module.exports = class BucketBar extends Plugin
else
$(element).append @element
@highlighter = options.highlighter ? highlighter # Test seam.
pluginInit: ->
$(window).on 'resize scroll', @update
......@@ -113,7 +115,7 @@ module.exports = class BucketBar extends Plugin
unless anchor.highlights?.length
return points
rect = highlighter.getBoundingClientRect(anchor.highlights)
rect = @highlighter.getBoundingClientRect(anchor.highlights)
x = rect.top
h = rect.bottom - rect.top
......@@ -251,7 +253,7 @@ module.exports = class BucketBar extends Plugin
scrollToClosest(@buckets[bucket], 'down')
else
annotations = (anchor.annotation for anchor in @buckets[bucket])
annotator.selectAnnotations annotations,
@annotator.selectAnnotations annotations,
(event.ctrlKey or event.metaKey),
this._buildTabs(@tabs, @buckets)
......
BucketBar = require('../bucket-bar')
# Return DOM elements for non-empty bucket indicators in a `BucketBar`.
nonEmptyBuckets = (bucketBar) ->
buckets = bucketBar.element[0].querySelectorAll('.annotator-bucket-indicator')
Array.from(buckets)
.filter((bucket) ->
label = bucket.querySelector('.label')
parseInt(label.textContent) > 0
)
createMouseEvent = (type, { ctrlKey, metaKey } = {}) ->
# In a modern browser we could use `new MouseEvent` constructor and pass
# `ctrlKey` and `metaKey` via the init object.
event = new Event(type)
event.ctrlKey = Boolean(ctrlKey)
event.metaKey = Boolean(metaKey)
event
describe 'BucketBar', ->
createBucketBar = (options) ->
element = document.createElement('div')
new BucketBar(element, options || {})
# Create a fake anchor, which is a combination of annotation object and
# associated highlight elements.
createAnchor = ->
annotation: { $tag: 'ann1' },
highlights: [document.createElement('span')]
context 'when a bucket is clicked', ->
bucketBar = null
fakeHighlighter = null
fakeAnnotator = null
beforeEach ->
fakeHighlighter =
getBoundingClientRect: -> { left: 0, top: 200, right: 200, bottom: 250 }
bucketBar = createBucketBar(highlighter: fakeHighlighter)
# This setup is done by `Guest#addPlugin` in the actual app.
bucketBar.annotator = {
anchors: [],
selectAnnotations: sinon.stub(),
}
# Create fake anchors and render buckets.
anchors = [createAnchor()]
bucketBar.annotator.anchors = anchors
bucketBar._update()
it 'selects the annotations', ->
# Click on the indicator for the non-empty bucket.
bucketEls = nonEmptyBuckets(bucketBar)
assert.equal(bucketEls.length, 1)
bucketEls[0].dispatchEvent(createMouseEvent('click'))
anns = bucketBar.annotator.anchors.map((anchor) -> anchor.annotation)
assert.calledWith(bucketBar.annotator.selectAnnotations, anns, false)
[
{ ctrlKey: true, metaKey: false },
{ ctrlKey: false, metaKey: true },
].forEach(({ ctrlKey, metaKey }) ->
it 'toggles selection of the annotations if Ctrl or Alt is pressed', ->
# Click on the indicator for the non-empty bucket.
bucketEls = nonEmptyBuckets(bucketBar)
assert.equal(bucketEls.length, 1)
bucketEls[0].dispatchEvent(
createMouseEvent('click', ctrlKey: ctrlKey, metaKey: metaKey)
)
anns = bucketBar.annotator.anchors.map((anchor) -> anchor.annotation)
assert.calledWith(bucketBar.annotator.selectAnnotations, anns, true)
)
# Yes this is testing a private method. Yes this is bad practice, but I'd
# rather test this functionality in a private method than not test it at all.
#
# Note: This could be tested using only the public APIs of the `BucketBar`
# class using the approach of the "when a bucket is clicked" tests above.
describe '_buildTabs', ->
setup = (tabs) ->
bucketBar = createBucketBar()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment