Skip to content

Commit

Permalink
Merge pull request #812 from CruGlobal/MHP-2313-refactor-auth-screens…
Browse files Browse the repository at this point in the history
…-into-flows

MHP-2313: Refactor auth screens into flows
  • Loading branch information
OzzieOrca committed Feb 27, 2019
2 parents e2e2cb8 + 9602a13 commit 8472d9e
Show file tree
Hide file tree
Showing 61 changed files with 2,598 additions and 1,612 deletions.
29 changes: 14 additions & 15 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { store, persistor } from './store';
import './utils/globals';
import LoadingScreen from './containers/LoadingScreen';
import AppWithNavigationState from './AppNavigator';
import { codeLogin } from './actions/auth';
import { codeLogin } from './actions/auth/anonymous';
import {
EXPIRED_ACCESS_TOKEN,
INVALID_ACCESS_TOKEN,
Expand All @@ -29,6 +29,7 @@ import { configureNotificationHandler } from './actions/notifications';
import { PlatformKeyboardAvoidingView } from './components/common';
import { setupFirebaseDynamicLinks } from './actions/deepLink';
import { COLORS } from './theme';
import { navigateToPostAuthScreen } from './actions/auth/auth';

import { PersistGate } from 'redux-persist/integration/react';

Expand Down Expand Up @@ -61,21 +62,19 @@ export default class App extends Component {
const iOSKey = 'org.cru.missionhub.clientIdKey'; // key from the old iOS app
const androidKey = 'account.guest.secret'; // key from the old android app

const getKey = key => {
DefaultPreference.get(key).then(value => {
if (value) {
store
.dispatch(codeLogin(value))
.then(() => {
// If we successfully logged in with the user's guest code, clear it out now
DefaultPreference.clear(key);
})
.catch(() => {
// This happens when there is a problem with the code from the API call
// We don't want to clear out the key here
});
const getKey = async key => {
const value = await DefaultPreference.get(key);
if (value) {
try {
await store.dispatch(codeLogin(value));
// If we successfully logged in with the user's guest code, clear it out now
DefaultPreference.clear(key);
store.dispatch(navigateToPostAuthScreen());
} catch (e) {
// This happens when there is a problem with the code from the API call
// We don't want to clear out the key here
}
});
}
};
if (isAndroid) {
DefaultPreference.setName('com.missionhub.accounts.AccountManager').then(
Expand Down
37 changes: 15 additions & 22 deletions src/AppRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {
import i18next from 'i18next';

import LandingScreen, { LANDING_SCREEN } from './containers/LandingScreen';
import KeyLoginScreen, {
KEY_LOGIN_SCREEN,
} from './containers/Auth/KeyLoginScreen';
import StepsScreen from './containers/StepsScreen';
import PeopleScreen from './containers/PeopleScreen';
import SelectMyStepScreen, {
Expand Down Expand Up @@ -67,15 +64,9 @@ import SearchPeopleFilterScreen, {
import SearchPeopleFilterRefineScreen, {
SEARCH_REFINE_SCREEN,
} from './containers/SearchPeopleFilterRefineScreen';
import UpgradeAccountScreen, {
UPGRADE_ACCOUNT_SCREEN,
} from './containers/Auth/UpgradeAccountScreen';
import NotificationOffScreen, {
NOTIFICATION_OFF_SCREEN,
} from './containers/NotificationOffScreen';
import MFACodeScreen, {
MFA_CODE_SCREEN,
} from './containers/Auth/MFACodeScreen';
import {
ALL_PERSON_TAB_ROUTES,
CONTACT_PERSON_SCREEN,
Expand Down Expand Up @@ -145,6 +136,9 @@ import {
JOIN_BY_CODE_FLOW,
JOIN_BY_CODE_ONBOARDING_FLOW,
COMPLETE_STEP_FLOW,
SIGN_IN_FLOW,
SIGN_UP_FLOW,
CREATE_COMMUNITY_UNAUTHENTICATED_FLOW,
} from './routes/constants';
import {
JoinByCodeFlowNavigator,
Expand All @@ -166,6 +160,12 @@ import {
CompleteStepFlowNavigator,
CompleteStepFlowScreens,
} from './routes/steps/completeStepFlow';
import { SignInFlowScreens, SignInFlowNavigator } from './routes/auth/signIn';
import { SignUpFlowScreens, SignUpFlowNavigator } from './routes/auth/signUp';
import {
CreateCommunityUnauthenticatedFlowNavigator,
CreateCommunityUnauthenticatedFlowScreens,
} from './routes/groups/createCommunityUnauthenticatedFlow';

// Do custom animations between pages
// import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator';
Expand Down Expand Up @@ -277,19 +277,6 @@ const buildPersonScreenRoute = screen =>
);

const screens = {
[UPGRADE_ACCOUNT_SCREEN]: buildTrackedScreen(
UpgradeAccountScreen,
buildTrackingObj('auth', 'auth'),
),
[KEY_LOGIN_SCREEN]: buildTrackedScreen(
KeyLoginScreen,
buildTrackingObj('auth : sign in', 'auth'),
{ gesturesEnabled: true },
),
[MFA_CODE_SCREEN]: buildTrackedScreen(
MFACodeScreen,
buildTrackingObj('auth : verification', 'auth'),
),
[WELCOME_SCREEN]: buildTrackedScreen(
wrapNextScreen(WelcomeScreen, SETUP_SCREEN),
buildTrackingObj('onboarding : welcome', 'onboarding'),
Expand Down Expand Up @@ -438,6 +425,9 @@ const screens = {
),
[ME_COMMUNITY_PERSON_SCREEN]: buildPersonScreenRoute(MeCommunityPersonScreen),
[MAIN_TABS]: MAIN_TABS_SCREEN,
[SIGN_IN_FLOW]: SignInFlowNavigator,
[SIGN_UP_FLOW]: SignUpFlowNavigator,
[CREATE_COMMUNITY_UNAUTHENTICATED_FLOW]: CreateCommunityUnauthenticatedFlowNavigator,
[JOIN_BY_CODE_FLOW]: JoinByCodeFlowNavigator,
[JOIN_BY_CODE_ONBOARDING_FLOW]: JoinByCodeOnboardingFlowNavigator,
[DEEP_LINK_JOIN_COMMUNITY_AUTHENTENTICATED_FLOW]: DeepLinkJoinCommunityAuthenticatedNavigator,
Expand All @@ -455,6 +445,9 @@ export const trackableScreens = {
...DeepLinkJoinCommunityAuthenticatedScreens,
...DeepLinkJoinCommunityUnauthenticatedScreens,
...CompleteStepFlowScreens,
...CreateCommunityUnauthenticatedFlowScreens,
...SignInFlowScreens,
...SignUpFlowScreens,
};

export const MainStackRoutes = createStackNavigator(
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
INVALID_GRANT,
NETWORK_REQUEST_FAILED,
} from '../constants';
import * as auth from '../actions/auth';
import * as auth from '../actions/auth/auth';
import locale from '../i18n/locales/en-US';
import { rollbar } from '../utils/rollbar.config';

Expand Down
49 changes: 0 additions & 49 deletions src/actions/__tests__/__snapshots__/auth.js.snap

This file was deleted.

81 changes: 41 additions & 40 deletions src/actions/__tests__/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ import {
INVALID_GRANT,
UPDATE_TOKEN,
} from '../../constants';
import { mockFnWithParams } from '../../../testUtils';
import * as auth from '../auth';
import * as facebook from '../facebook';
import { refreshAnonymousLogin } from '../auth/anonymous';
import { logout } from '../auth/auth';
import { refreshMissionHubFacebookAccess } from '../auth/facebook';
import { refreshAccessToken } from '../auth/key';

jest.mock('../../api');
jest.mock('../auth/anonymous');
jest.mock('../auth/auth');
jest.mock('../auth/facebook');
jest.mock('../auth/key');

const token = 'alsnjfjwqfpuqfeownposfnjnsaobjfaslkklnsfd';
const refreshToken = 'refresh';
Expand All @@ -35,11 +42,8 @@ const invalidGrantError = { error: INVALID_GRANT };

global.APILOG = jest.fn();

beforeEach(() => expect.assertions(1));

async function test(
state,
obj,
request,
error,
method,
Expand All @@ -49,18 +53,15 @@ async function test(
data,
) {
store = mockStore({ auth: { ...mockAuthState, ...state } });
mockFnWithParams(
API_CALLS,
request.name,
Promise.reject({ apiError: error }),
query,
data,
);
mockFnWithParams(obj, method, apiResult, ...methodParams);
API_CALLS[request.name].mockReturnValue(Promise.reject({ apiError: error }));
method.mockReturnValue(apiResult);

try {
await store.dispatch(callApi(request, query, data));
} catch (e) {
expect(API_CALLS[request.name]).toHaveBeenCalledWith(query, data);
expect(method).toHaveBeenCalledWith(...methodParams);

expect(store.getActions()).toEqual([
{
data,
Expand All @@ -75,10 +76,9 @@ async function test(
it('should refresh key access token if user is logged in with TheKey with expired token', () => {
return test(
{ refreshToken: 'refresh' },
auth,
getMeRequest,
expiredTokenError,
'refreshAccessToken',
refreshAccessToken,
[],
{ type: 'refreshed token' },
accessTokenQuery,
Expand All @@ -88,10 +88,9 @@ it('should refresh key access token if user is logged in with TheKey with expire
it('should refresh key access token if user is logged in with TheKey with invalid token', () => {
return test(
{ refreshToken: 'refresh' },
auth,
getMeRequest,
invalidTokenError,
'refreshAccessToken',
refreshAccessToken,
[],
{ type: 'refreshed token' },
accessTokenQuery,
Expand All @@ -102,10 +101,9 @@ it('should refresh key access token if user is logged in with TheKey with invali
it('should refresh anonymous login if user is Try It Now with expired token', () => {
return test(
{ isFirstTime: true },
auth,
getMeRequest,
expiredTokenError,
'refreshAnonymousLogin',
refreshAnonymousLogin,
[],
{ type: 'refreshed anonymous token' },
accessTokenQuery,
Expand All @@ -115,10 +113,9 @@ it('should refresh anonymous login if user is Try It Now with expired token', ()
it('should refresh anonymous login if user is Try It Now with invalid token', () => {
return test(
{ isFirstTime: true },
auth,
getMeRequest,
invalidTokenError,
'refreshAnonymousLogin',
refreshAnonymousLogin,
[],
{ type: 'refreshed anonymous token' },
accessTokenQuery,
Expand All @@ -129,10 +126,9 @@ it('should refresh anonymous login if user is Try It Now with invalid token', ()
it('should refresh facebook login if user is not logged in with TheKey or Try It Now with expired token', () => {
return test(
{},
facebook,
getMeRequest,
expiredTokenError,
'refreshMissionHubFacebookAccess',
refreshMissionHubFacebookAccess,
[],
{ type: 'refreshed fb login' },
accessTokenQuery,
Expand All @@ -142,10 +138,9 @@ it('should refresh facebook login if user is not logged in with TheKey or Try It
it('should refresh facebook login if user is not logged in with TheKey or Try It Now with invalid token', () => {
return test(
{},
facebook,
getMeRequest,
invalidTokenError,
'refreshMissionHubFacebookAccess',
refreshMissionHubFacebookAccess,
[],
{ type: 'refreshed fb login' },
accessTokenQuery,
Expand All @@ -156,46 +151,52 @@ it('should refresh facebook login if user is not logged in with TheKey or Try It
it('should logout if KEY_REFRESH_TOKEN fails with invalid_grant', () => {
return test(
{ refreshToken: 'refresh' },
auth,
refreshRequest,
invalidGrantError,
'logout',
logout,
[true],
{ type: 'logged out' },
{},
refreshTokenData,
);
});

it("should not logout if invalid_grant is returned and request wasn't KEY_REFRESH_TOKEN", () => {
auth.logout = jest.fn();
it("should not logout if invalid_grant is returned and request wasn't KEY_REFRESH_TOKEN", async () => {
store = mockStore({ auth: { ...mockAuthState } });

mockFnWithParams(
API_CALLS,
getMeRequest.name,
API_CALLS[getMeRequest.name].mockReturnValue(
Promise.reject({ apiError: invalidGrantError }),
);

await expect(store.dispatch(callApi(getMeRequest, {}, {}))).rejects.toEqual({
apiError: {
error: 'invalid_grant',
},
});

expect(API_CALLS[getMeRequest.name]).toHaveBeenCalledWith(
accessTokenQuery,
{},
);

expect(auth.logout).not.toHaveBeenCalled();
expect(logout).not.toHaveBeenCalled();
});

it('should update token if present in response', async () => {
store = mockStore({ auth: { ...mockAuthState } });
const newToken =
'pfiqwfioqwioefiqowfejiqwfipoioqwefpiowqniopnifiooiwfemiopqwoimefimwqefponioqwfenoiwefinonoiwqefnoip';
mockFnWithParams(
API_CALLS,
getMeRequest.name,

API_CALLS[getMeRequest.name].mockReturnValue(
Promise.resolve({ sessionHeader: newToken }),
accessTokenQuery,
{},
);

await store.dispatch(callApi(getMeRequest, {}, {}));

expect(API_CALLS[getMeRequest.name]).toHaveBeenCalledWith(
accessTokenQuery,
{},
);

expect(store.getActions()).toEqual([
{
data: {},
Expand Down

0 comments on commit 8472d9e

Please sign in to comment.