Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
thalia
ThaliApp
Commits
b0d86886
Commit
b0d86886
authored
Aug 29, 2018
by
Gijs Hendriksen
Browse files
Merge branch 'tc/introduce-session-saga' into 'master'
Introduce session saga See merge request
!185
parents
8747421c
34de57b1
Changes
29
Hide whitespace changes
Inline
Side-by-side
__tests__/actions/__snapshots__/
logi
n.spec.js.snap
→
__tests__/actions/__snapshots__/
sessio
n.spec.js.snap
View file @
b0d86886
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`
logi
n actions should create an action for a successful login 1`] = `
exports[`
sessio
n actions should create an action for a successful login 1`] = `
Object {
"payload": Object {
"token": "token",
"username": "username",
},
"type": "
LOGI
N_SUCCESS",
"type": "
SESSIO
N_SUCCESS",
}
`;
exports[`
logi
n actions should create an action for a successful user profile load 1`] = `
exports[`
sessio
n actions should create an action for a successful user profile load 1`] = `
Object {
"payload": Object {
"displayName": "displayName",
"photo": "photo",
},
"type": "
LOGI
N_PROFILE_SUCCESS",
"type": "
SESSIO
N_PROFILE_SUCCESS",
}
`;
exports[`login actions should create an action to load the user profile 1`] = `
exports[`session actions should create an action to init the session 1`] = `
Object {
"type": "SESSION_INIT",
}
`;
exports[`session actions should create an action to load the user profile 1`] = `
Object {
"payload": Object {
"token": "token",
},
"type": "
LOGI
N_PROFILE",
"type": "
SESSIO
N_PROFILE",
}
`;
exports[`
logi
n actions should create an action to log the user in 1`] = `
exports[`
sessio
n actions should create an action to log the user in 1`] = `
Object {
"payload": Object {
"pass": "password",
"user": "username",
},
"type": "LOGIN_LOGIN",
"type": "SESSION_LOGIN",
}
`;
exports[`session actions should create an action to log the user out 1`] = `
Object {
"type": "SESSION_LOGOUT",
}
`;
exports[`
logi
n actions should create an action to
log the user out
1`] = `
exports[`
sessio
n actions should create an action to
notify invalid token
1`] = `
Object {
"type": "
LOGIN_LOGOUT
",
"type": "
SESSION_TOKEN_INVALID
",
}
`;
__tests__/actions/
logi
n.spec.js
→
__tests__/actions/
sessio
n.spec.js
View file @
b0d86886
import
*
as
actions
from
'
../../app/actions/login
'
;
describe
(
'
login actions
'
,
()
=>
{
it
(
'
should expose the login actions
'
,
()
=>
{
expect
(
actions
.
SUCCESS
).
toEqual
(
'
LOGIN_SUCCESS
'
);
expect
(
actions
.
LOGIN
).
toEqual
(
'
LOGIN_LOGIN
'
);
expect
(
actions
.
LOGOUT
).
toEqual
(
'
LOGIN_LOGOUT
'
);
expect
(
actions
.
PROFILE
).
toEqual
(
'
LOGIN_PROFILE
'
);
expect
(
actions
.
PROFILE_SUCCESS
).
toEqual
(
'
LOGIN_PROFILE_SUCCESS
'
);
import
*
as
actions
from
'
../../app/actions/session
'
;
describe
(
'
session actions
'
,
()
=>
{
it
(
'
should expose the session actions
'
,
()
=>
{
expect
(
actions
.
INIT
).
toEqual
(
'
SESSION_INIT
'
);
expect
(
actions
.
SUCCESS
).
toEqual
(
'
SESSION_SUCCESS
'
);
expect
(
actions
.
LOGIN
).
toEqual
(
'
SESSION_LOGIN
'
);
expect
(
actions
.
TOKEN_INVALID
).
toEqual
(
'
SESSION_TOKEN_INVALID
'
);
expect
(
actions
.
LOGOUT
).
toEqual
(
'
SESSION_LOGOUT
'
);
expect
(
actions
.
PROFILE
).
toEqual
(
'
SESSION_PROFILE
'
);
expect
(
actions
.
PROFILE_SUCCESS
).
toEqual
(
'
SESSION_PROFILE_SUCCESS
'
);
});
it
(
'
should create an action to init the session
'
,
()
=>
{
expect
(
actions
.
init
()).
toMatchSnapshot
();
});
it
(
'
should create an action to notify invalid token
'
,
()
=>
{
expect
(
actions
.
tokenInvalid
()).
toMatchSnapshot
();
});
it
(
'
should create an action to log the user in
'
,
()
=>
{
...
...
__tests__/sagas/calendar.spec.js
View file @
b0d86886
...
...
@@ -8,6 +8,7 @@ import calendarSaga from '../../app/sagas/calendar';
import
*
as
calendarActions
from
'
../../app/actions/calendar
'
;
import
*
as
navActions
from
'
../../app/actions/navigation
'
;
import
{
EVENT_LIST_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
jest
.
mock
(
'
../../app/utils/url
'
,
()
=>
({
apiRequest
:
jest
.
fn
(()
=>
{}),
...
...
@@ -31,7 +32,7 @@ describe('calendar saga', () => {
[
select
(
tokenSelector
),
'
token
'
],
[
matchers
.
call
.
fn
(
apiRequest
),
[]],
])
.
dispatch
(
navActions
.
navigate
(
'
eventList
'
))
.
dispatch
(
navActions
.
navigate
(
EVENT_LIST_SCENE
))
.
put
(
calendarActions
.
fetching
())
.
silentRun
());
...
...
__tests__/sagas/deepLinking.spec.js
View file @
b0d86886
...
...
@@ -6,8 +6,9 @@ import * as deepLinkingActions from '../../app/actions/deepLinking';
import
{
url
as
siteURL
,
apiRequest
,
loggedInSelector
}
from
'
../../app/utils/url
'
;
import
*
as
navigationActions
from
'
../../app/actions/navigation
'
;
import
*
as
eventActions
from
'
../../app/actions/event
'
;
import
*
as
loginActions
from
'
../../app/actions/
logi
n
'
;
import
*
as
loginActions
from
'
../../app/actions/
sessio
n
'
;
import
*
as
pizzaActions
from
'
../../app/actions/pizza
'
;
import
{
EVENT_LIST_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
describe
(
'
calendar saga
'
,
()
=>
{
it
(
'
should parse a URL correctly
'
,
()
=>
{
...
...
@@ -40,7 +41,7 @@ describe('calendar saga', () => {
[
matchers
.
call
.
fn
(
apiRequest
),
[]],
])
.
dispatch
(
deepLinkingActions
.
deepLink
(
`
${
siteURL
}
/events/`
))
.
put
(
navigationActions
.
navigate
(
'
eventList
'
))
.
put
(
navigationActions
.
navigate
(
EVENT_LIST_SCENE
))
.
silentRun
());
it
(
'
shouldl load event on /events/{id} deeplink
'
,
()
=>
expectSaga
(
deepLinkingSaga
)
...
...
__tests__/sagas/event.spec.js
View file @
b0d86886
...
...
@@ -8,6 +8,7 @@ import eventSaga from '../../app/sagas/event';
import
*
as
eventActions
from
'
../../app/actions/event
'
;
import
*
as
navActions
from
'
../../app/actions/navigation
'
;
import
{
EVENT_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
jest
.
mock
(
'
../../app/utils/url
'
,
()
=>
({
apiRequest
:
jest
.
fn
(()
=>
{}),
...
...
@@ -18,13 +19,13 @@ describe('event saga', () => {
const
error
=
new
Error
(
'
error
'
);
it
(
'
should start fetching
'
,
()
=>
expectSaga
(
eventSaga
)
.
provide
([
[
select
(
tokenSelector
),
'
token
'
],
[
matchers
.
call
.
fn
(
apiRequest
),
[]],
])
.
dispatch
(
eventActions
.
event
(
1
))
.
put
(
eventActions
.
fetching
())
.
silentRun
());
.
provide
([
[
select
(
tokenSelector
),
'
token
'
],
[
matchers
.
call
.
fn
(
apiRequest
),
[]],
])
.
dispatch
(
eventActions
.
event
(
1
))
.
put
(
eventActions
.
fetching
())
.
silentRun
());
it
(
'
should navigate to the event scene
'
,
()
=>
expectSaga
(
eventSaga
)
.
provide
([
...
...
@@ -32,7 +33,7 @@ describe('event saga', () => {
[
matchers
.
call
.
fn
(
apiRequest
),
[]],
])
.
dispatch
(
eventActions
.
event
(
1
))
.
put
(
navActions
.
navigate
(
'
event
'
))
.
put
(
navActions
.
navigate
(
EVENT_SCENE
))
.
silentRun
());
it
(
'
should put an error when the api request fails
'
,
()
=>
expectSaga
(
eventSaga
)
...
...
__tests__/sagas/pizza.spec.js
View file @
b0d86886
...
...
@@ -6,6 +6,7 @@ import { apiRequest, tokenSelector } from '../../app/utils/url';
import
pizzaSaga
from
'
../../app/sagas/pizza
'
;
import
*
as
pizzaActions
from
'
../../app/actions/pizza
'
;
import
*
as
navigationActions
from
'
../../app/actions/navigation
'
;
import
{
PIZZA_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
jest
.
mock
(
'
../../app/utils/url
'
,
()
=>
({
apiRequest
:
jest
.
fn
(()
=>
{}),
...
...
@@ -28,7 +29,7 @@ describe('pizza saga', () => {
])
.
dispatch
(
pizzaActions
.
retrievePizzaInfo
())
.
put
(
pizzaActions
.
fetching
())
.
put
(
navigationActions
.
navigate
(
'
pizza
'
))
.
put
(
navigationActions
.
navigate
(
PIZZA_SCENE
))
.
silentRun
());
describe
(
'
failures
'
,
()
=>
{
...
...
__tests__/sagas/profile.spec.js
View file @
b0d86886
...
...
@@ -6,6 +6,7 @@ import profileSaga from '../../app/sagas/profile';
import
{
apiRequest
,
tokenSelector
}
from
'
../../app/utils/url
'
;
import
*
as
profileActions
from
'
../../app/actions/profile
'
;
import
*
as
navActions
from
'
../../app/actions/navigation
'
;
import
{
PROFILE_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
jest
.
mock
(
'
../../app/utils/url
'
,
()
=>
({
apiRequest
:
jest
.
fn
(()
=>
{}),
...
...
@@ -22,7 +23,7 @@ describe('profile saga', () => {
])
.
dispatch
(
profileActions
.
profile
(
'
token
'
,
1
))
.
put
(
profileActions
.
fetching
())
.
put
(
navActions
.
navigate
(
'
profile
'
))
.
put
(
navActions
.
navigate
(
PROFILE_SCENE
))
.
silentRun
());
it
(
'
should put success when the request succeeds
'
,
()
=>
expectSaga
(
profileSaga
)
...
...
__tests__/sagas/registration.spec.js
View file @
b0d86886
...
...
@@ -8,6 +8,7 @@ import registrationSaga, { eventSelector } from '../../app/sagas/registration';
import
{
apiRequest
,
tokenSelector
}
from
'
../../app/utils/url
'
;
import
*
as
eventActions
from
'
../../app/actions/event
'
;
import
*
as
navigationActions
from
'
../../app/actions/navigation
'
;
import
{
REGISTRATION_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
jest
.
mock
(
'
react-native-snackbar
'
,
()
=>
({
LENGTH_LONG
:
100
,
...
...
@@ -61,19 +62,19 @@ describe('registration saga', () => {
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Registration successful!
'
});
{
title
:
'
Registration successful!
'
},
);
}));
it
(
'
should put a retrieve fields action when they are available
'
,
()
=>
expectSaga
(
registrationSaga
)
.
provide
([
[
select
(
tokenSelector
),
'
token
'
],
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
events/1/registrations
'
]
}),
{
fields
:
{},
pk
:
2
}],
])
.
dispatch
(
registrationActions
.
register
(
1
))
.
put
(
registrationActions
.
retrieveFields
(
2
))
.
silentRun
());
it
(
'
should put a retrieve fields action when they are available
'
,
()
=>
expectSaga
(
registrationSaga
)
.
provide
([
[
select
(
tokenSelector
),
'
token
'
],
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
events/1/registrations
'
]
}),
{
fields
:
{},
pk
:
2
}],
])
.
dispatch
(
registrationActions
.
register
(
1
))
.
put
(
registrationActions
.
retrieveFields
(
2
))
.
silentRun
());
it
(
'
should show a failure action when the request fails
'
,
()
=>
expectSaga
(
registrationSaga
)
.
provide
([
...
...
@@ -139,7 +140,8 @@ describe('registration saga', () => {
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Successfully updated registration
'
});
{
title
:
'
Successfully updated registration
'
},
);
}));
it
(
'
should put failure action when the request fails
'
,
()
=>
expectSaga
(
registrationSaga
)
...
...
@@ -152,22 +154,22 @@ describe('registration saga', () => {
.
silentRun
());
it
(
'
should do a PUT request with fields
'
,
()
=>
expectSaga
(
registrationSaga
)
.
provide
([
[
select
(
tokenSelector
),
'
token
'
],
])
.
dispatch
(
registrationActions
.
update
(
2
,
{
key
:
'
value
'
}))
.
silentRun
()
.
then
(()
=>
{
expect
(
apiRequest
).
toBeCalledWith
(
'
registrations/2
'
,
{
body
:
'
{"fields[key]":"value"}
'
,
headers
:
{
Accept
:
'
application/json
'
,
Authorization
:
'
Token token
'
,
'
Content-Type
'
:
'
application/json
'
,
},
method
:
'
PUT
'
,
});
}));
.
provide
([
[
select
(
tokenSelector
),
'
token
'
],
])
.
dispatch
(
registrationActions
.
update
(
2
,
{
key
:
'
value
'
}))
.
silentRun
()
.
then
(()
=>
{
expect
(
apiRequest
).
toBeCalledWith
(
'
registrations/2
'
,
{
body
:
'
{"fields[key]":"value"}
'
,
headers
:
{
Accept
:
'
application/json
'
,
Authorization
:
'
Token token
'
,
'
Content-Type
'
:
'
application/json
'
,
},
method
:
'
PUT
'
,
});
}));
});
describe
(
'
cancelling
'
,
()
=>
{
...
...
@@ -191,7 +193,8 @@ describe('registration saga', () => {
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Successfully cancelled registration
'
});
{
title
:
'
Successfully cancelled registration
'
},
);
}));
it
(
'
should put event action when the request succeeds
'
,
()
=>
expectSaga
(
registrationSaga
)
...
...
@@ -252,7 +255,7 @@ describe('registration saga', () => {
it
(
'
should navigate to the registration screen
'
,
()
=>
expectSaga
(
registrationSaga
)
.
dispatch
(
registrationActions
.
retrieveFields
(
1
))
.
put
(
navigationActions
.
navigate
(
'
registration
'
))
.
put
(
navigationActions
.
navigate
(
REGISTRATION_SCENE
))
.
silentRun
());
it
(
'
should put showFields action when the request succeeds
'
,
()
=>
expectSaga
(
registrationSaga
)
...
...
__tests__/sagas/
logi
n.spec.js
→
__tests__/sagas/
sessio
n.spec.js
View file @
b0d86886
...
...
@@ -5,9 +5,11 @@ import Snackbar from 'react-native-snackbar';
import
{
AsyncStorage
}
from
'
react-native
'
;
import
{
Sentry
}
from
'
react-native-sentry
'
;
import
loginSaga
,
{
DISPLAYNAMEKEY
,
PHOTOKEY
,
TOKENKEY
,
USERNAMEKEY
}
from
'
../../app/sagas/login
'
;
import
sessionSaga
,
{
DISPLAYNAMEKEY
,
PHOTOKEY
,
TOKENKEY
,
USERNAMEKEY
}
from
'
../../app/sagas/session
'
;
import
{
apiRequest
}
from
'
../../app/utils/url
'
;
import
*
as
logi
nActions
from
'
../../app/actions/
logi
n
'
;
import
*
as
sessio
nActions
from
'
../../app/actions/
sessio
n
'
;
import
*
as
pushNotificationsActions
from
'
../../app/actions/pushNotifications
'
;
jest
.
mock
(
'
react-native-snackbar
'
,
()
=>
({
...
...
@@ -35,48 +37,49 @@ jest.mock('react-native-sentry', () => ({
},
}));
describe
(
'
logi
n saga
'
,
()
=>
{
describe
(
'
sessio
n saga
'
,
()
=>
{
const
error
=
new
Error
(
'
error
'
);
describe
(
'
logging in
'
,
()
=>
{
it
(
'
should show a snackbar on start
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
it
(
'
should show a snackbar on start
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Logging in
'
,
duration
:
Snackbar
.
LENGTH_INDEFINITE
});
{
title
:
'
Logging in
'
,
duration
:
Snackbar
.
LENGTH_INDEFINITE
},
);
}));
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
token-auth
'
]
}),
{
token
:
'
abc123
'
}],
[
matchers
.
call
.
like
({
fn
:
Sentry
.
setUserContext
}),
{}],
])
.
put
(
logi
nActions
.
success
(
'
username
'
,
'
abc123
'
))
.
put
(
logi
nActions
.
profile
(
'
abc123
'
))
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
put
(
sessio
nActions
.
success
(
'
username
'
,
'
abc123
'
))
.
put
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
());
it
(
'
should show a snackbar when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should show a snackbar when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
token-auth
'
]
}),
{
token
:
'
abc123
'
}],
[
matchers
.
call
.
like
({
fn
:
Sentry
.
setUserContext
}),
{}],
])
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
dismiss
).
toBeCalled
();
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Login successful
'
});
{
title
:
'
Login successful
'
},
);
}));
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
loginSaga
)
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
sessionSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
token-auth
'
]
}),
{
token
:
'
abc123
'
}],
[
matchers
.
call
.
like
({
fn
:
Sentry
.
setUserContext
}),
{}],
])
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
AsyncStorage
.
multiSet
).
toBeCalledWith
([
...
...
@@ -85,20 +88,21 @@ describe('login saga', () => {
]);
}));
it
(
'
should show a snackbar when the request fails
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should show a snackbar when the request fails
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
fn
(
apiRequest
),
throwError
(
error
)],
])
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
dismiss
).
toBeCalled
();
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Login failed
'
});
{
title
:
'
Login failed
'
},
);
}));
it
(
'
should do a POST request
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
it
(
'
should do a POST request
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
apiRequest
).
toBeCalledWith
(
'
token-auth
'
,
{
...
...
@@ -113,29 +117,30 @@ describe('login saga', () => {
});
describe
(
'
logging out
'
,
()
=>
{
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
logout
())
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
logout
())
.
silentRun
()
.
then
(()
=>
{
expect
(
AsyncStorage
.
multiRemove
).
toBeCalledWith
([
USERNAMEKEY
,
TOKENKEY
]);
}));
it
(
'
should put a push notification invalidation action
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should put a push notification invalidation action
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
put
(
pushNotificationsActions
.
invalidate
())
.
dispatch
(
logi
nActions
.
logout
())
.
dispatch
(
sessio
nActions
.
logout
())
.
silentRun
());
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
logout
())
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
logout
())
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Logout successful
'
});
{
title
:
'
Logout successful
'
},
);
}));
});
describe
(
'
getting profile
'
,
()
=>
{
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
members/me
'
]
}),
{
display_name
:
'
Johnny Test
'
,
...
...
@@ -144,11 +149,11 @@ describe('login saga', () => {
},
}],
])
.
put
(
logi
nActions
.
profileSuccess
(
'
Johnny Test
'
,
'
http://example.org/photo.png
'
))
.
dispatch
(
logi
nActions
.
profile
(
'
abc123
'
))
.
put
(
sessio
nActions
.
profileSuccess
(
'
Johnny Test
'
,
'
http://example.org/photo.png
'
))
.
dispatch
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
silentRun
());
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
members/me
'
]
}),
{
display_name
:
'
Johnny Test
'
,
...
...
@@ -157,7 +162,7 @@ describe('login saga', () => {
},
}],
])
.
dispatch
(
logi
nActions
.
profile
(
'
abc123
'
))
.
dispatch
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
AsyncStorage
.
multiSet
).
toBeCalledWith
([
...
...
@@ -166,15 +171,15 @@ describe('login saga', () => {
]);
}));
it
(
'
should not care about errors
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should not care about errors
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
fn
(
apiRequest
),
throwError
(
error
)],
])
.
dispatch
(
logi
nActions
.
profile
(
'
token
'
))
.
dispatch
(
sessio
nActions
.
profile
(
'
token
'
))
.
silentRun
());
it
(
'
should do a GET request
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
profile
(
'
abc123
'
))
it
(
'
should do a GET request
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
apiRequest
).
toBeCalledWith
(
'
members/me
'
,
{
...
...
__tests__/ui/components/navigator/ReduxNavigator.spec.js
View file @
b0d86886
...
...
@@ -4,12 +4,13 @@ import configureStore from 'redux-mock-store';
import
renderer
from
'
react-test-renderer
'
;
import
ReduxNavigator
from
'
../../../../app/ui/components/navigator/ReduxNavigator
'
;
import
reducer
from
'
../../../../app/reducers
'
;
import
{
LOGIN_SCENE
}
from
'
../../../../app/ui/components/navigator/scenes
'
;
describe
(
'
ReduxNavigator component
'
,
()
=>
{
const
mockStore
=
configureStore
(
reducer
);
const
initialState
=
{
navigation
:
{
currentScene
:
'
home
'
,
currentScene
:
LOGIN_SCENE
,
previousScenes
:
[],
drawerOpen
:
false
,
},
...
...
@@ -18,8 +19,12 @@ describe('ReduxNavigator component', () => {
it
(
'
renders correctly
'
,
()
=>
{
const
tree
=
renderer
.
create
(
<
Provider
store
=
{
store
}
><
ReduxNavigator
/><
/Provider>
)
.
create
(
<
Provider
store
=
{
store
}
>
<
ReduxNavigator
/>
<
/Provider>
,
)
.
toJSON
();
expect
(
tree
).
toMatchSnapshot
();
});
});
\ No newline at end of file
});
app/actions/
logi
n.js
→
app/actions/
sessio
n.js
View file @
b0d86886
export
const
LOGIN
=
'
LOGIN_LOGIN
'
;
export
const
SUCCESS
=
'
LOGIN_SUCCESS
'
;
export
const
LOGOUT
=
'
LOGIN_LOGOUT
'
;
export
const
TOKEN_INVALID
=
'
LOGIN_TOKEN_INVALID
'
;
export
const
PROFILE
=
'
LOGIN_PROFILE
'
;
export
const
PROFILE_SUCCESS
=
'
LOGIN_PROFILE_SUCCESS
'
;
export
const
LOGIN
=
'
SESSION_LOGIN
'
;
export
const
INIT
=
'
SESSION_INIT
'
;
export
const
SUCCESS
=
'
SESSION_SUCCESS
'
;
export
const
LOGOUT
=
'
SESSION_LOGOUT
'
;
export
const
TOKEN_INVALID
=
'
SESSION_TOKEN_INVALID
'
;
export
const
PROFILE
=
'
SESSION_PROFILE
'
;
export
const
PROFILE_SUCCESS
=
'
SESSION_PROFILE_SUCCESS
'
;
export
function
success
(
username
,
token
)
{
return
{
type
:
SUCCESS
,
payload
:
{
username
,
token
}
};
...
...
@@ -13,6 +14,10 @@ export function login(user, pass) {
return
{
type
:
LOGIN
,
payload
:
{
user
,
pass
}
};
}
export
function
init
()
{
return
{
type
:
INIT
};
}
export
function
logout
()
{
return
{
type
:
LOGOUT
};
}
...
...
app/app.js
View file @
b0d86886
import
React
,
{
Component
}
from
'
react
'
;
import
{
AsyncStorage
,
Linking
,
Platform
}
from
'
react-native
'
;
import
{
Linking
,
Platform
}
from
'
react-native
'
;
import
{
applyMiddleware
,
createStore
}
from
'
redux
'
;
import
{
Provider
}
from
'
react-redux
'
;
import
{
I18nextProvider
}
from
'
react-i18next
'
;
...
...
@@ -14,7 +14,7 @@ import reducers from './reducers';
import
i18n
from
'
./utils/i18n
'
;
import
sagas
from
'
./sagas
'
;
import
ReduxNavigator
from
'
./ui/components/navigator/ReduxNavigator
'
;
import
*
as
logi
nActions
from
'
./actions/
logi
n
'
;
import
*
as
sessio
nActions
from
'
./actions/
sessio
n
'
;
import
*
as
deepLinkingActions
from
'
./actions/deepLinking
'
;
import
{
register
}
from
'
./actions/pushNotifications
'
;
...
...
@@ -22,18 +22,6 @@ const sagaMiddleware = createSagaMiddleware();
const
store
=
createStore
(
reducers
,
applyMiddleware
(
sagaMiddleware
));
sagaMiddleware
.
run
(
sagas
);
const
USERNAMEKEY
=
'
@MyStore:username
'
;
const
TOKENKEY
=
'
@MyStore:token
'
;
const
DISPLAYNAMEKEY
=
'
@MyStore:displayName
'
;
const
PHOTOKEY
=
'
@MyStore:photo
'
;
const
PUSHCATEGORYKEY
=
'
@MyStore:pushCategories
'
;
const
pairsToObject
=
(
obj
,
pair
)
=>
{
const
obj2
=
{
...
obj
};
obj2
[
pair
[
0
]]
=
pair
[
1
];
return
obj2
;
};
FCM
.
on
(
FCMEvent
.
Notification
,
async
(
notif
)
=>
{
if
(
notif
.
fcm
)
{
FCM
.
presentLocalNotification
({