|
16 | 16 | */
|
17 | 17 | import '../test/setup';
|
18 | 18 | import { expect } from 'chai';
|
19 |
| -import { stub } from 'sinon'; |
20 |
| -import { activate, setTokenAutoRefreshEnabled } from './api'; |
| 19 | +import { stub, spy, restore } from 'sinon'; |
| 20 | +import { |
| 21 | + activate, |
| 22 | + setTokenAutoRefreshEnabled, |
| 23 | + getToken, |
| 24 | + onTokenChanged |
| 25 | +} from './api'; |
21 | 26 | import {
|
22 | 27 | FAKE_SITE_KEY,
|
23 | 28 | getFakeApp,
|
24 |
| - getFakeCustomTokenProvider |
| 29 | + getFakeCustomTokenProvider, |
| 30 | + getFakePlatformLoggingProvider, |
| 31 | + removegreCAPTCHAScriptsOnPage |
25 | 32 | } from '../test/util';
|
26 |
| -import { getState } from './state'; |
| 33 | +import { clearState, getState } from './state'; |
27 | 34 | import * as reCAPTCHA from './recaptcha';
|
28 | 35 | import { FirebaseApp } from '@firebase/app-types';
|
| 36 | +import * as internalApi from './internal-api'; |
| 37 | +import * as client from './client'; |
| 38 | +import * as storage from './storage'; |
29 | 39 |
|
30 | 40 | describe('api', () => {
|
31 | 41 | describe('activate()', () => {
|
@@ -86,4 +96,137 @@ describe('api', () => {
|
86 | 96 | expect(getState(app).isTokenAutoRefreshEnabled).to.equal(true);
|
87 | 97 | });
|
88 | 98 | });
|
| 99 | + describe('getToken()', () => { |
| 100 | + it('getToken() calls the internal getToken() function', async () => { |
| 101 | + const app = getFakeApp({ automaticDataCollectionEnabled: true }); |
| 102 | + const fakePlatformLoggingProvider = getFakePlatformLoggingProvider(); |
| 103 | + const internalGetToken = stub(internalApi, 'getToken').resolves({ |
| 104 | + token: 'a-token-string' |
| 105 | + }); |
| 106 | + await getToken(app, fakePlatformLoggingProvider, true); |
| 107 | + expect(internalGetToken).to.be.calledWith( |
| 108 | + app, |
| 109 | + fakePlatformLoggingProvider, |
| 110 | + true |
| 111 | + ); |
| 112 | + }); |
| 113 | + it('getToken() throws errors returned with token', async () => { |
| 114 | + const app = getFakeApp({ automaticDataCollectionEnabled: true }); |
| 115 | + const fakePlatformLoggingProvider = getFakePlatformLoggingProvider(); |
| 116 | + stub(internalApi, 'getToken').resolves({ |
| 117 | + token: 'a-token-string', |
| 118 | + error: Error('there was an error') |
| 119 | + }); |
| 120 | + await expect( |
| 121 | + getToken(app, fakePlatformLoggingProvider, true) |
| 122 | + ).to.be.rejectedWith('there was an error'); |
| 123 | + }); |
| 124 | + }); |
| 125 | + describe('onTokenChanged()', () => { |
| 126 | + afterEach(() => { |
| 127 | + clearState(); |
| 128 | + removegreCAPTCHAScriptsOnPage(); |
| 129 | + }); |
| 130 | + it('Listeners work when using top-level parameters pattern', async () => { |
| 131 | + const app = getFakeApp({ automaticDataCollectionEnabled: true }); |
| 132 | + activate(app, FAKE_SITE_KEY, true); |
| 133 | + const fakePlatformLoggingProvider = getFakePlatformLoggingProvider(); |
| 134 | + const fakeRecaptchaToken = 'fake-recaptcha-token'; |
| 135 | + const fakeRecaptchaAppCheckToken = { |
| 136 | + token: 'fake-recaptcha-app-check-token', |
| 137 | + expireTimeMillis: 123, |
| 138 | + issuedAtTimeMillis: 0 |
| 139 | + }; |
| 140 | + stub(reCAPTCHA, 'getToken').returns(Promise.resolve(fakeRecaptchaToken)); |
| 141 | + stub(client, 'exchangeToken').returns( |
| 142 | + Promise.resolve(fakeRecaptchaAppCheckToken) |
| 143 | + ); |
| 144 | + stub(storage, 'writeTokenToStorage').returns(Promise.resolve(undefined)); |
| 145 | + |
| 146 | + const listener1 = (): void => { |
| 147 | + throw new Error(); |
| 148 | + }; |
| 149 | + const listener2 = spy(); |
| 150 | + |
| 151 | + const errorFn1 = spy(); |
| 152 | + const errorFn2 = spy(); |
| 153 | + |
| 154 | + const unSubscribe1 = onTokenChanged( |
| 155 | + app, |
| 156 | + fakePlatformLoggingProvider, |
| 157 | + listener1, |
| 158 | + errorFn1 |
| 159 | + ); |
| 160 | + const unSubscribe2 = onTokenChanged( |
| 161 | + app, |
| 162 | + fakePlatformLoggingProvider, |
| 163 | + listener2, |
| 164 | + errorFn2 |
| 165 | + ); |
| 166 | + |
| 167 | + expect(getState(app).tokenListeners.length).to.equal(2); |
| 168 | + |
| 169 | + await getToken(app, fakePlatformLoggingProvider); |
| 170 | + |
| 171 | + expect(listener2).to.be.calledWith({ |
| 172 | + token: fakeRecaptchaAppCheckToken.token |
| 173 | + }); |
| 174 | + expect(errorFn1).to.be.calledOnce; |
| 175 | + expect(errorFn2).to.not.be.called; |
| 176 | + unSubscribe1(); |
| 177 | + unSubscribe2(); |
| 178 | + expect(getState(app).tokenListeners.length).to.equal(0); |
| 179 | + }); |
| 180 | + |
| 181 | + it('Listeners work when using Observer pattern', async () => { |
| 182 | + const app = getFakeApp({ automaticDataCollectionEnabled: true }); |
| 183 | + activate(app, FAKE_SITE_KEY, true); |
| 184 | + const fakePlatformLoggingProvider = getFakePlatformLoggingProvider(); |
| 185 | + const fakeRecaptchaToken = 'fake-recaptcha-token'; |
| 186 | + const fakeRecaptchaAppCheckToken = { |
| 187 | + token: 'fake-recaptcha-app-check-token', |
| 188 | + expireTimeMillis: 123, |
| 189 | + issuedAtTimeMillis: 0 |
| 190 | + }; |
| 191 | + stub(reCAPTCHA, 'getToken').returns(Promise.resolve(fakeRecaptchaToken)); |
| 192 | + stub(client, 'exchangeToken').returns( |
| 193 | + Promise.resolve(fakeRecaptchaAppCheckToken) |
| 194 | + ); |
| 195 | + stub(storage, 'writeTokenToStorage').returns(Promise.resolve(undefined)); |
| 196 | + |
| 197 | + const listener1 = (): void => { |
| 198 | + throw new Error(); |
| 199 | + }; |
| 200 | + const listener2 = spy(); |
| 201 | + |
| 202 | + const errorFn1 = spy(); |
| 203 | + const errorFn2 = spy(); |
| 204 | + |
| 205 | + /** |
| 206 | + * Reverse the order of adding the failed and successful handler, for extra |
| 207 | + * testing. |
| 208 | + */ |
| 209 | + const unSubscribe2 = onTokenChanged(app, fakePlatformLoggingProvider, { |
| 210 | + next: listener2, |
| 211 | + error: errorFn2 |
| 212 | + }); |
| 213 | + const unSubscribe1 = onTokenChanged(app, fakePlatformLoggingProvider, { |
| 214 | + next: listener1, |
| 215 | + error: errorFn1 |
| 216 | + }); |
| 217 | + |
| 218 | + expect(getState(app).tokenListeners.length).to.equal(2); |
| 219 | + |
| 220 | + await getToken(app, fakePlatformLoggingProvider); |
| 221 | + |
| 222 | + expect(listener2).to.be.calledWith({ |
| 223 | + token: fakeRecaptchaAppCheckToken.token |
| 224 | + }); |
| 225 | + expect(errorFn1).to.be.calledOnce; |
| 226 | + expect(errorFn2).to.not.be.called; |
| 227 | + unSubscribe1(); |
| 228 | + unSubscribe2(); |
| 229 | + expect(getState(app).tokenListeners.length).to.equal(0); |
| 230 | + }); |
| 231 | + }); |
89 | 232 | });
|
0 commit comments