Skip to content

Commit

Permalink
[FedCM] Move most tests to fedcm-network-requests
Browse files Browse the repository at this point in the history
This way they do not rely on the mojo mock and instead make real network
requests. This allows other browsers to run these tests and also tests
more of our code.

R=yigu@chromium.org

Bug: 1309251
Change-Id: I91ab663b65beb694da89265fb6b0294c3b4e50d8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3701092
Reviewed-by: Yi Gu <yigu@chromium.org>
Auto-Submit: Christian Biesinger <cbiesinger@chromium.org>
Commit-Queue: Christian Biesinger <cbiesinger@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1013621}
  • Loading branch information
cbiesinger authored and chromium-wpt-export-bot committed Jun 13, 2022
1 parent f1688b3 commit 29a7d56
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 167 deletions.
140 changes: 131 additions & 9 deletions credential-management/fedcm-network-requests.sub.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,138 @@
import {set_fedcm_cookie} from './support/fedcm-helper.js';

const url_prefix = 'https://{{host}}:{{ports[https][0]}}/credential-management/support/';
const test_options = {
federated: {
providers: [{
url: url_prefix,
clientId: '1',
}]
}
};
const login_options = {
nonce: '2',
};

promise_test(async t => {
await set_fedcm_cookie();
const result = await navigator.credentials.get({
federated: {
providers: [{
url: url_prefix,
clientId: '1',
}]
}
const cred = await navigator.credentials.get(test_options);
const token = await cred.login(login_options);
assert_equals(token.idToken, "token");
}, "Successfully obtaining id_token should resolve the promise.");

promise_test(async t => {
await set_fedcm_cookie();
const first = await navigator.credentials.get(test_options);
const second = await navigator.credentials.get(test_options);
const first_cred = first.login(login_options);
const second_cred = second.login(login_options);
// We have to call promise_rejects_dom here, because if we call it after
// the promise gets rejected, the unhandled rejection event handler is called
// and fails the test even if we handle the rejection later.
const rej = promise_rejects_dom(t, 'AbortError', second_cred);

const first_token = await first_cred;
assert_equals(first_token.idToken, "token");
return rej;
},
"When there's a pending request, a second `get` call should be rejected. ");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
clientId: '1',
nonce: '2',
}]
}
});
return promise_rejects_js(t, TypeError, result);
}, "Reject when url is missing" );

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'test',
clientId: '1',
}]
}
});
const token = await result.login({nonce: '1'});
return promise_rejects_dom(t, "InvalidStateError", result);
}, "Reject when url is invalid");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
clientId: '',
}]
}
});
return promise_rejects_dom(t, "InvalidStateError", result);
}, "Reject when clientId is empty");

promise_test(async t => {
const cred = await navigator.credentials.get(test_options);
const token = await cred.login({});

assert_equals(token.idToken, "token");
}, "nonce is not required in FederatedIdentityProvider.");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
}]
}
});
return promise_rejects_js(t, TypeError, result);
}, "Reject when clientId is missing" );

promise_test(async t => {
let controller = new AbortController();
const cred = await navigator.credentials.get(test_options);
const token_promise = cred.login({
nonce: '2',
signal: controller.signal,
});
controller.abort();
return promise_rejects_dom(t, 'AbortError', token_promise);
}, "test the abort signal");

promise_test(async t => {
let controller = new AbortController();
const cred = await navigator.credentials.get(test_options);
const token_promise = cred.login({
nonce: '2',
signal: controller.signal,
});
controller.abort();
await promise_rejects_dom(t, 'AbortError', token_promise);

const cred2 = await navigator.credentials.get(test_options);
const token = await cred2.login(login_options);
assert_equals(token.idToken, "token");
}, "get after abort should work");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'https://other-idp.test/',
clientId: '1',
}]
}
});
return promise_rejects_dom(t, "NetworkError", result);
}, "Provider URL should honor Content-Security-Policy.");

promise_test(async t => {
await set_fedcm_cookie();
const result = await navigator.credentials.get(test_options);
const token = await result.login(login_options);
assert_equals(token.idToken, 'token');
}, 'Test that COEP policy do not apply to FedCM requests');

Expand All @@ -34,6 +155,7 @@
}]
}
});
return promise_rejects_dom(t, 'NetworkError', result.login({nonce: '1'}));
return promise_rejects_dom(t, 'NetworkError', result.login(login_options));
}, 'Test that the promise is rejected if the manifest is not in the manifest list');

</script>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Cross-Origin-Embedder-Policy: credentialless
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src https://{{host}}:{{ports[https][0]}}/never/used/path
156 changes: 0 additions & 156 deletions credential-management/fedcm.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,167 +19,11 @@
};


fedcm_test(async (t, mock) => {
mock.returnIdToken("a_token");
const cred = await navigator.credentials.get(test_options);
const token = await cred.login(login_options);
assert_equals(token.idToken, "a_token");
}, "Successfully obtaining id_token should resolve the promise.");

fedcm_test(async (t, mock) => {
mock.returnError("ApprovalDeclined");
const cred = await navigator.credentials.get(test_options);
const token = cred.login(login_options);
return promise_rejects_dom(t, 'AbortError', token);
}, "User approval decline should reject the promise.");

fedcm_test(async (t, mock) => {
mock.returnError("ErrorTooManyRequests");
const first = await navigator.credentials.get(test_options);
const first_token = await first.login(login_options);
const second = await navigator.credentials.get(test_options);
const second_token = await second.login(login_options);
assert_equals(first_token.idToken, undefined);
return promise_rejects_dom(t, 'AbortError', second_token);
},
"When there's a pending request, a second `get` call should be rejected. ",
"Only one navigator.credentials.get request may be outstanding at one time.");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
clientId: '1',
nonce: '2',
}]
}
});
return promise_rejects_js(t, TypeError, result);
}, "Reject when url is missing" );

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'test',
clientId: '1',
nonce: '2',
}]
}
});
return promise_rejects_dom(t, "InvalidStateError", result);
}, "Reject when url is invalid");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
nonce: '2',
}]
}
});
return promise_rejects_js(t, TypeError, result);
}, "Reject when clientId is missing" );

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
clientId: '',
nonce: '1',
}]
}
});
return promise_rejects_dom(t, "InvalidStateError", result);
}, "Reject when clientId is empty");

fedcm_test(async (t, mock) => {
mock.returnIdToken("a_token");
const cred = await navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
clientId: '1',
}]
}
});
const token = await cred.login(login_options);

assert_equals(token.idToken, "a_token");
}, "nonce is not required in FederatedIdentityProvider.");

fedcm_test(async (t, mock) => {
let controller = new AbortController();
mock.returnPendingPromise();
let aborted = false;
const cred = await navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
clientId: '1',
}],
},
});
const token_promise = cred.login({
nonce: '2',
signal: controller.signal,
});
assert_equals(aborted, false);
controller.abort();
try {
await token_promise;
} catch (e) {
aborted = true;
assert_equals(e.name, "AbortError");
}
assert_equals(aborted, true);
}, "test the abort signal");

fedcm_test(async (t, mock) => {
let controller = new AbortController();
mock.returnPendingPromise();
let aborted = false;
const cred = await navigator.credentials.get({
federated: {
providers: [{
url: 'https://idp.test',
clientId: '1',
}],
},
});
const token_promise = cred.login({
nonce: '2',
signal: controller.signal,
});
assert_equals(aborted, false);
controller.abort();
try {
await token_promise;
} catch (e) {
aborted = true;
assert_equals(e.name, "AbortError");
}
assert_equals(aborted, true);

mock.returnIdToken("a_token");
const cred2 = await navigator.credentials.get(test_options);
const token = await cred2.login(login_options);
assert_equals(token.idToken, "a_token");
}, "get after abort should work");

promise_test(async t => {
const result = navigator.credentials.get({
federated: {
providers: [{
url: 'https://other-idp.test/',
clientId: '1',
nonce: '1',
}]
}
});
return promise_rejects_dom(t, "NetworkError", result);
}, "Provider URL should honor Content-Security-Policy.");

</script>
1 change: 0 additions & 1 deletion credential-management/fedcm.https.html.headers

This file was deleted.

0 comments on commit 29a7d56

Please sign in to comment.