Check for response.ok in fetch calls

It's possible for a call to fetch to trigger then "then" callback
even thought the response is an error [1]. We should test for both
scenarios, since they are handled differently. To avoid duplicating
the tests, I've used Jest's parameterisation feature [2].

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
[2]: https://jestjs.io/docs/api#testeachtablename-fn-timeout
This commit is contained in:
Ben Thorner
2021-05-12 17:16:03 +01:00
parent 6948f5f003
commit 9ee01a2567
2 changed files with 28 additions and 6 deletions

View File

@@ -9,6 +9,10 @@
fetch('/webauthn/register')
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
return response.arrayBuffer();
})
.then((data) => {
@@ -21,7 +25,11 @@
credential.response, component.data('csrfToken')
);
})
.then(() => {
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
window.location.reload();
})
.catch((error) => {

View File

@@ -77,16 +77,23 @@ describe('Register security key', () => {
expect(decodedData.clientDataJSON).toEqual(new Uint8Array([4,5,6]))
expect(decodedData.attestationObject).toEqual(new Uint8Array([1,2,3]))
expect(options.headers['X-CSRFToken']).toBe()
return Promise.resolve()
return Promise.resolve({ ok: true })
}
})
button.click()
})
test('alerts if fetching WebAuthn options fails', (done) => {
test.each([
['network'],
['server'],
])('alerts if fetching WebAuthn options fails (%s error)', (errorType, done) => {
jest.spyOn(window, 'fetch').mockImplementation((_url, options = {}) => {
return Promise.reject('error')
if (errorType == 'network') {
return Promise.reject('error')
} else {
return Promise.resolve({ ok: false, statusText: 'error' })
}
})
jest.spyOn(window, 'alert').mockImplementation((msg) => {
@@ -97,7 +104,10 @@ describe('Register security key', () => {
button.click()
})
test('alerts if sending WebAuthn credentials fails', (done) => {
test.each([
['network'],
['server'],
])('alerts if sending WebAuthn credentials fails (%s error)', ({errorType}, done) => {
Object.defineProperty(window.navigator, 'credentials', {
value: {
// fake PublicKeyCredential response from WebAuthn API
@@ -120,7 +130,11 @@ describe('Register security key', () => {
// subsequent POST of credential data to server
} else {
return Promise.reject('error')
if (errorType == 'network') {
return Promise.reject('error')
} else {
return Promise.resolve({ ok: false, statusText: 'error' })
}
}
})