Commit fcf7fa1b authored by Sean Hammond's avatar Sean Hammond

Remove `annotation` global from tests

Remove the global variable `annotation` from annotation-test.js.

This paves the way for having different helper functions for creating
different
kinds of annotation and passing them in to the directive initialization.

Some describe()s still use their own global annotation objects, these
should be
factored out as well.
parent e7e0f0b6
...@@ -303,7 +303,6 @@ describe('annotation.js', function() { ...@@ -303,7 +303,6 @@ describe('annotation.js', function() {
var $scope; var $scope;
var $timeout; var $timeout;
var $window; var $window;
var annotation;
var fakeAnnotationMapper; var fakeAnnotationMapper;
var fakeAnnotationUI; var fakeAnnotationUI;
var fakeDocumentDomainFilter; var fakeDocumentDomainFilter;
...@@ -321,13 +320,30 @@ describe('annotation.js', function() { ...@@ -321,13 +320,30 @@ describe('annotation.js', function() {
var fakeUrlEncodeFilter; var fakeUrlEncodeFilter;
var sandbox; var sandbox;
function createDirective() { /** Return the default domain model object that createDirective() uses if
* no custom one is passed to it. */
function defaultAnnotation() {
return {
id: 'deadbeef',
document: {
title: 'A special document'
},
target: [{}],
uri: 'http://example.com',
user: 'acct:bill@localhost'
};
}
function createDirective(annotation) {
annotation = annotation || defaultAnnotation();
$scope.annotation = annotation;
var element = angular.element('<div annotation="annotation">'); var element = angular.element('<div annotation="annotation">');
compileService()(element)($scope); compileService()(element)($scope);
$scope.$digest(); $scope.$digest();
var controller = element.controller('annotation'); var controller = element.controller('annotation');
var scope = element.isolateScope(); var scope = element.isolateScope();
return { return {
annotation: annotation,
controller: controller, controller: controller,
element: element, element: element,
scope: scope scope: scope
...@@ -453,15 +469,6 @@ describe('annotation.js', function() { ...@@ -453,15 +469,6 @@ describe('annotation.js', function() {
$timeout = _$timeout_; $timeout = _$timeout_;
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.annotation = annotation = {
id: 'deadbeef',
document: {
title: 'A special document'
},
target: [{}],
uri: 'http://example.com',
user: 'acct:bill@localhost'
};
} }
) )
); );
...@@ -472,6 +479,7 @@ describe('annotation.js', function() { ...@@ -472,6 +479,7 @@ describe('annotation.js', function() {
describe('AnnotationController() initialization', function() { describe('AnnotationController() initialization', function() {
it('saves new highlights to the server on initialization', function() { it('saves new highlights to the server on initialization', function() {
var annotation = defaultAnnotation();
// New highlights have no id and have $highlight: true. // New highlights have no id and have $highlight: true.
annotation.id = null; annotation.id = null;
annotation.$highlight = true; annotation.$highlight = true;
...@@ -483,12 +491,13 @@ describe('annotation.js', function() { ...@@ -483,12 +491,13 @@ describe('annotation.js', function() {
then: function() {} then: function() {}
}); });
createDirective(); createDirective(annotation);
assert.called(annotation.$create); assert.called(annotation.$create);
}); });
it('saves new highlights to drafts if not logged in', function() { it('saves new highlights to drafts if not logged in', function() {
var annotation = defaultAnnotation();
// New highlights have no id and have $highlight: true. // New highlights have no id and have $highlight: true.
annotation.id = null; annotation.id = null;
annotation.$highlight = true; annotation.$highlight = true;
...@@ -500,13 +509,14 @@ describe('annotation.js', function() { ...@@ -500,13 +509,14 @@ describe('annotation.js', function() {
then: function() {} then: function() {}
}); });
createDirective(); createDirective(annotation);
assert.notCalled(annotation.$create); assert.notCalled(annotation.$create);
assert.called(fakeDrafts.update); assert.called(fakeDrafts.update);
}); });
it('does not save new annotations on initialization', function() { it('does not save new annotations on initialization', function() {
var annotation = defaultAnnotation();
// New annotations have no id and no $highlight. // New annotations have no id and no $highlight.
annotation.id = null; annotation.id = null;
annotation.$highlight = undefined; annotation.$highlight = undefined;
...@@ -515,12 +525,13 @@ describe('annotation.js', function() { ...@@ -515,12 +525,13 @@ describe('annotation.js', function() {
then: function() {} then: function() {}
}); });
createDirective(); createDirective(annotation);
assert.notCalled(annotation.$create); assert.notCalled(annotation.$create);
}); });
it('does not save old highlights on initialization', function() { it('does not save old highlights on initialization', function() {
var annotation = defaultAnnotation();
// Old highlights (ones that the client has received from the server, // Old highlights (ones that the client has received from the server,
// rather than created locally itself) have an id and do not have any // rather than created locally itself) have an id and do not have any
// $highlight. // $highlight.
...@@ -538,12 +549,13 @@ describe('annotation.js', function() { ...@@ -538,12 +549,13 @@ describe('annotation.js', function() {
then: function() {} then: function() {}
}); });
createDirective(); createDirective(annotation);
assert.notCalled(annotation.$create); assert.notCalled(annotation.$create);
}); });
it('does not save old annotations on initialization', function() { it('does not save old annotations on initialization', function() {
var annotation = defaultAnnotation();
// Old annotations (ones that the client has received from the server, // Old annotations (ones that the client has received from the server,
// rather than created locally itself) have an id and do not have any // rather than created locally itself) have an id and do not have any
// $highlight. // $highlight.
...@@ -562,12 +574,13 @@ describe('annotation.js', function() { ...@@ -562,12 +574,13 @@ describe('annotation.js', function() {
then: function() {} then: function() {}
}); });
createDirective(); createDirective(annotation);
assert.notCalled(annotation.$create); assert.notCalled(annotation.$create);
}); });
it('edits new annotations on initialization', function() { it('edits new annotations on initialization', function() {
var annotation = defaultAnnotation();
// When the user creates a new annotation and we create a new // When the user creates a new annotation and we create a new
// AnnotationController instance, we automatically open the // AnnotationController instance, we automatically open the
// annotation's editor. // annotation's editor.
...@@ -582,12 +595,13 @@ describe('annotation.js', function() { ...@@ -582,12 +595,13 @@ describe('annotation.js', function() {
// A new annotation won't have any saved drafts yet. // A new annotation won't have any saved drafts yet.
fakeDrafts.get.returns(null); fakeDrafts.get.returns(null);
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
assert.isTrue(controller.editing()); assert.isTrue(controller.editing());
}); });
it('edits annotations with drafts on initialization', function() { it('edits annotations with drafts on initialization', function() {
var annotation = defaultAnnotation();
// This is not a new annotation. // This is not a new annotation.
annotation.id = 'annotation_id'; annotation.id = 'annotation_id';
// This is not a highlight. // This is not a highlight.
...@@ -597,12 +611,13 @@ describe('annotation.js', function() { ...@@ -597,12 +611,13 @@ describe('annotation.js', function() {
// The drafts service has some draft changes for this annotation. // The drafts service has some draft changes for this annotation.
fakeDrafts.get.returns('foo'); fakeDrafts.get.returns('foo');
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
assert.isTrue(controller.editing()); assert.isTrue(controller.editing());
}); });
it('does not edit new highlights on initialization', function() { it('does not edit new highlights on initialization', function() {
var annotation = defaultAnnotation();
// This is a new annotation. // This is a new annotation.
annotation.id = undefined; annotation.id = undefined;
fakeDrafts.get.returns(null); fakeDrafts.get.returns(null);
...@@ -615,12 +630,13 @@ describe('annotation.js', function() { ...@@ -615,12 +630,13 @@ describe('annotation.js', function() {
then: function() {} then: function() {}
}); });
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
assert.isFalse(controller.editing()); assert.isFalse(controller.editing());
}); });
it('edits highlights with drafts on initialization', function() { it('edits highlights with drafts on initialization', function() {
var annotation = defaultAnnotation();
// You can edit a highlight, enter some text or tags, and save it (the // You can edit a highlight, enter some text or tags, and save it (the
// highlight then becomes an annotation). You can also edit a highlight // highlight then becomes an annotation). You can also edit a highlight
// and then change focus to another group and back without saving the // and then change focus to another group and back without saving the
...@@ -635,7 +651,7 @@ describe('annotation.js', function() { ...@@ -635,7 +651,7 @@ describe('annotation.js', function() {
// This highlight has draft edits. // This highlight has draft edits.
fakeDrafts.get.returns('foo'); fakeDrafts.get.returns('foo');
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
assert.isTrue(controller.editing()); assert.isTrue(controller.editing());
}); });
...@@ -663,27 +679,30 @@ describe('annotation.js', function() { ...@@ -663,27 +679,30 @@ describe('annotation.js', function() {
describe('AnnotationController.isHighlight()', function() { describe('AnnotationController.isHighlight()', function() {
it('returns true for new highlights', function() { it('returns true for new highlights', function() {
var annotation = defaultAnnotation();
// New highlights have no id and have $highlight: true. // New highlights have no id and have $highlight: true.
annotation.id = undefined; annotation.id = undefined;
annotation.$highlight = true; annotation.$highlight = true;
// We need to define $create because it'll try to call it. // We need to define $create because it'll try to call it.
annotation.$create = function() {return {then: function() {}};}; annotation.$create = function() {return {then: function() {}};};
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isTrue(vm.isHighlight()); assert.isTrue(vm.isHighlight());
}); });
it('returns false for new annotations', function() { it('returns false for new annotations', function() {
var annotation = defaultAnnotation();
// New annotations have no id and no $highlight. // New annotations have no id and no $highlight.
annotation.id = annotation.$highlight = undefined; annotation.id = annotation.$highlight = undefined;
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isFalse(vm.isHighlight()); assert.isFalse(vm.isHighlight());
}); });
it('returns false for page notes', function() { it('returns false for page notes', function() {
var annotation = defaultAnnotation();
annotation.$highlight = undefined; annotation.$highlight = undefined;
// Page notes have no targets. // Page notes have no targets.
annotation.target = []; annotation.target = [];
...@@ -694,12 +713,13 @@ describe('annotation.js', function() { ...@@ -694,12 +713,13 @@ describe('annotation.js', function() {
annotation.text = ''; annotation.text = '';
annotation.tags = []; annotation.tags = [];
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isFalse(vm.isHighlight()); assert.isFalse(vm.isHighlight());
}); });
it('returns false for replies', function() { it('returns false for replies', function() {
var annotation = defaultAnnotation();
annotation.$highlight = undefined; annotation.$highlight = undefined;
// This is not a page note. // This is not a page note.
annotation.target = ['foo']; annotation.target = ['foo'];
...@@ -710,12 +730,13 @@ describe('annotation.js', function() { ...@@ -710,12 +730,13 @@ describe('annotation.js', function() {
annotation.text = ''; annotation.text = '';
annotation.tags = []; annotation.tags = [];
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isFalse(vm.isHighlight()); assert.isFalse(vm.isHighlight());
}); });
it('returns false for annotations with text', function() { it('returns false for annotations with text', function() {
var annotation = defaultAnnotation();
// Not a highlight, reply or page note. // Not a highlight, reply or page note.
annotation.$highlight = undefined; annotation.$highlight = undefined;
annotation.target = ['foo']; annotation.target = ['foo'];
...@@ -725,12 +746,13 @@ describe('annotation.js', function() { ...@@ -725,12 +746,13 @@ describe('annotation.js', function() {
annotation.text = 'This is my annotation'; annotation.text = 'This is my annotation';
annotation.tags = []; annotation.tags = [];
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isFalse(vm.isHighlight()); assert.isFalse(vm.isHighlight());
}); });
it('returns false for annotations with tags', function() { it('returns false for annotations with tags', function() {
var annotation = defaultAnnotation();
// Not a highlight, reply or page note. // Not a highlight, reply or page note.
annotation.$highlight = undefined; annotation.$highlight = undefined;
annotation.target = ['foo']; annotation.target = ['foo'];
...@@ -740,12 +762,13 @@ describe('annotation.js', function() { ...@@ -740,12 +762,13 @@ describe('annotation.js', function() {
annotation.text = ''; annotation.text = '';
annotation.tags = ['foo']; annotation.tags = ['foo'];
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isFalse(vm.isHighlight()); assert.isFalse(vm.isHighlight());
}); });
it('returns true for annotations with no text or tags', function() { it('returns true for annotations with no text or tags', function() {
var annotation = defaultAnnotation();
// Not a new highlight, reply or page note. // Not a new highlight, reply or page note.
annotation.$highlight = undefined; annotation.$highlight = undefined;
annotation.target = ['foo']; annotation.target = ['foo'];
...@@ -755,14 +778,17 @@ describe('annotation.js', function() { ...@@ -755,14 +778,17 @@ describe('annotation.js', function() {
annotation.text = ''; annotation.text = '';
annotation.tags = []; annotation.tags = [];
var vm = createDirective().controller; var vm = createDirective(annotation).controller;
assert.isTrue(vm.isHighlight()); assert.isTrue(vm.isHighlight());
}); });
}); });
describe('when the annotation is a highlight', function() { describe('when the annotation is a highlight', function() {
var annotation;
beforeEach(function() { beforeEach(function() {
annotation = defaultAnnotation();
annotation.$highlight = true; annotation.$highlight = true;
annotation.$create = sinon.stub().returns({ annotation.$create = sinon.stub().returns({
then: angular.noop, then: angular.noop,
...@@ -773,7 +799,7 @@ describe('annotation.js', function() { ...@@ -773,7 +799,7 @@ describe('annotation.js', function() {
it('is private', function() { it('is private', function() {
delete annotation.id; delete annotation.id;
createDirective(); createDirective(annotation);
$scope.$digest(); $scope.$digest();
assert.deepEqual(annotation.permissions, { assert.deepEqual(annotation.permissions, {
read: ['justme'] read: ['justme']
...@@ -782,7 +808,10 @@ describe('annotation.js', function() { ...@@ -782,7 +808,10 @@ describe('annotation.js', function() {
}); });
describe('#reply', function() { describe('#reply', function() {
var annotation;
beforeEach(function() { beforeEach(function() {
annotation = defaultAnnotation();
annotation.permissions = { annotation.permissions = {
read: ['acct:joe@localhost'], read: ['acct:joe@localhost'],
update: ['acct:joe@localhost'], update: ['acct:joe@localhost'],
...@@ -792,7 +821,7 @@ describe('annotation.js', function() { ...@@ -792,7 +821,7 @@ describe('annotation.js', function() {
}); });
it('creates a new reply with the proper uri and references', function() { it('creates a new reply with the proper uri and references', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
controller.reply(); controller.reply();
var match = sinon.match({ var match = sinon.match({
references: [annotation.id], references: [annotation.id],
...@@ -802,7 +831,7 @@ describe('annotation.js', function() { ...@@ -802,7 +831,7 @@ describe('annotation.js', function() {
}); });
it('makes the annotation shared if the parent is shared', function() { it('makes the annotation shared if the parent is shared', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
var reply = {}; var reply = {};
fakeAnnotationMapper.createAnnotation.returns(reply); fakeAnnotationMapper.createAnnotation.returns(reply);
fakePermissions.isShared.returns(true); fakePermissions.isShared.returns(true);
...@@ -813,7 +842,7 @@ describe('annotation.js', function() { ...@@ -813,7 +842,7 @@ describe('annotation.js', function() {
}); });
it('makes the annotation shared if the parent is shared', function() { it('makes the annotation shared if the parent is shared', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
$scope.annotation.group = 'my group'; $scope.annotation.group = 'my group';
$scope.annotation.permissions = { $scope.annotation.permissions = {
read: ['my group'] read: ['my group']
...@@ -835,7 +864,7 @@ describe('annotation.js', function() { ...@@ -835,7 +864,7 @@ describe('annotation.js', function() {
it( it(
'does not add the world readable principal if the parent is private', 'does not add the world readable principal if the parent is private',
function() { function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
var reply = {}; var reply = {};
fakeAnnotationMapper.createAnnotation.returns(reply); fakeAnnotationMapper.createAnnotation.returns(reply);
fakePermissions.isShared.returns(false); fakePermissions.isShared.returns(false);
...@@ -847,7 +876,7 @@ describe('annotation.js', function() { ...@@ -847,7 +876,7 @@ describe('annotation.js', function() {
); );
it('sets the reply\'s group to be the same as its parent\'s', function() { it('sets the reply\'s group to be the same as its parent\'s', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
$scope.annotation.group = 'my group'; $scope.annotation.group = 'my group';
var reply = {}; var reply = {};
fakeAnnotationMapper.createAnnotation.returns(reply); fakeAnnotationMapper.createAnnotation.returns(reply);
...@@ -858,58 +887,58 @@ describe('annotation.js', function() { ...@@ -858,58 +887,58 @@ describe('annotation.js', function() {
describe('#setPrivacy', function() { describe('#setPrivacy', function() {
it('makes the annotation private when level is "private"', function() { it('makes the annotation private when level is "private"', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.$update = sinon.stub().returns(Promise.resolve()); parts.annotation.$update = sinon.stub().returns(Promise.resolve());
controller.edit(); parts.controller.edit();
controller.setPrivacy('private'); parts.controller.setPrivacy('private');
return controller.save().then(function() { return parts.controller.save().then(function() {
// Verify that the permissions are updated once the annotation // Verify that the permissions are updated once the annotation
// is saved. // is saved.
assert.deepEqual(annotation.permissions, { assert.deepEqual(parts.annotation.permissions, {
read: ['justme'] read: ['justme']
}); });
}); });
}); });
it('makes the annotation shared when level is "shared"', function() { it('makes the annotation shared when level is "shared"', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.$update = sinon.stub().returns(Promise.resolve()); parts.annotation.$update = sinon.stub().returns(Promise.resolve());
controller.edit(); parts.controller.edit();
controller.setPrivacy('shared'); parts.controller.setPrivacy('shared');
return controller.save().then(function() { return parts.controller.save().then(function() {
assert.deepEqual(annotation.permissions, { assert.deepEqual(parts.annotation.permissions, {
read: ['everybody'] read: ['everybody']
}); });
}); });
}); });
it('saves the "shared" visibility level to localStorage', function() { it('saves the "shared" visibility level to localStorage', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.$update = sinon.stub().returns(Promise.resolve()); parts.annotation.$update = sinon.stub().returns(Promise.resolve());
controller.edit(); parts.controller.edit();
controller.setPrivacy('shared'); parts.controller.setPrivacy('shared');
return controller.save().then(function() { return parts.controller.save().then(function() {
assert(fakePermissions.setDefault.calledWithExactly('shared')); assert(fakePermissions.setDefault.calledWithExactly('shared'));
}); });
}); });
it('saves the "private" visibility level to localStorage', function() { it('saves the "private" visibility level to localStorage', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.$update = sinon.stub().returns(Promise.resolve()); parts.annotation.$update = sinon.stub().returns(Promise.resolve());
controller.edit(); parts.controller.edit();
controller.setPrivacy('private'); parts.controller.setPrivacy('private');
return controller.save().then(function() { return parts.controller.save().then(function() {
assert(fakePermissions.setDefault.calledWithExactly('private')); assert(fakePermissions.setDefault.calledWithExactly('private'));
}); });
}); });
it('doesn\'t save the visibility if the annotation is a reply', function() { it('doesn\'t save the visibility if the annotation is a reply', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.$update = sinon.stub().returns(Promise.resolve()); parts.annotation.$update = sinon.stub().returns(Promise.resolve());
annotation.references = ['parent id']; parts.annotation.references = ['parent id'];
controller.edit(); parts.controller.edit();
controller.setPrivacy('private'); parts.controller.setPrivacy('private');
return controller.save().then(function() { return parts.controller.save().then(function() {
assert(!fakePermissions.setDefault.called); assert(!fakePermissions.setDefault.called);
}); });
}); });
...@@ -965,15 +994,15 @@ describe('annotation.js', function() { ...@@ -965,15 +994,15 @@ describe('annotation.js', function() {
}); });
it('is called exactly once on model changes', function() { it('is called exactly once on model changes', function() {
var controller = createDirective().controller; var parts = createDirective();
sandbox.spy(controller, 'render'); sandbox.spy(parts.controller, 'render');
assert.notCalled(controller.render); assert.notCalled(parts.controller.render);
annotation['delete'] = true; parts.annotation['delete'] = true;
$scope.$digest(); $scope.$digest();
assert.calledOnce(controller.render); assert.calledOnce(parts.controller.render);
annotation.booz = 'baz'; parts.annotation.booz = 'baz';
$scope.$digest(); $scope.$digest();
assert.calledTwice(controller.render); assert.calledTwice(parts.controller.render);
}); });
it('provides a document title', function() { it('provides a document title', function() {
...@@ -983,18 +1012,18 @@ describe('annotation.js', function() { ...@@ -983,18 +1012,18 @@ describe('annotation.js', function() {
}); });
it('uses the first title when there are more than one', function() { it('uses the first title when there are more than one', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.document.title = ['first title', 'second title']; parts.annotation.document.title = ['first title', 'second title'];
controller.render(); parts.controller.render();
assert.equal(controller.document.title, 'first title'); assert.equal(parts.controller.document.title, 'first title');
}); });
it('truncates long titles', function() { it('truncates long titles', function() {
var controller = createDirective().controller; var parts = createDirective();
annotation.document.title = 'A very very very long title that really\nshouldn\'t be found on a page on the internet.'; parts.annotation.document.title = 'A very very very long title that really\nshouldn\'t be found on a page on the internet.';
controller.render(); parts.controller.render();
assert.equal( assert.equal(
controller.document.title, 'A very very very long title th…'); parts.controller.document.title, 'A very very very long title th…');
}); });
it('provides a document uri', function() { it('provides a document uri', function() {
...@@ -1010,47 +1039,49 @@ describe('annotation.js', function() { ...@@ -1010,47 +1039,49 @@ describe('annotation.js', function() {
}); });
it('uses the domain for the title if the title is not present', function() { it('uses the domain for the title if the title is not present', function() {
var controller = createDirective().controller; var parts = createDirective();
delete annotation.document.title; delete parts.annotation.document.title;
controller.render(); parts.controller.render();
assert.equal(controller.document.title, 'example.com'); assert.equal(parts.controller.document.title, 'example.com');
}); });
it( it(
'still sets the uri correctly if the annotation has no document', 'still sets the uri correctly if the annotation has no document',
function() { function() {
var controller = createDirective().controller; var parts = createDirective();
delete annotation.document; delete parts.annotation.document;
controller.render(); parts.controller.render();
assert(controller.document.uri === $scope.annotation.uri); assert(parts.controller.document.uri === $scope.annotation.uri);
} }
); );
it( it(
'still sets the domain correctly if the annotation has no document', 'still sets the domain correctly if the annotation has no document',
function() { function() {
var controller = createDirective().controller; var parts = createDirective();
delete annotation.document; delete parts.annotation.document;
controller.render(); parts.controller.render();
assert(controller.document.domain === 'example.com'); assert(parts.controller.document.domain === 'example.com');
} }
); );
it( it(
'uses the domain for the title when the annotation has no document', 'uses the domain for the title when the annotation has no document',
function() { function() {
var controller = createDirective().controller; var parts = createDirective();
delete annotation.document; delete parts.annotation.document;
controller.render(); parts.controller.render();
assert(controller.document.title === 'example.com'); assert(parts.controller.document.title === 'example.com');
} }
); );
describe('timestamp', function() { describe('timestamp', function() {
var annotation;
var clock; var clock;
beforeEach(function() { beforeEach(function() {
clock = sinon.useFakeTimers(); clock = sinon.useFakeTimers();
annotation = defaultAnnotation();
annotation.created = (new Date()).toString(); annotation.created = (new Date()).toString();
annotation.updated = (new Date()).toString(); annotation.updated = (new Date()).toString();
}); });
...@@ -1061,7 +1092,7 @@ describe('annotation.js', function() { ...@@ -1061,7 +1092,7 @@ describe('annotation.js', function() {
it('is not updated for unsaved annotations', function() { it('is not updated for unsaved annotations', function() {
annotation.updated = null; annotation.updated = null;
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
// Unsaved annotations don't have an updated time yet so a timestamp // Unsaved annotations don't have an updated time yet so a timestamp
// string can't be computed for them. // string can't be computed for them.
$scope.$digest(); $scope.$digest();
...@@ -1069,13 +1100,13 @@ describe('annotation.js', function() { ...@@ -1069,13 +1100,13 @@ describe('annotation.js', function() {
}); });
it('is updated on first digest', function() { it('is updated on first digest', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
$scope.$digest(); $scope.$digest();
assert.equal(controller.timestamp, 'a while ago'); assert.equal(controller.timestamp, 'a while ago');
}); });
it('is updated after a timeout', function() { it('is updated after a timeout', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
fakeTime.nextFuzzyUpdate.returns(10); fakeTime.nextFuzzyUpdate.returns(10);
fakeTime.toFuzzyString.returns('ages ago'); fakeTime.toFuzzyString.returns('ages ago');
$scope.$digest(); $scope.$digest();
...@@ -1085,7 +1116,7 @@ describe('annotation.js', function() { ...@@ -1085,7 +1116,7 @@ describe('annotation.js', function() {
}); });
it('is no longer updated after the scope is destroyed', function() { it('is no longer updated after the scope is destroyed', function() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
$scope.$digest(); $scope.$digest();
$scope.$destroy(); $scope.$destroy();
$timeout.flush(); $timeout.flush();
...@@ -1095,13 +1126,10 @@ describe('annotation.js', function() { ...@@ -1095,13 +1126,10 @@ describe('annotation.js', function() {
describe('share', function() { describe('share', function() {
it('sets and unsets the open class on the share wrapper', function() { it('sets and unsets the open class on the share wrapper', function() {
var components = createDirective(); var parts = createDirective();
var controller = components.controller; var dialog = parts.element.find('.share-dialog-wrapper');
var element = components.element;
var scope = components.scope;
var dialog = element.find('.share-dialog-wrapper');
dialog.find('button').click(); dialog.find('button').click();
scope.$digest(); parts.scope.$digest();
assert.ok(dialog.hasClass('open')); assert.ok(dialog.hasClass('open'));
documentService().click(); documentService().click();
assert.notOk(dialog.hasClass('open')); assert.notOk(dialog.hasClass('open'));
...@@ -1118,11 +1146,13 @@ describe('annotation.js', function() { ...@@ -1118,11 +1146,13 @@ describe('annotation.js', function() {
it( it(
'calls annotationMapper.delete() if the delete is confirmed', 'calls annotationMapper.delete() if the delete is confirmed',
function(done) { function(done) {
var controller = createDirective().controller; var parts = createDirective();
sandbox.stub($window, 'confirm').returns(true); sandbox.stub($window, 'confirm').returns(true);
fakeAnnotationMapper.deleteAnnotation.returns($q.resolve()); fakeAnnotationMapper.deleteAnnotation.returns($q.resolve());
controller['delete']().then(function() { parts.controller['delete']().then(function() {
assert(fakeAnnotationMapper.deleteAnnotation.calledWith(annotation)); assert(
fakeAnnotationMapper.deleteAnnotation.calledWith(
parts.annotation));
done(); done();
}); });
$timeout.flush(); $timeout.flush();
...@@ -1184,13 +1214,16 @@ describe('annotation.js', function() { ...@@ -1184,13 +1214,16 @@ describe('annotation.js', function() {
}); });
describe('saving a new annotation', function() { describe('saving a new annotation', function() {
var annotation;
beforeEach(function() { beforeEach(function() {
fakeFlash.error = sandbox.stub(); fakeFlash.error = sandbox.stub();
annotation = defaultAnnotation();
annotation.$create = sandbox.stub(); annotation.$create = sandbox.stub();
}); });
function controllerWithActionCreate() { function controllerWithActionCreate() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
controller.action = 'create'; controller.action = 'create';
return controller; return controller;
} }
...@@ -1252,13 +1285,16 @@ describe('annotation.js', function() { ...@@ -1252,13 +1285,16 @@ describe('annotation.js', function() {
}); });
describe('saving an edited an annotation', function() { describe('saving an edited an annotation', function() {
var annotation;
beforeEach(function() { beforeEach(function() {
fakeFlash.error = sandbox.stub(); fakeFlash.error = sandbox.stub();
annotation = defaultAnnotation();
annotation.$update = sandbox.stub(); annotation.$update = sandbox.stub();
}); });
function controllerWithActionEdit() { function controllerWithActionEdit() {
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
controller.action = 'edit'; controller.action = 'edit';
return controller; return controller;
} }
...@@ -1308,9 +1344,9 @@ describe('annotation.js', function() { ...@@ -1308,9 +1344,9 @@ describe('annotation.js', function() {
describe('drafts', function() { describe('drafts', function() {
it('creates a draft when editing an annotation', function() { it('creates a draft when editing an annotation', function() {
var controller = createDirective().controller; var parts = createDirective();
controller.edit(); parts.controller.edit();
assert.calledWith(fakeDrafts.update, annotation); assert.calledWith(fakeDrafts.update, parts.annotation);
}); });
it( it(
...@@ -1320,14 +1356,15 @@ describe('annotation.js', function() { ...@@ -1320,14 +1356,15 @@ describe('annotation.js', function() {
// "changes" object that aren't actually set on the annotation. In this // "changes" object that aren't actually set on the annotation. In this
// case, both permissions and tags are null so shouldn't be saved in // case, both permissions and tags are null so shouldn't be saved in
// the draft. // the draft.
var controller = createDirective().controller; var parts = createDirective();
annotation.permissions = null; parts.annotation.permissions = null;
annotation.text = 'Hello!'; parts.annotation.text = 'Hello!';
annotation.tags = null; parts.annotation.tags = null;
controller.edit(); parts.controller.edit();
assert.calledWith(fakeDrafts.update, annotation, {text: 'Hello!'}); assert.calledWith(
fakeDrafts.update, parts.annotation, {text: 'Hello!'});
} }
); );
...@@ -1359,15 +1396,16 @@ describe('annotation.js', function() { ...@@ -1359,15 +1396,16 @@ describe('annotation.js', function() {
}); });
it('removes the draft when changes are discarded', function() { it('removes the draft when changes are discarded', function() {
var controller = createDirective().controller; var parts = createDirective();
controller.edit(); parts.controller.edit();
controller.revert(); parts.controller.revert();
assert.calledWith(fakeDrafts.remove, annotation); assert.calledWith(fakeDrafts.remove, parts.annotation);
}); });
it('removes the draft when changes are saved', function() { it('removes the draft when changes are saved', function() {
var annotation = defaultAnnotation();
annotation.$update = sandbox.stub().returns(Promise.resolve()); annotation.$update = sandbox.stub().returns(Promise.resolve());
var controller = createDirective().controller; var controller = createDirective(annotation).controller;
controller.edit(); controller.edit();
controller.save(); controller.save();
...@@ -1383,17 +1421,17 @@ describe('annotation.js', function() { ...@@ -1383,17 +1421,17 @@ describe('annotation.js', function() {
describe('when the focused group changes', function() { describe('when the focused group changes', function() {
it('updates the current draft', function() { it('updates the current draft', function() {
var controller = createDirective().controller; var parts = createDirective();
controller.edit(); parts.controller.edit();
controller.annotation.text = 'unsaved-text'; parts.controller.annotation.text = 'unsaved-text';
controller.annotation.tags = []; parts.controller.annotation.tags = [];
controller.annotation.permissions = 'new permissions'; parts.controller.annotation.permissions = 'new permissions';
fakeDrafts.get = sinon.stub().returns({ fakeDrafts.get = sinon.stub().returns({
text: 'old-draft' text: 'old-draft'
}); });
fakeDrafts.update = sinon.stub(); fakeDrafts.update = sinon.stub();
$rootScope.$broadcast(events.GROUP_FOCUSED); $rootScope.$broadcast(events.GROUP_FOCUSED);
assert.calledWith(fakeDrafts.update, annotation, { assert.calledWith(fakeDrafts.update, parts.annotation, {
text: 'unsaved-text', text: 'unsaved-text',
tags: [], tags: [],
permissions: 'new permissions' permissions: 'new permissions'
...@@ -1410,8 +1448,9 @@ describe('annotation.js', function() { ...@@ -1410,8 +1448,9 @@ describe('annotation.js', function() {
}); });
it('moves new annotations to the focused group', function() { it('moves new annotations to the focused group', function() {
var annotation = defaultAnnotation();
annotation.id = null; annotation.id = null;
createDirective(); createDirective(annotation);
fakeGroups.focused = sinon.stub().returns({ fakeGroups.focused = sinon.stub().returns({
id: 'new-group' id: 'new-group'
}); });
...@@ -1425,6 +1464,7 @@ describe('annotation.js', function() { ...@@ -1425,6 +1464,7 @@ describe('annotation.js', function() {
function() { function() {
// id must be null so that AnnotationController considers this a new // id must be null so that AnnotationController considers this a new
// annotation. // annotation.
var annotation = defaultAnnotation();
annotation.id = null; annotation.id = null;
annotation.group = 'old-group'; annotation.group = 'old-group';
annotation.permissions = { annotation.permissions = {
...@@ -1432,7 +1472,7 @@ describe('annotation.js', function() { ...@@ -1432,7 +1472,7 @@ describe('annotation.js', function() {
}; };
// This is a shared annotation. // This is a shared annotation.
fakePermissions.isShared.returns(true); fakePermissions.isShared.returns(true);
createDirective(); createDirective(annotation);
// Make permissions.shared() behave like we expect it to. // Make permissions.shared() behave like we expect it to.
fakePermissions.shared = function(groupId) { fakePermissions.shared = function(groupId) {
return { return {
...@@ -1450,6 +1490,7 @@ describe('annotation.js', function() { ...@@ -1450,6 +1490,7 @@ describe('annotation.js', function() {
it('saves shared permissions for the new group to drafts', function() { it('saves shared permissions for the new group to drafts', function() {
// id must be null so that AnnotationController considers this a new // id must be null so that AnnotationController considers this a new
// annotation. // annotation.
var annotation = defaultAnnotation();
annotation.id = null; annotation.id = null;
annotation.group = 'old-group'; annotation.group = 'old-group';
annotation.permissions = { annotation.permissions = {
...@@ -1457,7 +1498,7 @@ describe('annotation.js', function() { ...@@ -1457,7 +1498,7 @@ describe('annotation.js', function() {
}; };
// This is a shared annotation. // This is a shared annotation.
fakePermissions.isShared.returns(true); fakePermissions.isShared.returns(true);
createDirective(); createDirective(annotation);
// drafts.get() needs to return something truthy, otherwise // drafts.get() needs to return something truthy, otherwise
// AnnotationController won't try to update the draft for the annotation. // AnnotationController won't try to update the draft for the annotation.
fakeDrafts.get.returns(true); fakeDrafts.get.returns(true);
...@@ -1481,12 +1522,13 @@ describe('annotation.js', function() { ...@@ -1481,12 +1522,13 @@ describe('annotation.js', function() {
it('does not change perms when moving new private annotations', function() { it('does not change perms when moving new private annotations', function() {
// id must be null so that AnnotationController considers this a new // id must be null so that AnnotationController considers this a new
// annotation. // annotation.
var annotation = defaultAnnotation();
annotation.id = null; annotation.id = null;
annotation.group = 'old-group'; annotation.group = 'old-group';
annotation.permissions = { annotation.permissions = {
read: ['acct:bill@localhost'] read: ['acct:bill@localhost']
}; };
createDirective(); createDirective(annotation);
// This is a private annotation. // This is a private annotation.
fakePermissions.isShared.returns(false); fakePermissions.isShared.returns(false);
fakeGroups.focused = sinon.stub().returns({ fakeGroups.focused = sinon.stub().returns({
......
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