@@ -11,6 +11,17 @@ function getDate(num) {
1111 return date .getFullYear () + num;
1212}
1313
14+ async function fillAndSubmit () {
15+ await fillIn (' [name="firstName"]' , ' b' );
16+ await fillIn (' [name="email"]' , ' c@name.com' );
17+ await fillIn (' [name="password"]' , ' Test1234' );
18+ await fillIn (' [name="repeatPassword"]' , ' Test1234' );
19+ await fillIn (' [name="birthday"]' , ' 1991' );
20+ await click (' [name="agreement"]' );
21+ await click (' [id="male"]' );
22+ await click (' [data-test-submit-form]' );
23+ }
24+
1425module (' Integration | Component | registration-form' , function (hooks ) {
1526 setupRenderingTest (hooks);
1627 setupIntl (hooks, ' en-us' );
@@ -25,42 +36,32 @@ module('Integration | Component | registration-form', function (hooks) {
2536 });
2637
2738 test (' it send register request if all fields filled' , async function (assert ) {
28- assert .expect (6 );
29-
3039 // eslint-disable-next-line ember/no-classic-classes
3140 const MockFirebaseAuthenticator = EmberObject .extend ({
3241 registerUser () {
3342 return Promise .resolve ();
3443 },
3544 });
3645
37- let loadCurrentUserCallCount = 0 ;
38- let patchUserInfoCalled = false ;
39-
4046 class MockNetwork extends Service {
4147 loadCurrentUser () {
42- loadCurrentUserCallCount++ ;
43- if (patchUserInfoCalled) {
44- assert .ok (true , ' loadCurrentUser called after patchUserInfo to refresh profile data' );
45- }
48+ assert .step (' loadCurrentUser' );
4649 return Promise .resolve ();
4750 }
4851 loadCloudUrl () {
4952 return Promise .resolve ();
5053 }
5154 patchUserInfo (fields ) {
52- patchUserInfoCalled = true ;
55+ assert . step ( ' patchUserInfo ' ) ;
5356 assert .ok (fields, ' patchUserInfo called with user fields' );
5457 return Promise .resolve (fields);
5558 }
5659 }
5760
5861 class MockSession extends Service {
5962 isAuthenticated = false ;
60- authenticate (type , login , password ) {
61- assert .ok (type, ' authenticate called with type' );
62- assert .ok (login, ' authenticate called with login' );
63- assert .ok (password, ' authenticate called with password' );
63+ authenticate () {
64+ assert .step (' authenticate' );
6465 return Promise .resolve ();
6566 }
6667 }
@@ -70,25 +71,126 @@ module('Integration | Component | registration-form', function (hooks) {
7071 this .owner .register (' service:network' , MockNetwork);
7172
7273 await render (<template ><RegistrationForm /></template >);
73- await fillIn (' [name="firstName"]' , ' b' );
74- await fillIn (' [name="email"]' , ' c@name.com' );
75- await fillIn (' [name="password"]' , ' Test1234' );
76- await fillIn (' [name="repeatPassword"]' , ' Test1234' );
77- await fillIn (' [name="birthday"]' , ' 1991' );
78- await click (' [name="agreement"]' );
79- await click (' [id="male"]' );
80- await click (' [data-test-submit-form]' );
81-
82- assert .strictEqual (loadCurrentUserCallCount, 2 , ' loadCurrentUser called twice: once during login, once after patchUserInfo' );
74+ await fillAndSubmit ();
75+
76+ // Login loads the user, then the profile is patched and the user reloaded.
77+ assert .verifySteps ([
78+ ' authenticate' ,
79+ ' loadCurrentUser' ,
80+ ' patchUserInfo' ,
81+ ' loadCurrentUser' ,
82+ ]);
8383 });
8484
85- test (' it able to handle registration error' , async function (assert ) {
86- assert .expect (2 );
85+ test (' redirects to index only after the profile is patched and reloaded' , async function (assert ) {
86+ // eslint-disable-next-line ember/no-classic-classes
87+ const MockFirebaseAuthenticator = EmberObject .extend ({
88+ registerUser () {
89+ return Promise .resolve ();
90+ },
91+ });
92+
93+ class MockNetwork extends Service {
94+ loadCurrentUser () {
95+ assert .step (' loadCurrentUser' );
96+ return Promise .resolve ();
97+ }
98+ loadCloudUrl () {
99+ return Promise .resolve ();
100+ }
101+ patchUserInfo (fields ) {
102+ assert .step (' patchUserInfo' );
103+ return Promise .resolve (fields);
104+ }
105+ }
87106
107+ class MockSession extends Service {
108+ isAuthenticated = false ;
109+ authenticate () {
110+ // Mirror production: the session becomes authenticated after login.
111+ this .isAuthenticated = true ;
112+ return Promise .resolve ();
113+ }
114+ }
115+
116+ this .owner .register (' authenticator:firebase' , MockFirebaseAuthenticator);
117+ this .owner .register (' service:session' , MockSession);
118+ this .owner .register (' service:network' , MockNetwork);
119+
120+ // Spy on the real router's transitionTo so the template's <LinkTo>s keep
121+ // rendering while we record when the redirect happens.
122+ this .owner .lookup (' service:router' ).transitionTo = (route ) => {
123+ assert .step (` transitionTo:${ route} ` );
124+ };
125+
126+ await render (<template ><RegistrationForm /></template >);
127+ await fillAndSubmit ();
128+
129+ // The redirect must come last — after the profile is patched and reloaded.
130+ // Redirecting earlier cancels the in-flight task and leaves the profile
131+ // blank (the bug this fixes).
132+ assert .verifySteps ([
133+ ' loadCurrentUser' ,
134+ ' patchUserInfo' ,
135+ ' loadCurrentUser' ,
136+ ' transitionTo:index' ,
137+ ]);
138+ });
139+
140+ test (' still redirects into the app when the profile patch fails after auth' , async function (assert ) {
88141 // eslint-disable-next-line ember/no-classic-classes
89142 const MockFirebaseAuthenticator = EmberObject .extend ({
90143 registerUser () {
91- assert .ok (true , ' registerUser was called' );
144+ return Promise .resolve ();
145+ },
146+ });
147+
148+ class MockNetwork extends Service {
149+ loadCurrentUser () {
150+ return Promise .resolve ();
151+ }
152+ loadCloudUrl () {
153+ return Promise .resolve ();
154+ }
155+ patchUserInfo () {
156+ assert .step (' patchUserInfo' );
157+ // The account is already created/authenticated; only the profile save
158+ // fails (e.g. a transient backend error).
159+ return Promise .reject (
160+ Object .assign (new Error (' save failed' ), { errors: [' save failed' ] }),
161+ );
162+ }
163+ }
164+
165+ class MockSession extends Service {
166+ isAuthenticated = false ;
167+ authenticate () {
168+ this .isAuthenticated = true ;
169+ return Promise .resolve ();
170+ }
171+ }
172+
173+ this .owner .register (' authenticator:firebase' , MockFirebaseAuthenticator);
174+ this .owner .register (' service:session' , MockSession);
175+ this .owner .register (' service:network' , MockNetwork);
176+
177+ this .owner .lookup (' service:router' ).transitionTo = (route ) => {
178+ assert .step (` transitionTo:${ route} ` );
179+ };
180+
181+ await render (<template ><RegistrationForm /></template >);
182+ await fillAndSubmit ();
183+
184+ // The registered+authenticated user is sent into the app instead of being
185+ // trapped on the form, even though the profile save failed.
186+ assert .verifySteps ([' patchUserInfo' , ' transitionTo:index' ]);
187+ });
188+
189+ test (' it able to handle registration error' , async function (assert ) {
190+ // eslint-disable-next-line ember/no-classic-classes
191+ const MockFirebaseAuthenticator = EmberObject .extend ({
192+ registerUser () {
193+ assert .step (' registerUser' );
92194 return Promise .reject (new Error (' foo' ));
93195 },
94196 });
@@ -117,14 +219,10 @@ module('Integration | Component | registration-form', function (hooks) {
117219 this .owner .register (' service:network' , MockNetwork);
118220
119221 await render (<template ><RegistrationForm /></template >);
120- await fillIn (' [name="firstName"]' , ' b' );
121- await fillIn (' [name="email"]' , ' c@name.com' );
122- await fillIn (' [name="password"]' , ' Test1234' );
123- await fillIn (' [name="repeatPassword"]' , ' Test1234' );
124- await fillIn (' [name="birthday"]' , ' 1991' );
125- await click (' [name="agreement"]' );
126- await click (' [id="male"]' );
127- await click (' [data-test-submit-form]' );
222+ await fillAndSubmit ();
223+
224+ // registerUser fails, so login/patch never run.
225+ assert .verifySteps ([' registerUser' ]);
128226 assert .dom (' [data-test-form-error]' ).hasText (' foo' );
129227 });
130228
0 commit comments