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

Merge pull request #1317 from hypothesis/namespace-direct-linked-module

Namespace the direct-linked module
parents 4bc0827e f89877a0
...@@ -151,7 +151,7 @@ function SidebarContentController( ...@@ -151,7 +151,7 @@ function SidebarContentController(
this.scrollTo = scrollToAnnotation; this.scrollTo = scrollToAnnotation;
this.selectedGroupUnavailable = function() { this.selectedGroupUnavailable = function() {
return store.getState().directLinkedGroupFetchFailed; return store.getRootState().directLinked.directLinkedGroupFetchFailed;
}; };
this.selectedAnnotationUnavailable = function() { this.selectedAnnotationUnavailable = function() {
...@@ -169,7 +169,7 @@ function SidebarContentController( ...@@ -169,7 +169,7 @@ function SidebarContentController(
// If user has not landed on a direct linked annotation // If user has not landed on a direct linked annotation
// don't show the CTA. // don't show the CTA.
if (!store.getState().directLinkedAnnotationId) { if (!store.getRootState().directLinked.directLinkedAnnotationId) {
return false; return false;
} }
......
...@@ -179,7 +179,8 @@ function groups( ...@@ -179,7 +179,8 @@ function groups(
// If there is a direct-linked annotation, fetch the annotation in case // If there is a direct-linked annotation, fetch the annotation in case
// the associated group has not already been fetched and we need to make // the associated group has not already been fetched and we need to make
// an additional request for it. // an additional request for it.
const directLinkedAnnId = store.getState().directLinkedAnnotationId; const directLinkedAnnId = store.getRootState().directLinked
.directLinkedAnnotationId;
let directLinkedAnnApi = null; let directLinkedAnnApi = null;
if (directLinkedAnnId) { if (directLinkedAnnId) {
directLinkedAnnApi = api.annotation directLinkedAnnApi = api.annotation
...@@ -193,7 +194,8 @@ function groups( ...@@ -193,7 +194,8 @@ function groups(
// If there is a direct-linked group, add an API request to get that // If there is a direct-linked group, add an API request to get that
// particular group since it may not be in the set of groups that are // particular group since it may not be in the set of groups that are
// fetched by other requests. // fetched by other requests.
const directLinkedGroupId = store.getState().directLinkedGroupId; const directLinkedGroupId = store.getRootState().directLinked
.directLinkedGroupId;
let directLinkedGroupApi = null; let directLinkedGroupApi = null;
if (directLinkedGroupId) { if (directLinkedGroupId) {
directLinkedGroupApi = fetchGroup({ directLinkedGroupApi = fetchGroup({
......
...@@ -60,9 +60,11 @@ describe('groups', function() { ...@@ -60,9 +60,11 @@ describe('groups', function() {
mainFrame: { uri: 'http://example.org' }, mainFrame: { uri: 'http://example.org' },
focusedGroup: null, focusedGroup: null,
groups: [], groups: [],
directLinked: {
directLinkedGroupId: null, directLinkedGroupId: null,
directLinkedAnnotationId: null, directLinkedAnnotationId: null,
}, },
},
{ {
focusGroup: sinon.stub(), focusGroup: sinon.stub(),
getGroup: sinon.stub(), getGroup: sinon.stub(),
...@@ -164,7 +166,9 @@ describe('groups', function() { ...@@ -164,7 +166,9 @@ describe('groups', function() {
scopes: { enforced: true, uri_patterns: ['http://foo.com'] }, scopes: { enforced: true, uri_patterns: ['http://foo.com'] },
}; };
fakeStore.setState({ fakeStore.setState({
directLinked: {
directLinkedGroupId: outOfScopeEnforcedGroup.id, directLinkedGroupId: outOfScopeEnforcedGroup.id,
},
}); });
fakeApi.group.read.returns(Promise.resolve(outOfScopeEnforcedGroup)); fakeApi.group.read.returns(Promise.resolve(outOfScopeEnforcedGroup));
return svc.load().then(groups => { return svc.load().then(groups => {
...@@ -180,7 +184,11 @@ describe('groups', function() { ...@@ -180,7 +184,11 @@ describe('groups', function() {
it('catches error from api.group.read request', () => { it('catches error from api.group.read request', () => {
const svc = service(); const svc = service();
fakeLocalStorage.getItem.returns(dummyGroups[0].id); fakeLocalStorage.getItem.returns(dummyGroups[0].id);
fakeStore.setState({ directLinkedGroupId: 'does-not-exist' }); fakeStore.setState({
directLinked: {
directLinkedGroupId: 'does-not-exist',
},
});
fakeApi.group.read.returns( fakeApi.group.read.returns(
Promise.reject( Promise.reject(
new Error( new Error(
...@@ -219,7 +227,11 @@ describe('groups', function() { ...@@ -219,7 +227,11 @@ describe('groups', function() {
const svc = service(); const svc = service();
// Set the direct-linked group to dummyGroups[0]. // Set the direct-linked group to dummyGroups[0].
fakeStore.setState({ directLinkedGroupId: dummyGroups[0].id }); fakeStore.setState({
directLinkedGroupId: {
directLinkedGroupId: dummyGroups[0].id,
},
});
fakeApi.group.read.returns(Promise.resolve(dummyGroups[0])); fakeApi.group.read.returns(Promise.resolve(dummyGroups[0]));
// Include the dummyGroups[0] in the featured groups. // Include the dummyGroups[0] in the featured groups.
...@@ -235,7 +247,11 @@ describe('groups', function() { ...@@ -235,7 +247,11 @@ describe('groups', function() {
it('combines groups from all 3 endpoints if there is a selectedGroup', () => { it('combines groups from all 3 endpoints if there is a selectedGroup', () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedGroupId: 'selected-id' }); fakeStore.setState({
directLinked: {
directLinkedGroupId: 'selected-id',
},
});
const groups = [ const groups = [
{ id: 'groupa', name: 'GroupA' }, { id: 'groupa', name: 'GroupA' },
{ id: 'groupb', name: 'GroupB' }, { id: 'groupb', name: 'GroupB' },
...@@ -254,7 +270,11 @@ describe('groups', function() { ...@@ -254,7 +270,11 @@ describe('groups', function() {
it('passes the direct-linked group id from the store to the api.group.read call', () => { it('passes the direct-linked group id from the store to the api.group.read call', () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedGroupId: 'selected-id' }); fakeStore.setState({
directLinked: {
directLinkedGroupId: 'selected-id',
},
});
const group = { id: 'selected-id', name: 'Selected Group' }; const group = { id: 'selected-id', name: 'Selected Group' };
fakeApi.profile.groups.read.returns(Promise.resolve([])); fakeApi.profile.groups.read.returns(Promise.resolve([]));
...@@ -284,7 +304,11 @@ describe('groups', function() { ...@@ -284,7 +304,11 @@ describe('groups', function() {
fakeApi.groups.list.returns( fakeApi.groups.list.returns(
Promise.resolve([{ id: 'groupa', name: 'GroupA' }]) Promise.resolve([{ id: 'groupa', name: 'GroupA' }])
); );
fakeStore.setState({ directLinkedGroupId: 'group-id' }); fakeStore.setState({
directLinked: {
directLinkedGroupId: 'group-id',
},
});
return svc.load().then(() => { return svc.load().then(() => {
assert.calledWith( assert.calledWith(
...@@ -313,8 +337,10 @@ describe('groups', function() { ...@@ -313,8 +337,10 @@ describe('groups', function() {
it("sets the direct-linked annotation's group to take precedence over the group saved in local storage and the direct-linked group", () => { it("sets the direct-linked annotation's group to take precedence over the group saved in local storage and the direct-linked group", () => {
const svc = service(); const svc = service();
fakeStore.setState({ fakeStore.setState({
directLinked: {
directLinkedAnnotationId: 'ann-id', directLinkedAnnotationId: 'ann-id',
directLinkedGroupId: dummyGroups[1].id, directLinkedGroupId: dummyGroups[1].id,
},
}); });
fakeLocalStorage.getItem.returns(dummyGroups[0].id); fakeLocalStorage.getItem.returns(dummyGroups[0].id);
fakeApi.groups.list.returns(Promise.resolve(dummyGroups)); fakeApi.groups.list.returns(Promise.resolve(dummyGroups));
...@@ -331,7 +357,11 @@ describe('groups', function() { ...@@ -331,7 +357,11 @@ describe('groups', function() {
it("sets the focused group to the direct-linked annotation's group", () => { it("sets the focused group to the direct-linked annotation's group", () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedAnnotationId: 'ann-id' }); fakeStore.setState({
directLinked: {
directLinkedAnnotationId: 'ann-id',
},
});
fakeApi.groups.list.returns(Promise.resolve(dummyGroups)); fakeApi.groups.list.returns(Promise.resolve(dummyGroups));
fakeLocalStorage.getItem.returns(dummyGroups[0].id); fakeLocalStorage.getItem.returns(dummyGroups[0].id);
fakeApi.annotation.get.returns( fakeApi.annotation.get.returns(
...@@ -347,7 +377,11 @@ describe('groups', function() { ...@@ -347,7 +377,11 @@ describe('groups', function() {
it('sets the direct-linked group to take precedence over the group saved in local storage', () => { it('sets the direct-linked group to take precedence over the group saved in local storage', () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedGroupId: dummyGroups[1].id }); fakeStore.setState({
directLinked: {
directLinkedGroupId: dummyGroups[1].id,
},
});
fakeLocalStorage.getItem.returns(dummyGroups[0].id); fakeLocalStorage.getItem.returns(dummyGroups[0].id);
fakeApi.groups.list.returns(Promise.resolve(dummyGroups)); fakeApi.groups.list.returns(Promise.resolve(dummyGroups));
return svc.load().then(() => { return svc.load().then(() => {
...@@ -357,7 +391,11 @@ describe('groups', function() { ...@@ -357,7 +391,11 @@ describe('groups', function() {
it('sets the focused group to the direct-linked group', () => { it('sets the focused group to the direct-linked group', () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedGroupId: dummyGroups[1].id }); fakeStore.setState({
directLinked: {
directLinkedGroupId: dummyGroups[1].id,
},
});
fakeApi.groups.list.returns(Promise.resolve(dummyGroups)); fakeApi.groups.list.returns(Promise.resolve(dummyGroups));
return svc.load().then(() => { return svc.load().then(() => {
assert.calledWith(fakeStore.focusGroup, dummyGroups[1].id); assert.calledWith(fakeStore.focusGroup, dummyGroups[1].id);
...@@ -366,7 +404,11 @@ describe('groups', function() { ...@@ -366,7 +404,11 @@ describe('groups', function() {
it('clears the directLinkedGroupFetchFailed state if loading a direct-linked group', () => { it('clears the directLinkedGroupFetchFailed state if loading a direct-linked group', () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedGroupId: dummyGroups[1].id }); fakeStore.setState({
directLinked: {
directLinkedGroupId: dummyGroups[1].id,
},
});
fakeApi.groups.list.returns(Promise.resolve(dummyGroups)); fakeApi.groups.list.returns(Promise.resolve(dummyGroups));
return svc.load().then(() => { return svc.load().then(() => {
assert.called(fakeStore.clearDirectLinkedGroupFetchFailed); assert.called(fakeStore.clearDirectLinkedGroupFetchFailed);
...@@ -501,7 +543,11 @@ describe('groups', function() { ...@@ -501,7 +543,11 @@ describe('groups', function() {
it("includes the direct-linked annotation's group when it is not in the normal list of groups", () => { it("includes the direct-linked annotation's group when it is not in the normal list of groups", () => {
const svc = service(); const svc = service();
fakeStore.setState({ directLinkedAnnotationId: 'ann-id' }); fakeStore.setState({
directLinked: {
directLinkedAnnotationId: 'ann-id',
},
});
fakeApi.profile.groups.read.returns(Promise.resolve([])); fakeApi.profile.groups.read.returns(Promise.resolve([]));
fakeApi.groups.list.returns( fakeApi.groups.list.returns(
...@@ -534,8 +580,10 @@ describe('groups', function() { ...@@ -534,8 +580,10 @@ describe('groups', function() {
const svc = service(); const svc = service();
fakeStore.setState({ fakeStore.setState({
directLinked: {
directLinkedGroupId: 'out-of-scope', directLinkedGroupId: 'out-of-scope',
directLinkedAnnotationId: 'ann-id', directLinkedAnnotationId: 'ann-id',
},
}); });
fakeApi.profile.groups.read.returns(Promise.resolve([])); fakeApi.profile.groups.read.returns(Promise.resolve([]));
...@@ -573,8 +621,10 @@ describe('groups', function() { ...@@ -573,8 +621,10 @@ describe('groups', function() {
const svc = service(); const svc = service();
fakeStore.setState({ fakeStore.setState({
directLinked: {
directLinkedGroupId: '__world__', directLinkedGroupId: '__world__',
directLinkedAnnotationId: null, directLinkedAnnotationId: null,
},
}); });
fakeApi.profile.groups.read.returns(Promise.resolve([])); fakeApi.profile.groups.read.returns(Promise.resolve([]));
...@@ -614,7 +664,7 @@ describe('groups', function() { ...@@ -614,7 +664,7 @@ describe('groups', function() {
}) })
); );
fakeStore.setState({ fakeStore.setState({
directLinkedAnnotationId: 'direct-linked-ann', directLinked: { directLinkedAnnotationId: 'direct-linked-ann' },
}); });
} }
......
...@@ -129,6 +129,7 @@ function clearDirectLinkedIds() { ...@@ -129,6 +129,7 @@ function clearDirectLinkedIds() {
module.exports = { module.exports = {
init, init,
namespace: 'directLinked',
update, update,
actions: { actions: {
setDirectLinkedGroupFetchFailed, setDirectLinkedGroupFetchFailed,
......
...@@ -7,6 +7,10 @@ describe('sidebar/store/modules/direct-linked', () => { ...@@ -7,6 +7,10 @@ describe('sidebar/store/modules/direct-linked', () => {
let store; let store;
let fakeSettings = {}; let fakeSettings = {};
const getDirectLinkedState = () => {
return store.getRootState().directLinked;
};
beforeEach(() => { beforeEach(() => {
store = createStore([directLinked], [fakeSettings]); store = createStore([directLinked], [fakeSettings]);
}); });
...@@ -15,7 +19,7 @@ describe('sidebar/store/modules/direct-linked', () => { ...@@ -15,7 +19,7 @@ describe('sidebar/store/modules/direct-linked', () => {
it('sets directLinkedGroupFetchFailed to true', () => { it('sets directLinkedGroupFetchFailed to true', () => {
store.setDirectLinkedGroupFetchFailed(); store.setDirectLinkedGroupFetchFailed();
assert.isTrue(store.getState().directLinkedGroupFetchFailed); assert.isTrue(getDirectLinkedState().directLinkedGroupFetchFailed);
}); });
}); });
...@@ -25,7 +29,7 @@ describe('sidebar/store/modules/direct-linked', () => { ...@@ -25,7 +29,7 @@ describe('sidebar/store/modules/direct-linked', () => {
store.clearDirectLinkedGroupFetchFailed(); store.clearDirectLinkedGroupFetchFailed();
assert.isFalse(store.getState().directLinkedGroupFetchFailed); assert.isFalse(getDirectLinkedState().directLinkedGroupFetchFailed);
}); });
}); });
...@@ -34,14 +38,14 @@ describe('sidebar/store/modules/direct-linked', () => { ...@@ -34,14 +38,14 @@ describe('sidebar/store/modules/direct-linked', () => {
store = createStore([directLinked], [fakeSettings]); store = createStore([directLinked], [fakeSettings]);
assert.equal(store.getState().directLinkedAnnotationId, 'ann-id'); assert.equal(getDirectLinkedState().directLinkedAnnotationId, 'ann-id');
}); });
describe('setDirectLinkedAnnotationId', () => { describe('setDirectLinkedAnnotationId', () => {
it('sets directLinkedAnnotationId to the specified annotation id', () => { it('sets directLinkedAnnotationId to the specified annotation id', () => {
store.setDirectLinkedAnnotationId('ann-id'); store.setDirectLinkedAnnotationId('ann-id');
assert.equal(store.getState().directLinkedAnnotationId, 'ann-id'); assert.equal(getDirectLinkedState().directLinkedAnnotationId, 'ann-id');
}); });
}); });
...@@ -50,14 +54,14 @@ describe('sidebar/store/modules/direct-linked', () => { ...@@ -50,14 +54,14 @@ describe('sidebar/store/modules/direct-linked', () => {
store = createStore([directLinked], [fakeSettings]); store = createStore([directLinked], [fakeSettings]);
assert.equal(store.getState().directLinkedGroupId, 'group-id'); assert.equal(getDirectLinkedState().directLinkedGroupId, 'group-id');
}); });
describe('setDirectLinkedGroupId', () => { describe('setDirectLinkedGroupId', () => {
it('sets directLinkedGroupId to the specified group id', () => { it('sets directLinkedGroupId to the specified group id', () => {
store.setDirectLinkedGroupId('group-id'); store.setDirectLinkedGroupId('group-id');
assert.equal(store.getState().directLinkedGroupId, 'group-id'); assert.equal(getDirectLinkedState().directLinkedGroupId, 'group-id');
}); });
}); });
...@@ -68,8 +72,8 @@ describe('sidebar/store/modules/direct-linked', () => { ...@@ -68,8 +72,8 @@ describe('sidebar/store/modules/direct-linked', () => {
store.clearDirectLinkedIds(); store.clearDirectLinkedIds();
assert.equal(store.getState().directLinkedAnnotationId, null); assert.equal(getDirectLinkedState().directLinkedAnnotationId, null);
assert.equal(store.getState().directLinkedGroupId, null); assert.equal(getDirectLinkedState().directLinkedGroupId, null);
}); });
}); });
}); });
...@@ -76,17 +76,19 @@ describe('store', function() { ...@@ -76,17 +76,19 @@ describe('store', function() {
it('sets `directLinkedGroupFetchFailed` to false', () => { it('sets `directLinkedGroupFetchFailed` to false', () => {
store.clearSelection(); store.clearSelection();
assert.isFalse(store.getState().directLinkedGroupFetchFailed); assert.isFalse(
store.getRootState().directLinked.directLinkedGroupFetchFailed
);
}); });
it('sets `directLinkedAnnotationId` to null', () => { it('sets `directLinkedAnnotationId` to null', () => {
store.clearSelection(); store.clearSelection();
assert.isNull(store.getState().directLinkedAnnotationId); assert.isNull(store.getRootState().directLinked.directLinkedAnnotationId);
}); });
it('sets `directLinkedGroupId` to null', () => { it('sets `directLinkedGroupId` to null', () => {
store.clearSelection(); store.clearSelection();
assert.isNull(store.getState().directLinkedGroupId); assert.isNull(store.getRootState().directLinked.directLinkedGroupId);
}); });
it('sets `sortKey` to default annotation sort key if set to Orphans', () => { it('sets `sortKey` to default annotation sort key if set to Orphans', () => {
......
...@@ -24,6 +24,10 @@ function fakeStore(initialState, methods) { ...@@ -24,6 +24,10 @@ function fakeStore(initialState, methods) {
const store = redux.createStore(update, initialState); const store = redux.createStore(update, initialState);
store.getRootState = () => {
return store.getState();
};
store.setState = function(state) { store.setState = function(state) {
store.dispatch({ type: 'SET_STATE', state: state }); store.dispatch({ type: 'SET_STATE', state: state });
}; };
......
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