Commit e1620fc8 authored by Robert Knight's avatar Robert Knight

Refactor duplicated AnnotationController tests

There were two describe('AnnotationController') blocks
containing very similar code.

Remove the tests from the second block which duplicated
those in the first and merge the others.

 * Also remove unused 'momentFilter' dep
parent 7609264a
...@@ -430,9 +430,7 @@ describe('annotation', function() { ...@@ -430,9 +430,7 @@ describe('annotation', function() {
var fakeFeatures; var fakeFeatures;
var fakeFlash; var fakeFlash;
var fakeGroups; var fakeGroups;
var fakeMomentFilter;
var fakePermissions; var fakePermissions;
var fakePersonaFilter;
var fakeSession; var fakeSession;
var fakeSettings; var fakeSettings;
var fakeTags; var fakeTags;
...@@ -588,8 +586,6 @@ describe('annotation', function() { ...@@ -588,8 +586,6 @@ describe('annotation', function() {
fakeFlash = sandbox.stub(); fakeFlash = sandbox.stub();
fakeMomentFilter = sandbox.stub().returns('ages ago');
fakePermissions = { fakePermissions = {
isShared: sandbox.stub().returns(true), isShared: sandbox.stub().returns(true),
isPrivate: sandbox.stub().returns(false), isPrivate: sandbox.stub().returns(false),
...@@ -638,7 +634,6 @@ describe('annotation', function() { ...@@ -638,7 +634,6 @@ describe('annotation', function() {
$provide.value('drafts', fakeDrafts); $provide.value('drafts', fakeDrafts);
$provide.value('features', fakeFeatures); $provide.value('features', fakeFeatures);
$provide.value('flash', fakeFlash); $provide.value('flash', fakeFlash);
$provide.value('momentFilter', fakeMomentFilter);
$provide.value('permissions', fakePermissions); $provide.value('permissions', fakePermissions);
$provide.value('session', fakeSession); $provide.value('session', fakeSession);
$provide.value('settings', fakeSettings); $provide.value('settings', fakeSettings);
...@@ -664,7 +659,7 @@ describe('annotation', function() { ...@@ -664,7 +659,7 @@ describe('annotation', function() {
sandbox.restore(); sandbox.restore();
}); });
describe('AnnotationController() initialization', function() { describe('initialization', function() {
it('sets the user of annotations that don\'t have one', function() { it('sets the user of annotations that don\'t have one', function() {
// You can create annotations while logged out and then login. // You can create annotations while logged out and then login.
// When you login a new AnnotationController instance is created for // When you login a new AnnotationController instance is created for
...@@ -679,23 +674,45 @@ describe('annotation', function() { ...@@ -679,23 +674,45 @@ describe('annotation', function() {
assert.equal(annotation.user, 'acct:bill@localhost'); assert.equal(annotation.user, 'acct:bill@localhost');
}); });
it( it('sets the permissions of new annotations', function() {
'sets the permissions of annotations that don\'t have any',
function() {
// You can create annotations while logged out and then login. // You can create annotations while logged out and then login.
// When you login a new AnnotationController instance is created for // When you login a new AnnotationController instance is created for
// each of your annotations, and on initialization it will set the // each of your annotations, and on initialization it will set the
// annotation's permissions using your username from the session. // annotation's permissions using your username from the session.
var annotation = newAnnotation(); var annotation = newAnnotation();
annotation.user = annotation.permissions = undefined; annotation.user = annotation.permissions = undefined;
annotation.group = '__world__';
fakeSession.state.userid = 'acct:bill@localhost'; fakeSession.state.userid = 'acct:bill@localhost';
fakePermissions.default.returns('default permissions'); fakePermissions.default = function (group) {
return 'default permissions for ' + group;
};
createDirective(annotation); createDirective(annotation);
assert.equal(annotation.permissions, 'default permissions'); assert.equal(annotation.permissions,
'default permissions for __world__');
});
it('preserves the permissions of existing annotations', function() {
var annotation = newAnnotation();
annotation.permissions = {
permissions: {
read: ['foo'],
update: ['bar'],
'delete': ['gar'],
admin: ['har']
} }
); };
var originalPermissions = JSON.parse(JSON.stringify(
annotation.permissions));
fakePermissions['default'] = function () {
return 'new permissions';
};
fakePermissions.isShared = function () {};
fakePermissions.isPrivate = function () {};
createDirective(annotation);
assert.deepEqual(annotation.permissions, originalPermissions);
});
it('saves new highlights to the server on initialization', function() { it('saves new highlights to the server on initialization', function() {
var annotation = newHighlight(); var annotation = newHighlight();
...@@ -802,7 +819,7 @@ describe('annotation', function() { ...@@ -802,7 +819,7 @@ describe('annotation', function() {
}); });
}); });
describe('AnnotationController.editing()', function() { describe('.editing()', function() {
it('returns true if action is "create"', function() { it('returns true if action is "create"', function() {
var controller = createDirective().controller; var controller = createDirective().controller;
controller.action = 'create'; controller.action = 'create';
...@@ -822,7 +839,7 @@ describe('annotation', function() { ...@@ -822,7 +839,7 @@ describe('annotation', function() {
}); });
}); });
describe('AnnotationController.isHighlight()', function() { describe('.isHighlight()', function() {
it('returns true for new highlights', function() { it('returns true for new highlights', function() {
var annotation = newHighlight(); var annotation = newHighlight();
// We need to define $create because it'll try to call it. // We need to define $create because it'll try to call it.
...@@ -1404,6 +1421,26 @@ describe('annotation', function() { ...@@ -1404,6 +1421,26 @@ describe('annotation', function() {
assert.ok(controller.editing()); assert.ok(controller.editing());
}); });
}); });
it(
'Passes group:<id> to the server when saving a new annotation',
function() {
fakeGroups.focused = function () {
return { id: 'test-id' }
};
var annotation = {
user: 'acct:fred@hypothes.is',
text: 'foo',
};
annotation.$create = sinon.stub().returns(Promise.resolve());
var controller = createDirective(annotation).controller;
controller.action = 'create';
return controller.save().then(function() {
assert.equal(annotation.$create.lastCall.thisValue.group,
'test-id');
});
}
);
}); });
describe('saving an edited an annotation', function() { describe('saving an edited an annotation', function() {
...@@ -1593,243 +1630,15 @@ describe('annotation', function() { ...@@ -1593,243 +1630,15 @@ describe('annotation', function() {
} }
); );
}); });
});
describe('AnnotationController', function() {
before(function() {
angular.module('h', [])
.directive('annotation', annotationDirective());
});
beforeEach(module('h'));
beforeEach(module('h.templates'));
/** Return Angular's $rootScope. */
function getRootScope() {
var $rootScope;
inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
});
return $rootScope;
}
/**
Return an annotation directive instance and stub services etc.
*/
function createAnnotationDirective(args) {
var session = args.session || {
state: {
userid: 'acct:fred@hypothes.is'
}
};
var locals = {
personaFilter: args.personaFilter || function() {},
momentFilter: args.momentFilter || {},
urlencodeFilter: args.urlencodeFilter || {},
drafts: args.drafts || {
update: function() {},
remove: function() {},
get: function() {}
},
features: args.features || {
flagEnabled: function() {
return true;
}
},
flash: args.flash || {
info: function() {},
error: function() {}
},
permissions: args.permissions || {
isShared: function(permissions, group) {
if (permissions.read) {
return permissions.read.indexOf(group) !== -1;
} else {
return false;
}
},
isPrivate: function(permissions, user) {
if (permissions.read) {
return permissions.read.indexOf(user) !== -1;
} else {
return false;
}
},
permits: function() {
return true;
},
shared: function() {
return {};
},
'private': function() {
return {};
},
'default': function() {
return {};
},
setDefault: function() {}
},
session: session,
settings: {
serviceUrl: 'https://test.hypothes.is/'
},
tags: args.tags || {
store: function() {}
},
time: args.time || {
toFuzzyString: function() {},
decayingInterval: function() {}
},
annotationUI: args.annotationUI || {},
annotationMapper: args.annotationMapper || {},
groups: args.groups || {
get: function() {},
focused: function() {
return {};
}
},
documentTitleFilter: args.documentTitleFilter || function() {
return '';
},
documentDomainFilter: args.documentDomainFilter || function() {
return '';
},
localStorage: args.localStorage || {
setItem: function() {},
getItem: function() {}
}
};
module(function($provide) {
$provide.value('personaFilter', locals.personaFilter);
$provide.value('momentFilter', locals.momentFilter);
$provide.value('urlencodeFilter', locals.urlencodeFilter);
$provide.value('drafts', locals.drafts);
$provide.value('features', locals.features);
$provide.value('flash', locals.flash);
$provide.value('permissions', locals.permissions);
$provide.value('session', locals.session);
$provide.value('settings', locals.settings);
$provide.value('tags', locals.tags);
$provide.value('time', locals.time);
$provide.value('annotationUI', locals.annotationUI);
$provide.value('annotationMapper', locals.annotationMapper);
$provide.value('groups', locals.groups);
$provide.value('documentTitleFilter', locals.documentTitleFilter);
$provide.value('documentDomainFilter', locals.documentDomainFilter);
$provide.value('localStorage', locals.localStorage);
});
locals.element = angular.element('<annotation annotation="annotation">');
var compiledElement = compileService()(locals.element);
locals.$rootScope = getRootScope();
locals.parentScope = locals.$rootScope.$new();
locals.parentScope.annotation = args.annotation || {};
locals.directive = compiledElement(locals.parentScope);
locals.$rootScope.$digest();
locals.controller = locals.element.controller('annotation');
locals.isolateScope = locals.element.isolateScope();
return locals;
}
describe('createAnnotationDirective', function() {
it('creates the directive without crashing', function() {
createAnnotationDirective({});
});
});
it('sets the user of new annotations', function() {
var annotation = {};
var session = createAnnotationDirective({
annotation: annotation
}).session;
assert.equal(annotation.user, session.state.userid);
});
it('sets the permissions of new annotations', function() { describe('reverting edits', function () {
// This is a new annotation, doesn't have any permissions yet. // Simulate what happens when the user edits an annotation,
var annotation = { // clicks Save, gets an error because the server fails to save the
group: 'test-group' // annotation, then clicks Cancel - in the frontend the annotation should
}; // be restored to its original value, the edits lost.
var permissions = { it('restores the original text', function() {
'default': sinon.stub().returns('default permissions'), var controller = createDirective({
isShared: function() {},
isPrivate: function() {}
};
createAnnotationDirective({
annotation: annotation,
permissions: permissions
});
assert(permissions['default'].calledWithExactly('test-group'));
assert.equal(
annotation.permissions, 'default permissions',
'It should set a new annotation\'s permissions to what ' +
'permissions.default() returns');
});
it(
'doesn\'t overwrite permissions if the annotation already has them',
function() {
var annotation = {
permissions: {
read: ['foo'],
update: ['bar'],
'delete': ['gar'],
admin: ['har']
}
};
var originalPermissions = JSON.parse(JSON.stringify(
annotation.permissions));
var permissions = {
'default': sinon.stub().returns('new permissions'),
isShared: function() {},
isPrivate: function() {}
};
createAnnotationDirective({
annotation: annotation,
permissions: permissions
});
assert.deepEqual(annotation.permissions, originalPermissions);
}
);
describe('save', function() {
it(
'Passes group:<id> to the server when saving a new annotation',
function() {
var annotation = {
user: 'acct:fred@hypothes.is',
text: 'foo'
};
annotation.$create = sinon.stub().returns(Promise.resolve());
var group = {
id: 'test-id'
};
var controller = createAnnotationDirective({
annotation: annotation,
groups: {
focused: function() {
return group;
},
get: function() {}
}
}).controller;
controller.action = 'create';
return controller.save().then(function() {
assert(annotation.$create.lastCall.thisValue.group === 'test-id');
});
}
);
});
/*
Simulate what happens when the user edits an annotation, clicks Save,
gets an error because the server fails to save the annotation, then clicks
Cancel - in the frontend the annotation should be restored to its original
value, the edits lost.
*/
it('restores the original text when editing is cancelled', function() {
var controller = createAnnotationDirective({
annotation: {
id: 'test-annotation-id', id: 'test-annotation-id',
user: 'acct:bill@localhost', user: 'acct:bill@localhost',
text: 'Initial annotation body text', text: 'Initial annotation body text',
...@@ -1845,7 +1654,6 @@ describe('annotation', function() { ...@@ -1845,7 +1654,6 @@ describe('annotation', function() {
data: {} data: {}
}); });
} }
}
}).controller; }).controller;
var originalText = controller.form.text; var originalText = controller.form.text;
// Simulate the user clicking the Edit button on the annotation. // Simulate the user clicking the Edit button on the annotation.
...@@ -1863,14 +1671,12 @@ describe('annotation', function() { ...@@ -1863,14 +1671,12 @@ describe('annotation', function() {
assert(controller.form.text === originalText); assert(controller.form.text === originalText);
}); });
// test that editing reverting changes to an annotation with // Test that editing reverting changes to an annotation with
// no text resets the text to be empty. // no text resets the text to be empty.
it('clears the text when reverting changes to a highlight', function() { it('clears the text if the text was originally empty', function() {
var controller = createAnnotationDirective({ var controller = createDirective({
annotation: {
id: 'test-annotation-id', id: 'test-annotation-id',
user: 'acct:bill@localhost', user: 'acct:bill@localhost',
}
}).controller; }).controller;
controller.edit(); controller.edit();
assert.equal(controller.action, 'edit'); assert.equal(controller.action, 'edit');
...@@ -1879,11 +1685,10 @@ describe('annotation', function() { ...@@ -1879,11 +1685,10 @@ describe('annotation', function() {
assert.equal(controller.form.text, void 0); assert.equal(controller.form.text, void 0);
}); });
it('reverts to the most recently saved version when canceling changes', it('reverts to the most recently saved version',
function () { function () {
var controller = createAnnotationDirective({ var controller = createDirective({
annotation: {
user: 'acct:bill@localhost', user: 'acct:bill@localhost',
$create: function () { $create: function () {
this.id = 'new-annotation-id'; this.id = 'new-annotation-id';
...@@ -1892,7 +1697,6 @@ describe('annotation', function() { ...@@ -1892,7 +1697,6 @@ describe('annotation', function() {
$update: function () { $update: function () {
return Promise.resolve(this); return Promise.resolve(this);
}, },
},
}).controller; }).controller;
controller.edit(); controller.edit();
controller.form.text = 'New annotation text'; controller.form.text = 'New annotation text';
...@@ -1907,4 +1711,5 @@ describe('annotation', function() { ...@@ -1907,4 +1711,5 @@ describe('annotation', function() {
}); });
}); });
}); });
});
}); });
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