Unverified Commit d97b07ac authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #691 from hypothesis/rename-store-service

Rename src/sidebar/{store => services/api}
parents ae142778 db95bfeb
......@@ -12,7 +12,7 @@ function getExistingAnnotation(annotationUI, id) {
// Wraps the annotation store to trigger events for the CRUD actions
// @ngInject
function annotationMapper($rootScope, annotationUI, store) {
function annotationMapper($rootScope, annotationUI, api) {
function loadAnnotations(annotations, replies) {
annotations = annotations.concat(replies || []);
......@@ -46,7 +46,7 @@ function annotationMapper($rootScope, annotationUI, store) {
}
function deleteAnnotation(annotation) {
return store.annotation.delete({
return api.annotation.delete({
id: annotation.id,
}).then(function () {
$rootScope.$broadcast(events.ANNOTATION_DELETED, annotation);
......@@ -55,7 +55,7 @@ function annotationMapper($rootScope, annotationUI, store) {
}
function flagAnnotation(annot) {
return store.annotation.flag({
return api.annotation.flag({
id: annot.id,
}).then(function () {
$rootScope.$broadcast(events.ANNOTATION_FLAGGED, annot);
......
......@@ -5,18 +5,18 @@
*
* @return Promise<Array<Annotation>>
*/
function fetchThread(store, id) {
function fetchThread(api, id) {
var annot;
return store.annotation.get({id: id}).then(function (annot) {
return api.annotation.get({id: id}).then(function (annot) {
if (annot.references && annot.references.length) {
// This is a reply, fetch the top-level annotation
return store.annotation.get({id: annot.references[0]});
return api.annotation.get({id: annot.references[0]});
} else {
return annot;
}
}).then(function (annot_) {
annot = annot_;
return store.search({references: annot.id});
return api.search({references: annot.id});
}).then(function (searchResult) {
return [annot].concat(searchResult.rows);
});
......@@ -24,7 +24,7 @@ function fetchThread(store, id) {
// @ngInject
function AnnotationViewerContentController (
$location, $routeParams, annotationUI, rootThread, streamer, store,
$location, $routeParams, annotationUI, api, rootThread, streamer,
streamFilter, annotationMapper
) {
var self = this;
......@@ -45,7 +45,7 @@ function AnnotationViewerContentController (
annotationUI.setCollapsed(id, collapsed);
};
this.ready = fetchThread(store, id).then(function (annots) {
this.ready = fetchThread(api, id).then(function (annots) {
annotationMapper.loadAnnotations(annots);
var topLevelAnnot = annots.filter(function (annot) {
......
......@@ -26,8 +26,8 @@ function updateModel(annotation, changes, permissions) {
// @ngInject
function AnnotationController(
$document, $rootScope, $scope, $timeout, $window, analytics, annotationUI,
annotationMapper, drafts, flash, groups, permissions, serviceUrl,
session, settings, store, streamer) {
annotationMapper, api, drafts, flash, groups, permissions, serviceUrl,
session, settings, streamer) {
var self = this;
var newlyCreatedByHighlightButton;
......@@ -38,9 +38,9 @@ function AnnotationController(
var updating = !!annot.id;
if (updating) {
saved = store.annotation.update({id: annot.id}, annot);
saved = api.annotation.update({id: annot.id}, annot);
} else {
saved = store.annotation.create({}, annot);
saved = api.annotation.create({}, annot);
}
return saved.then(function (savedAnnot) {
......
......@@ -3,7 +3,7 @@
var annotationMetadata = require('../annotation-metadata');
// @ngInject
function ModerationBannerController(annotationUI, flash, store) {
function ModerationBannerController(annotationUI, flash, api) {
var self = this;
this.flagCount = function () {
......@@ -27,7 +27,7 @@ function ModerationBannerController(annotationUI, flash, store) {
* Hide an annotation from non-moderator users.
*/
this.hideAnnotation = function () {
store.annotation.hide({id: self.annotation.id}).then(function () {
api.annotation.hide({id: self.annotation.id}).then(function () {
annotationUI.hideAnnotation(self.annotation.id);
}).catch(function () {
flash.error('Failed to hide annotation');
......@@ -38,7 +38,7 @@ function ModerationBannerController(annotationUI, flash, store) {
* Un-hide an annotation from non-moderator users.
*/
this.unhideAnnotation = function () {
store.annotation.unhide({id: self.annotation.id}).then(function () {
api.annotation.unhide({id: self.annotation.id}).then(function () {
annotationUI.unhideAnnotation(self.annotation.id);
}).catch(function () {
flash.error('Failed to unhide annotation');
......
......@@ -34,8 +34,8 @@ function groupIDFromSelection(selection, results) {
// @ngInject
function SidebarContentController(
$scope, analytics, annotationUI, annotationMapper, drafts, features, frameSync,
groups, rootThread, settings, streamer, streamFilter, store
$scope, analytics, annotationUI, annotationMapper, api, drafts, features, frameSync,
groups, rootThread, settings, streamer, streamFilter
) {
var self = this;
......@@ -100,7 +100,7 @@ function SidebarContentController(
}
function _loadAnnotationsFor(uris, group) {
var searchClient = new SearchClient(store.search, {
var searchClient = new SearchClient(api.search, {
// If no group is specified, we are fetching annotations from
// all groups in order to find out which group contains the selected
// annotation, therefore we need to load all chunks before processing
......
......@@ -3,7 +3,7 @@
// @ngInject
function StreamContentController(
$scope, $location, $route, $routeParams, annotationMapper, annotationUI,
queryParser, rootThread, searchFilter, store, streamFilter, streamer
api, queryParser, rootThread, searchFilter, streamFilter, streamer
) {
var self = this;
......@@ -28,7 +28,7 @@ function StreamContentController(
limit: limit,
}, searchFilter.toObject($routeParams.q));
store.search(query)
api.search(query)
.then(load)
.catch(function (err) {
console.error(err);
......
......@@ -104,7 +104,7 @@ describe('annotation', function() {
var fakeServiceUrl;
var fakeSession;
var fakeSettings;
var fakeStore;
var fakeApi;
var fakeStreamer;
var sandbox;
......@@ -222,7 +222,7 @@ describe('annotation', function() {
authDomain: 'localhost',
};
fakeStore = {
fakeApi = {
annotation: {
create: sinon.spy(function (annot) {
return Promise.resolve(Object.assign({}, annot));
......@@ -240,6 +240,7 @@ describe('annotation', function() {
$provide.value('analytics', fakeAnalytics);
$provide.value('annotationMapper', fakeAnnotationMapper);
$provide.value('annotationUI', fakeAnnotationUI);
$provide.value('api', fakeApi);
$provide.value('drafts', fakeDrafts);
$provide.value('flash', fakeFlash);
$provide.value('groups', fakeGroups);
......@@ -247,7 +248,6 @@ describe('annotation', function() {
$provide.value('session', fakeSession);
$provide.value('serviceUrl', fakeServiceUrl);
$provide.value('settings', fakeSettings);
$provide.value('store', fakeStore);
$provide.value('streamer', fakeStreamer);
}));
......@@ -345,7 +345,7 @@ describe('annotation', function() {
annotation.user = fakeSession.state.userid = 'acct:bill@localhost';
createDirective(annotation);
assert.called(fakeStore.annotation.create);
assert.called(fakeApi.annotation.create);
});
it('saves new highlights to drafts if not logged in', function() {
......@@ -355,7 +355,7 @@ describe('annotation', function() {
createDirective(annotation);
assert.notCalled(fakeStore.annotation.create);
assert.notCalled(fakeApi.annotation.create);
assert.called(fakeDrafts.update);
});
......@@ -364,7 +364,7 @@ describe('annotation', function() {
createDirective(annotation);
assert.notCalled(fakeStore.annotation.create);
assert.notCalled(fakeApi.annotation.create);
});
it('does not save old highlights on initialization', function() {
......@@ -372,7 +372,7 @@ describe('annotation', function() {
createDirective(annotation);
assert.notCalled(fakeStore.annotation.create);
assert.notCalled(fakeApi.annotation.create);
});
it('does not save old annotations on initialization', function() {
......@@ -380,7 +380,7 @@ describe('annotation', function() {
createDirective(annotation);
assert.notCalled(fakeStore.annotation.create);
assert.notCalled(fakeApi.annotation.create);
});
it('creates drafts for new annotations on initialization', function() {
......@@ -945,7 +945,7 @@ describe('annotation', function() {
it('flashes an error if saving the annotation fails on the server', function() {
var controller = createController();
var err = new Error('500 Server Error');
fakeStore.annotation.create = sinon.stub().returns(Promise.reject(err));
fakeApi.annotation.create = sinon.stub().returns(Promise.reject(err));
return controller.save().then(function() {
assert.calledWith(fakeFlash.error,
'500 Server Error', 'Saving annotation failed');
......@@ -962,7 +962,7 @@ describe('annotation', function() {
it('shows a saving indicator when saving an annotation', function() {
var controller = createController();
var create;
fakeStore.annotation.create = sinon.stub().returns(new Promise(function (resolve) {
fakeApi.annotation.create = sinon.stub().returns(new Promise(function (resolve) {
create = resolve;
}));
var saved = controller.save();
......@@ -975,7 +975,7 @@ describe('annotation', function() {
it('does not remove the draft if saving fails', function () {
var controller = createController();
fakeStore.annotation.create = sinon.stub().returns(Promise.reject({status: -1}));
fakeApi.annotation.create = sinon.stub().returns(Promise.reject({status: -1}));
return controller.save().then(function () {
assert.notCalled(fakeDrafts.remove);
});
......@@ -1005,7 +1005,7 @@ describe('annotation', function() {
it('flashes an error if saving the annotation fails on the server', function () {
var controller = createController();
var err = new Error('500 Server Error');
fakeStore.annotation.update = sinon.stub().returns(Promise.reject(err));
fakeApi.annotation.update = sinon.stub().returns(Promise.reject(err));
return controller.save().then(function() {
assert.calledWith(fakeFlash.error,
'500 Server Error', 'Saving annotation failed');
......
......@@ -4,7 +4,7 @@ var angular = require('angular');
// Fake implementation of the API for fetching annotations and replies to
// annotations.
function FakeStore(annots) {
function FakeApi(annots) {
this.annots = annots;
this.annotation = {
......@@ -51,12 +51,12 @@ describe('annotationViewerContent', function () {
highlightAnnotations: sinon.stub(),
subscribe: sinon.stub(),
},
api: opts.api,
rootThread: {thread: sinon.stub()},
streamer: {
setConfig: function () {},
connect: function () {},
},
store: opts.store,
streamFilter: {
setMatchPolicyIncludeAny: function () {
return {
......@@ -86,24 +86,24 @@ describe('annotationViewerContent', function () {
describe('the standalone view for a top-level annotation', function () {
it('loads the annotation and all replies', function () {
var fakeStore = new FakeStore([
var fakeApi = new FakeApi([
{id: 'test_annotation_id'},
{id: 'test_reply_id', references: ['test_annotation_id']},
]);
var controller = createController({store: fakeStore});
var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () {
assert.calledOnce(controller.annotationMapper.loadAnnotations);
assert.calledWith(controller.annotationMapper.loadAnnotations,
sinon.match(fakeStore.annots));
sinon.match(fakeApi.annots));
});
});
it('does not highlight any annotations', function () {
var fakeStore = new FakeStore([
var fakeApi = new FakeApi([
{id: 'test_annotation_id'},
{id: 'test_reply_id', references: ['test_annotation_id']},
]);
var controller = createController({store: fakeStore});
var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () {
assert.notCalled(controller.annotationUI.highlightAnnotations);
});
......@@ -112,23 +112,23 @@ describe('annotationViewerContent', function () {
describe('the standalone view for a reply', function () {
it('loads the top-level annotation and all replies', function () {
var fakeStore = new FakeStore([
var fakeApi = new FakeApi([
{id: 'parent_id'},
{id: 'test_annotation_id', references: ['parent_id']},
]);
var controller = createController({store: fakeStore});
var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () {
assert.calledWith(controller.annotationMapper.loadAnnotations,
sinon.match(fakeStore.annots));
sinon.match(fakeApi.annots));
});
});
it('expands the thread', function () {
var fakeStore = new FakeStore([
var fakeApi = new FakeApi([
{id: 'parent_id'},
{id: 'test_annotation_id', references: ['parent_id']},
]);
var controller = createController({store: fakeStore});
var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () {
assert.calledWith(controller.annotationUI.setCollapsed, 'parent_id', false);
assert.calledWith(controller.annotationUI.setCollapsed, 'test_annotation_id', false);
......@@ -136,11 +136,11 @@ describe('annotationViewerContent', function () {
});
it('highlights the reply', function () {
var fakeStore = new FakeStore([
var fakeApi = new FakeApi([
{id: 'parent_id'},
{id: 'test_annotation_id', references: ['parent_id']},
]);
var controller = createController({store: fakeStore});
var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () {
assert.calledWith(controller.annotationUI.highlightAnnotations,
sinon.match(['test_annotation_id']));
......
......@@ -12,7 +12,7 @@ describe('moderationBanner', function () {
var bannerEl;
var fakeAnnotationUI;
var fakeFlash;
var fakeStore;
var fakeApi;
before(function () {
angular.module('app', [])
......@@ -29,7 +29,7 @@ describe('moderationBanner', function () {
error: sinon.stub(),
};
fakeStore = {
fakeApi = {
annotation: {
hide: sinon.stub().returns(Promise.resolve()),
unhide: sinon.stub().returns(Promise.resolve()),
......@@ -38,8 +38,8 @@ describe('moderationBanner', function () {
angular.mock.module('app', {
annotationUI: fakeAnnotationUI,
api: fakeApi,
flash: fakeFlash,
store: fakeStore,
});
});
......@@ -114,13 +114,13 @@ describe('moderationBanner', function () {
var ann = moderatedAnnotation({ flagCount: 10 });
var banner = createBanner({ annotation: ann });
banner.querySelector('button').click();
assert.calledWith(fakeStore.annotation.hide, {id: 'ann-id'});
assert.calledWith(fakeApi.annotation.hide, {id: 'ann-id'});
});
it('reports an error if hiding the annotation fails', function (done) {
var ann = moderatedAnnotation({ flagCount: 10 });
var banner = createBanner({ annotation: ann });
fakeStore.annotation.hide.returns(Promise.reject(new Error('Network Error')));
fakeApi.annotation.hide.returns(Promise.reject(new Error('Network Error')));
banner.querySelector('button').click();
......@@ -139,7 +139,7 @@ describe('moderationBanner', function () {
banner.querySelector('button').click();
assert.calledWith(fakeStore.annotation.unhide, {id: 'ann-id'});
assert.calledWith(fakeApi.annotation.unhide, {id: 'ann-id'});
});
it('reports an error if unhiding the annotation fails', function (done) {
......@@ -148,7 +148,7 @@ describe('moderationBanner', function () {
hidden: true,
});
var banner = createBanner({ annotation: ann });
fakeStore.annotation.unhide.returns(Promise.reject(new Error('Network Error')));
fakeApi.annotation.unhide.returns(Promise.reject(new Error('Network Error')));
banner.querySelector('button').click();
......
......@@ -49,7 +49,7 @@ describe('sidebar.components.sidebar-content', function () {
var fakeGroups;
var fakeRootThread;
var fakeSettings;
var fakeStore;
var fakeApi;
var fakeStreamer;
var fakeStreamFilter;
var sandbox;
......@@ -116,17 +116,17 @@ describe('sidebar.components.sidebar-content', function () {
fakeSettings = {};
fakeStore = {
fakeApi = {
search: sinon.stub(),
};
$provide.value('analytics', fakeAnalytics);
$provide.value('annotationMapper', fakeAnnotationMapper);
$provide.value('api', fakeApi);
$provide.value('drafts', fakeDrafts);
$provide.value('features', fakeFeatures);
$provide.value('frameSync', fakeFrameSync);
$provide.value('rootThread', fakeRootThread);
$provide.value('store', fakeStore);
$provide.value('streamer', fakeStreamer);
$provide.value('streamFilter', fakeStreamFilter);
$provide.value('groups', fakeGroups);
......
......@@ -19,7 +19,7 @@ describe('StreamContentController', function () {
var fakeQueryParser;
var fakeRootThread;
var fakeSearchFilter;
var fakeStore;
var fakeApi;
var fakeStreamer;
var fakeStreamFilter;
......@@ -59,7 +59,7 @@ describe('StreamContentController', function () {
toObject: sinon.stub().returns({}),
};
fakeStore = {
fakeApi = {
search: sinon.spy(function () {
return Promise.resolve({rows: [], total: 0});
}),
......@@ -85,10 +85,10 @@ describe('StreamContentController', function () {
$routeParams: fakeRouteParams,
annotationMapper: fakeAnnotationMapper,
annotationUI: fakeAnnotationUI,
api: fakeApi,
queryParser: fakeQueryParser,
rootThread: fakeRootThread,
searchFilter: fakeSearchFilter,
store: fakeStore,
streamFilter: fakeStreamFilter,
streamer: fakeStreamer,
});
......@@ -110,11 +110,11 @@ describe('StreamContentController', function () {
it('calls the search API with `_separate_replies: true`', function () {
createController();
assert.equal(fakeStore.search.firstCall.args[0]._separate_replies, true);
assert.equal(fakeApi.search.firstCall.args[0]._separate_replies, true);
});
it('passes the annotations and replies from search to loadAnnotations()', function () {
fakeStore.search = function () {
fakeApi.search = function () {
return Promise.resolve({
'rows': ['annotation_1', 'annotation_2'],
'replies': ['reply_1', 'reply_2', 'reply_3'],
......
......@@ -18,8 +18,8 @@ var { awaitStateChange } = require('./util/state-util');
var serviceConfig = require('./service-config');
// @ngInject
function groups(annotationUI, isSidebar, localStorage, serviceUrl, session,
settings, $rootScope, store) {
function groups($rootScope, annotationUI, api, isSidebar, localStorage, serviceUrl, session,
settings) {
// The currently focused group. This is the group that's shown as selected in
// the groups dropdown, the annotations displayed are filtered to only ones
// that belong to this group, and any new annotations that the user creates
......@@ -65,7 +65,7 @@ function groups(annotationUI, isSidebar, localStorage, serviceUrl, session,
if (uri) {
params.document_uri = uri;
}
return store.groups.list(params);
return api.groups.list(params);
}).then(gs => {
$rootScope.$apply(() => {
var focGroup = focused();
......@@ -104,7 +104,7 @@ function groups(annotationUI, isSidebar, localStorage, serviceUrl, session,
// The groups list will be updated in response to a session state
// change notification from the server. We could improve the UX here
// by optimistically updating the session state
return store.group.member.delete({
return api.group.member.delete({
pubid: id,
user: 'me',
});
......
......@@ -187,6 +187,7 @@ module.exports = angular.module('h', [
.service('analytics', require('./analytics'))
.service('annotationMapper', require('./annotation-mapper'))
.service('annotationUI', require('./annotation-ui'))
.service('api', require('./services/api'))
.service('apiRoutes', require('./api-routes'))
.service('auth', require('./oauth-auth'))
.service('bridge', require('../shared/bridge'))
......@@ -208,8 +209,6 @@ module.exports = angular.module('h', [
.service('unicode', require('./unicode'))
.service('viewFilter', require('./view-filter'))
.factory('store', require('./store'))
.value('Discovery', require('../shared/discovery'))
.value('ExcerptOverflowMonitor', require('./util/excerpt-overflow-monitor'))
.value('OAuthClient', require('./util/oauth-client'))
......
......@@ -2,7 +2,7 @@
var get = require('lodash.get');
var urlUtil = require('./util/url-util');
var urlUtil = require('../util/url-util');
/**
* Translate the response from a failed API call into an Error-like object.
......@@ -156,7 +156,7 @@ function createAPICall($http, $q, links, route, tokenGetter) {
* not use authentication.
*/
// @ngInject
function store($http, $q, apiRoutes, auth) {
function api($http, $q, apiRoutes, auth) {
var links = apiRoutes.routes();
function apiCall(route) {
return createAPICall($http, $q, links, route, auth.tokenGetter);
......@@ -192,4 +192,4 @@ function store($http, $q, apiRoutes, auth) {
};
}
module.exports = store;
module.exports = api;
......@@ -3,7 +3,7 @@
var angular = require('angular');
var proxyquire = require('proxyquire');
var util = require('../../shared/test/util');
var util = require('../../../shared/test/util');
// API route directory.
// This should mirror the structure (but not the exact URLs) of
......@@ -60,14 +60,14 @@ var routes = {
},
};
describe('sidebar.store', function () {
describe('sidebar.services.api', function () {
var $httpBackend = null;
var sandbox = null;
var store = null;
var api = null;
before(function () {
angular.module('h', [])
.service('store', proxyquire('../store', util.noCallThru({
.service('api', proxyquire('../api', util.noCallThru({
angular: angular,
'./retry-util': {
retryPromiseOperation: function (fn) {
......@@ -108,13 +108,13 @@ describe('sidebar.store', function () {
sandbox.restore();
});
beforeEach(angular.mock.inject(function (_$httpBackend_, _store_) {
beforeEach(angular.mock.inject(function (_$httpBackend_, _api_) {
$httpBackend = _$httpBackend_;
store = _store_;
api = _api_;
}));
it('saves a new annotation', function (done) {
store.annotation.create({}, {}).then(function (saved) {
api.annotation.create({}, {}).then(function (saved) {
assert.isNotNull(saved.id);
done();
});
......@@ -127,7 +127,7 @@ describe('sidebar.store', function () {
});
it('updates an annotation', function (done) {
store.annotation.update({id: 'an-id'}, {text: 'updated'}).then(function () {
api.annotation.update({id: 'an-id'}, {text: 'updated'}).then(function () {
done();
});
......@@ -139,7 +139,7 @@ describe('sidebar.store', function () {
});
it('deletes an annotation', function (done) {
store.annotation.delete({id: 'an-id'}, {}).then(function () {
api.annotation.delete({id: 'an-id'}, {}).then(function () {
done();
});
......@@ -151,7 +151,7 @@ describe('sidebar.store', function () {
});
it('flags an annotation', function (done) {
store.annotation.flag({id: 'an-id'}).then(function () {
api.annotation.flag({id: 'an-id'}).then(function () {
done();
});
......@@ -163,7 +163,7 @@ describe('sidebar.store', function () {
});
it('hides an annotation', function (done) {
store.annotation.hide({id: 'an-id'}).then(function () {
api.annotation.hide({id: 'an-id'}).then(function () {
done();
});
......@@ -175,7 +175,7 @@ describe('sidebar.store', function () {
});
it('unhides an annotation', function (done) {
store.annotation.unhide({id: 'an-id'}).then(function () {
api.annotation.unhide({id: 'an-id'}).then(function () {
done();
});
......@@ -188,7 +188,7 @@ describe('sidebar.store', function () {
describe('#group.member.delete', () => {
it('removes current user from a group', (done) => {
store.group.member.delete({pubid: 'an-id', user: 'me'}).then(function () {
api.group.member.delete({pubid: 'an-id', user: 'me'}).then(function () {
done();
});
......@@ -206,7 +206,7 @@ describe('sidebar.store', function () {
$notme: 'nooooo!',
allowed: 123,
};
store.annotation.create({}, annotation).then(function () {
api.annotation.create({}, annotation).then(function () {
done();
});
......@@ -220,7 +220,7 @@ describe('sidebar.store', function () {
// Our backend service interprets semicolons as query param delimiters, so we
// must ensure to encode them in the query string.
it('encodes semicolons in query parameters', function (done) {
store.search({'uri': 'http://example.com/?foo=bar;baz=qux'}).then(function () {
api.search({'uri': 'http://example.com/?foo=bar;baz=qux'}).then(function () {
done();
});
......@@ -231,7 +231,7 @@ describe('sidebar.store', function () {
it("fetches the user's profile", function (done) {
var profile = {userid: 'acct:user@publisher.org'};
store.profile.read({authority: 'publisher.org'}).then(function (profile_) {
api.profile.read({authority: 'publisher.org'}).then(function (profile_) {
assert.deepEqual(profile_, profile);
done();
});
......@@ -241,7 +241,7 @@ describe('sidebar.store', function () {
});
it("updates a user's profile", function (done) {
store.profile.update({}, {preferences: {}}).then(function () {
api.profile.update({}, {preferences: {}}).then(function () {
done();
});
......@@ -254,7 +254,7 @@ describe('sidebar.store', function () {
context('when an API calls fail', function () {
util.unroll('rejects the call with an Error', function (done, testCase) {
store.profile.update({}, {preferences: {}}).catch(function (err) {
api.profile.update({}, {preferences: {}}).catch(function (err) {
assert(err instanceof Error);
assert.equal(err.message, testCase.expectedMessage);
done();
......@@ -286,7 +286,7 @@ describe('sidebar.store', function () {
}]);
it("exposes details in the Error's `response` property", function (done) {
store.profile.update({}, {preferences: {}}).catch(function (err) {
api.profile.update({}, {preferences: {}}).catch(function (err) {
assert.match(err.response, sinon.match({
status: 404,
statusText: 'Not found',
......
......@@ -20,8 +20,8 @@ var CACHE_TTL = 5 * 60 * 1000; // 5 minutes
*
* @ngInject
*/
function session($q, $rootScope, analytics, annotationUI, auth,
flash, raven, settings, serviceConfig, store) {
function session($q, $rootScope, analytics, annotationUI, api, auth,
flash, raven, settings, serviceConfig) {
// Cache the result of load()
var lastLoad;
var lastLoadTime;
......@@ -62,7 +62,7 @@ function session($q, $rootScope, analytics, annotationUI, auth,
if (authority) {
opts.authority = authority;
}
return store.profile.read(opts);
return api.profile.read(opts);
}, profileFetchRetryOpts).then(function (session) {
update(session);
lastLoadTime = Date.now();
......@@ -80,7 +80,7 @@ function session($q, $rootScope, analytics, annotationUI, auth,
* tutorial and then update the local profile data.
*/
function dismissSidebarTutorial() {
return store.profile.update({}, {preferences: {show_sidebar_tutorial: false}}).then(update);
return api.profile.update({}, {preferences: {show_sidebar_tutorial: false}}).then(update);
}
/**
......
......@@ -9,11 +9,11 @@ describe('annotationMapper', function() {
var sandbox = sinon.sandbox.create();
var $rootScope;
var annotationUI;
var fakeStore;
var fakeApi;
var annotationMapper;
beforeEach(function () {
fakeStore = {
fakeApi = {
annotation: {
delete: sinon.stub().returns(Promise.resolve({})),
flag: sinon.stub().returns(Promise.resolve({})),
......@@ -22,8 +22,8 @@ describe('annotationMapper', function() {
angular.module('app', [])
.service('annotationMapper', require('../annotation-mapper'))
.service('annotationUI', require('../annotation-ui'))
.value('settings', {})
.value('store', fakeStore);
.value('api', fakeApi)
.value('settings', {});
angular.mock.module('app');
angular.mock.inject(function (_$rootScope_, _annotationUI_, _annotationMapper_) {
......@@ -129,8 +129,8 @@ describe('annotationMapper', function() {
it('flags an annotation', function () {
var ann = {id: 'test-id'};
annotationMapper.flagAnnotation(ann);
assert.calledOnce(fakeStore.annotation.flag);
assert.calledWith(fakeStore.annotation.flag, {id: ann.id});
assert.calledOnce(fakeApi.annotation.flag);
assert.calledWith(fakeApi.annotation.flag, {id: ann.id});
});
it('emits the "annotationFlagged" event', function (done) {
......@@ -163,7 +163,7 @@ describe('annotationMapper', function() {
it('deletes the annotation on the server', function () {
var ann = {id: 'test-id'};
annotationMapper.deleteAnnotation(ann);
assert.calledWith(fakeStore.annotation.delete, {id: 'test-id'});
assert.calledWith(fakeApi.annotation.delete, {id: 'test-id'});
});
it('triggers the "annotationDeleted" event on success', function (done) {
......@@ -178,7 +178,7 @@ describe('annotationMapper', function() {
it('does not emit an event on error', function (done) {
sandbox.stub($rootScope, '$broadcast');
fakeStore.annotation.delete.returns(Promise.reject());
fakeApi.annotation.delete.returns(Promise.reject());
var ann = {id: 'test-id'};
annotationMapper.deleteAnnotation(ann).catch(function () {
assert.notCalled($rootScope.$broadcast);
......
......@@ -17,7 +17,7 @@ describe('groups', function() {
var fakeIsSidebar;
var fakeSession;
var fakeSettings;
var fakeStore;
var fakeApi;
var fakeLocalStorage;
var fakeRootScope;
var fakeServiceUrl;
......@@ -54,7 +54,7 @@ describe('groups', function() {
$broadcast: sandbox.stub(),
};
fakeStore = {
fakeApi = {
group: {
member: {
delete: sandbox.stub().returns(Promise.resolve()),
......@@ -77,8 +77,8 @@ describe('groups', function() {
});
function service() {
return groups(fakeAnnotationUI, fakeIsSidebar, fakeLocalStorage, fakeServiceUrl, fakeSession,
fakeSettings, fakeRootScope, fakeStore);
return groups(fakeRootScope, fakeAnnotationUI, fakeApi, fakeIsSidebar, fakeLocalStorage, fakeServiceUrl,
fakeSession, fakeSettings);
}
describe('#all()', function() {
......@@ -120,7 +120,7 @@ describe('groups', function() {
return svc.load().then(() => {
svc.focus('id2');
}).then(() => {
fakeStore.groups.list = sandbox.stub().returns(Promise.resolve([
fakeApi.groups.list = sandbox.stub().returns(Promise.resolve([
{name: 'Group 3', id: 'id3'},
{name: 'Group 1', id: 'id1'},
]));
......@@ -139,7 +139,7 @@ describe('groups', function() {
fakeAnnotationUI.setState({ searchUris: ['https://asite.com'] });
return loaded.then(() => {
assert.calledWith(fakeStore.groups.list, { document_uri: 'https://asite.com' });
assert.calledWith(fakeApi.groups.list, { document_uri: 'https://asite.com' });
});
});
});
......@@ -153,7 +153,7 @@ describe('groups', function() {
fakeAnnotationUI.setState({ searchUris: [] });
var svc = service();
return svc.load().then(() => {
assert.calledWith(fakeStore.groups.list, {});
assert.calledWith(fakeApi.groups.list, {});
});
});
});
......@@ -162,7 +162,7 @@ describe('groups', function() {
fakeSettings.services = [{ authority: 'publisher.org' }];
var svc = service();
return svc.load().then(() => {
assert.calledWith(fakeStore.groups.list, sinon.match({ authority: 'publisher.org' }));
assert.calledWith(fakeApi.groups.list, sinon.match({ authority: 'publisher.org' }));
});
});
});
......@@ -270,7 +270,7 @@ describe('groups', function() {
it('should call the group leave API', function () {
var s = service();
return s.leave('id2').then(() => {
assert.calledWithMatch(fakeStore.group.member.delete, {
assert.calledWithMatch(fakeApi.group.member.delete, {
pubid: 'id2',
user: 'me',
});
......@@ -289,7 +289,7 @@ describe('groups', function() {
service();
return fakeRootScope.eventCallbacks[testCase.event]().then(() => {
assert.calledOnce(fakeStore.groups.list);
assert.calledOnce(fakeApi.groups.list);
});
}, changeEvents);
});
......
......@@ -15,7 +15,7 @@ describe('sidebar.session', function () {
var fakeRaven;
var fakeServiceConfig;
var fakeSettings;
var fakeStore;
var fakeApi;
var sandbox;
var session;
......@@ -47,7 +47,7 @@ describe('sidebar.session', function () {
fakeRaven = {
setUserInfo: sandbox.spy(),
};
fakeStore = {
fakeApi = {
profile: {
read: sandbox.stub(),
update: sandbox.stub().returns(Promise.resolve({})),
......@@ -61,12 +61,12 @@ describe('sidebar.session', function () {
mock.module('h', {
analytics: fakeAnalytics,
annotationUI: fakeAnnotationUI,
api: fakeApi,
auth: fakeAuth,
flash: fakeFlash,
raven: fakeRaven,
settings: fakeSettings,
serviceConfig: fakeServiceConfig,
store: fakeStore,
});
});
......@@ -87,14 +87,14 @@ describe('sidebar.session', function () {
authority: 'publisher.org',
grantToken: 'a.jwt.token',
});
fakeStore.profile.read.returns(Promise.resolve({
fakeApi.profile.read.returns(Promise.resolve({
userid: 'acct:user@publisher.org',
}));
});
it('should pass the "authority" param when fetching the profile', function () {
return session.load().then(function () {
assert.calledWith(fakeStore.profile.read, {authority: 'publisher.org'});
assert.calledWith(fakeApi.profile.read, {authority: 'publisher.org'});
});
});
......@@ -109,7 +109,7 @@ describe('sidebar.session', function () {
var clock;
beforeEach(() => {
fakeStore.profile.read.returns(Promise.resolve({
fakeApi.profile.read.returns(Promise.resolve({
userid: 'acct:user@hypothes.is',
}));
});
......@@ -122,15 +122,15 @@ describe('sidebar.session', function () {
it('should fetch profile data from the API', () => {
return session.load().then(() => {
assert.calledWith(fakeStore.profile.read);
assert.calledWith(fakeApi.profile.read);
});
});
it('should retry the profile fetch if it fails', () => {
fakeStore.profile.read.onCall(0).returns(
fakeApi.profile.read.onCall(0).returns(
Promise.reject(new Error('Server error'))
);
fakeStore.profile.read.onCall(1).returns(
fakeApi.profile.read.onCall(1).returns(
Promise.resolve({userid: 'acct:user@hypothes.is', groups: []})
);
......@@ -152,7 +152,7 @@ describe('sidebar.session', function () {
return session.load().then(() => {
return session.load();
}).then(() => {
assert.calledOnce(fakeStore.profile.read);
assert.calledOnce(fakeApi.profile.read);
});
});
......@@ -164,7 +164,7 @@ describe('sidebar.session', function () {
clock.tick(CACHE_TTL * 2);
return session.load();
}).then(() => {
assert.calledTwice(fakeStore.profile.read);
assert.calledTwice(fakeApi.profile.read);
});
});
});
......@@ -192,14 +192,14 @@ describe('sidebar.session', function () {
describe('#dismissSidebarTutorial()', function () {
beforeEach(function () {
fakeStore.profile.update.returns(Promise.resolve({
fakeApi.profile.update.returns(Promise.resolve({
preferences: {},
}));
});
it('disables the tutorial for the user', function () {
session.dismissSidebarTutorial();
assert.calledWith(fakeStore.profile.update, {}, {preferences: {show_sidebar_tutorial: false}});
assert.calledWith(fakeApi.profile.update, {}, {preferences: {show_sidebar_tutorial: false}});
});
it('should update the session with the response from the API', function () {
......@@ -212,14 +212,14 @@ describe('sidebar.session', function () {
describe('#reload', () => {
beforeEach(() => {
// Load the initial profile data, as the client will do on startup.
fakeStore.profile.read.returns(Promise.resolve({
fakeApi.profile.read.returns(Promise.resolve({
userid: 'acct:user_a@hypothes.is',
}));
return session.load();
});
it('should clear cached data and reload', () => {
fakeStore.profile.read.returns(Promise.resolve({
fakeApi.profile.read.returns(Promise.resolve({
userid: 'acct:user_b@hypothes.is',
}));
......@@ -239,7 +239,7 @@ describe('sidebar.session', function () {
});
// Fake profile response after logout.
fakeStore.profile.read = () => Promise.resolve({
fakeApi.profile.read = () => Promise.resolve({
userid: null,
loggedIn,
});
......@@ -266,14 +266,14 @@ describe('sidebar.session', function () {
context('when another client changes the current login', () => {
it('reloads the profile', () => {
fakeStore.profile.read.returns(Promise.resolve({
fakeApi.profile.read.returns(Promise.resolve({
userid: 'acct:initial_user@hypothes.is',
}));
return session.load().then(() => {
// Simulate login change happening in a different tab.
fakeStore.profile.read.returns(Promise.resolve({
fakeApi.profile.read.returns(Promise.resolve({
userid: 'acct:different_user@hypothes.is',
}));
$rootScope.$broadcast(events.OAUTH_TOKENS_CHANGED);
......
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