Unverified Commit 599e8d75 authored by Kyle Keating's avatar Kyle Keating Committed by GitHub

Merge pull request #1350 from hypothesis/namespace-annotations-module

Namespace annotations module
parents e1cb9919 9b46e378
......@@ -45,7 +45,7 @@ function SidebarContentController(
const id = Object.keys(
store.getRootState().selection.selectedAnnotationMap
)[0];
return store.getState().annotations.find(function(annot) {
return store.getRootState().annotations.annotations.find(function(annot) {
return annot.id === id;
});
} else {
......
......@@ -5,7 +5,7 @@ const angular = require('angular');
const events = require('../events');
function getExistingAnnotation(store, id) {
return store.getState().annotations.find(function(annot) {
return store.getRootState().annotations.annotations.find(function(annot) {
return annot.id === id;
});
}
......
......@@ -56,9 +56,9 @@ function FrameSync($rootScope, $window, Discovery, store, bridge) {
let prevPublicAnns = 0;
store.subscribe(function() {
const state = store.getState();
const state = store.getRootState();
if (
state.annotations === prevAnnotations &&
state.annotations.annotations === prevAnnotations &&
state.frames === prevFrames
) {
return;
......@@ -68,7 +68,7 @@ function FrameSync($rootScope, $window, Discovery, store, bridge) {
const inSidebar = new Set();
const added = [];
state.annotations.forEach(function(annot) {
state.annotations.annotations.forEach(function(annot) {
if (metadata.isReply(annot)) {
// The frame does not need to know about replies
return;
......@@ -86,7 +86,7 @@ function FrameSync($rootScope, $window, Discovery, store, bridge) {
const deleted = prevAnnotations.filter(function(annot) {
return !inSidebar.has(annot.$tag);
});
prevAnnotations = state.annotations;
prevAnnotations = state.annotations.annotations;
prevFrames = state.frames;
// We currently only handle adding and removing annotations from the frame
......
......@@ -83,7 +83,7 @@ function RootThread($rootScope, store, searchFilter, viewFilter) {
// Get the currently loaded annotations and the set of inputs which
// determines what is visible and build the visible thread structure
return buildThread(state.base.annotations, {
return buildThread(state.annotations.annotations, {
forceVisible: truthyKeys(state.selection.forceVisible),
expanded: state.selection.expanded,
highlighted: state.selection.highlighted,
......@@ -127,8 +127,8 @@ function RootThread($rootScope, store, searchFilter, viewFilter) {
// logic in this event handler can be moved to the annotations reducer.
$rootScope.$on(events.GROUP_FOCUSED, function(event, focusedGroupId) {
const updatedAnnots = store
.getState()
.annotations.filter(function(ann) {
.getRootState()
.annotations.annotations.filter(function(ann) {
return metadata.isNew(ann) && !metadata.isReply(ann);
})
.map(function(ann) {
......
......@@ -110,7 +110,9 @@ describe('sidebar.frame-sync', function() {
context('when annotations are loaded into the sidebar', function() {
it('sends a "loadAnnotations" message to the frame', function() {
fakeStore.setState({ annotations: [fixtures.ann] });
fakeStore.setState({
annotations: { annotations: [fixtures.ann] },
});
assert.calledWithMatch(
fakeBridge.call,
'loadAnnotations',
......@@ -120,10 +122,14 @@ describe('sidebar.frame-sync', function() {
it('sends a "loadAnnotations" message only for new annotations', function() {
const ann2 = Object.assign({}, fixtures.ann, { $tag: 't2', id: 'a2' });
fakeStore.setState({ annotations: [fixtures.ann] });
fakeStore.setState({
annotations: { annotations: [fixtures.ann] },
});
fakeBridge.call.reset();
fakeStore.setState({ annotations: [fixtures.ann, ann2] });
fakeStore.setState({
annotations: { annotations: [fixtures.ann, ann2] },
});
assert.calledWithMatch(
fakeBridge.call,
......@@ -133,7 +139,9 @@ describe('sidebar.frame-sync', function() {
});
it('does not send a "loadAnnotations" message for replies', function() {
fakeStore.setState({ annotations: [annotationFixtures.newReply()] });
fakeStore.setState({
annotations: { annotations: [annotationFixtures.newReply()] },
});
assert.isFalse(fakeBridge.call.calledWith('loadAnnotations'));
});
});
......@@ -141,7 +149,7 @@ describe('sidebar.frame-sync', function() {
context('when annotation count has changed', function() {
it('sends a "publicAnnotationCountChanged" message to the frame when there are public annotations', function() {
fakeStore.setState({
annotations: [annotationFixtures.publicAnnotation()],
annotations: { annotations: [annotationFixtures.publicAnnotation()] },
});
assert.calledWithMatch(
fakeBridge.call,
......@@ -152,7 +160,7 @@ describe('sidebar.frame-sync', function() {
it('sends a "publicAnnotationCountChanged" message to the frame when there are only private annotations', function() {
fakeStore.setState({
annotations: [annotationFixtures.defaultAnnotation()],
annotations: { annotations: [annotationFixtures.defaultAnnotation()] },
});
assert.calledWithMatch(
fakeBridge.call,
......@@ -164,7 +172,7 @@ describe('sidebar.frame-sync', function() {
it('does not send a "publicAnnotationCountChanged" message to the frame if annotation fetch is not complete', function() {
fakeStore.frames.returns([{ uri: 'http://example.com' }]);
fakeStore.setState({
annotations: [annotationFixtures.publicAnnotation()],
annotations: { annotations: [annotationFixtures.publicAnnotation()] },
});
assert.isFalse(
fakeBridge.call.calledWith('publicAnnotationCountChanged')
......@@ -174,7 +182,7 @@ describe('sidebar.frame-sync', function() {
it('does not send a "publicAnnotationCountChanged" message if there are no connected frames', function() {
fakeStore.frames.returns([]);
fakeStore.setState({
annotations: [annotationFixtures.publicAnnotation()],
annotations: { annotations: [annotationFixtures.publicAnnotation()] },
});
assert.isFalse(
fakeBridge.call.calledWith('publicAnnotationCountChanged')
......@@ -184,8 +192,12 @@ describe('sidebar.frame-sync', function() {
context('when annotations are removed from the sidebar', function() {
it('sends a "deleteAnnotation" message to the frame', function() {
fakeStore.setState({ annotations: [fixtures.ann] });
fakeStore.setState({ annotations: [] });
fakeStore.setState({
annotations: { annotations: [fixtures.ann] },
});
fakeStore.setState({
annotations: { annotations: [] },
});
assert.calledWithMatch(
fakeBridge.call,
'deleteAnnotation',
......
......@@ -34,7 +34,7 @@ describe('rootThread', function() {
beforeEach(function() {
fakeStore = {
state: {
base: {
annotations: {
annotations: [],
},
viewer: {
......@@ -53,8 +53,8 @@ describe('rootThread', function() {
sortKeysAvailable: ['Location'],
},
},
getState: function() {
return this.state.base;
getRootState: function() {
return this.state;
},
subscribe: sinon.stub(),
......@@ -115,7 +115,7 @@ describe('rootThread', function() {
it('passes loaded annotations to buildThread()', function() {
const annotation = annotationFixtures.defaultAnnotation();
fakeStore.state.base.annotations = [annotation];
fakeStore.state.annotations.annotations = [annotation];
rootThread.thread(fakeStore.state);
assert.calledWith(fakeBuildThread, sinon.match([annotation]));
});
......@@ -389,7 +389,7 @@ describe('rootThread', function() {
$rootScope.$on(events.ANNOTATION_DELETED, onDelete);
existingNewAnnot = { $tag: 'a-new-tag' };
fakeStore.state.base.annotations.push(existingNewAnnot);
fakeStore.state.annotations.annotations.push(existingNewAnnot);
});
it('does not remove annotations that have non-empty drafts', function() {
......@@ -405,7 +405,7 @@ describe('rootThread', function() {
it('does not remove saved annotations', function() {
const ann = annotationFixtures.defaultAnnotation();
fakeStore.state.base.annotations = [ann];
fakeStore.state.annotations.annotations = [ann];
$rootScope.$broadcast(
events.BEFORE_ANNOTATION_CREATED,
......@@ -420,7 +420,7 @@ describe('rootThread', function() {
describe('when the focused group changes', function() {
it('moves new annotations to the focused group', function() {
fakeStore.state.base.annotations = [{ $tag: 'a-tag' }];
fakeStore.state.annotations.annotations = [{ $tag: 'a-tag' }];
$rootScope.$broadcast(events.GROUP_FOCUSED, 'private-group');
......@@ -436,7 +436,7 @@ describe('rootThread', function() {
});
it('does not move replies to the new group', function() {
fakeStore.state.annotations = [annotationFixtures.newReply()];
fakeStore.state.annotations.annotations = [annotationFixtures.newReply()];
$rootScope.$broadcast(events.GROUP_FOCUSED, 'private-group');
......@@ -444,7 +444,9 @@ describe('rootThread', function() {
});
it('does not move saved annotations to the new group', function() {
fakeStore.state.annotations = [annotationFixtures.defaultAnnotation()];
fakeStore.state.annotations.annotations = [
annotationFixtures.defaultAnnotation(),
];
$rootScope.$broadcast(events.GROUP_FOCUSED, 'private-group');
......
......@@ -243,13 +243,13 @@ function addAnnotations(annotations, now) {
return function(dispatch, getState) {
const added = annotations.filter(function(annot) {
return !findByID(getState().base.annotations, annot.id);
return !findByID(getState().annotations.annotations, annot.id);
});
dispatch({
type: actions.ADD_ANNOTATIONS,
annotations: annotations,
currentAnnotationCount: getState().base.annotations.length,
currentAnnotationCount: getState().annotations.annotations.length,
});
if (!getState().viewer.isSidebar) {
......@@ -267,7 +267,7 @@ function addAnnotations(annotations, now) {
if (anchoringIDs.length > 0) {
setTimeout(() => {
// Find annotations which haven't yet been anchored in the document.
const anns = getState().base.annotations;
const anns = getState().annotations.annotations;
const annsStillAnchoring = anchoringIDs
.map(id => findByID(anns, id))
.filter(ann => ann && metadata.isWaitingToAnchor(ann));
......@@ -290,7 +290,7 @@ function addAnnotations(annotations, now) {
function removeAnnotations(annotations) {
return (dispatch, getState) => {
const remainingAnnotations = excludeAnnotations(
getState().base.annotations,
getState().annotations.annotations,
annotations
);
dispatch({
......@@ -380,14 +380,14 @@ function unhideAnnotation(id) {
* @param {state} - The global app state
*/
function savedAnnotations(state) {
return state.annotations.filter(function(ann) {
return state.annotations.annotations.filter(function(ann) {
return !metadata.isNew(ann);
});
}
/** Return true if the annotation with a given ID is currently loaded. */
function annotationExists(state, id) {
return state.annotations.some(function(annot) {
return state.annotations.annotations.some(function(annot) {
return annot.id === id;
});
}
......@@ -403,7 +403,7 @@ function annotationExists(state, id) {
function findIDsForTags(state, tags) {
const ids = [];
tags.forEach(function(tag) {
const annot = findByTag(state.annotations, tag);
const annot = findByTag(state.annotations.annotations, tag);
if (annot && annot.id) {
ids.push(annot.id);
}
......@@ -415,14 +415,14 @@ function findIDsForTags(state, tags) {
* Return the annotation with the given ID.
*/
function findAnnotationByID(state, id) {
return findByID(state.annotations, id);
return findByID(state.annotations.annotations, id);
}
/**
* Return the number of page notes.
*/
const noteCount = createSelector(
state => state.annotations,
state => state.annotations.annotations,
annotations => arrayUtil.countIf(annotations, metadata.isPageNote)
);
......@@ -430,7 +430,7 @@ const noteCount = createSelector(
* Returns the number of annotations (as opposed to notes or orphans).
*/
const annotationCount = createSelector(
state => state.annotations,
state => state.annotations.annotations,
annotations => arrayUtil.countIf(annotations, metadata.isAnnotation)
);
......@@ -438,7 +438,7 @@ const annotationCount = createSelector(
* Returns the number of orphaned annotations.
*/
const orphanCount = createSelector(
state => state.annotations,
state => state.annotations.annotations,
annotations => arrayUtil.countIf(annotations, metadata.isOrphan)
);
......@@ -446,12 +446,13 @@ const orphanCount = createSelector(
* Returns true if some annotations have not been anchored yet.
*/
const isWaitingToAnchorAnnotations = createSelector(
state => state.annotations,
state => state.annotations.annotations,
annotations => annotations.some(metadata.isWaitingToAnchor)
);
module.exports = {
init: init,
namespace: 'annotations',
update: update,
actions: {
addAnnotations,
......
......@@ -113,7 +113,7 @@ function receiveRealTimeUpdates({
// even if the annotation is from the current group, it might be for a
// new annotation (saved in pendingUpdates and removed above), that has
// not yet been loaded.
if (annotationSelectors.annotationExists(getState().base, ann.id)) {
if (annotationSelectors.annotationExists(getState(), ann.id)) {
pendingDeletions[ann.id] = true;
}
});
......
......@@ -7,7 +7,6 @@ const fixtures = require('../../../test/annotation-fixtures');
const selection = require('../selection');
const viewer = require('../viewer');
const uiConstants = require('../../../ui-constants');
const unroll = require('../../../../shared/test/util').unroll;
const { actions, selectors } = annotations;
......@@ -21,24 +20,28 @@ function createStore() {
// Tests for most of the functionality in reducers/annotations.js are currently
// in the tests for the whole Redux store
describe('annotations reducer', function() {
describe('sidebar/store/modules/annotations', function() {
describe('isWaitingToAnchorAnnotations', () => {
it('returns true if there are unanchored annotations', () => {
const unanchored = Object.assign(fixtures.oldAnnotation(), {
$orphan: 'undefined',
});
const state = {
annotations: [unanchored, fixtures.defaultAnnotation()],
annotations: {
annotations: [unanchored, fixtures.defaultAnnotation()],
},
};
assert.isTrue(selectors.isWaitingToAnchorAnnotations(state));
});
it('returns false if all annotations are anchored', () => {
const state = {
annotations: [
Object.assign(fixtures.oldPageNote(), { $orphan: false }),
Object.assign(fixtures.defaultAnnotation(), { $orphan: false }),
],
annotations: {
annotations: [
Object.assign(fixtures.oldPageNote(), { $orphan: false }),
Object.assign(fixtures.defaultAnnotation(), { $orphan: false }),
],
},
};
assert.isFalse(selectors.isWaitingToAnchorAnnotations(state));
});
......@@ -47,11 +50,13 @@ describe('annotations reducer', function() {
describe('noteCount', () => {
it('returns number of page notes', () => {
const state = {
annotations: [
fixtures.oldPageNote(),
fixtures.oldAnnotation(),
fixtures.defaultAnnotation(),
],
annotations: {
annotations: [
fixtures.oldPageNote(),
fixtures.oldAnnotation(),
fixtures.defaultAnnotation(),
],
},
};
assert.deepEqual(selectors.noteCount(state), 1);
});
......@@ -60,11 +65,13 @@ describe('annotations reducer', function() {
describe('annotationCount', () => {
it('returns number of annotations', () => {
const state = {
annotations: [
fixtures.oldPageNote(),
fixtures.oldAnnotation(),
fixtures.defaultAnnotation(),
],
annotations: {
annotations: [
fixtures.oldPageNote(),
fixtures.oldAnnotation(),
fixtures.defaultAnnotation(),
],
},
};
assert.deepEqual(selectors.annotationCount(state), 2);
});
......@@ -74,11 +81,13 @@ describe('annotations reducer', function() {
it('returns number of orphaned annotations', () => {
const orphan = Object.assign(fixtures.oldAnnotation(), { $orphan: true });
const state = {
annotations: [
orphan,
fixtures.oldAnnotation(),
fixtures.defaultAnnotation(),
],
annotations: {
annotations: [
orphan,
fixtures.oldAnnotation(),
fixtures.defaultAnnotation(),
],
},
};
assert.deepEqual(selectors.orphanCount(state), 1);
});
......@@ -89,7 +98,9 @@ describe('annotations reducer', function() {
it('returns annotations which are saved', function() {
const state = {
annotations: [fixtures.newAnnotation(), fixtures.defaultAnnotation()],
annotations: {
annotations: [fixtures.newAnnotation(), fixtures.defaultAnnotation()],
},
};
assert.deepEqual(savedAnnotations(state), [fixtures.defaultAnnotation()]);
});
......@@ -101,7 +112,9 @@ describe('annotations reducer', function() {
it('returns the IDs corresponding to the provided local tags', function() {
const ann = fixtures.defaultAnnotation();
const state = {
annotations: [Object.assign(ann, { $tag: 't1' })],
annotations: {
annotations: [Object.assign(ann, { $tag: 't1' })],
},
};
assert.deepEqual(findIDsForTags(state, ['t1']), [ann.id]);
});
......@@ -109,7 +122,9 @@ describe('annotations reducer', function() {
it('does not return IDs for annotations that do not have an ID', function() {
const ann = fixtures.newAnnotation();
const state = {
annotations: [Object.assign(ann, { $tag: 't1' })],
annotations: {
annotations: [Object.assign(ann, { $tag: 't1' })],
},
};
assert.deepEqual(findIDsForTags(state, ['t1']), []);
});
......@@ -123,7 +138,10 @@ describe('annotations reducer', function() {
store.dispatch(actions.addAnnotations([ann]));
store.dispatch(actions.hideAnnotation(ann.id));
const storeAnn = selectors.findAnnotationByID(store.getState(), ann.id);
const storeAnn = selectors.findAnnotationByID(
store.getRootState(),
ann.id
);
assert.equal(storeAnn.hidden, true);
});
});
......@@ -136,7 +154,10 @@ describe('annotations reducer', function() {
store.dispatch(actions.addAnnotations([ann]));
store.dispatch(actions.unhideAnnotation(ann.id));
const storeAnn = selectors.findAnnotationByID(store.getState(), ann.id);
const storeAnn = selectors.findAnnotationByID(
store.getRootState(),
ann.id
);
assert.equal(storeAnn.hidden, false);
});
});
......@@ -147,14 +168,56 @@ describe('annotations reducer', function() {
const ann = fixtures.defaultAnnotation();
store.dispatch(actions.addAnnotations([ann]));
store.dispatch(actions.removeAnnotations([ann]));
assert.equal(store.getState().annotations.length, 0);
assert.equal(store.getRootState().annotations.annotations.length, 0);
});
});
describe('#updateFlagStatus', function() {
unroll(
'updates the flagged status of an annotation',
function(testCase) {
[
{
description: 'non-moderator flags annotation',
wasFlagged: false,
nowFlagged: true,
oldModeration: undefined,
newModeration: undefined,
},
{
description: 'non-moderator un-flags an annotation',
wasFlagged: true,
nowFlagged: false,
oldModeration: undefined,
newModeration: undefined,
},
{
description: 'moderator un-flags an already un-flagged annotation',
wasFlagged: false,
nowFlagged: false,
oldModeration: { flagCount: 1 },
newModeration: { flagCount: 1 },
},
{
description: 'moderator flags an already flagged annotation',
wasFlagged: true,
nowFlagged: true,
oldModeration: { flagCount: 1 },
newModeration: { flagCount: 1 },
},
{
description: 'moderator flags an annotation',
wasFlagged: false,
nowFlagged: true,
oldModeration: { flagCount: 0 },
newModeration: { flagCount: 1 },
},
{
description: 'moderator un-flags an annotation',
wasFlagged: true,
nowFlagged: false,
oldModeration: { flagCount: 1 },
newModeration: { flagCount: 0 },
},
].forEach(testCase => {
it(`updates the flagged status of an annotation when a ${testCase.description}`, () => {
const store = createStore();
const ann = fixtures.defaultAnnotation();
ann.flagged = testCase.wasFlagged;
......@@ -163,55 +226,14 @@ describe('annotations reducer', function() {
store.dispatch(actions.addAnnotations([ann]));
store.dispatch(actions.updateFlagStatus(ann.id, testCase.nowFlagged));
const storeAnn = selectors.findAnnotationByID(store.getState(), ann.id);
const storeAnn = selectors.findAnnotationByID(
store.getRootState(),
ann.id
);
assert.equal(storeAnn.flagged, testCase.nowFlagged);
assert.deepEqual(storeAnn.moderation, testCase.newModeration);
},
[
{
// Non-moderator flags annotation
wasFlagged: false,
nowFlagged: true,
oldModeration: undefined,
newModeration: undefined,
},
{
// Non-moderator un-flags annotation
wasFlagged: true,
nowFlagged: false,
oldModeration: undefined,
newModeration: undefined,
},
{
// Moderator un-flags an already unflagged annotation
wasFlagged: false,
nowFlagged: false,
oldModeration: { flagCount: 1 },
newModeration: { flagCount: 1 },
},
{
// Moderator flags an already flagged annotation
wasFlagged: true,
nowFlagged: true,
oldModeration: { flagCount: 1 },
newModeration: { flagCount: 1 },
},
{
// Moderator flags annotation
wasFlagged: false,
nowFlagged: true,
oldModeration: { flagCount: 0 },
newModeration: { flagCount: 1 },
},
{
// Moderator un-flags annotation
wasFlagged: true,
nowFlagged: false,
oldModeration: { flagCount: 1 },
newModeration: { flagCount: 0 },
},
]
);
});
});
});
describe('#createAnnotation', function() {
......@@ -220,7 +242,7 @@ describe('annotations reducer', function() {
const ann = fixtures.oldAnnotation();
store.dispatch(actions.createAnnotation(ann));
assert.equal(
selectors.findAnnotationByID(store.getState(), ann.id).id,
selectors.findAnnotationByID(store.getRootState(), ann.id).id,
ann.id
);
});
......
......@@ -144,7 +144,9 @@ describe('store', function() {
it('adds annotations not in the store', function() {
const annot = defaultAnnotation();
store.addAnnotations([annot]);
assert.match(store.getState().annotations, [sinon.match(annot)]);
assert.match(store.getRootState().annotations.annotations, [
sinon.match(annot),
]);
});
it('does not change `selectedTab` state if annotations are already loaded', function() {
......@@ -183,9 +185,11 @@ describe('store', function() {
store.addAnnotations([annotA, annotB]);
const tags = store.getState().annotations.map(function(a) {
return a.$tag;
});
const tags = store
.getRootState()
.annotations.annotations.map(function(a) {
return a.$tag;
});
assert.deepEqual(tags, ['t1', 't2']);
});
......@@ -196,7 +200,7 @@ describe('store', function() {
const update = Object.assign({}, defaultAnnotation(), { text: 'update' });
store.addAnnotations([update]);
const updatedAnnot = store.getState().annotations[0];
const updatedAnnot = store.getRootState().annotations.annotations[0];
assert.equal(updatedAnnot.text, 'update');
});
......@@ -208,7 +212,7 @@ describe('store', function() {
const saved = Object.assign({}, annot, { id: 'server-id' });
store.addAnnotations([saved]);
const annots = store.getState().annotations;
const annots = store.getRootState().annotations.annotations;
assert.equal(annots.length, 1);
assert.equal(annots[0].id, 'server-id');
});
......@@ -221,7 +225,7 @@ describe('store', function() {
const nowStr = now.toISOString();
store.addAnnotations([newAnnotation()], now);
const annot = store.getState().annotations[0];
const annot = store.getRootState().annotations.annotations[0];
assert.equal(annot.created, nowStr);
assert.equal(annot.updated, nowStr);
......@@ -234,7 +238,7 @@ describe('store', function() {
annot.updated = '2000-01-01T04:05:06Z';
store.addAnnotations([annot], now);
const result = store.getState().annotations[0];
const result = store.getRootState().annotations.annotations[0];
assert.equal(result.created, annot.created);
assert.equal(result.updated, annot.updated);
......@@ -248,7 +252,7 @@ describe('store', function() {
const update = Object.assign({}, defaultAnnotation(), { text: 'update' });
store.addAnnotations([update]);
const updatedAnnot = store.getState().annotations[0];
const updatedAnnot = store.getRootState().annotations.annotations[0];
assert.isFalse(updatedAnnot.$orphan);
});
......@@ -258,7 +262,9 @@ describe('store', function() {
clock.tick(ANCHOR_TIME_LIMIT);
assert.isTrue(store.getState().annotations[0].$anchorTimeout);
assert.isTrue(
store.getRootState().annotations.annotations[0].$anchorTimeout
);
});
it('does not set the timeout flag on annotations that do anchor within a time limit', function() {
......@@ -268,7 +274,9 @@ describe('store', function() {
clock.tick(ANCHOR_TIME_LIMIT);
assert.isFalse(store.getState().annotations[0].$anchorTimeout);
assert.isFalse(
store.getRootState().annotations.annotations[0].$anchorTimeout
);
});
it('does not attempt to modify orphan status if annotations are removed before anchoring timeout expires', function() {
......@@ -284,7 +292,9 @@ describe('store', function() {
it('does not expect annotations to anchor on the stream', function() {
const isOrphan = function() {
return !!metadata.isOrphan(store.getState().annotations[0]);
return !!metadata.isOrphan(
store.getRootState().annotations.annotations[0]
);
};
const annot = defaultAnnotation();
......@@ -298,14 +308,14 @@ describe('store', function() {
it('initializes the $orphan field for new annotations', function() {
store.addAnnotations([newAnnotation()]);
assert.isFalse(store.getState().annotations[0].$orphan);
assert.isFalse(store.getRootState().annotations.annotations[0].$orphan);
});
it('adds multiple new annotations', function() {
store.addAnnotations([fixtures.newPair[0]]);
store.addAnnotations([fixtures.newPair[1]]);
assert.equal(store.getState().annotations.length, 2);
assert.equal(store.getRootState().annotations.annotations.length, 2);
});
});
......@@ -314,14 +324,14 @@ describe('store', function() {
const annot = defaultAnnotation();
store.addAnnotations([annot]);
store.removeAnnotations([annot]);
assert.deepEqual(store.getState().annotations, []);
assert.deepEqual(store.getRootState().annotations.annotations, []);
});
it('matches annotations to remove by ID', function() {
store.addAnnotations(fixtures.pair);
store.removeAnnotations([{ id: fixtures.pair[0].id }]);
const ids = store.getState().annotations.map(function(a) {
const ids = store.getRootState().annotations.annotations.map(function(a) {
return a.id;
});
assert.deepEqual(ids, [fixtures.pair[1].id]);
......@@ -331,9 +341,11 @@ describe('store', function() {
store.addAnnotations(fixtures.pair);
store.removeAnnotations([{ $tag: fixtures.pair[0].$tag }]);
const tags = store.getState().annotations.map(function(a) {
return a.$tag;
});
const tags = store
.getRootState()
.annotations.annotations.map(function(a) {
return a.$tag;
});
assert.deepEqual(tags, [fixtures.pair[1].$tag]);
});
......@@ -354,7 +366,7 @@ describe('store', function() {
const annot = defaultAnnotation();
store.addAnnotations([annot]);
store.clearAnnotations();
assert.deepEqual(store.getState().annotations, []);
assert.deepEqual(store.getRootState().annotations.annotations, []);
});
});
......@@ -377,7 +389,10 @@ describe('store', function() {
const annot = defaultAnnotation();
store.addAnnotations([annot]);
store.updateAnchorStatus({ [tagForID(annot.id)]: 'orphan' });
assert.equal(store.getState().annotations[0].$orphan, true);
assert.equal(
store.getRootState().annotations.annotations[0].$orphan,
true
);
});
});
});
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