Switch to jest.spyOn for navigator.credentials

This follows the same approach as for window.fetch, using the Jest
before/afterAll() blocks to handle the idiosynchrosies of whether
the object/function is defined in the test environment.
This commit is contained in:
Ben Thorner
2021-05-12 17:27:54 +01:00
parent 9ee01a2567
commit aae01bf8e2

View File

@@ -8,6 +8,7 @@ beforeAll(() => {
// populate missing values to allow consistent jest.spyOn() // populate missing values to allow consistent jest.spyOn()
window.fetch = () => {} window.fetch = () => {}
window.navigator.credentials = { create: () => {} }
}) })
afterAll(() => { afterAll(() => {
@@ -15,6 +16,7 @@ afterAll(() => {
// restore window attributes to their original undefined state // restore window attributes to their original undefined state
delete window.fetch delete window.fetch
delete window.navigator.credentials
}) })
describe('Register security key', () => { describe('Register security key', () => {
@@ -31,29 +33,20 @@ describe('Register security key', () => {
}) })
test('creates a new credential and reloads', (done) => { test('creates a new credential and reloads', (done) => {
// pretend window.navigator.credentials exists in test env jest.spyOn(window.navigator.credentials, 'create').mockImplementation((options) => {
// defineProperty is used as window.navigator is read-only expect(options).toEqual('options')
Object.defineProperty(window.navigator, 'credentials', {
value: {
// fake PublicKeyCredential response from WebAuthn API
// both of the nested properties are Array(Buffer) objects
create: (options) => {
expect(options).toEqual('options')
return Promise.resolve({ // fake PublicKeyCredential response from WebAuthn API
response: { // both of the nested properties are Array(Buffer) objects
attestationObject: [1, 2, 3], return Promise.resolve({
clientDataJSON: [4, 5, 6], response: {
} attestationObject: [1, 2, 3],
}) clientDataJSON: [4, 5, 6],
} }
}, })
// allow global property to be redefined in other tests
writable: true,
}) })
// pretend window.location exists in test env // pretend window.location exists in test env
// defineProperty is used as window.location is read-only
Object.defineProperty(window, 'location', { Object.defineProperty(window, 'location', {
// signal that the async promise chain was called // signal that the async promise chain was called
value: { reload: () => done() }, value: { reload: () => done() },
@@ -108,15 +101,9 @@ describe('Register security key', () => {
['network'], ['network'],
['server'], ['server'],
])('alerts if sending WebAuthn credentials fails (%s error)', ({errorType}, done) => { ])('alerts if sending WebAuthn credentials fails (%s error)', ({errorType}, done) => {
Object.defineProperty(window.navigator, 'credentials', { jest.spyOn(window.navigator.credentials, 'create').mockImplementation(() => {
value: { // fake PublicKeyCredential response from WebAuthn API
// fake PublicKeyCredential response from WebAuthn API return Promise.resolve({ response: {} })
create: (options) => {
return Promise.resolve({ response: {} })
}
},
// allow global property to be redefined in other tests
writable: true,
}) })
jest.spyOn(window, 'fetch').mockImplementation((_url, options = {}) => { jest.spyOn(window, 'fetch').mockImplementation((_url, options = {}) => {
@@ -147,14 +134,8 @@ describe('Register security key', () => {
}) })
test('alerts if comms with the authenticator fails', (done) => { test('alerts if comms with the authenticator fails', (done) => {
Object.defineProperty(window.navigator, 'credentials', { jest.spyOn(window.navigator.credentials, 'create').mockImplementation(() => {
value: { return Promise.reject(new DOMException('error'))
create: () => {
return Promise.reject(new DOMException('error'))
}
},
// allow global property to be redefined in other tests
writable: true,
}) })
jest.spyOn(window, 'fetch').mockImplementation((_url, options) => { jest.spyOn(window, 'fetch').mockImplementation((_url, options) => {