Skip to content

Commit 6ae654f

Browse files
authored
Fix issue 78 Load story configuration (C039_geostory) (#4096)
* Fix issue 78 Load story configuration * removed unneeded action in epic stream * removed unneeded comment * skip failing test
1 parent c40d0d1 commit 6ae654f

22 files changed

Lines changed: 4283 additions & 3269 deletions

File tree

package-lock.json

Lines changed: 3669 additions & 3109 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/client/actions/__tests__/geostory-test.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
const expect = require('expect');
99

1010
import {
11-
ADD,
12-
add,
13-
CHANGE_MODE,
14-
setEditing,
15-
SET_CURRENT_STORY,
16-
setCurrentStory,
17-
UPDATE,
18-
update
19-
11+
ADD, add,
12+
CHANGE_MODE, setEditing,
13+
SET_CURRENT_STORY, setCurrentStory,
14+
UPDATE, update,
15+
LOAD_GEOSTORY, loadGeostory,
16+
LOADING_GEOSTORY, loadingGeostory,
17+
LOAD_GEOSTORY_ERROR, loadGeostoryError
2018
} from '../geostory';
2119
const { Modes } = require('../../utils/GeoStoryUtils');
2220
import TEST_STORY from "json-loader!../../test-resources/geostory/sampleStory_1.json";
@@ -56,4 +54,28 @@ describe('test geostory action creators', () => {
5654
expect(action.element).toBe(SECTION);
5755
expect(action.mode).toBe('replace');
5856
});
57+
it('loadGeostory', () => {
58+
const id = 'sampleStory';
59+
const action = loadGeostory(id);
60+
expect(action.type).toBe(LOAD_GEOSTORY);
61+
expect(action.id).toBe(id);
62+
});
63+
it('loadingGeostory', () => {
64+
// defaults
65+
const action = loadingGeostory();
66+
expect(action.type).toBe(LOADING_GEOSTORY);
67+
expect(action.value).toBe(false);
68+
expect(action.name).toBe("loading");
69+
// with sample values
70+
const action2 = loadingGeostory(true, "saving");
71+
expect(action2.type).toBe(LOADING_GEOSTORY);
72+
expect(action2.value).toBe(true);
73+
expect(action2.name).toBe("saving");
74+
});
75+
it('loadGeostoryError', () => {
76+
const error = {message: "this stoyry does not exist"};
77+
const action = loadGeostoryError(error);
78+
expect(action.type).toBe(LOAD_GEOSTORY_ERROR);
79+
expect(action.error).toEqual(error);
80+
});
5981
});

web/client/actions/geostory.js

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,36 @@ import { Modes } from '../utils/GeoStoryUtils';
1010
import uuid from "uuid";
1111

1212
export const CHANGE_MODE = "GEOSTORY:CHANGE_MODE";
13+
export const SET_CURRENT_STORY = "GEOSTORY:SET_CURRENT_STORY";
14+
export const ADD = "GEOSTORY:ADD";
15+
export const UPDATE = "GEOSTORY:UPDATE";
16+
export const LOAD_GEOSTORY = "GEOSTORY:LOAD_GEOSTORY";
17+
export const LOADING_GEOSTORY = "GEOSTORY:LOADING_GEOSTORY";
18+
export const LOAD_GEOSTORY_ERROR = "GEOSTORY:LOAD_GEOSTORY_ERROR";
19+
1320
/**
1421
* Turn on/off editing mode.
1522
* @param {boolean} editing editing mode. true to activate, false to deactivate.
16-
*/
23+
*/
1724
export const setEditing = (editing) => ({ type: CHANGE_MODE, mode: editing ? Modes.EDIT : Modes.VIEW});
18-
export const SET_CURRENT_STORY = "GEOSTORY:SET_CURRENT_STORY";
19-
2025
/**
2126
* Sets the current story for editor/viewer
2227
* @param {object} story the story object
23-
*/
28+
*/
2429
export const setCurrentStory = (story) => ({ type: SET_CURRENT_STORY, story});
25-
26-
export const ADD = "GEOSTORY:ADD";
27-
2830
/**
2931
* Adds an entry to current story. The entry can be a section, a content or anything to append in an array (even sub-content)
3032
* @param {string} path path where to add the element. It can contain path like this `sections[{id: "abc"}].contents[{id: "def"}]` to resolve the predicate between brackets.
3133
* @param {string|number} [position] the ID or the index of the section where to place the section (if not present the section will be appended at the end)
3234
* @param {string|object} content the object to add or the content template to apply. can be a section, a content or whatever. If it is a string, it will be used the template with that name.
33-
*/
35+
*/
3436
export const add = (path, position, element) => ({
3537
type: ADD,
3638
id: element && element.id || uuid(), // automatically assign an ID
3739
path,
3840
position,
3941
element
4042
});
41-
42-
export const UPDATE = "GEOSTORY:UPDATE";
43-
4443
/**
4544
* Updates a value or an object in the current Story. Useful to update contents, settings and so on.
4645
* @param {string} path the path of the element to modify. It can contain path like this `sections[{id: "abc"}].contents[{id: "def"}]` to resolve the predicate between brackets.
@@ -53,3 +52,19 @@ export const update = (path, element, mode = "replace") => ({
5352
element,
5453
mode
5554
});
55+
/**
56+
* Load geostory from configuration
57+
* @param {string} id the story name of .json file
58+
*/
59+
export const loadGeostory = (id) => ({ type: LOAD_GEOSTORY, id});
60+
/**
61+
* Loading status of geostory
62+
* @param {boolean} value the status of the loading process
63+
* @param {string} name of the loading process
64+
*/
65+
export const loadingGeostory = (value = false, name = "loading") => ({ type: LOADING_GEOSTORY, value, name});
66+
/**
67+
* load failed and this intercept error
68+
* @param {object} error the status of the loading process
69+
*/
70+
export const loadGeostoryError = (error) => ({ type: LOAD_GEOSTORY_ERROR, error});

web/client/components/home/Home.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Home extends React.Component {
2929
render() {
3030
let tooltip = <Tooltip id="toolbar-home-button">{<Message msgId="gohome"/>}</Tooltip>;
3131
return (
32-
<OverlayTrigger overlay={tooltip}>
32+
<OverlayTrigger overlay={tooltip} placement="left">
3333
<Button
3434
{...this.props}
3535
id="home-button"
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
* Copyright 2019, GeoSolutions Sas.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
import expect from 'expect';
10+
import TEST_STORY from "json-loader!../../test-resources/geostory/sampleStory_1.json";
11+
12+
import {loadGeostoryEpic} from '../geostory';
13+
import {
14+
LOADING_GEOSTORY,
15+
loadGeostory,
16+
SET_CURRENT_STORY,
17+
LOAD_GEOSTORY_ERROR
18+
} from '../../actions/geostory';
19+
import { SHOW_NOTIFICATION } from '../../actions/notifications';
20+
import {testEpic} from './epicTestUtils';
21+
const axios = require('../../libs/ajax');
22+
const MockAdapter = require('axios-mock-adapter');
23+
24+
let mockAxios;
25+
describe('Geostory Epics', () => {
26+
beforeEach(done => {
27+
mockAxios = new MockAdapter(axios);
28+
setTimeout(done);
29+
});
30+
31+
afterEach(done => {
32+
mockAxios.restore();
33+
setTimeout(done);
34+
});
35+
it('loadGeostoryEpic loading one sample story', (done) => {
36+
const NUM_ACTIONS = 3;
37+
mockAxios.onGet().reply(200, TEST_STORY);
38+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("sampleStory"), (actions) => {
39+
expect(actions.length).toBe(NUM_ACTIONS);
40+
actions.map((a, i) => {
41+
switch (a.type) {
42+
case LOADING_GEOSTORY:
43+
expect(a.name).toBe("loading");
44+
expect(a.value).toBe(i === 0);
45+
break;
46+
case SET_CURRENT_STORY:
47+
expect(a.story).toEqual(TEST_STORY);
48+
break;
49+
default: expect(true).toBe(false);
50+
break;
51+
}
52+
});
53+
done();
54+
}, {
55+
geostory: {}
56+
});
57+
});
58+
it('loadGeostoryEpic loading wrong story', (done) => {
59+
const NUM_ACTIONS = 5;
60+
mockAxios.onGet().reply(404);
61+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("wrongStoryName"), (actions) => {
62+
expect(actions.length).toBe(NUM_ACTIONS);
63+
actions.map((a, i) => {
64+
switch (a.type) {
65+
case LOADING_GEOSTORY:
66+
expect(a.name).toBe("loading");
67+
expect(a.value).toBe(i === 0);
68+
break;
69+
case SET_CURRENT_STORY:
70+
expect(a.story).toEqual({});
71+
break;
72+
case LOAD_GEOSTORY_ERROR:
73+
expect(a.error.messageId).toEqual("geostory.errors.loading.geostoryDoesNotExist");
74+
break;
75+
case SHOW_NOTIFICATION:
76+
expect(a.message).toEqual("geostory.errors.loading.geostoryDoesNotExist");
77+
break;
78+
default: expect(true).toBe(false);
79+
break;
80+
}
81+
});
82+
done();
83+
}, {
84+
geostory: {}
85+
});
86+
});
87+
88+
it('loadGeostoryEpic loading a story without permissions for a non logged user', (done) => {
89+
const NUM_ACTIONS = 5;
90+
mockAxios.onGet().reply(403);
91+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("wrongStoryName"), (actions) => {
92+
expect(actions.length).toBe(NUM_ACTIONS);
93+
actions.map((a, i) => {
94+
switch (a.type) {
95+
case LOADING_GEOSTORY:
96+
expect(a.name).toBe("loading");
97+
expect(a.value).toBe(i === 0);
98+
break;
99+
case SET_CURRENT_STORY:
100+
expect(a.story).toEqual({});
101+
break;
102+
case LOAD_GEOSTORY_ERROR:
103+
expect(a.error.messageId).toEqual("geostory.errors.loading.pleaseLogin");
104+
break;
105+
case SHOW_NOTIFICATION:
106+
expect(a.message).toEqual("geostory.errors.loading.pleaseLogin");
107+
break;
108+
default: expect(true).toBe(false);
109+
break;
110+
}
111+
});
112+
done();
113+
}, {
114+
geostory: {}
115+
});
116+
});
117+
it('loadGeostoryEpic loading a story without permissions for a logged user', (done) => {
118+
const NUM_ACTIONS = 5;
119+
mockAxios.onGet().reply(403);
120+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("wrongStoryName"), (actions) => {
121+
expect(actions.length).toBe(NUM_ACTIONS);
122+
actions.map((a, i) => {
123+
switch (a.type) {
124+
case LOADING_GEOSTORY:
125+
expect(a.name).toBe("loading");
126+
expect(a.value).toBe(i === 0);
127+
break;
128+
case SET_CURRENT_STORY:
129+
expect(a.story).toEqual({});
130+
break;
131+
case LOAD_GEOSTORY_ERROR:
132+
expect(a.error.messageId).toEqual("geostory.errors.loading.geostoryNotAccessible");
133+
break;
134+
case SHOW_NOTIFICATION:
135+
expect(a.message).toEqual("geostory.errors.loading.geostoryNotAccessible");
136+
break;
137+
default: expect(true).toBe(false);
138+
break;
139+
}
140+
});
141+
done();
142+
}, {
143+
geostory: {},
144+
security: {
145+
user: {
146+
name: "Nina"
147+
}
148+
}
149+
});
150+
});
151+
it('loadGeostoryEpic loading a story with unknownError', (done) => {
152+
const NUM_ACTIONS = 5;
153+
mockAxios.onGet().reply(500);
154+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("wrongStoryName"), (actions) => {
155+
expect(actions.length).toBe(NUM_ACTIONS);
156+
actions.map((a, i) => {
157+
switch (a.type) {
158+
case LOADING_GEOSTORY:
159+
expect(a.name).toBe("loading");
160+
expect(a.value).toBe(i === 0);
161+
break;
162+
case SET_CURRENT_STORY:
163+
expect(a.story).toEqual({});
164+
break;
165+
case LOAD_GEOSTORY_ERROR:
166+
expect(a.error.messageId).toEqual("geostory.errors.loading.unknownError");
167+
break;
168+
case SHOW_NOTIFICATION:
169+
expect(a.message).toEqual("geostory.errors.loading.unknownError");
170+
break;
171+
default: expect(true).toBe(false);
172+
break;
173+
}
174+
});
175+
done();
176+
}, {
177+
geostory: {}
178+
});
179+
});
180+
it.skip('loadGeostoryEpic loading a story with malformed json configuration', (done) => {
181+
const NUM_ACTIONS = 5;
182+
mockAxios.onGet().reply(200, `{"description":"Sample story with 1 paragraph and 1 immersive section, two columns","type":"cascade","sections":[{"type":"paragraph","id":"SomeID","title":"Abstract","contents":[{"id":"SomeID","type":'text',"background":{},"html":"<p>this is some html content</p>"}]}]}`);
183+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("StoryWithError"), (actions) => {
184+
expect(actions.length).toBe(NUM_ACTIONS);
185+
actions.map((a, i) => {
186+
switch (a.type) {
187+
case LOADING_GEOSTORY:
188+
expect(a.name).toBe("loading");
189+
expect(a.value).toBe(i === 0);
190+
break;
191+
case SET_CURRENT_STORY:
192+
expect(a.story).toEqual({});
193+
break;
194+
case LOAD_GEOSTORY_ERROR:
195+
expect(a.error.messageId).toEqual("Unexpected token \' in JSON at position 200");
196+
break;
197+
case SHOW_NOTIFICATION:
198+
expect(a.message).toEqual("Unexpected token \' in JSON at position 200");
199+
break;
200+
default: expect(true).toBe(false);
201+
break;
202+
}
203+
});
204+
done();
205+
}, {
206+
geostory: {}
207+
});
208+
});
209+
it('loadGeostoryEpic loading a bad story format', (done) => {
210+
const NUM_ACTIONS = 3;
211+
mockAxios.onGet().reply(200, false);
212+
testEpic(loadGeostoryEpic, NUM_ACTIONS, loadGeostory("wrongStoryName"), (actions) => {
213+
expect(actions.length).toBe(NUM_ACTIONS);
214+
actions.map((a, i) => {
215+
switch (a.type) {
216+
case LOADING_GEOSTORY:
217+
expect(a.name).toBe("loading");
218+
expect(a.value).toBe(i === 0);
219+
break;
220+
case SET_CURRENT_STORY:
221+
expect(a.story).toEqual({});
222+
break;
223+
default: expect(true).toBe(false);
224+
break;
225+
}
226+
});
227+
done();
228+
}, {
229+
geostory: {}
230+
});
231+
});
232+
});

0 commit comments

Comments
 (0)