Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancing User Session #10657 #10712

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
13 changes: 11 additions & 2 deletions web/client/actions/__tests__/usersession-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {SAVE_USER_SESSION, USER_SESSION_SAVED, LOAD_USER_SESSION, USER_SESSION_L
REMOVE_USER_SESSION, USER_SESSION_REMOVED, SAVE_MAP_CONFIG, USER_SESSION_START_SAVING, USER_SESSION_STOP_SAVING,
SET_USER_SESSION,
saveUserSession, userSessionSaved, loadUserSession, userSessionLoaded, loading, setUserSession,
removeUserSession, userSessionRemoved, saveMapConfig, userSessionStartSaving, userSessionStopSaving} from "../usersession";
removeUserSession, userSessionRemoved, saveMapConfig, userSessionStartSaving, userSessionStopSaving,
setCheckedSessionToClear,
SET_CHECKED_SESSION_TO_CLEAR} from "../usersession";

describe('Test correctness of the usersession actions', () => {

Expand Down Expand Up @@ -51,8 +53,9 @@ describe('Test correctness of the usersession actions', () => {
expect(action.type).toBe(REMOVE_USER_SESSION);
});
it('user session removed', () => {
const action = userSessionRemoved();
const action = userSessionRemoved({map: { zoom: 20}});
expect(action.type).toBe(USER_SESSION_REMOVED);
expect(action.newSession).toExist();
});
it('user session start saving', () => {
const action = userSessionStartSaving();
Expand All @@ -75,4 +78,10 @@ describe('Test correctness of the usersession actions', () => {
expect(action.type).toBe(SAVE_MAP_CONFIG);
expect(action.config).toExist();
});
it("set Checked session to remove", () => {
const action = setCheckedSessionToClear(["map_pos"]);
expect(action.type).toBe(SET_CHECKED_SESSION_TO_CLEAR);
expect(action.checks).toExist();
expect(action.checks.length).toBe(1);
});
});
6 changes: 5 additions & 1 deletion web/client/actions/usersession.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@ export const USER_SESSION_START_SAVING = "USER_SESSION:START_SAVING";
export const USER_SESSION_STOP_SAVING = "USER_SESSION:STOP_SAVING";
export const SET_USER_SESSION = "USER_SESSION:SET";
export const ENABLE_AUTO_SAVE = "USER_SESSION:ENABLE_AUTO_SAVE";
export const SET_CHECKED_SESSION_TO_CLEAR = "USER_SESSION:SET_CHECKED_SESSION_TO_CLEAR";
export const CLEAR_SESSION_IF_PLUGIN_MISSING = "USER_SESSION:CLEAR_SESSION_IF_PLUGIN_MISSING";

export const saveUserSession = () => ({type: SAVE_USER_SESSION});
export const userSessionSaved = (id, session) => ({type: USER_SESSION_SAVED, id, session});
export const loadUserSession = (name = "") => ({type: LOAD_USER_SESSION, name});
export const userSessionLoaded = (id, session) => ({type: USER_SESSION_LOADED, id, session});
export const removeUserSession = () => ({type: REMOVE_USER_SESSION});
export const userSessionRemoved = () => ({type: USER_SESSION_REMOVED});
export const userSessionRemoved = (newSession) => ({type: USER_SESSION_REMOVED, newSession});
export const userSessionStartSaving = () => ({type: USER_SESSION_START_SAVING});
export const userSessionStopSaving = () => ({type: USER_SESSION_STOP_SAVING});
export const saveMapConfig = (config) => ({type: SAVE_MAP_CONFIG, config});
export const setUserSession = (session) => ({type: SET_USER_SESSION, session});
export const setCheckedSessionToClear = (checks) => ({type: SET_CHECKED_SESSION_TO_CLEAR, checks});
export const clearSessionIfPluginMissing = (id, currentSession) => ({type: CLEAR_SESSION_IF_PLUGIN_MISSING, id, currentSession});
/**
* Action to enable/disable the auto-save functionality.
* @param {boolean} enabled flag to enable/disable the auto-save for session
Expand Down
201 changes: 195 additions & 6 deletions web/client/epics/__tests__/usersession-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
* LICENSE file in the root directory of this source tree.
*/
import { testEpic } from './epicTestUtils';
import { saveUserSessionEpicCreator, autoSaveSessionEpicCreator, loadUserSessionEpicCreator, removeUserSessionEpicCreator } from "../usersession";
import { saveUserSessionEpicCreator, autoSaveSessionEpicCreator, loadUserSessionEpicCreator, removeUserSessionEpicCreator, clearSessionIfPluginMissingEpic } from "../usersession";
import { saveUserSession, loadUserSession,
USER_SESSION_SAVED, USER_SESSION_LOADING, SAVE_USER_SESSION, USER_SESSION_LOADED, USER_SESSION_REMOVED, userSessionStartSaving, userSessionStopSaving, removeUserSession
USER_SESSION_SAVED, USER_SESSION_LOADING, SAVE_USER_SESSION, USER_SESSION_LOADED, USER_SESSION_REMOVED, userSessionStartSaving, userSessionStopSaving, removeUserSession, clearSessionIfPluginMissing
} from "../../actions/usersession";
import { CLOSE_FEATURE_GRID } from '../../actions/featuregrid';
import { TEXT_SEARCH_RESET } from '../../actions/search';
import expect from "expect";
import {Providers} from "../../api/usersession";
import {Observable} from "rxjs";
import ConfigUtils from "../../utils/ConfigUtils";
import { LOAD_MAP_CONFIG } from '../../actions/config';

describe('usersession Epics', () => {
const initialState = {
Expand Down Expand Up @@ -124,16 +125,204 @@ describe('usersession Epics', () => {
testEpic(removeUserSessionEpicCreator(idSelector), 6, removeUserSession(), (actions) => {
expect(actions[0].type).toBe(USER_SESSION_LOADING);
expect(actions[1].type).toBe(USER_SESSION_REMOVED);
expect(actions[1].id).toBeFalsy();
expect(actions[1].session).toBeFalsy();
}, initialState, done);
expect(actions[1].newSession).toBeTruthy();
}, {...initialState,
map: {
present: {
center: {
x: -71.88845339541245,
y: 37.25911173702324,
crs: 'EPSG:4326'
},
maxExtent: [
-20037508.34,
-20037508.34,
20037508.34,
20037508.34
]
}
}
}, done);
});

it("user Session Update on Partial Session Remove - Background Layers", (done) => {
const states = {
...initialState,
map: {
present: {
center: {
x: 118.91601562499996,
y: 42.617791432823395,
crs: 'EPSG:4326'
},
zoom: 16
}
},
layers: [{id: "layer1", group: 'background'}, {id: "layer2"}, {id: "layer3]"}],
toc: {test: false},
usersession: {
checkedSessionToClear: ['background_layers'],
config: {
map: {
layers: []
}
}
}
};

// remove background layers
testEpic(removeUserSessionEpicCreator(idSelector), 6, removeUserSession(), (actions) => {
// only background layers are removed
expect(actions[1].newSession.map.zoom).toBe(16);
expect(actions[1].newSession.map.center).toEqual({
x: 118.91601562499996,
y: 42.617791432823395,
crs: 'EPSG:4326'
});
expect(actions[1].newSession.map.layers.some(l => l.group === 'background')).toBe(false);
}, states, done);
});

it("user Session Update on Partial Session Remove - Annotation Layers", (done) => {
const states = {
...initialState,
map: {
present: {
center: {
x: 118.91601562499996,
y: 42.617791432823395,
crs: 'EPSG:4326'
},
zoom: 16
}
},
layers: [{id: "annotations-1", group: 'background'}, {id: "layer2"}, {id: "layer3]"}],
toc: {test: false},
usersession: {
checkedSessionToClear: ['annotations_layer'],
config: {
map: {
layers: [{
id: "annotations-from-original"
}]
}
}
}
};
// remove annotation layers
testEpic(removeUserSessionEpicCreator(idSelector), 6, removeUserSession(), (actions) => {
// removed from session
expect(actions[1].newSession.map.layers.some(l => l.id === 'annotations-1')).toBe(false);
// retrieved from original Config
expect(actions[1].newSession.map.layers.some(l => l.id === 'annotations-from-original')).toBe(true);
}, states, done);
});

it("Check background layers after reset: find background layer of original config after reset", (done) => {
const states = {
...initialState,
map: {
},
layers: [{id: "layer1", group: 'background'}, {id: "layer2"}, {id: "layer3]"}],
toc: {test: false},
usersession: {
checkedSessionToClear: ['background_layers'],
config: {
map: {
layers: [{id: "background_from_original_config", group: 'background'}]
}
}
}
};

// reset background layers
testEpic(removeUserSessionEpicCreator(idSelector), 6, removeUserSession(), (actions) => {
expect(actions[1].newSession.map.layers.some(l => l.id === 'layer1')).toBe(false);
expect(actions[1].newSession.map.layers.some(l => l.id === 'background_from_original_config')).toBe(true);
}, states, done);
});


it("user Session Update on Partial Session Remove - Map Positions", (done) => {
const states = {
...initialState,
map: {
present: {
center: {
x: 118.91601562499996,
y: 42.617791432823395,
crs: 'EPSG:4326'
},
zoom: 16
}
},
layers: [{id: "layer1", group: 'background'}, {id: "layer2"}, {id: "layer3"}],
toc: {test: false},
usersession: {
checkedSessionToClear: ['map_pos'],
config: {
map: {
layers: [],
center: {
"x": 11.26,
"y": 43.77,
"crs": "EPSG:4326"
},
zoom: 12
}
}
}
};
// remove map positions
testEpic(removeUserSessionEpicCreator(idSelector), 6, removeUserSession(), (actions) => {
// console.log(actions[1].newSession, "newSessionTest");
expect(actions[1].newSession.map.center.x).toBe(11.26);
expect(actions[1].newSession.map.center.y).toBe(43.77);
expect(actions[1].newSession.map.zoom).toBe(12);
// check others session is same
expect(actions[1].newSession.map.layers.length).toEqual([3]);

}, states, done);
});


it('CLOSE_FEATURE_GRID and TEXT_SEARCH_RESET actions are triggered', (done) => {
testEpic(removeUserSessionEpicCreator(idSelector), 6, removeUserSession(), (actions) => {
expect(actions[2].type).toBe(CLOSE_FEATURE_GRID);
expect(actions[3].type).toBe(TEXT_SEARCH_RESET);
}, initialState, done);
}, {...initialState, map: {
present: {
center: {
x: -71.88845339541245,
y: 37.25911173702324,
crs: 'EPSG:4326'
},
maxExtent: [
-20037508.34,
-20037508.34,
20037508.34,
20037508.34
]
}
}}, done);
});

it("clearSessionIfPluginMissingEpic: re-update mapConfig with default Config ", (done) => {
testEpic(clearSessionIfPluginMissingEpic, 1, clearSessionIfPluginMissing("sessionId", {dummySession: "yes"} ), (actions) =>{
// after removing session removes session and updates with default config(LOAD_MAP_CONFIG)
expect(actions[0].type).toBe(LOAD_MAP_CONFIG);
expect(actions[0].overrideConfig).toEqual({});
expect(actions[0].config.map.layers.length).toBe(2);
},
{
...initialState,
usersession: {
// this indicates userSession plugin is missing
autoSave: false,
config: {map: {layers: [{id: "1"}, {id: "2"}]}}
}
}, done);

});

});
14 changes: 6 additions & 8 deletions web/client/epics/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { Observable } from 'rxjs';
import axios from '../libs/ajax';
import { get, merge, isNaN, find, head } from 'lodash';
import { get, isNaN, find, head } from 'lodash';
import {
LOAD_NEW_MAP,
LOAD_MAP_CONFIG,
Expand Down Expand Up @@ -48,10 +48,12 @@ import {
import { getSupportedFormat } from '../api/WMS';
import { wrapStartStop } from '../observables/epics';
import { error } from '../actions/notifications';
import { applyOverrides } from '../utils/ConfigUtils';


const prepareMapConfiguration = (data, override, state) => {
const queryParamsMap = getRequestParameterValue('map', state);
let mapConfig = merge({}, data, override);
let mapConfig = applyOverrides(data, override);
mapConfig = {
...mapConfig,
...(queryParamsMap ?? {}),
Expand Down Expand Up @@ -104,7 +106,7 @@ const mapFlowWithOverride = (configName, mapId, config, mapInfo, state, override
const isNumberId = !isNaN(parseFloat(mapId));
return (
config ?
Observable.of({data: merge({}, config, overrideConfig), staticConfig: true}).delay(100) :
Observable.of({data: applyOverrides(config, overrideConfig ), staticConfig: true}).delay(100) :
Observable.defer(() => axios.get(configName)))
.switchMap(response => {
// added !config in order to avoid showing login modal when a new.json mapConfig is used in a public context
Expand Down Expand Up @@ -161,12 +163,8 @@ export const loadMapConfigAndConfigureMap = (action$, store) =>
const userName = userSelector(store.getState())?.name;
return Observable.of(loadUserSession(buildSessionName(null, mapId, userName))).merge(
action$.ofType(USER_SESSION_LOADED).switchMap(({session}) => {
const sessionData = {
...(session?.map && {map: session.map}),
...(session?.featureGrid && {featureGrid: session.featureGrid})
};
return Observable.merge(
mapFlowWithOverride(configName, mapId, config, mapInfo, store.getState(), sessionData),
mapFlowWithOverride(configName, mapId, config, mapInfo, store.getState(), session),
Observable.of(userSessionStartSaving())
);
})
Expand Down
3 changes: 1 addition & 2 deletions web/client/epics/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ const createSessionFlow = (mapId, contextName, resourceCategory, action$, getSta
return Observable.of(loadUserSession(buildSessionName(id, mapId, userName))).merge(
action$.ofType(USER_SESSION_LOADED).take(1).switchMap(({session}) => {
const sessionData = {
...(session?.map && {map: session.map}),
...(session?.featureGrid && {featureGrid: session.featureGrid})
...session
};
const contextSession = session?.context && {
...session.context
Expand Down
7 changes: 5 additions & 2 deletions web/client/epics/maptemplates.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ export const setAllowedTemplatesEpic = (action$, store) => action$
[attr.name]: attr.value
}), {});
};

// Since templates comes from api, override with session attributes
const sessionMapTemplates = store?.getState().usersession?.session?.mapTemplates;
return templates.length > 0
? Observable
.defer(() => Api.searchListByAttributes(makeFilter(), {params: { includeAttributes: true }}, '/resources/search/list'))
Expand All @@ -84,7 +85,9 @@ export const setAllowedTemplatesEpic = (action$, store) => action$
...pick(resource, 'id', 'name', 'description'),
...extractAttributes(resource),
dataLoaded: false,
loading: false
loading: false,
// override properties from userSession if any
...sessionMapTemplates?.find(template => template.id === resource.id)
}));
return Observable.of(setTemplates(newTemplates), setMapTemplatesLoaded(true));
})
Expand Down
Loading