Commit f308df84 authored by Robert Knight's avatar Robert Knight

Use real annotationUI object rather than fake in tests

Since putting the annotationUI store into the desired state and
asserting that the state is correct after interactions is quite
straightforward, using the real object rather than a fake seems
appropriate at present.
parent 76e14557
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
var angular = require('angular'); var angular = require('angular');
var createFakeStore = require('./create-fake-store'); var annotationUIFactory = require('../annotation-ui');
describe('AnnotationUIController', function () { describe('AnnotationUIController', function () {
var $scope; var $scope;
...@@ -24,16 +24,7 @@ describe('AnnotationUIController', function () { ...@@ -24,16 +24,7 @@ describe('AnnotationUIController', function () {
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.search = {}; $scope.search = {};
var store = createFakeStore({ annotationUI = annotationUIFactory({});
selectedAnnotationMap: null,
focusedAnnotationsMap: null,
});
annotationUI = {
removeSelectedAnnotation: sandbox.stub(),
setState: store.setState,
getState: store.getState,
subscribe: store.subscribe,
};
$controller('AnnotationUIController', { $controller('AnnotationUIController', {
$scope: $scope, $scope: $scope,
...@@ -46,30 +37,34 @@ describe('AnnotationUIController', function () { ...@@ -46,30 +37,34 @@ describe('AnnotationUIController', function () {
}); });
it('updates the view when the selection changes', function () { it('updates the view when the selection changes', function () {
annotationUI.setState({selectedAnnotationMap: { 1: true, 2: true }}); annotationUI.selectAnnotations(['1','2']);
assert.deepEqual($scope.selectedAnnotations, { 1: true, 2: true }); assert.deepEqual($scope.selectedAnnotations, { 1: true, 2: true });
}); });
it('updates the selection counter when the selection changes', function () { it('updates the selection counter when the selection changes', function () {
annotationUI.setState({selectedAnnotationMap: { 1: true, 2: true }}); annotationUI.selectAnnotations(['1','2']);
assert.deepEqual($scope.selectedAnnotationsCount, 2); assert.deepEqual($scope.selectedAnnotationsCount, 2);
}); });
it('clears the selection when no annotations are selected', function () { it('clears the selection when no annotations are selected', function () {
annotationUI.setState({selectedAnnotationMap: null}); annotationUI.selectAnnotations([]);
assert.deepEqual($scope.selectedAnnotations, null); assert.deepEqual($scope.selectedAnnotations, null);
assert.deepEqual($scope.selectedAnnotationsCount, 0); assert.deepEqual($scope.selectedAnnotationsCount, 0);
}); });
it('updates the focused annotations when the focus map changes', function () { it('updates the focused annotations when the focus map changes', function () {
annotationUI.setState({focusedAnnotationMap: { 1: true, 2: true }}); annotationUI.focusAnnotations([
{$$tag: '1'},
{$$tag: '2'},
]);
assert.deepEqual($scope.focusedAnnotations, { 1: true, 2: true }); assert.deepEqual($scope.focusedAnnotations, { 1: true, 2: true });
}); });
describe('on annotationDeleted', function () { describe('on annotationDeleted', function () {
it('removes the deleted annotation from the selection', function () { it('removes the deleted annotation from the selection', function () {
annotationUI.selectAnnotations(['1']);
$rootScope.$emit('annotationDeleted', { id: 1 }); $rootScope.$emit('annotationDeleted', { id: 1 });
assert.calledWith(annotationUI.removeSelectedAnnotation, { id: 1 }); assert.equal(annotationUI.getState().selectedAnnotationMap, null);
}); });
}); });
}); });
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
var angular = require('angular'); var angular = require('angular');
var createFakeStore = require('./create-fake-store'); var annotationUIFactory = require('../annotation-ui');
describe('AnnotationUISync', function () { describe('AnnotationUISync', function () {
var sandbox = sinon.sandbox.create(); var sandbox = sinon.sandbox.create();
var $digest; var $digest;
var publish; var publish;
var fakeBridge; var fakeBridge;
var fakeAnnotationUI; var annotationUI;
var fakeAnnotationSync; var fakeAnnotationSync;
var createAnnotationUISync; var createAnnotationUISync;
var createChannel = function () { var createChannel = function () {
...@@ -45,23 +45,18 @@ describe('AnnotationUISync', function () { ...@@ -45,23 +45,18 @@ describe('AnnotationUISync', function () {
fakeAnnotationSync = { fakeAnnotationSync = {
getAnnotationForTag: function (tag) { getAnnotationForTag: function (tag) {
return { id: Number(tag.replace('tag', '')) }; return {
id: Number(tag.replace('tag', '')),
$$tag: tag,
};
} }
}; };
var store = createFakeStore({visibleHighlights: false}); annotationUI = annotationUIFactory({});
fakeAnnotationUI = {
focusAnnotations: sandbox.stub(),
selectAnnotations: sandbox.stub(),
xorSelectedAnnotations: sandbox.stub(),
setShowHighlights: sandbox.stub(),
getState: store.getState,
};
createAnnotationUISync = function () { createAnnotationUISync = function () {
new AnnotationUISync( new AnnotationUISync(
$rootScope, fakeWindow, fakeBridge, fakeAnnotationSync, $rootScope, fakeWindow, fakeBridge, fakeAnnotationSync,
fakeAnnotationUI annotationUI
); );
}; };
})); }));
...@@ -97,10 +92,11 @@ describe('AnnotationUISync', function () { ...@@ -97,10 +92,11 @@ describe('AnnotationUISync', function () {
it('updates the annotationUI to include the shown annotations', function () { it('updates the annotationUI to include the shown annotations', function () {
createAnnotationUISync(); createAnnotationUISync();
publish('showAnnotations', ['tag1', 'tag2', 'tag3']); publish('showAnnotations', ['tag1', 'tag2', 'tag3']);
assert.called(fakeAnnotationUI.selectAnnotations); assert.deepEqual(annotationUI.getState().selectedAnnotationMap, {
assert.calledWith(fakeAnnotationUI.selectAnnotations, [ 1: true,
{ id: 1 }, { id: 2 }, { id: 3 } 2: true,
]); 3: true,
});
}); });
it('triggers a digest', function () { it('triggers a digest', function () {
...@@ -114,10 +110,11 @@ describe('AnnotationUISync', function () { ...@@ -114,10 +110,11 @@ describe('AnnotationUISync', function () {
it('updates the annotationUI to show the provided annotations', function () { it('updates the annotationUI to show the provided annotations', function () {
createAnnotationUISync(); createAnnotationUISync();
publish('focusAnnotations', ['tag1', 'tag2', 'tag3']); publish('focusAnnotations', ['tag1', 'tag2', 'tag3']);
assert.called(fakeAnnotationUI.focusAnnotations); assert.deepEqual(annotationUI.getState().focusedAnnotationMap, {
assert.calledWith(fakeAnnotationUI.focusAnnotations, [ tag1: true,
{ id: 1 }, { id: 2 }, { id: 3 } tag2: true,
]); tag3: true,
});
}); });
it('triggers a digest', function () { it('triggers a digest', function () {
...@@ -131,10 +128,11 @@ describe('AnnotationUISync', function () { ...@@ -131,10 +128,11 @@ describe('AnnotationUISync', function () {
it('updates the annotationUI to show the provided annotations', function () { it('updates the annotationUI to show the provided annotations', function () {
createAnnotationUISync(); createAnnotationUISync();
publish('toggleAnnotationSelection', ['tag1', 'tag2', 'tag3']); publish('toggleAnnotationSelection', ['tag1', 'tag2', 'tag3']);
assert.called(fakeAnnotationUI.xorSelectedAnnotations); assert.deepEqual(annotationUI.getState().selectedAnnotationMap, {
assert.calledWith(fakeAnnotationUI.xorSelectedAnnotations, [ 1: true,
{ id: 1 }, { id: 2 }, { id: 3 } 2: true,
]); 3: true,
});
}); });
it('triggers a digest', function () { it('triggers a digest', function () {
...@@ -148,7 +146,7 @@ describe('AnnotationUISync', function () { ...@@ -148,7 +146,7 @@ describe('AnnotationUISync', function () {
it('updates the annotationUI state', function () { it('updates the annotationUI state', function () {
createAnnotationUISync(); createAnnotationUISync();
publish('setVisibleHighlights', true); publish('setVisibleHighlights', true);
assert.calledWith(fakeAnnotationUI.setShowHighlights, true); assert.equal(annotationUI.getState().visibleHighlights, true);
}); });
it('notifies the other frames of the change', function () { it('notifies the other frames of the change', function () {
......
'use strict';
var redux = require('redux');
function reducer(state, action) {
if (action.type === 'STATE_UPDATE') {
return Object.assign({}, state, action.update);
} else {
return state;
}
}
/**
* Creates a fake Redux store for use in tests.
*
* Unlike a normal Redux store where the user provides a function that
* transforms the state in response to actions and calls dispatch() to update
* the state when actions occur, this store has a setState() method for
* replacing state fields directly.
*/
function createFakeStore(initialState) {
var store = redux.createStore(reducer, initialState);
store.setState = function (update) {
store.dispatch({
type: 'STATE_UPDATE',
update: update,
});
};
return store;
}
module.exports = createFakeStore;
...@@ -5,7 +5,7 @@ var inherits = require('inherits'); ...@@ -5,7 +5,7 @@ var inherits = require('inherits');
var proxyquire = require('proxyquire'); var proxyquire = require('proxyquire');
var EventEmitter = require('tiny-emitter'); var EventEmitter = require('tiny-emitter');
var createFakeStore = require('./create-fake-store'); var annotationUIFactory = require('../annotation-ui');
var events = require('../events'); var events = require('../events');
var noCallThru = require('./util').noCallThru; var noCallThru = require('./util').noCallThru;
...@@ -29,8 +29,8 @@ inherits(FakeSearchClient, EventEmitter); ...@@ -29,8 +29,8 @@ inherits(FakeSearchClient, EventEmitter);
describe('WidgetController', function () { describe('WidgetController', function () {
var $scope = null; var $scope = null;
var $rootScope = null; var $rootScope = null;
var annotationUI = null;
var fakeAnnotationMapper = null; var fakeAnnotationMapper = null;
var fakeAnnotationUI = null;
var fakeCrossFrame = null; var fakeCrossFrame = null;
var fakeDrafts = null; var fakeDrafts = null;
var fakeStore = null; var fakeStore = null;
...@@ -63,28 +63,7 @@ describe('WidgetController', function () { ...@@ -63,28 +63,7 @@ describe('WidgetController', function () {
unloadAnnotations: sandbox.spy() unloadAnnotations: sandbox.spy()
}; };
var store = createFakeStore({selectedAnnotationMap: {}}); annotationUI = annotationUIFactory({});
fakeAnnotationUI = {
clearSelectedAnnotations: sandbox.spy(),
hasSelectedAnnotations: function () {
return !!this.getState().selectedAnnotationMap &&
Object.keys(this.getState().selectedAnnotationMap).length > 0;
},
getState: store.getState,
subscribe: store.subscribe,
_select: function (ids) {
if (!ids.length) {
store.setState({selectedAnnotationMap: null});
return;
}
store.setState({
selectedAnnotationMap: ids.reduce(function (map, id) {
map[id] = true;
return map;
}, {}),
});
},
};
fakeCrossFrame = { fakeCrossFrame = {
call: sinon.stub(), call: sinon.stub(),
frames: [], frames: [],
...@@ -125,7 +104,7 @@ describe('WidgetController', function () { ...@@ -125,7 +104,7 @@ describe('WidgetController', function () {
}; };
$provide.value('annotationMapper', fakeAnnotationMapper); $provide.value('annotationMapper', fakeAnnotationMapper);
$provide.value('annotationUI', fakeAnnotationUI); $provide.value('annotationUI', annotationUI);
$provide.value('crossframe', fakeCrossFrame); $provide.value('crossframe', fakeCrossFrame);
$provide.value('drafts', fakeDrafts); $provide.value('drafts', fakeDrafts);
$provide.value('store', fakeStore); $provide.value('store', fakeStore);
...@@ -187,7 +166,7 @@ describe('WidgetController', function () { ...@@ -187,7 +166,7 @@ describe('WidgetController', function () {
beforeEach(function () { beforeEach(function () {
fakeCrossFrame.frames = [{uri: uri}]; fakeCrossFrame.frames = [{uri: uri}];
fakeAnnotationUI._select([id]); annotationUI.selectAnnotations([id]);
$scope.$digest(); $scope.$digest();
}); });
...@@ -232,7 +211,7 @@ describe('WidgetController', function () { ...@@ -232,7 +211,7 @@ describe('WidgetController', function () {
beforeEach(function () { beforeEach(function () {
fakeCrossFrame.frames = [{uri: uri}]; fakeCrossFrame.frames = [{uri: uri}];
fakeAnnotationUI._select([id]); annotationUI.selectAnnotations([id]);
fakeGroups.focused = function () { return { id: 'private-group' }; }; fakeGroups.focused = function () { return { id: 'private-group' }; };
$scope.$digest(); $scope.$digest();
}); });
...@@ -248,7 +227,7 @@ describe('WidgetController', function () { ...@@ -248,7 +227,7 @@ describe('WidgetController', function () {
describe('when an annotation is anchored', function () { describe('when an annotation is anchored', function () {
it('focuses and scrolls to the annotation if already selected', function () { it('focuses and scrolls to the annotation if already selected', function () {
var uri = 'http://example.com'; var uri = 'http://example.com';
fakeAnnotationUI._select(['123']); annotationUI.selectAnnotations(['123']);
fakeCrossFrame.frames.push({uri: uri}); fakeCrossFrame.frames.push({uri: uri});
var annot = { var annot = {
$$tag: 'atag', $$tag: 'atag',
...@@ -311,21 +290,21 @@ describe('WidgetController', function () { ...@@ -311,21 +290,21 @@ describe('WidgetController', function () {
describe('direct linking messages', function () { describe('direct linking messages', function () {
it('displays a message if the selection is unavailable', function () { it('displays a message if the selection is unavailable', function () {
fakeAnnotationUI._select(['missing']); annotationUI.selectAnnotations(['missing']);
fakeThreading.idTable = {'123': {}}; fakeThreading.idTable = {'123': {}};
$scope.$digest(); $scope.$digest();
assert.isTrue($scope.selectedAnnotationUnavailable()); assert.isTrue($scope.selectedAnnotationUnavailable());
}); });
it('does not show a message if the selection is available', function () { it('does not show a message if the selection is available', function () {
fakeAnnotationUI._select(['123']); annotationUI.selectAnnotations(['123']);
fakeThreading.idTable = {'123': {}}; fakeThreading.idTable = {'123': {}};
$scope.$digest(); $scope.$digest();
assert.isFalse($scope.selectedAnnotationUnavailable()); assert.isFalse($scope.selectedAnnotationUnavailable());
}); });
it('does not a show a message if there is no selection', function () { it('does not a show a message if there is no selection', function () {
fakeAnnotationUI._select([]); annotationUI.selectAnnotations([]);
$scope.$digest(); $scope.$digest();
assert.isFalse($scope.selectedAnnotationUnavailable()); assert.isFalse($scope.selectedAnnotationUnavailable());
}); });
...@@ -334,7 +313,7 @@ describe('WidgetController', function () { ...@@ -334,7 +313,7 @@ describe('WidgetController', function () {
$scope.auth = { $scope.auth = {
status: 'signed-out' status: 'signed-out'
}; };
fakeAnnotationUI._select(['123']); annotationUI.selectAnnotations(['123']);
fakeThreading.idTable = {'123': {}}; fakeThreading.idTable = {'123': {}};
$scope.$digest(); $scope.$digest();
assert.isTrue($scope.shouldShowLoggedOutMessage()); assert.isTrue($scope.shouldShowLoggedOutMessage());
...@@ -344,7 +323,7 @@ describe('WidgetController', function () { ...@@ -344,7 +323,7 @@ describe('WidgetController', function () {
$scope.auth = { $scope.auth = {
status: 'signed-out' status: 'signed-out'
}; };
fakeAnnotationUI._select(['missing']); annotationUI.selectAnnotations(['missing']);
fakeThreading.idTable = {'123': {}}; fakeThreading.idTable = {'123': {}};
$scope.$digest(); $scope.$digest();
assert.isFalse($scope.shouldShowLoggedOutMessage()); assert.isFalse($scope.shouldShowLoggedOutMessage());
...@@ -354,7 +333,7 @@ describe('WidgetController', function () { ...@@ -354,7 +333,7 @@ describe('WidgetController', function () {
$scope.auth = { $scope.auth = {
status: 'signed-out' status: 'signed-out'
}; };
fakeAnnotationUI._select([]); annotationUI.selectAnnotations([]);
$scope.$digest(); $scope.$digest();
assert.isFalse($scope.shouldShowLoggedOutMessage()); assert.isFalse($scope.shouldShowLoggedOutMessage());
}); });
...@@ -363,7 +342,7 @@ describe('WidgetController', function () { ...@@ -363,7 +342,7 @@ describe('WidgetController', function () {
$scope.auth = { $scope.auth = {
status: 'signed-in' status: 'signed-in'
}; };
fakeAnnotationUI._select(['123']); annotationUI.selectAnnotations(['123']);
fakeThreading.idTable = {'123': {}}; fakeThreading.idTable = {'123': {}};
$scope.$digest(); $scope.$digest();
assert.isFalse($scope.shouldShowLoggedOutMessage()); assert.isFalse($scope.shouldShowLoggedOutMessage());
...@@ -374,7 +353,7 @@ describe('WidgetController', function () { ...@@ -374,7 +353,7 @@ describe('WidgetController', function () {
status: 'signed-out' status: 'signed-out'
}; };
delete fakeSettings.annotations; delete fakeSettings.annotations;
fakeAnnotationUI._select(['123']); annotationUI.selectAnnotations(['123']);
fakeThreading.idTable = {'123': {}}; fakeThreading.idTable = {'123': {}};
$scope.$digest(); $scope.$digest();
assert.isFalse($scope.shouldShowLoggedOutMessage()); assert.isFalse($scope.shouldShowLoggedOutMessage());
......
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