Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
d97b07ac
Unverified
Commit
d97b07ac
authored
Mar 20, 2018
by
Robert Knight
Committed by
GitHub
Mar 20, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #691 from hypothesis/rename-store-service
Rename src/sidebar/{store => services/api}
parents
ae142778
db95bfeb
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
129 additions
and
130 deletions
+129
-130
annotation-mapper.js
src/sidebar/annotation-mapper.js
+3
-3
annotation-viewer-content.js
src/sidebar/components/annotation-viewer-content.js
+6
-6
annotation.js
src/sidebar/components/annotation.js
+4
-4
moderation-banner.js
src/sidebar/components/moderation-banner.js
+3
-3
sidebar-content.js
src/sidebar/components/sidebar-content.js
+3
-3
stream-content.js
src/sidebar/components/stream-content.js
+2
-2
annotation-test.js
src/sidebar/components/test/annotation-test.js
+12
-12
annotation-viewer-content-test.js
...sidebar/components/test/annotation-viewer-content-test.js
+14
-14
moderation-banner-test.js
src/sidebar/components/test/moderation-banner-test.js
+7
-7
sidebar-content-test.js
src/sidebar/components/test/sidebar-content-test.js
+3
-3
stream-content-test.js
src/sidebar/components/test/stream-content-test.js
+5
-5
groups.js
src/sidebar/groups.js
+4
-4
index.js
src/sidebar/index.js
+1
-2
api.js
src/sidebar/services/api.js
+3
-3
api-test.js
src/sidebar/services/test/api-test.js
+19
-19
session.js
src/sidebar/session.js
+4
-4
annotation-mapper-test.js
src/sidebar/test/annotation-mapper-test.js
+8
-8
groups-test.js
src/sidebar/test/groups-test.js
+10
-10
session-test.js
src/sidebar/test/session-test.js
+18
-18
No files found.
src/sidebar/annotation-mapper.js
View file @
d97b07ac
...
...
@@ -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
);
...
...
src/sidebar/components/annotation-viewer-content.js
View file @
d97b07ac
...
...
@@ -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
)
{
...
...
src/sidebar/components/annotation.js
View file @
d97b07ac
...
...
@@ -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
,
st
ore
,
st
reamer
)
{
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
)
{
...
...
src/sidebar/components/moderation-banner.js
View file @
d97b07ac
...
...
@@ -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'
);
...
...
src/sidebar/components/sidebar-content.js
View file @
d97b07ac
...
...
@@ -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
...
...
src/sidebar/components/stream-content.js
View file @
d97b07ac
...
...
@@ -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
);
...
...
src/sidebar/components/test/annotation-test.js
View file @
d97b07ac
...
...
@@ -104,7 +104,7 @@ describe('annotation', function() {
var
fakeServiceUrl
;
var
fakeSession
;
var
fakeSettings
;
var
fake
Store
;
var
fake
Api
;
var
fakeStreamer
;
var
sandbox
;
...
...
@@ -222,7 +222,7 @@ describe('annotation', function() {
authDomain
:
'localhost'
,
};
fake
Store
=
{
fake
Api
=
{
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
(
fake
Store
.
annotation
.
create
);
assert
.
called
(
fake
Api
.
annotation
.
create
);
});
it
(
'saves new highlights to drafts if not logged in'
,
function
()
{
...
...
@@ -355,7 +355,7 @@ describe('annotation', function() {
createDirective
(
annotation
);
assert
.
notCalled
(
fake
Store
.
annotation
.
create
);
assert
.
notCalled
(
fake
Api
.
annotation
.
create
);
assert
.
called
(
fakeDrafts
.
update
);
});
...
...
@@ -364,7 +364,7 @@ describe('annotation', function() {
createDirective
(
annotation
);
assert
.
notCalled
(
fake
Store
.
annotation
.
create
);
assert
.
notCalled
(
fake
Api
.
annotation
.
create
);
});
it
(
'does not save old highlights on initialization'
,
function
()
{
...
...
@@ -372,7 +372,7 @@ describe('annotation', function() {
createDirective
(
annotation
);
assert
.
notCalled
(
fake
Store
.
annotation
.
create
);
assert
.
notCalled
(
fake
Api
.
annotation
.
create
);
});
it
(
'does not save old annotations on initialization'
,
function
()
{
...
...
@@ -380,7 +380,7 @@ describe('annotation', function() {
createDirective
(
annotation
);
assert
.
notCalled
(
fake
Store
.
annotation
.
create
);
assert
.
notCalled
(
fake
Api
.
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'
);
fake
Store
.
annotation
.
create
=
sinon
.
stub
().
returns
(
Promise
.
reject
(
err
));
fake
Api
.
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
;
fake
Store
.
annotation
.
create
=
sinon
.
stub
().
returns
(
new
Promise
(
function
(
resolve
)
{
fake
Api
.
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
();
fake
Store
.
annotation
.
create
=
sinon
.
stub
().
returns
(
Promise
.
reject
({
status
:
-
1
}));
fake
Api
.
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'
);
fake
Store
.
annotation
.
update
=
sinon
.
stub
().
returns
(
Promise
.
reject
(
err
));
fake
Api
.
annotation
.
update
=
sinon
.
stub
().
returns
(
Promise
.
reject
(
err
));
return
controller
.
save
().
then
(
function
()
{
assert
.
calledWith
(
fakeFlash
.
error
,
'500 Server Error'
,
'Saving annotation failed'
);
...
...
src/sidebar/components/test/annotation-viewer-content-test.js
View file @
d97b07ac
...
...
@@ -4,7 +4,7 @@ var angular = require('angular');
// Fake implementation of the API for fetching annotations and replies to
// annotations.
function
Fake
Store
(
annots
)
{
function
Fake
Api
(
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
fake
Store
=
new
FakeStore
([
var
fake
Api
=
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
(
fake
Store
.
annots
));
sinon
.
match
(
fake
Api
.
annots
));
});
});
it
(
'does not highlight any annotations'
,
function
()
{
var
fake
Store
=
new
FakeStore
([
var
fake
Api
=
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
fake
Store
=
new
FakeStore
([
var
fake
Api
=
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
(
fake
Store
.
annots
));
sinon
.
match
(
fake
Api
.
annots
));
});
});
it
(
'expands the thread'
,
function
()
{
var
fake
Store
=
new
FakeStore
([
var
fake
Api
=
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
fake
Store
=
new
FakeStore
([
var
fake
Api
=
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'
]));
...
...
src/sidebar/components/test/moderation-banner-test.js
View file @
d97b07ac
...
...
@@ -12,7 +12,7 @@ describe('moderationBanner', function () {
var
bannerEl
;
var
fakeAnnotationUI
;
var
fakeFlash
;
var
fake
Store
;
var
fake
Api
;
before
(
function
()
{
angular
.
module
(
'app'
,
[])
...
...
@@ -29,7 +29,7 @@ describe('moderationBanner', function () {
error
:
sinon
.
stub
(),
};
fake
Store
=
{
fake
Api
=
{
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
(
fake
Store
.
annotation
.
hide
,
{
id
:
'ann-id'
});
assert
.
calledWith
(
fake
Api
.
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
});
fake
Store
.
annotation
.
hide
.
returns
(
Promise
.
reject
(
new
Error
(
'Network Error'
)));
fake
Api
.
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
(
fake
Store
.
annotation
.
unhide
,
{
id
:
'ann-id'
});
assert
.
calledWith
(
fake
Api
.
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
});
fake
Store
.
annotation
.
unhide
.
returns
(
Promise
.
reject
(
new
Error
(
'Network Error'
)));
fake
Api
.
annotation
.
unhide
.
returns
(
Promise
.
reject
(
new
Error
(
'Network Error'
)));
banner
.
querySelector
(
'button'
).
click
();
...
...
src/sidebar/components/test/sidebar-content-test.js
View file @
d97b07ac
...
...
@@ -49,7 +49,7 @@ describe('sidebar.components.sidebar-content', function () {
var
fakeGroups
;
var
fakeRootThread
;
var
fakeSettings
;
var
fake
Store
;
var
fake
Api
;
var
fakeStreamer
;
var
fakeStreamFilter
;
var
sandbox
;
...
...
@@ -116,17 +116,17 @@ describe('sidebar.components.sidebar-content', function () {
fakeSettings
=
{};
fake
Store
=
{
fake
Api
=
{
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
);
...
...
src/sidebar/components/test/stream-content-test.js
View file @
d97b07ac
...
...
@@ -19,7 +19,7 @@ describe('StreamContentController', function () {
var
fakeQueryParser
;
var
fakeRootThread
;
var
fakeSearchFilter
;
var
fake
Store
;
var
fake
Api
;
var
fakeStreamer
;
var
fakeStreamFilter
;
...
...
@@ -59,7 +59,7 @@ describe('StreamContentController', function () {
toObject
:
sinon
.
stub
().
returns
({}),
};
fake
Store
=
{
fake
Api
=
{
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
(
fake
Store
.
search
.
firstCall
.
args
[
0
].
_separate_replies
,
true
);
assert
.
equal
(
fake
Api
.
search
.
firstCall
.
args
[
0
].
_separate_replies
,
true
);
});
it
(
'passes the annotations and replies from search to loadAnnotations()'
,
function
()
{
fake
Store
.
search
=
function
()
{
fake
Api
.
search
=
function
()
{
return
Promise
.
resolve
({
'rows'
:
[
'annotation_1'
,
'annotation_2'
],
'replies'
:
[
'reply_1'
,
'reply_2'
,
'reply_3'
],
...
...
src/sidebar/groups.js
View file @
d97b07ac
...
...
@@ -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'
,
});
...
...
src/sidebar/index.js
View file @
d97b07ac
...
...
@@ -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'
))
...
...
src/sidebar/s
tore
.js
→
src/sidebar/s
ervices/api
.js
View file @
d97b07ac
...
...
@@ -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
;
src/sidebar/
test/store
-test.js
→
src/sidebar/
services/test/api
-test.js
View file @
d97b07ac
...
...
@@ -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.s
tore
'
,
function
()
{
describe
(
'sidebar.s
ervices.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'
,
...
...
src/sidebar/session.js
View file @
d97b07ac
...
...
@@ -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
,
a
pi
,
a
uth
,
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
);
}
/**
...
...
src/sidebar/test/annotation-mapper-test.js
View file @
d97b07ac
...
...
@@ -9,11 +9,11 @@ describe('annotationMapper', function() {
var
sandbox
=
sinon
.
sandbox
.
create
();
var
$rootScope
;
var
annotationUI
;
var
fake
Store
;
var
fake
Api
;
var
annotationMapper
;
beforeEach
(
function
()
{
fake
Store
=
{
fake
Api
=
{
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
(
's
tore'
,
fakeStore
);
.
value
(
'
api'
,
fakeApi
)
.
value
(
's
ettings'
,
{}
);
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
(
fake
Store
.
annotation
.
flag
);
assert
.
calledWith
(
fake
Store
.
annotation
.
flag
,
{
id
:
ann
.
id
});
assert
.
calledOnce
(
fake
Api
.
annotation
.
flag
);
assert
.
calledWith
(
fake
Api
.
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
(
fake
Store
.
annotation
.
delete
,
{
id
:
'test-id'
});
assert
.
calledWith
(
fake
Api
.
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'
);
fake
Store
.
annotation
.
delete
.
returns
(
Promise
.
reject
());
fake
Api
.
annotation
.
delete
.
returns
(
Promise
.
reject
());
var
ann
=
{
id
:
'test-id'
};
annotationMapper
.
deleteAnnotation
(
ann
).
catch
(
function
()
{
assert
.
notCalled
(
$rootScope
.
$broadcast
);
...
...
src/sidebar/test/groups-test.js
View file @
d97b07ac
...
...
@@ -17,7 +17,7 @@ describe('groups', function() {
var
fakeIsSidebar
;
var
fakeSession
;
var
fakeSettings
;
var
fake
Store
;
var
fake
Api
;
var
fakeLocalStorage
;
var
fakeRootScope
;
var
fakeServiceUrl
;
...
...
@@ -54,7 +54,7 @@ describe('groups', function() {
$broadcast
:
sandbox
.
stub
(),
};
fake
Store
=
{
fake
Api
=
{
group
:
{
member
:
{
delete
:
sandbox
.
stub
().
returns
(
Promise
.
resolve
()),
...
...
@@ -77,8 +77,8 @@ describe('groups', function() {
});
function
service
()
{
return
groups
(
fake
AnnotationUI
,
fakeIsSidebar
,
fakeLocalStorage
,
fakeServiceUrl
,
fakeSession
,
fakeSe
ttings
,
fakeRootScope
,
fakeStore
);
return
groups
(
fake
RootScope
,
fakeAnnotationUI
,
fakeApi
,
fakeIsSidebar
,
fakeLocalStorage
,
fakeServiceUrl
,
fakeSe
ssion
,
fakeSettings
);
}
describe
(
'#all()'
,
function
()
{
...
...
@@ -120,7 +120,7 @@ describe('groups', function() {
return
svc
.
load
().
then
(()
=>
{
svc
.
focus
(
'id2'
);
}).
then
(()
=>
{
fake
Store
.
groups
.
list
=
sandbox
.
stub
().
returns
(
Promise
.
resolve
([
fake
Api
.
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
(
fake
Store
.
groups
.
list
,
{
document_uri
:
'https://asite.com'
});
assert
.
calledWith
(
fake
Api
.
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
(
fake
Store
.
groups
.
list
,
{});
assert
.
calledWith
(
fake
Api
.
groups
.
list
,
{});
});
});
});
...
...
@@ -162,7 +162,7 @@ describe('groups', function() {
fakeSettings
.
services
=
[{
authority
:
'publisher.org'
}];
var
svc
=
service
();
return
svc
.
load
().
then
(()
=>
{
assert
.
calledWith
(
fake
Store
.
groups
.
list
,
sinon
.
match
({
authority
:
'publisher.org'
}));
assert
.
calledWith
(
fake
Api
.
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
(
fake
Store
.
group
.
member
.
delete
,
{
assert
.
calledWithMatch
(
fake
Api
.
group
.
member
.
delete
,
{
pubid
:
'id2'
,
user
:
'me'
,
});
...
...
@@ -289,7 +289,7 @@ describe('groups', function() {
service
();
return
fakeRootScope
.
eventCallbacks
[
testCase
.
event
]().
then
(()
=>
{
assert
.
calledOnce
(
fake
Store
.
groups
.
list
);
assert
.
calledOnce
(
fake
Api
.
groups
.
list
);
});
},
changeEvents
);
});
...
...
src/sidebar/test/session-test.js
View file @
d97b07ac
...
...
@@ -15,7 +15,7 @@ describe('sidebar.session', function () {
var
fakeRaven
;
var
fakeServiceConfig
;
var
fakeSettings
;
var
fake
Store
;
var
fake
Api
;
var
sandbox
;
var
session
;
...
...
@@ -47,7 +47,7 @@ describe('sidebar.session', function () {
fakeRaven
=
{
setUserInfo
:
sandbox
.
spy
(),
};
fake
Store
=
{
fake
Api
=
{
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'
,
});
fake
Store
.
profile
.
read
.
returns
(
Promise
.
resolve
({
fake
Api
.
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
(
fake
Store
.
profile
.
read
,
{
authority
:
'publisher.org'
});
assert
.
calledWith
(
fake
Api
.
profile
.
read
,
{
authority
:
'publisher.org'
});
});
});
...
...
@@ -109,7 +109,7 @@ describe('sidebar.session', function () {
var
clock
;
beforeEach
(()
=>
{
fake
Store
.
profile
.
read
.
returns
(
Promise
.
resolve
({
fake
Api
.
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
(
fake
Store
.
profile
.
read
);
assert
.
calledWith
(
fake
Api
.
profile
.
read
);
});
});
it
(
'should retry the profile fetch if it fails'
,
()
=>
{
fake
Store
.
profile
.
read
.
onCall
(
0
).
returns
(
fake
Api
.
profile
.
read
.
onCall
(
0
).
returns
(
Promise
.
reject
(
new
Error
(
'Server error'
))
);
fake
Store
.
profile
.
read
.
onCall
(
1
).
returns
(
fake
Api
.
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
(
fake
Store
.
profile
.
read
);
assert
.
calledOnce
(
fake
Api
.
profile
.
read
);
});
});
...
...
@@ -164,7 +164,7 @@ describe('sidebar.session', function () {
clock
.
tick
(
CACHE_TTL
*
2
);
return
session
.
load
();
}).
then
(()
=>
{
assert
.
calledTwice
(
fake
Store
.
profile
.
read
);
assert
.
calledTwice
(
fake
Api
.
profile
.
read
);
});
});
});
...
...
@@ -192,14 +192,14 @@ describe('sidebar.session', function () {
describe
(
'#dismissSidebarTutorial()'
,
function
()
{
beforeEach
(
function
()
{
fake
Store
.
profile
.
update
.
returns
(
Promise
.
resolve
({
fake
Api
.
profile
.
update
.
returns
(
Promise
.
resolve
({
preferences
:
{},
}));
});
it
(
'disables the tutorial for the user'
,
function
()
{
session
.
dismissSidebarTutorial
();
assert
.
calledWith
(
fake
Store
.
profile
.
update
,
{},
{
preferences
:
{
show_sidebar_tutorial
:
false
}});
assert
.
calledWith
(
fake
Api
.
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.
fake
Store
.
profile
.
read
.
returns
(
Promise
.
resolve
({
fake
Api
.
profile
.
read
.
returns
(
Promise
.
resolve
({
userid
:
'acct:user_a@hypothes.is'
,
}));
return
session
.
load
();
});
it
(
'should clear cached data and reload'
,
()
=>
{
fake
Store
.
profile
.
read
.
returns
(
Promise
.
resolve
({
fake
Api
.
profile
.
read
.
returns
(
Promise
.
resolve
({
userid
:
'acct:user_b@hypothes.is'
,
}));
...
...
@@ -239,7 +239,7 @@ describe('sidebar.session', function () {
});
// Fake profile response after logout.
fake
Store
.
profile
.
read
=
()
=>
Promise
.
resolve
({
fake
Api
.
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'
,
()
=>
{
fake
Store
.
profile
.
read
.
returns
(
Promise
.
resolve
({
fake
Api
.
profile
.
read
.
returns
(
Promise
.
resolve
({
userid
:
'acct:initial_user@hypothes.is'
,
}));
return
session
.
load
().
then
(()
=>
{
// Simulate login change happening in a different tab.
fake
Store
.
profile
.
read
.
returns
(
Promise
.
resolve
({
fake
Api
.
profile
.
read
.
returns
(
Promise
.
resolve
({
userid
:
'acct:different_user@hypothes.is'
,
}));
$rootScope
.
$broadcast
(
events
.
OAUTH_TOKENS_CHANGED
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment