Verified Commit 090e884a authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Rename session actions

parent 8c3dc976
...@@ -3,12 +3,12 @@ import * as actions from '../../app/actions/session'; ...@@ -3,12 +3,12 @@ import * as actions from '../../app/actions/session';
describe('session actions', () => { describe('session actions', () => {
it('should expose the session actions', () => { it('should expose the session actions', () => {
expect(actions.INIT).toEqual('SESSION_INIT'); expect(actions.INIT).toEqual('SESSION_INIT');
expect(actions.SUCCESS).toEqual('SESSION_SUCCESS'); expect(actions.SIGNED_IN).toEqual('SESSION_SUCCESS');
expect(actions.LOGIN).toEqual('SESSION_LOGIN'); expect(actions.SIGN_IN).toEqual('SESSION_LOGIN');
expect(actions.TOKEN_INVALID).toEqual('SESSION_TOKEN_INVALID'); expect(actions.TOKEN_INVALID).toEqual('SESSION_TOKEN_INVALID');
expect(actions.LOGOUT).toEqual('SESSION_LOGOUT'); expect(actions.SIGN_OUT).toEqual('SESSION_LOGOUT');
expect(actions.PROFILE).toEqual('SESSION_PROFILE'); expect(actions.FETCH_USER_INFO).toEqual('SESSION_PROFILE');
expect(actions.PROFILE_SUCCESS).toEqual('SESSION_PROFILE_SUCCESS'); expect(actions.SET_USER_INFO).toEqual('SESSION_PROFILE_SUCCESS');
}); });
it('should create an action to init the session', () => { it('should create an action to init the session', () => {
...@@ -20,15 +20,15 @@ describe('session actions', () => { ...@@ -20,15 +20,15 @@ describe('session actions', () => {
}); });
it('should create an action to log the user in', () => { it('should create an action to log the user in', () => {
expect(actions.login('username', 'password')).toMatchSnapshot(); expect(actions.signIn('username', 'password')).toMatchSnapshot();
}); });
it('should create an action for a successful login', () => { it('should create an action for a successful login', () => {
expect(actions.success('username', 'token')).toMatchSnapshot(); expect(actions.signedIn('username', 'token')).toMatchSnapshot();
}); });
it('should create an action to log the user out', () => { it('should create an action to log the user out', () => {
expect(actions.logout()).toMatchSnapshot(); expect(actions.signOut()).toMatchSnapshot();
}); });
it('should create an action to load the user profile', () => { it('should create an action to load the user profile', () => {
...@@ -36,6 +36,6 @@ describe('session actions', () => { ...@@ -36,6 +36,6 @@ describe('session actions', () => {
}); });
it('should create an action for a successful user profile load', () => { it('should create an action for a successful user profile load', () => {
expect(actions.profileSuccess('displayName', 'photo')).toMatchSnapshot(); expect(actions.userInfoSuccess('displayName', 'photo')).toMatchSnapshot();
}); });
}); });
\ No newline at end of file
...@@ -31,7 +31,7 @@ describe('calendar saga', () => { ...@@ -31,7 +31,7 @@ describe('calendar saga', () => {
[matchers.call.fn(apiRequest), []], [matchers.call.fn(apiRequest), []],
]) ])
.dispatch(deepLinkingActions.deepLink(`${siteURL}/events/1/`)) .dispatch(deepLinkingActions.deepLink(`${siteURL}/events/1/`))
.dispatch(loginActions.success('', '')) .dispatch(loginActions.signedIn('', ''))
.put(eventActions.event('1')) .put(eventActions.event('1'))
.silentRun()); .silentRun());
......
...@@ -6,7 +6,7 @@ import { AsyncStorage } from 'react-native'; ...@@ -6,7 +6,7 @@ import { AsyncStorage } from 'react-native';
import { Sentry } from 'react-native-sentry'; import { Sentry } from 'react-native-sentry';
import sessionSaga, { import sessionSaga, {
DISPLAYNAMEKEY, PHOTOKEY, TOKENKEY, USERNAMEKEY DISPLAYNAMEKEY, PHOTOKEY, TOKENKEY, USERNAMEKEY,
} from '../../app/sagas/session'; } from '../../app/sagas/session';
import { apiRequest } from '../../app/utils/url'; import { apiRequest } from '../../app/utils/url';
import * as sessionActions from '../../app/actions/session'; import * as sessionActions from '../../app/actions/session';
...@@ -42,7 +42,7 @@ describe('session saga', () => { ...@@ -42,7 +42,7 @@ describe('session saga', () => {
describe('logging in', () => { describe('logging in', () => {
it('should show a snackbar on start', () => expectSaga(sessionSaga) it('should show a snackbar on start', () => expectSaga(sessionSaga)
.dispatch(sessionActions.login('username', 'password')) .dispatch(sessionActions.signIn('username', 'password'))
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(Snackbar.show).toBeCalledWith( expect(Snackbar.show).toBeCalledWith(
...@@ -55,9 +55,9 @@ describe('session saga', () => { ...@@ -55,9 +55,9 @@ describe('session saga', () => {
[matchers.call.like({ fn: apiRequest, args: ['token-auth'] }), { token: 'abc123' }], [matchers.call.like({ fn: apiRequest, args: ['token-auth'] }), { token: 'abc123' }],
[matchers.call.like({ fn: Sentry.setUserContext }), {}], [matchers.call.like({ fn: Sentry.setUserContext }), {}],
]) ])
.put(sessionActions.success('username', 'abc123')) .put(sessionActions.signedIn('username', 'abc123'))
.put(sessionActions.profile('abc123')) .put(sessionActions.profile('abc123'))
.dispatch(sessionActions.login('username', 'password')) .dispatch(sessionActions.signIn('username', 'password'))
.silentRun()); .silentRun());
it('should show a snackbar when the request succeeds', () => expectSaga(sessionSaga) it('should show a snackbar when the request succeeds', () => expectSaga(sessionSaga)
...@@ -65,7 +65,7 @@ describe('session saga', () => { ...@@ -65,7 +65,7 @@ describe('session saga', () => {
[matchers.call.like({ fn: apiRequest, args: ['token-auth'] }), { token: 'abc123' }], [matchers.call.like({ fn: apiRequest, args: ['token-auth'] }), { token: 'abc123' }],
[matchers.call.like({ fn: Sentry.setUserContext }), {}], [matchers.call.like({ fn: Sentry.setUserContext }), {}],
]) ])
.dispatch(sessionActions.login('username', 'password')) .dispatch(sessionActions.signIn('username', 'password'))
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(Snackbar.dismiss).toBeCalled(); expect(Snackbar.dismiss).toBeCalled();
...@@ -79,7 +79,7 @@ describe('session saga', () => { ...@@ -79,7 +79,7 @@ describe('session saga', () => {
[matchers.call.like({ fn: apiRequest, args: ['token-auth'] }), { token: 'abc123' }], [matchers.call.like({ fn: apiRequest, args: ['token-auth'] }), { token: 'abc123' }],
[matchers.call.like({ fn: Sentry.setUserContext }), {}], [matchers.call.like({ fn: Sentry.setUserContext }), {}],
]) ])
.dispatch(sessionActions.login('username', 'password')) .dispatch(sessionActions.signIn('username', 'password'))
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(AsyncStorage.multiSet).toBeCalledWith([ expect(AsyncStorage.multiSet).toBeCalledWith([
...@@ -92,7 +92,7 @@ describe('session saga', () => { ...@@ -92,7 +92,7 @@ describe('session saga', () => {
.provide([ .provide([
[matchers.call.fn(apiRequest), throwError(error)], [matchers.call.fn(apiRequest), throwError(error)],
]) ])
.dispatch(sessionActions.login('username', 'password')) .dispatch(sessionActions.signIn('username', 'password'))
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(Snackbar.dismiss).toBeCalled(); expect(Snackbar.dismiss).toBeCalled();
...@@ -102,7 +102,7 @@ describe('session saga', () => { ...@@ -102,7 +102,7 @@ describe('session saga', () => {
})); }));
it('should do a POST request', () => expectSaga(sessionSaga) it('should do a POST request', () => expectSaga(sessionSaga)
.dispatch(sessionActions.login('username', 'password')) .dispatch(sessionActions.signIn('username', 'password'))
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(apiRequest).toBeCalledWith('token-auth', { expect(apiRequest).toBeCalledWith('token-auth', {
...@@ -118,7 +118,7 @@ describe('session saga', () => { ...@@ -118,7 +118,7 @@ describe('session saga', () => {
describe('logging out', () => { describe('logging out', () => {
it('should remove the token from the AsyncStorage', () => expectSaga(sessionSaga) it('should remove the token from the AsyncStorage', () => expectSaga(sessionSaga)
.dispatch(sessionActions.logout()) .dispatch(sessionActions.signOut())
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(AsyncStorage.multiRemove).toBeCalledWith([USERNAMEKEY, TOKENKEY]); expect(AsyncStorage.multiRemove).toBeCalledWith([USERNAMEKEY, TOKENKEY]);
...@@ -126,11 +126,11 @@ describe('session saga', () => { ...@@ -126,11 +126,11 @@ describe('session saga', () => {
it('should put a push notification invalidation action', () => expectSaga(sessionSaga) it('should put a push notification invalidation action', () => expectSaga(sessionSaga)
.put(pushNotificationsActions.invalidate()) .put(pushNotificationsActions.invalidate())
.dispatch(sessionActions.logout()) .dispatch(sessionActions.signOut())
.silentRun()); .silentRun());
it('should remove the token from the AsyncStorage', () => expectSaga(sessionSaga) it('should remove the token from the AsyncStorage', () => expectSaga(sessionSaga)
.dispatch(sessionActions.logout()) .dispatch(sessionActions.signOut())
.silentRun() .silentRun()
.then(() => { .then(() => {
expect(Snackbar.show).toBeCalledWith( expect(Snackbar.show).toBeCalledWith(
...@@ -149,7 +149,7 @@ describe('session saga', () => { ...@@ -149,7 +149,7 @@ describe('session saga', () => {
}, },
}], }],
]) ])
.put(sessionActions.profileSuccess('Johnny Test', 'http://example.org/photo.png')) .put(sessionActions.userInfoSuccess('Johnny Test', 'http://example.org/photo.png'))
.dispatch(sessionActions.profile('abc123')) .dispatch(sessionActions.profile('abc123'))
.silentRun()); .silentRun());
......
export const LOGIN = 'SESSION_LOGIN';
export const INIT = 'SESSION_INIT'; export const INIT = 'SESSION_INIT';
export const SUCCESS = 'SESSION_SUCCESS'; export const SIGN_IN = 'SESSION_SIGN_IN';
export const LOGOUT = 'SESSION_LOGOUT'; export const SIGNED_IN = 'SESSION_SIGNED_IN';
export const SIGN_OUT = 'SESSION_SIGN_OUT';
export const TOKEN_INVALID = 'SESSION_TOKEN_INVALID'; export const TOKEN_INVALID = 'SESSION_TOKEN_INVALID';
export const PROFILE = 'SESSION_PROFILE'; export const FETCH_USER_INFO = 'SESSION_FETCH_USER_INFO';
export const PROFILE_SUCCESS = 'SESSION_PROFILE_SUCCESS'; export const SET_USER_INFO = 'SESSION_SET_USER_INFO';
export function success(username, token) { export function init() {
return { type: SUCCESS, payload: { username, token } }; return { type: INIT };
} }
export function login(user, pass) { export function signIn(user, pass) {
return { type: LOGIN, payload: { user, pass } }; return { type: SIGN_IN, payload: { user, pass } };
} }
export function init() { export function signOut() {
return { type: INIT }; return { type: SIGN_OUT };
} }
export function logout() { export function signedIn(username, token) {
return { type: LOGOUT }; return { type: SIGNED_IN, payload: { username, token } };
} }
export function tokenInvalid() { export function tokenInvalid() {
return { type: TOKEN_INVALID }; return { type: TOKEN_INVALID };
} }
export function profile(token) { export function fetchUserInfo(token) {
return { type: PROFILE, payload: { token } }; return { type: FETCH_USER_INFO, payload: { token } };
} }
export function profileSuccess(displayName, photo) { export function setUserInfo(displayName, photo) {
return { type: PROFILE_SUCCESS, payload: { displayName, photo } }; return { type: SET_USER_INFO, payload: { displayName, photo } };
} }
...@@ -13,7 +13,7 @@ const initialState = { ...@@ -13,7 +13,7 @@ const initialState = {
export default function navigate(state = initialState, action = {}) { export default function navigate(state = initialState, action = {}) {
const { currentScene, previousScenes, drawerOpen } = state; const { currentScene, previousScenes, drawerOpen } = state;
switch (action.type) { switch (action.type) {
case sessionActions.SUCCESS: { case sessionActions.SIGNED_IN: {
return { return {
...state, ...state,
loggedIn: true, loggedIn: true,
...@@ -64,7 +64,7 @@ export default function navigate(state = initialState, action = {}) { ...@@ -64,7 +64,7 @@ export default function navigate(state = initialState, action = {}) {
}; };
} }
case sessionActions.TOKEN_INVALID: case sessionActions.TOKEN_INVALID:
case sessionActions.LOGOUT: { case sessionActions.SIGN_OUT: {
return { return {
...initialState, ...initialState,
currentScene: LOGIN_SCENE, currentScene: LOGIN_SCENE,
......
...@@ -11,20 +11,20 @@ const initialState = { ...@@ -11,20 +11,20 @@ const initialState = {
export default function session(state = initialState, action = {}) { export default function session(state = initialState, action = {}) {
switch (action.type) { switch (action.type) {
case sessionActions.SUCCESS: case sessionActions.SIGNED_IN:
return { return {
...state, ...state,
username: action.payload.username, username: action.payload.username,
token: action.payload.token, token: action.payload.token,
}; };
case sessionActions.PROFILE_SUCCESS: case sessionActions.SET_USER_INFO:
return { return {
...state, ...state,
displayName: action.payload.displayName, displayName: action.payload.displayName,
photo: action.payload.photo, photo: action.payload.photo,
}; };
case sessionActions.TOKEN_INVALID: case sessionActions.TOKEN_INVALID:
case sessionActions.LOGOUT: case sessionActions.SIGN_OUT:
return initialState; return initialState;
default: default:
return state; return state;
......
...@@ -44,7 +44,7 @@ const deepLink = function* deepLink(action) { ...@@ -44,7 +44,7 @@ const deepLink = function* deepLink(action) {
const loggedIn = yield select(loggedInSelector); const loggedIn = yield select(loggedInSelector);
if (!loggedIn) { if (!loggedIn) {
yield take(loginActions.SUCCESS); yield take(loginActions.SIGNED_IN);
} }
const patterns = [ const patterns = [
......
import { call, put, takeEvery } from 'redux-saga/effects'; import {
call, put, takeEvery, select,
} from 'redux-saga/effects';
import { AsyncStorage } from 'react-native'; import { AsyncStorage } from 'react-native';
import Snackbar from 'react-native-snackbar'; import Snackbar from 'react-native-snackbar';
import { Sentry } from 'react-native-sentry'; import { Sentry } from 'react-native-sentry';
import { apiRequest } from '../utils/url'; import { apiRequest, tokenSelector } from '../utils/url';
import * as sessionActions from '../actions/session'; import * as sessionActions from '../actions/session';
import * as pushNotificationsActions from '../actions/pushNotifications'; import * as pushNotificationsActions from '../actions/pushNotifications';
import { navigate } from '../actions/navigation'; import { navigate } from '../actions/navigation';
...@@ -37,9 +39,9 @@ function* init() { ...@@ -37,9 +39,9 @@ function* init() {
const pushCategories = JSON.parse(values[PUSHCATEGORYKEY]); const pushCategories = JSON.parse(values[PUSHCATEGORYKEY]);
if (username !== null && token !== null) { if (username !== null && token !== null) {
yield put(sessionActions.success(username, token)); yield put(sessionActions.signedIn(username, token));
yield put(sessionActions.profileSuccess(displayName, photo)); yield put(sessionActions.setUserInfo(displayName, photo));
yield put(sessionActions.profile(token)); yield put(sessionActions.fetchUserInfo());
yield put(pushNotificationsActions.register(pushCategories)); yield put(pushNotificationsActions.register(pushCategories));
} else { } else {
yield put(navigate(LOGIN_SCENE, true)); yield put(navigate(LOGIN_SCENE, true));
...@@ -49,7 +51,7 @@ function* init() { ...@@ -49,7 +51,7 @@ function* init() {
} }
} }
function* login(action) { function* signIn(action) {
const { user, pass } = action.payload; const { user, pass } = action.payload;
Snackbar.show({ title: 'Logging in', duration: Snackbar.LENGTH_INDEFINITE }); Snackbar.show({ title: 'Logging in', duration: Snackbar.LENGTH_INDEFINITE });
...@@ -73,30 +75,32 @@ function* login(action) { ...@@ -73,30 +75,32 @@ function* login(action) {
[USERNAMEKEY, user], [USERNAMEKEY, user],
[TOKENKEY, token], [TOKENKEY, token],
]); ]);
yield put(sessionActions.success(user, token)); yield put(sessionActions.signedIn(user, token));
yield put(sessionActions.profile(token)); yield put(sessionActions.fetchUserInfo());
yield put(pushNotificationsActions.register()); yield put(pushNotificationsActions.register());
Snackbar.dismiss(); Snackbar.dismiss();
Snackbar.show({ title: 'Login successful' }); Snackbar.show({ title: 'Login successful' });
} catch (error) { } catch (e) {
Sentry.captureException(e);
Snackbar.dismiss(); Snackbar.dismiss();
Snackbar.show({ title: 'Login failed' }); Snackbar.show({ title: 'Login failed' });
} }
} }
function* logout() { function* signOut() {
yield call(AsyncStorage.multiRemove, [USERNAMEKEY, TOKENKEY]); yield call(AsyncStorage.clear);
yield put(pushNotificationsActions.invalidate()); yield put(pushNotificationsActions.invalidate());
Snackbar.show({ title: 'Logout successful' }); Snackbar.show({ title: 'Logout successful' });
} }
function* tokenInvalid() { function* signedIn({ payload }) {
yield call(AsyncStorage.clear); const { username } = payload;
yield put(pushNotificationsActions.invalidate()); yield put(navigate(WELCOME_SCENE, true));
yield call(Sentry.setUserContext, { username });
} }
function* profile(action) { function* userInfo() {
const { token } = action.payload; const token = yield select(tokenSelector);
const data = { const data = {
method: 'GET', method: 'GET',
...@@ -114,25 +118,24 @@ function* profile(action) { ...@@ -114,25 +118,24 @@ function* profile(action) {
[DISPLAYNAMEKEY, userProfile.display_name], [DISPLAYNAMEKEY, userProfile.display_name],
[PHOTOKEY, userProfile.avatar.medium], [PHOTOKEY, userProfile.avatar.medium],
]); ]);
yield put(sessionActions.profileSuccess(userProfile.display_name, userProfile.avatar.medium)); yield put(sessionActions.setUserInfo(userProfile.display_name, userProfile.avatar.medium));
} catch (error) { } catch (error) {
Sentry.captureException(error); Sentry.captureException(error);
} }
} }
function* success({ payload }) { function* tokenInvalid() {
const { username } = payload; yield call(AsyncStorage.clear);
yield put(navigate(WELCOME_SCENE, true)); yield put(pushNotificationsActions.invalidate());
yield call(Sentry.setUserContext, { username });
} }
const sessionSaga = function* sessionSaga() { const sessionSaga = function* sessionSaga() {
yield takeEvery(sessionActions.INIT, init); yield takeEvery(sessionActions.INIT, init);
yield takeEvery(sessionActions.LOGIN, login); yield takeEvery(sessionActions.SIGN_IN, signIn);
yield takeEvery(sessionActions.LOGOUT, logout); yield takeEvery(sessionActions.SIGN_OUT, signOut);
yield takeEvery(sessionActions.PROFILE, profile); yield takeEvery(sessionActions.SIGNED_IN, signedIn);
yield takeEvery(sessionActions.FETCH_USER_INFO, userInfo);
yield takeEvery(sessionActions.TOKEN_INVALID, tokenInvalid); yield takeEvery(sessionActions.TOKEN_INVALID, tokenInvalid);
yield takeEvery(sessionActions.SUCCESS, success);
}; };
export default sessionSaga; export default sessionSaga;
...@@ -65,7 +65,7 @@ const Sidebar = (props) => { ...@@ -65,7 +65,7 @@ const Sidebar = (props) => {
borderTopColor: Colors.lightGray, borderTopColor: Colors.lightGray,
borderTopWidth: 1, borderTopWidth: 1,
}, },
scene: 'logout', scene: 'signOut',
}, },
]; ];
...@@ -137,7 +137,7 @@ const mapStateToProps = state => ({ ...@@ -137,7 +137,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
navigate: (scene, newSection = false) => dispatch(navigationActions.navigate(scene, newSection)), navigate: (scene, newSection = false) => dispatch(navigationActions.navigate(scene, newSection)),
logout: () => dispatch(loginActions.logout()), logout: () => dispatch(loginActions.signOut()),
loadProfile: token => dispatch(profileActions.profile(token)), loadProfile: token => dispatch(profileActions.profile(token)),
}); });
......
...@@ -88,7 +88,7 @@ const mapStateToProps = state => state.session; ...@@ -88,7 +88,7 @@ const mapStateToProps = state => state.session;
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
login: (username, password) => { login: (username, password) => {
Keyboard.dismiss(); Keyboard.dismiss();
dispatch(actions.login(username, password)); dispatch(actions.signIn(username, password));
}, },
}); });
......
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