@@ -8,23 +8,28 @@ import configureStore from '../../configureStore';
8
8
import { actions as apiActions } from '../../reducers/api' ;
9
9
import { actions as userActions } from '../../reducers/users' ;
10
10
import {
11
+ updateWithProps ,
11
12
createContextWithFakeRouter ,
12
13
fakeUser ,
14
+ getFakeLogger ,
13
15
shallowUntilTarget ,
14
16
} from '../../test-helpers' ;
15
17
import Navbar from '../Navbar' ;
18
+ import * as api from '../../api' ;
16
19
17
- import App , { AppBase } from '.' ;
20
+ import App , { AppBase , DefaultProps } from '.' ;
18
21
19
22
describe ( __filename , ( ) => {
20
23
type RenderParams = {
21
- store ?: Store ;
24
+ _log ?: DefaultProps [ '_log' ] ;
22
25
authToken ?: string | null ;
26
+ store ?: Store ;
23
27
} ;
24
28
25
- const render = ( {
26
- store = configureStore ( ) ,
29
+ const render = async ( {
30
+ _log ,
27
31
authToken = 'some-token' ,
32
+ store = configureStore ( ) ,
28
33
} : RenderParams = { } ) => {
29
34
const contextWithRouter = createContextWithFakeRouter ( ) ;
30
35
const context = {
@@ -35,71 +40,125 @@ describe(__filename, () => {
35
40
} ,
36
41
} ;
37
42
38
- const root = shallowUntilTarget ( < App authToken = { authToken } /> , AppBase , {
43
+ const props = {
44
+ _log,
45
+ authToken,
46
+ } ;
47
+
48
+ return shallowUntilTarget ( < App { ...props } /> , AppBase , {
39
49
shallowOptions : { ...context } ,
40
50
} ) ;
41
-
42
- return root ;
43
51
} ;
44
52
45
- it ( 'renders without an authentication token' , ( ) => {
46
- const root = render ( { authToken : null } ) ;
53
+ it ( 'renders without an authentication token' , async ( ) => {
54
+ const root = await render ( { authToken : null } ) ;
47
55
48
56
expect ( root . find ( Container ) ) . toHaveClassName ( styles . container ) ;
49
57
expect ( root . find ( `.${ styles . content } ` ) ) . toHaveLength ( 1 ) ;
50
58
expect ( root . find ( Navbar ) ) . toHaveLength ( 1 ) ;
51
59
} ) ;
52
60
53
- it ( 'renders with an empty authentication token' , ( ) => {
54
- const root = render ( { authToken : '' } ) ;
61
+ it ( 'renders with an empty authentication token' , async ( ) => {
62
+ const root = await render ( { authToken : '' } ) ;
55
63
56
64
expect ( root . find ( Container ) ) . toHaveClassName ( styles . container ) ;
57
65
expect ( root . find ( `.${ styles . content } ` ) ) . toHaveLength ( 1 ) ;
58
66
expect ( root . find ( Navbar ) ) . toHaveLength ( 1 ) ;
59
67
} ) ;
60
68
61
- it ( 'displays a loading message until the user profile gets loaded' , ( ) => {
62
- const root = render ( ) ;
69
+ it ( 'displays a loading message until the user profile gets loaded' , async ( ) => {
70
+ const root = await render ( ) ;
63
71
64
72
expect ( root ) . toIncludeText ( 'Getting your workspace ready' ) ;
65
73
expect ( root . find ( Navbar ) ) . toHaveLength ( 0 ) ;
66
74
} ) ;
67
75
68
- it ( 'dispatches setAuthToken on mount when authToken is valid' , ( ) => {
76
+ it ( 'dispatches setAuthToken on mount when authToken is valid' , async ( ) => {
69
77
const authToken = 'my-token' ;
70
78
const store = configureStore ( ) ;
71
79
const dispatch = jest . spyOn ( store , 'dispatch' ) ;
72
80
73
- render ( { authToken, store } ) ;
81
+ await render ( { authToken, store } ) ;
74
82
75
83
expect ( dispatch ) . toHaveBeenCalledWith (
76
84
apiActions . setAuthToken ( { authToken } ) ,
77
85
) ;
78
86
} ) ;
79
87
80
- it ( 'does not dispatch setAuthToken on mount when authToken is null' , ( ) => {
88
+ it ( 'does not dispatch setAuthToken on mount when authToken is null' , async ( ) => {
81
89
const store = configureStore ( ) ;
82
90
const dispatch = jest . spyOn ( store , 'dispatch' ) ;
83
91
84
- render ( { authToken : null , store } ) ;
92
+ await render ( { authToken : null , store } ) ;
85
93
86
94
expect ( dispatch ) . not . toHaveBeenCalled ( ) ;
87
95
} ) ;
88
96
89
- it ( 'configures no route when the user is not logged in' , ( ) => {
90
- const root = render ( { authToken : null } ) ;
97
+ it ( 'configures no route when the user is not logged in' , async ( ) => {
98
+ const root = await render ( { authToken : null } ) ;
91
99
92
100
expect ( root . find ( Route ) ) . toHaveLength ( 0 ) ;
93
101
expect ( root . find ( `.${ styles . loginMessage } ` ) ) . toIncludeText ( 'Please log in' ) ;
94
102
} ) ;
95
103
96
- it ( 'exposes more routes when the user is logged in' , ( ) => {
104
+ it ( 'exposes more routes when the user is logged in' , async ( ) => {
97
105
const store = configureStore ( ) ;
98
106
store . dispatch ( userActions . loadCurrentUser ( { user : fakeUser } ) ) ;
99
107
100
- const root = render ( { store } ) ;
108
+ const root = await render ( { store } ) ;
101
109
102
110
expect ( root . find ( Route ) ) . toHaveLength ( 3 ) ;
103
111
expect ( root . find ( `.${ styles . loginMessage } ` ) ) . toHaveLength ( 0 ) ;
104
112
} ) ;
113
+
114
+ it ( 'dispatches loadCurrentUser() on update' , async ( ) => {
115
+ const _log = getFakeLogger ( ) ;
116
+ const authToken = 'my-token' ;
117
+ const user = fakeUser ;
118
+
119
+ const store = configureStore ( ) ;
120
+ const dispatch = jest . spyOn ( store , 'dispatch' ) ;
121
+
122
+ const mockApi = jest . spyOn ( api , 'getCurrentUserProfile' ) ;
123
+ mockApi . mockReturnValue ( Promise . resolve ( user ) ) ;
124
+
125
+ const root = await render ( { _log, authToken : null , store } ) ;
126
+
127
+ // Set the authentication token into the state.
128
+ store . dispatch ( apiActions . setAuthToken ( { authToken } ) ) ;
129
+ const { api : apiState } = store . getState ( ) ;
130
+ dispatch . mockReset ( ) ;
131
+
132
+ // Wait until componentDidUpdate() logic has been executed with the new
133
+ // props.
134
+ await updateWithProps ( root , { apiState } ) ;
135
+
136
+ expect ( dispatch ) . toHaveBeenCalledWith (
137
+ userActions . loadCurrentUser ( {
138
+ user,
139
+ } ) ,
140
+ ) ;
141
+ } ) ;
142
+
143
+ it ( 'logs an error when the API request to retrieve the current user profile has failed' , async ( ) => {
144
+ const _log = getFakeLogger ( ) ;
145
+ const authToken = 'my-token' ;
146
+ const store = configureStore ( ) ;
147
+
148
+ const error = new Error ( 'server error' ) ;
149
+ const mockApi = jest . spyOn ( api , 'getCurrentUserProfile' ) ;
150
+ mockApi . mockReturnValue ( Promise . resolve ( { error } ) ) ;
151
+
152
+ const root = await render ( { _log, store } ) ;
153
+
154
+ // Set the authentication token into the state.
155
+ store . dispatch ( apiActions . setAuthToken ( { authToken } ) ) ;
156
+ const { api : apiState } = store . getState ( ) ;
157
+
158
+ // Wait until componentDidUpdate() logic has been executed with the new
159
+ // props.
160
+ await updateWithProps ( root , { apiState } ) ;
161
+
162
+ expect ( _log . error ) . toHaveBeenCalled ( ) ;
163
+ } ) ;
105
164
} ) ;
0 commit comments