Commit d3ddbe75 authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #528 from hypothesis/use-leave-group-api

Use the `group.member.delete` API route to leave a group
parents ca516d3a a3b0c454
...@@ -16,7 +16,7 @@ var STORAGE_KEY = 'hypothesis.groups.focus'; ...@@ -16,7 +16,7 @@ var STORAGE_KEY = 'hypothesis.groups.focus';
var events = require('./events'); var events = require('./events');
// @ngInject // @ngInject
function groups(localStorage, serviceUrl, session, $rootScope, $http) { function groups(localStorage, serviceUrl, session, $rootScope, store) {
// The currently focused group. This is the group that's shown as selected in // 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 // the groups dropdown, the annotations displayed are filtered to only ones
// that belong to this group, and any new annotations that the user creates // that belong to this group, and any new annotations that the user creates
...@@ -38,20 +38,18 @@ function groups(localStorage, serviceUrl, session, $rootScope, $http) { ...@@ -38,20 +38,18 @@ function groups(localStorage, serviceUrl, session, $rootScope, $http) {
return null; return null;
} }
/** Leave the group with the given ID. /**
* Leave the group with the given ID.
* Returns a promise which resolves when the action completes. * Returns a promise which resolves when the action completes.
*/ */
function leave(id) { function leave(id) {
var response = $http({ // The groups list will be updated in response to a session state
method: 'POST',
url: serviceUrl('groups.leave', {id: id}),
});
// the groups list will be updated in response to a session state
// change notification from the server. We could improve the UX here // change notification from the server. We could improve the UX here
// by optimistically updating the session state // by optimistically updating the session state
return store.group.member.delete({
return response; pubid: id,
user: 'me',
});
} }
......
...@@ -173,6 +173,11 @@ function store($http, $q, apiRoutes, auth) { ...@@ -173,6 +173,11 @@ function store($http, $q, apiRoutes, auth) {
hide: apiCall('annotation.hide'), hide: apiCall('annotation.hide'),
unhide: apiCall('annotation.unhide'), unhide: apiCall('annotation.unhide'),
}, },
group: {
member: {
delete: apiCall('group.member.delete'),
},
},
profile: { profile: {
read: apiCall('profile.read'), read: apiCall('profile.read'),
update: apiCall('profile.update'), update: apiCall('profile.update'),
......
...@@ -18,9 +18,9 @@ var sessionWithThreeGroups = function() { ...@@ -18,9 +18,9 @@ var sessionWithThreeGroups = function() {
describe('groups', function() { describe('groups', function() {
var fakeSession; var fakeSession;
var fakeStore;
var fakeLocalStorage; var fakeLocalStorage;
var fakeRootScope; var fakeRootScope;
var fakeHttp;
var fakeServiceUrl; var fakeServiceUrl;
var sandbox; var sandbox;
...@@ -43,7 +43,13 @@ describe('groups', function() { ...@@ -43,7 +43,13 @@ describe('groups', function() {
} }
}, },
}; };
fakeHttp = sandbox.stub(); fakeStore = {
group: {
member: {
delete: sandbox.stub().returns(Promise.resolve()),
},
},
};
fakeServiceUrl = sandbox.stub(); fakeServiceUrl = sandbox.stub();
}); });
...@@ -53,7 +59,7 @@ describe('groups', function() { ...@@ -53,7 +59,7 @@ describe('groups', function() {
function service() { function service() {
return groups(fakeLocalStorage, fakeServiceUrl, fakeSession, return groups(fakeLocalStorage, fakeServiceUrl, fakeSession,
fakeRootScope, fakeHttp); fakeRootScope, fakeStore);
} }
describe('.all()', function() { describe('.all()', function() {
...@@ -171,15 +177,13 @@ describe('groups', function() { ...@@ -171,15 +177,13 @@ describe('groups', function() {
}); });
describe('.leave()', function () { describe('.leave()', function () {
it('should call the /groups/<id>/leave service', function () { it('should call the group leave API', function () {
var s = service(); var s = service();
fakeServiceUrl return s.leave('id2').then(() => {
.withArgs('groups.leave', {id: 'id2'}) assert.calledWithMatch(fakeStore.group.member.delete, {
.returns('https://hyp.is/groups/leave'); pubid: 'id2',
s.leave('id2'); user: 'me',
assert.calledWithMatch(fakeHttp, { });
url: 'https://hyp.is/groups/leave',
method: 'POST',
}); });
}); });
}); });
......
...@@ -36,6 +36,14 @@ var routes = { ...@@ -36,6 +36,14 @@ var routes = {
url: 'http://example.com/api/annotations/:id/hide', url: 'http://example.com/api/annotations/:id/hide',
}, },
}, },
group: {
member: {
delete: {
method: 'DELETE',
url: 'http://example.com/api/groups/:pubid/members/:user',
},
},
},
search: { search: {
method: 'GET', method: 'GET',
url: 'http://example.com/api/search', url: 'http://example.com/api/search',
...@@ -178,6 +186,20 @@ describe('sidebar.store', function () { ...@@ -178,6 +186,20 @@ describe('sidebar.store', function () {
$httpBackend.flush(); $httpBackend.flush();
}); });
describe('#group.member.delete', () => {
it('removes current user from a group', (done) => {
store.group.member.delete({pubid: 'an-id', user: 'me'}).then(function () {
done();
});
$httpBackend.expectDELETE('http://example.com/api/groups/an-id/members/me')
.respond(() => {
return [204, {}, {}];
});
$httpBackend.flush();
});
});
it('removes internal properties before sending data to the server', function (done) { it('removes internal properties before sending data to the server', function (done) {
var annotation = { var annotation = {
$highlight: true, $highlight: true,
......
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