OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <memory> | |
6 | |
7 #include "base/mac/foundation_util.h" | |
8 #include "base/mac/scoped_nsobject.h" | |
Eugene But (OOO till 7-30)
2016/07/13 22:30:31
s/include/import
vabr (Chromium)
2016/07/14 07:36:31
Done.
| |
9 #include "base/strings/utf_string_conversions.h" | |
10 #include "base/values.h" | |
11 #import "ios/chrome/browser/passwords/js_credential_manager.h" | |
12 #include "ios/web/public/web_state/credential.h" | |
13 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" | |
14 #import "ios/web/public/web_state/web_state.h" | |
15 #include "ios/web/public/web_state/web_state_observer.h" | |
16 #import "ios/web/public/test/web_test_with_web_state.h" | |
17 #include "testing/gmock/include/gmock/gmock.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 #include "testing/gtest_mac.h" | |
20 #include "url/gurl.h" | |
21 | |
22 namespace { | |
23 | |
24 using ::testing::_; | |
25 | |
26 // Matcher to match web::Credential. | |
27 MATCHER_P(IsEqualTo, value, "") { | |
28 return arg.type == value.type && arg.id == value.id && | |
29 arg.name == value.name && arg.avatar_url == value.avatar_url && | |
30 arg.password == value.password && | |
31 arg.federation_origin.Serialize() == | |
32 value.federation_origin.Serialize(); | |
33 } | |
34 | |
35 // A mock WebStateObserver for testing the Credential Manager API. | |
36 class MockWebStateObserver : public web::WebStateObserver { | |
37 public: | |
38 explicit MockWebStateObserver(web::WebState* web_state) | |
39 : web::WebStateObserver(web_state) {} | |
40 ~MockWebStateObserver() override {} | |
41 | |
42 MOCK_METHOD5( | |
43 CredentialsRequested, | |
44 void(int, const GURL&, bool, const std::vector<std::string>&, bool)); | |
45 MOCK_METHOD3(SignedIn, void(int, const GURL&, const web::Credential&)); | |
46 MOCK_METHOD2(SignedIn, void(int, const GURL&)); | |
47 MOCK_METHOD2(SignedOut, void(int, const GURL&)); | |
48 MOCK_METHOD3(SignInFailed, void(int, const GURL&, const web::Credential&)); | |
49 MOCK_METHOD2(SignInFailed, void(int, const GURL&)); | |
50 | |
51 private: | |
52 DISALLOW_COPY_AND_ASSIGN(MockWebStateObserver); | |
53 }; | |
54 | |
55 // Unit tests for the Credential Manager JavaScript and associated plumbing. | |
56 class CredentialManagerJsTest : public web::WebTestWithWebState { | |
57 public: | |
58 CredentialManagerJsTest() {} | |
59 | |
60 void SetUp() override { | |
61 web::WebTestWithWebState::SetUp(); | |
62 js_credential_manager_.reset(base::mac::ObjCCastStrict<JSCredentialManager>( | |
63 [[web_state()->GetJSInjectionReceiver() | |
64 instanceOfClass:[JSCredentialManager class]] retain])); | |
65 observer_.reset(new MockWebStateObserver(web_state())); | |
66 } | |
67 | |
68 // Sets up a web page and injects the JSCredentialManager. Must be called | |
69 // before any interaction with the page. | |
70 void Inject() { | |
71 LoadHtml(@""); | |
72 [js_credential_manager_ inject]; | |
73 } | |
74 | |
75 // Returns the mock observer. | |
76 MockWebStateObserver& observer() { return *observer_; } | |
77 | |
78 // Returns a string that creates a Credential object for JavaScript testing. | |
79 NSString* test_credential_js() { | |
80 return @"new PasswordCredential('bob', 'bobiscool', 'Bob Boblaw'," | |
81 @"'https://bobboblawslawblog.com/bob.jpg')"; | |
82 } | |
83 | |
84 // Returns a Credential to match the one returned by |test_credential_js()|. | |
85 web::Credential test_credential() { | |
86 web::Credential test_credential; | |
87 test_credential.type = web::CredentialType::CREDENTIAL_TYPE_PASSWORD; | |
88 test_credential.id = base::ASCIIToUTF16("bob"); | |
89 test_credential.password = base::ASCIIToUTF16("bobiscool"); | |
90 test_credential.name = base::ASCIIToUTF16("Bob Boblaw"); | |
91 test_credential.avatar_url = GURL("https://bobboblawslawblog.com/bob.jpg"); | |
92 return test_credential; | |
93 } | |
94 | |
95 // Adds handlers for resolving and rejecting the promise returned by | |
96 // executing the code in |promise|. | |
97 void PrepareResolverAndRejecter(NSString* promise) { | |
98 EvaluateJavaScriptAsString( | |
99 [NSString stringWithFormat:@"var resolved = false; " | |
100 @"var rejected = false; " | |
101 @"var resolvedCredential = null; " | |
102 @"var rejectedError = null; " | |
103 @"function resolve(credential) { " | |
104 @" resolved = true; " | |
105 @" resolvedCredential = credential;" | |
106 @"} " | |
107 @"function reject(error) { " | |
108 @" rejected = true; " | |
109 @" rejectedError = error; " | |
110 @"} " | |
111 @"%@.then(resolve, reject); ", | |
112 promise]); | |
113 // Wait until the promise executor has executed. | |
114 WaitForCondition(^bool { | |
115 return [EvaluateJavaScriptAsString( | |
116 @"Object.keys(__gCrWeb.credentialManager.resolvers_).length > 0") | |
117 isEqualToString:@"true"]; | |
118 }); | |
119 } | |
120 | |
121 // Checks that the Credential returned to the resolve handler in JavaScript | |
122 // matches the structure of |test_credential()|. | |
123 void CheckResolvedCredentialMatchesTestCredential() { | |
124 EXPECT_NSEQ(@"true", EvaluateJavaScriptAsString(@"resolved")); | |
125 EXPECT_NSEQ( | |
126 @"PasswordCredential", | |
127 EvaluateJavaScriptAsString(@"resolvedCredential.constructor.name")); | |
128 EXPECT_NSEQ(@"bob", EvaluateJavaScriptAsString(@"resolvedCredential.id")); | |
129 EXPECT_NSEQ(@"bobiscool", | |
130 EvaluateJavaScriptAsString(@"resolvedCredential.password_")); | |
131 EXPECT_NSEQ(@"Bob Boblaw", | |
132 EvaluateJavaScriptAsString(@"resolvedCredential.name")); | |
133 EXPECT_NSEQ(@"https://bobboblawslawblog.com/bob.jpg", | |
134 EvaluateJavaScriptAsString(@"resolvedCredential.avatarURL")); | |
135 } | |
136 | |
137 // Checks that the promise set up by |PrepareResolverAndRejecter| was resolved | |
138 // without a credential. | |
139 void CheckResolvedWithoutCredential() { | |
140 EXPECT_NSEQ(@"true", EvaluateJavaScriptAsString(@"resolved")); | |
141 EXPECT_NSEQ(@"false", EvaluateJavaScriptAsString(@"!!resolvedCredential")); | |
142 } | |
143 | |
144 // Checks that the promise set up by |PrepareResolverAndRejecter| was rejected | |
145 // with an error with name |error_name| and |message|. | |
146 void CheckRejected(NSString* error_name, NSString* message) { | |
147 EXPECT_NSEQ(@"true", EvaluateJavaScriptAsString(@"rejected")); | |
148 EXPECT_NSEQ(error_name, EvaluateJavaScriptAsString(@"rejectedError.name")); | |
149 EXPECT_NSEQ(message, EvaluateJavaScriptAsString(@"rejectedError.message")); | |
150 } | |
151 | |
152 // Waits until the promise set up by |PrepareResolverAndRejecter| has been | |
153 // either resolved or rejected. | |
154 void WaitUntilPromiseResolvedOrRejected() { | |
155 WaitForCondition(^bool { | |
156 return [EvaluateJavaScriptAsString(@"resolved || rejected") | |
157 isEqualToString:@"true"]; | |
158 }); | |
159 } | |
160 | |
161 // Resolves the promise set up by |PrepareResolverAndRejecter| and associated | |
162 // with |request_id| with |test_credential()|. | |
163 void ResolvePromiseWithTestCredential(int request_id) { | |
164 __block bool finished = false; | |
165 [js_credential_manager() resolvePromiseWithRequestID:request_id | |
166 credential:test_credential() | |
167 completionHandler:^(BOOL success) { | |
168 EXPECT_TRUE(success); | |
169 finished = true; | |
170 }]; | |
171 WaitForCondition(^bool { | |
172 return finished; | |
173 }); | |
174 WaitUntilPromiseResolvedOrRejected(); | |
175 } | |
176 | |
177 // Resolves the promise set up by |PrepareResolverAndRejecter| and associated | |
178 // with |request_id| without a credential. | |
179 void ResolvePromiseWithoutCredential(int request_id) { | |
180 __block bool finished = false; | |
181 [js_credential_manager() resolvePromiseWithRequestID:request_id | |
182 completionHandler:^(BOOL success) { | |
183 EXPECT_TRUE(success); | |
184 finished = true; | |
185 }]; | |
186 WaitForCondition(^bool { | |
187 return finished; | |
188 }); | |
189 WaitUntilPromiseResolvedOrRejected(); | |
190 } | |
191 | |
192 // Rejects the promise set up by |PrepareResolverAndRejecter| and associated | |
193 // with |request_id| with an error of type |error_type| and |message|. | |
194 void RejectPromise(int request_id, NSString* error_type, NSString* message) { | |
195 __block bool finished = false; | |
196 [js_credential_manager() rejectPromiseWithRequestID:request_id | |
197 errorType:error_type | |
198 message:message | |
199 completionHandler:^(BOOL success) { | |
200 EXPECT_TRUE(success); | |
201 finished = true; | |
202 }]; | |
203 WaitForCondition(^bool { | |
204 return finished; | |
205 }); | |
206 WaitUntilPromiseResolvedOrRejected(); | |
207 } | |
208 | |
209 // Tests that the promise set up by |PrepareResolverAndRejecter| wasn't | |
210 // rejected. | |
211 void CheckNeverRejected() { | |
212 EXPECT_NSEQ(@"false", EvaluateJavaScriptAsString(@"rejected")); | |
213 } | |
214 | |
215 // Tests that the promise set up by |PrepareResolverAndRejecter| wasn't | |
216 // resolved. | |
217 void CheckNeverResolved() { | |
218 EXPECT_NSEQ(@"false", EvaluateJavaScriptAsString(@"resolved")); | |
219 } | |
220 | |
221 // Returns the JSCredentialManager for testing. | |
222 JSCredentialManager* js_credential_manager() { | |
223 return js_credential_manager_; | |
224 } | |
225 | |
226 // Tests that resolving the promise returned by |promise| and associated with | |
227 // |request_id| with |test_credential()| correctly forwards that credential | |
228 // to the client. | |
229 void TestPromiseResolutionWithCredential(int request_id, NSString* promise) { | |
230 PrepareResolverAndRejecter(promise); | |
231 ResolvePromiseWithTestCredential(request_id); | |
232 CheckResolvedCredentialMatchesTestCredential(); | |
233 CheckNeverRejected(); | |
234 } | |
235 | |
236 // Tests that resolving the promise returned by |promise| and associated with | |
237 // |request_id| without a credential correctly invokes the client. | |
238 void TestPromiseResolutionWithoutCredential(int request_id, | |
239 NSString* promise) { | |
240 PrepareResolverAndRejecter(promise); | |
241 ResolvePromiseWithoutCredential(request_id); | |
242 CheckResolvedWithoutCredential(); | |
243 CheckNeverRejected(); | |
244 } | |
245 | |
246 // Tests that rejecting the promise returned by |promise| and associated with | |
247 // |request_id| with an error of type |error| and message |message| correctly | |
248 // forwards that error to the client. | |
249 void TestPromiseRejection(int request_id, | |
250 NSString* error, | |
251 NSString* message, | |
252 NSString* promise) { | |
253 PrepareResolverAndRejecter(promise); | |
254 RejectPromise(request_id, error, message); | |
255 CheckRejected(error, message); | |
256 CheckNeverResolved(); | |
257 } | |
258 | |
259 private: | |
260 // Manager for injected credential manager JavaScript. | |
261 base::scoped_nsobject<JSCredentialManager> js_credential_manager_; | |
262 | |
263 // Mock observer for testing. | |
264 std::unique_ptr<MockWebStateObserver> observer_; | |
265 | |
266 DISALLOW_COPY_AND_ASSIGN(CredentialManagerJsTest); | |
267 }; | |
268 | |
269 // Tests that navigator.credentials calls use distinct request identifiers. | |
270 TEST_F(CredentialManagerJsTest, RequestIdentifiersDiffer) { | |
271 Inject(); | |
272 EXPECT_CALL(observer(), CredentialsRequested(0, _, _, _, _)); | |
273 EvaluateJavaScriptAsString(@"navigator.credentials.request()"); | |
274 EXPECT_CALL(observer(), SignInFailed(1, _)); | |
275 EvaluateJavaScriptAsString(@"navigator.credentials.notifyFailedSignIn()"); | |
276 EXPECT_CALL(observer(), SignInFailed(2, _)); | |
277 EvaluateJavaScriptAsString(@"navigator.credentials.notifyFailedSignIn()"); | |
278 EXPECT_CALL(observer(), SignedIn(3, _)); | |
279 EvaluateJavaScriptAsString(@"navigator.credentials.notifySignedIn()"); | |
280 EXPECT_CALL(observer(), SignedOut(4, _)); | |
281 EvaluateJavaScriptAsString(@"navigator.credentials.notifySignedOut()"); | |
282 EXPECT_CALL(observer(), CredentialsRequested(5, _, _, _, _)); | |
283 EvaluateJavaScriptAsString(@"navigator.credentials.request()"); | |
284 } | |
285 | |
286 // Tests that navigator.credentials.request() creates and forwards the right | |
287 // arguments to the app side. | |
288 // TODO(rohitrao): Fails after merge r376674. https://crbug.com/588706. | |
289 TEST_F(CredentialManagerJsTest, DISABLED_RequestToApp) { | |
290 Inject(); | |
291 std::vector<std::string> empty_federations; | |
292 std::vector<std::string> nonempty_federations; | |
293 nonempty_federations.push_back("foo"); | |
294 nonempty_federations.push_back("bar"); | |
295 | |
296 EXPECT_CALL(observer(), | |
297 CredentialsRequested(0, _, false, empty_federations, _)); | |
298 EvaluateJavaScriptAsString(@"navigator.credentials.request()"); | |
299 | |
300 EXPECT_CALL(observer(), | |
301 CredentialsRequested(1, _, false, empty_federations, _)); | |
302 EvaluateJavaScriptAsString(@"navigator.credentials.request({})"); | |
303 | |
304 EXPECT_CALL(observer(), | |
305 CredentialsRequested(2, _, true, empty_federations, _)); | |
306 EvaluateJavaScriptAsString( | |
307 @"navigator.credentials.request({suppressUI: true})"); | |
308 | |
309 EXPECT_CALL(observer(), | |
310 CredentialsRequested(3, _, false, nonempty_federations, _)); | |
311 EvaluateJavaScriptAsString( | |
312 @"navigator.credentials.request({federations: ['foo', 'bar']})"); | |
313 | |
314 EXPECT_CALL(observer(), | |
315 CredentialsRequested(4, _, true, nonempty_federations, _)); | |
316 EvaluateJavaScriptAsString( | |
317 @"navigator.credentials.request(" | |
318 @" { suppressUI: true, federations: ['foo', 'bar'] })"); | |
319 | |
320 EXPECT_CALL(observer(), | |
321 CredentialsRequested(5, _, false, empty_federations, _)); | |
322 EvaluateJavaScriptAsString(@"navigator.credentials.request(" | |
323 @" { suppressUI: false, federations: [] })"); | |
324 } | |
325 | |
326 // Tests that navigator.credentials.notifySignedIn() creates and forwards the | |
327 // right arguments to the app side. | |
328 TEST_F(CredentialManagerJsTest, NotifySignedInToApp) { | |
329 Inject(); | |
330 EXPECT_CALL(observer(), SignedIn(0, _)); | |
331 EvaluateJavaScriptAsString(@"navigator.credentials.notifySignedIn()"); | |
332 | |
333 EXPECT_CALL(observer(), SignedIn(1, _, IsEqualTo(test_credential()))); | |
334 EvaluateJavaScriptAsString( | |
335 [NSString stringWithFormat:@"navigator.credentials.notifySignedIn(%@)", | |
336 test_credential_js()]); | |
337 } | |
338 | |
339 // Tests that navigator.credentials.notifySignedOut() creates and forwards the | |
340 // right arguments to the app side. | |
341 TEST_F(CredentialManagerJsTest, NotifySignedOutToApp) { | |
342 Inject(); | |
343 EXPECT_CALL(observer(), SignedOut(0, _)); | |
344 EvaluateJavaScriptAsString(@"navigator.credentials.notifySignedOut()"); | |
345 } | |
346 | |
347 // Tests that navigator.credentials.notifyFailedSignIn() creates and forwards | |
348 // the right arguments to the app side. | |
349 TEST_F(CredentialManagerJsTest, NotifyFailedSignInToApp) { | |
350 Inject(); | |
351 EXPECT_CALL(observer(), SignInFailed(0, _)); | |
352 EvaluateJavaScriptAsString(@"navigator.credentials.notifyFailedSignIn()"); | |
353 | |
354 EXPECT_CALL(observer(), SignInFailed(1, _, IsEqualTo(test_credential()))); | |
355 EvaluateJavaScriptAsString([NSString | |
356 stringWithFormat:@"navigator.credentials.notifyFailedSignIn(%@)", | |
357 test_credential_js()]); | |
358 } | |
359 | |
360 // Tests that resolving the promise returned by a call to | |
361 // navigator.credentials.request() with a credential correctly forwards that | |
362 // credential to the client. | |
363 TEST_F(CredentialManagerJsTest, ResolveRequestPromiseWithCredential) { | |
364 Inject(); | |
365 const int request_id = 0; | |
366 EXPECT_CALL(observer(), CredentialsRequested(request_id, _, _, _, _)); | |
367 TestPromiseResolutionWithCredential(request_id, | |
368 @"navigator.credentials.request()"); | |
369 } | |
370 | |
371 // Tests that resolving the promise returned by a call to | |
372 // navigator.credentials.request() without a credential correctly invokes the | |
373 // client handler. | |
374 TEST_F(CredentialManagerJsTest, ResolveRequestPromiseWithoutCredential) { | |
375 Inject(); | |
376 const int request_id = 0; | |
377 EXPECT_CALL(observer(), CredentialsRequested(request_id, _, _, _, _)); | |
378 TestPromiseResolutionWithoutCredential(request_id, | |
379 @"navigator.credentials.request()"); | |
380 } | |
381 | |
382 // Tests that resolving the promise returned by a call to | |
383 // navigator.credentials.notifySignedIn() without a credential correctly invokes | |
384 // the client handler. | |
385 TEST_F(CredentialManagerJsTest, ResolveNotifySignedInPromiseWithoutCredential) { | |
386 Inject(); | |
387 const int request_id = 0; | |
388 EXPECT_CALL(observer(), SignedIn(request_id, _)); | |
389 TestPromiseResolutionWithoutCredential( | |
390 request_id, @"navigator.credentials.notifySignedIn()"); | |
391 } | |
392 | |
393 // Tests that resolving the promise returned by a call to | |
394 // navigator.credentials.notifyFailedSignIn() without a credential correctly | |
395 // invokes the client handler. | |
396 TEST_F(CredentialManagerJsTest, | |
397 ResolveNotifyFailedSignInPromiseWithoutCredential) { | |
398 Inject(); | |
399 const int request_id = 0; | |
400 EXPECT_CALL(observer(), SignInFailed(request_id, _)); | |
401 TestPromiseResolutionWithoutCredential( | |
402 request_id, @"navigator.credentials.notifyFailedSignIn()"); | |
403 } | |
404 | |
405 // Tests that resolving the promise returned by a call to | |
406 // navigator.credentials.notifyFailedSignIn() without a credential correctly | |
407 // invokes the client handler. | |
408 TEST_F(CredentialManagerJsTest, | |
409 ResolveNotifySignedOutPromiseWithoutCredential) { | |
410 Inject(); | |
411 const int request_id = 0; | |
412 EXPECT_CALL(observer(), SignedOut(request_id, _)); | |
413 TestPromiseResolutionWithoutCredential( | |
414 request_id, @"navigator.credentials.notifySignedOut()"); | |
415 } | |
416 | |
417 // Tests that rejecting the promise returned by a call to | |
418 // navigator.credentials.request() with a InvalidStateError correctly forwards | |
419 // that error to the client. | |
420 TEST_F(CredentialManagerJsTest, RejectRequestPromiseWithInvalidStateError) { | |
421 Inject(); | |
422 const int request_id = 0; | |
423 EXPECT_CALL(observer(), CredentialsRequested(request_id, _, _, _, _)); | |
424 TestPromiseRejection(request_id, @"InvalidStateError", @"foo", | |
425 @"navigator.credentials.request()"); | |
426 } | |
427 | |
428 // Tests that rejecting the promise returned by a call to | |
429 // navigator.credentials.notifySignedIn() with a InvalidStateError correctly | |
430 // forwards that error to the client. | |
431 TEST_F(CredentialManagerJsTest, | |
432 RejectNotifySignedInPromiseWithInvalidStateError) { | |
433 Inject(); | |
434 const int request_id = 0; | |
435 EXPECT_CALL(observer(), SignedIn(request_id, _)); | |
436 TestPromiseRejection(request_id, @"InvalidStateError", @"foo", | |
437 @"navigator.credentials.notifySignedIn()"); | |
438 } | |
439 | |
440 // Tests that rejecting the promise returned by a call to | |
441 // navigator.credentials.notifyFailedSignIn() with a InvalidStateError correctly | |
442 // forwards that error to the client. | |
443 TEST_F(CredentialManagerJsTest, | |
444 RejectNotifyFailedSignInPromiseWithInvalidStateError) { | |
445 Inject(); | |
446 const int request_id = 0; | |
447 EXPECT_CALL(observer(), SignInFailed(request_id, _)); | |
448 TestPromiseRejection(request_id, @"InvalidStateError", @"foo", | |
449 @"navigator.credentials.notifyFailedSignIn()"); | |
450 } | |
451 | |
452 // Tests that rejecting the promise returned by a call to | |
453 // navigator.credentials.notifySignedOut() with a InvalidStateError correctly | |
454 // forwards that error to the client. | |
455 TEST_F(CredentialManagerJsTest, | |
456 RejectNotifySignedOutPromiseWithInvalidStateError) { | |
457 Inject(); | |
458 const int request_id = 0; | |
459 EXPECT_CALL(observer(), SignedOut(request_id, _)); | |
460 TestPromiseRejection(request_id, @"InvalidStateError", @"foo", | |
461 @"navigator.credentials.notifySignedOut()"); | |
462 } | |
463 | |
464 // Tests that rejecting the promise returned by a call to | |
465 // navigator.credentials.request() with a SecurityError correctly forwards that | |
466 // error to the client. | |
467 TEST_F(CredentialManagerJsTest, RejectRequestPromiseWithSecurityError) { | |
468 Inject(); | |
469 const int request_id = 0; | |
470 EXPECT_CALL(observer(), CredentialsRequested(request_id, _, _, _, _)); | |
471 TestPromiseRejection(request_id, @"SecurityError", @"foo", | |
472 @"navigator.credentials.request()"); | |
473 } | |
474 | |
475 // Tests that rejecting the promise returned by a call to | |
476 // navigator.credentials.notifySignedIn() with a SecurityError correctly | |
477 // forwards that error to the client. | |
478 TEST_F(CredentialManagerJsTest, RejectNotifySignedInPromiseWithSecurityError) { | |
479 Inject(); | |
480 const int request_id = 0; | |
481 EXPECT_CALL(observer(), SignedIn(request_id, _)); | |
482 TestPromiseRejection(request_id, @"SecurityError", @"foo", | |
483 @"navigator.credentials.notifySignedIn()"); | |
484 } | |
485 | |
486 // Tests that rejecting the promise returned by a call to | |
487 // navigator.credentials.notifyFailedSignIn() with a SecurityError correctly | |
488 // forwards that error to the client. | |
489 TEST_F(CredentialManagerJsTest, | |
490 RejectPromiseWithSecurityError_notifyFailedSignIn) { | |
491 Inject(); | |
492 const int request_id = 0; | |
493 EXPECT_CALL(observer(), SignInFailed(request_id, _)); | |
494 TestPromiseRejection(request_id, @"SecurityError", @"foo", | |
495 @"navigator.credentials.notifyFailedSignIn()"); | |
496 } | |
497 | |
498 // Tests that rejecting the promise returned by a call to | |
499 // navigator.credentials.notifySignedOut() with a SecurityError correctly | |
500 // forwards that error to the client. | |
501 TEST_F(CredentialManagerJsTest, | |
502 RejectPromiseWithSecurityError_notifySignedOut) { | |
503 Inject(); | |
504 const int request_id = 0; | |
505 EXPECT_CALL(observer(), SignedOut(request_id, _)); | |
506 TestPromiseRejection(request_id, @"SecurityError", @"foo", | |
507 @"navigator.credentials.notifySignedOut()"); | |
508 } | |
509 | |
510 } // namespace | |
OLD | NEW |