diff --git a/packages/messaging/index.ts b/packages/messaging/index.ts index 82990883925..2d6ca89aabd 100644 --- a/packages/messaging/index.ts +++ b/packages/messaging/index.ts @@ -16,30 +16,47 @@ */ import firebase from '@firebase/app'; +import '@firebase/installations'; import { _FirebaseNamespace, - FirebaseServiceFactory + FirebaseService } from '@firebase/app-types/private'; import { FirebaseMessaging } from '@firebase/messaging-types'; - import { SwController } from './src/controllers/sw-controller'; import { WindowController } from './src/controllers/window-controller'; import { ErrorCode, errorFactory } from './src/models/errors'; +import { + Component, + ComponentType, + ComponentContainer +} from '@firebase/component'; +import { FirebaseInternalServices } from './src/interfaces/internal-services'; export function registerMessaging(instance: _FirebaseNamespace): void { const messagingName = 'messaging'; - const factoryMethod: FirebaseServiceFactory = app => { + const factoryMethod = (container: ComponentContainer): FirebaseService => { + /* Dependencies */ + const app = container.getProvider('app').getImmediate(); + const installations = container.getProvider('installations').getImmediate(); + const analyticsProvider = container.getProvider('analytics-internal'); + + const firebaseServices: FirebaseInternalServices = { + app, + installations, + analyticsProvider + }; + if (!isSupported()) { throw errorFactory.create(ErrorCode.UNSUPPORTED_BROWSER); } if (self && 'ServiceWorkerGlobalScope' in self) { // Running in ServiceWorker context - return new SwController(app); + return new SwController(firebaseServices); } else { // Assume we are in the window context. - return new WindowController(app); + return new WindowController(firebaseServices); } }; @@ -47,10 +64,12 @@ export function registerMessaging(instance: _FirebaseNamespace): void { isSupported }; - instance.INTERNAL.registerService( - messagingName, - factoryMethod, - namespaceExports + instance.INTERNAL.registerComponent( + new Component( + messagingName, + factoryMethod, + ComponentType.PUBLIC + ).setServiceProps(namespaceExports) ); } diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 0803a760915..8d1638a2e22 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -29,6 +29,7 @@ "@firebase/installations": "0.3.2", "@firebase/messaging-types": "0.3.4", "@firebase/util": "0.2.31", + "@firebase/component": "0.1.0", "tslib": "1.10.0" }, "devDependencies": { diff --git a/packages/messaging/src/controllers/base-controller.ts b/packages/messaging/src/controllers/base-controller.ts index 7a81f49def3..f0ee2b3e6e2 100644 --- a/packages/messaging/src/controllers/base-controller.ts +++ b/packages/messaging/src/controllers/base-controller.ts @@ -33,6 +33,7 @@ import { ErrorCode, errorFactory } from '../models/errors'; import { SubscriptionManager } from '../models/subscription-manager'; import { TokenDetailsModel } from '../models/token-details-model'; import { VapidDetailsModel } from '../models/vapid-details-model'; +import { FirebaseInternalServices } from '../interfaces/internal-services'; export type BgMessageHandler = ( payload: MessagePayload @@ -43,11 +44,14 @@ export const TOKEN_EXPIRATION_MILLIS = 7 * 24 * 60 * 60 * 1000; // 7 days export abstract class BaseController implements FirebaseMessaging { INTERNAL: FirebaseServiceInternals; + readonly app: FirebaseApp; private readonly tokenDetailsModel: TokenDetailsModel; private readonly vapidDetailsModel = new VapidDetailsModel(); private readonly subscriptionManager = new SubscriptionManager(); - constructor(readonly app: FirebaseApp) { + constructor(protected readonly services: FirebaseInternalServices) { + const { app } = services; + this.app = app; if ( !app.options.messagingSenderId || typeof app.options.messagingSenderId !== 'string' @@ -59,7 +63,7 @@ export abstract class BaseController implements FirebaseMessaging { delete: () => this.delete() }; - this.tokenDetailsModel = new TokenDetailsModel(app); + this.tokenDetailsModel = new TokenDetailsModel(services); } async getToken(): Promise { @@ -147,7 +151,7 @@ export abstract class BaseController implements FirebaseMessaging { try { const updatedToken = await this.subscriptionManager.updateToken( tokenDetails, - this.app, + this.services, pushSubscription, publicVapidKey ); @@ -155,7 +159,7 @@ export abstract class BaseController implements FirebaseMessaging { const allDetails: TokenDetails = { swScope: swReg.scope, vapidKey: publicVapidKey, - fcmSenderId: this.app.options.messagingSenderId!, + fcmSenderId: this.services.app.options.messagingSenderId!, fcmToken: updatedToken, createTime: Date.now(), endpoint: pushSubscription.endpoint, @@ -181,7 +185,7 @@ export abstract class BaseController implements FirebaseMessaging { publicVapidKey: Uint8Array ): Promise { const newToken = await this.subscriptionManager.getToken( - this.app, + this.services, pushSubscription, publicVapidKey ); @@ -228,7 +232,7 @@ export abstract class BaseController implements FirebaseMessaging { */ private async deleteTokenFromDB(token: string): Promise { const tokenDetails = await this.tokenDetailsModel.deleteToken(token); - await this.subscriptionManager.deleteToken(this.app, tokenDetails); + await this.subscriptionManager.deleteToken(this.services, tokenDetails); } // Visible for testing diff --git a/packages/messaging/src/controllers/sw-controller.ts b/packages/messaging/src/controllers/sw-controller.ts index 5667cf7a63c..8c2b291550b 100644 --- a/packages/messaging/src/controllers/sw-controller.ts +++ b/packages/messaging/src/controllers/sw-controller.ts @@ -16,9 +16,6 @@ */ import './sw-types'; - -import { FirebaseApp } from '@firebase/app-types'; - import { MessagePayload, NotificationDetails @@ -30,6 +27,7 @@ import { } from '../models/fcm-details'; import { InternalMessage, MessageType } from '../models/worker-page-message'; import { BaseController, BgMessageHandler } from './base-controller'; +import { FirebaseInternalServices } from '../interfaces/internal-services'; // Let TS know that this is a service worker declare const self: ServiceWorkerGlobalScope; @@ -39,8 +37,8 @@ const FCM_MSG = 'FCM_MSG'; export class SwController extends BaseController { private bgMessageHandler: BgMessageHandler | null = null; - constructor(app: FirebaseApp) { - super(app); + constructor(services: FirebaseInternalServices) { + super(services); self.addEventListener('push', e => { this.onPush(e); diff --git a/packages/messaging/src/controllers/window-controller.ts b/packages/messaging/src/controllers/window-controller.ts index 7f990ad160d..2b97786effd 100644 --- a/packages/messaging/src/controllers/window-controller.ts +++ b/packages/messaging/src/controllers/window-controller.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import { FirebaseApp } from '@firebase/app-types'; import { _FirebaseApp } from '@firebase/app-types/private'; import { CompleteFn, @@ -39,6 +38,7 @@ import { } from '../models/fcm-details'; import { InternalMessage, MessageType } from '../models/worker-page-message'; import { BaseController } from './base-controller'; +import { FirebaseInternalServices } from '../interfaces/internal-services'; export class WindowController extends BaseController { private registrationToUse: ServiceWorkerRegistration | null = null; @@ -63,8 +63,8 @@ export class WindowController extends BaseController { /** * A service that provides a MessagingService instance. */ - constructor(app: FirebaseApp) { - super(app); + constructor(services: FirebaseInternalServices) { + super(services); this.setupSWMessageListener_(); } @@ -308,16 +308,23 @@ export class WindowController extends BaseController { // This message has a campaign id, meaning it was sent using the FN Console. // Analytics is enabled on this message, so we should log it. const eventType = getEventType(firebaseMessagingType); - (this.app as _FirebaseApp).INTERNAL.analytics.logEvent( - eventType, - /* eslint-disable camelcase */ - { - message_name: data[FN_CAMPAIGN_NAME], - message_id: data[FN_CAMPAIGN_ID], - message_time: data[FN_CAMPAIGN_TIME], - message_device_time: Math.floor(Date.now() / 1000) + this.services.analyticsProvider.get().then( + analytics => { + analytics.logEvent( + eventType, + /* eslint-disable camelcase */ + { + message_name: data[FN_CAMPAIGN_NAME], + message_id: data[FN_CAMPAIGN_ID], + message_time: data[FN_CAMPAIGN_TIME], + message_device_time: Math.floor(Date.now() / 1000) + } + /* eslint-enable camelcase */ + ); + }, + () => { + /* it will never reject */ } - /* eslint-enable camelcase */ ); } }, diff --git a/packages/messaging/src/interfaces/internal-services.ts b/packages/messaging/src/interfaces/internal-services.ts new file mode 100644 index 00000000000..b122ddaae83 --- /dev/null +++ b/packages/messaging/src/interfaces/internal-services.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FirebaseApp } from '@firebase/app-types'; +import { FirebaseInstallations } from '@firebase/installations-types'; +import { FirebaseAnalyticsInternal } from '@firebase/analytics-interop-types'; +import { Provider } from '@firebase/component'; + +export interface FirebaseInternalServices { + app: FirebaseApp; + installations: FirebaseInstallations; + analyticsProvider: Provider; +} diff --git a/packages/messaging/src/models/clean-v1-undefined.ts b/packages/messaging/src/models/clean-v1-undefined.ts index 7952d338934..bbedc93c4b6 100644 --- a/packages/messaging/src/models/clean-v1-undefined.ts +++ b/packages/messaging/src/models/clean-v1-undefined.ts @@ -28,12 +28,12 @@ */ import { SubscriptionManager } from './subscription-manager'; -import { FirebaseApp } from '@firebase/app-types'; +import { FirebaseInternalServices } from '../interfaces/internal-services'; const OLD_DB_NAME = 'undefined'; const OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store'; -function handleDb(db: IDBDatabase, app: FirebaseApp): void { +function handleDb(db: IDBDatabase, services: FirebaseInternalServices): void { if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) { // We found a database with the name 'undefined', but our expected object // store isn't defined. @@ -59,7 +59,7 @@ function handleDb(db: IDBDatabase, app: FirebaseApp): void { const tokenDetails = cursor.value; // eslint-disable-next-line @typescript-eslint/no-floating-promises - subscriptionManager.deleteToken(app, tokenDetails); + subscriptionManager.deleteToken(services, tokenDetails); cursor.continue(); } else { @@ -69,13 +69,13 @@ function handleDb(db: IDBDatabase, app: FirebaseApp): void { }; } -export function cleanV1(app: FirebaseApp): void { +export function cleanV1(services: FirebaseInternalServices): void { const request: IDBOpenDBRequest = indexedDB.open(OLD_DB_NAME); request.onerror = _event => { // NOOP - Nothing we can do. }; request.onsuccess = _event => { const db = request.result; - handleDb(db, app); + handleDb(db, services); }; } diff --git a/packages/messaging/src/models/subscription-manager.ts b/packages/messaging/src/models/subscription-manager.ts index 54c871d13c6..16a62732419 100644 --- a/packages/messaging/src/models/subscription-manager.ts +++ b/packages/messaging/src/models/subscription-manager.ts @@ -20,8 +20,8 @@ import { isArrayBufferEqual } from '../helpers/is-array-buffer-equal'; import { ErrorCode, errorFactory } from './errors'; import { DEFAULT_PUBLIC_VAPID_KEY, ENDPOINT } from './fcm-details'; import { FirebaseApp } from '@firebase/app-types'; -import '@firebase/installations'; import { TokenDetails } from '../interfaces/token-details'; +import { FirebaseInternalServices } from '../interfaces/internal-services'; interface ApiResponse { token?: string; @@ -39,11 +39,11 @@ interface TokenRequestBody { export class SubscriptionManager { async getToken( - app: FirebaseApp, + services: FirebaseInternalServices, subscription: PushSubscription, vapidKey: Uint8Array ): Promise { - const headers = await getHeaders(app); + const headers = await getHeaders(services); const body = getBody(subscription, vapidKey); const subscribeOptions = { @@ -54,7 +54,7 @@ export class SubscriptionManager { let responseData: ApiResponse; try { - const response = await fetch(getEndpoint(app), subscribeOptions); + const response = await fetch(getEndpoint(services.app), subscribeOptions); responseData = await response.json(); } catch (err) { throw errorFactory.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, { @@ -81,11 +81,11 @@ export class SubscriptionManager { */ async updateToken( tokenDetails: TokenDetails, - app: FirebaseApp, + services: FirebaseInternalServices, subscription: PushSubscription, vapidKey: Uint8Array ): Promise { - const headers = await getHeaders(app); + const headers = await getHeaders(services); const body = getBody(subscription, vapidKey); const updateOptions = { @@ -97,7 +97,7 @@ export class SubscriptionManager { let responseData: ApiResponse; try { const response = await fetch( - `${getEndpoint(app)}/${tokenDetails.fcmToken}`, + `${getEndpoint(services.app)}/${tokenDetails.fcmToken}`, updateOptions ); responseData = await response.json(); @@ -122,11 +122,11 @@ export class SubscriptionManager { } async deleteToken( - app: FirebaseApp, + services: FirebaseInternalServices, tokenDetails: TokenDetails ): Promise { // TODO: Add FIS header - const headers = await getHeaders(app); + const headers = await getHeaders(services); const unsubscribeOptions = { method: 'DELETE', @@ -135,7 +135,7 @@ export class SubscriptionManager { try { const response = await fetch( - `${getEndpoint(app)}/${tokenDetails.fcmToken}`, + `${getEndpoint(services.app)}/${tokenDetails.fcmToken}`, unsubscribeOptions ); const responseData: ApiResponse = await response.json(); @@ -157,8 +157,10 @@ function getEndpoint(app: FirebaseApp): string { return `${ENDPOINT}/projects/${app.options.projectId!}/registrations`; } -async function getHeaders(app: FirebaseApp): Promise { - const installations = app.installations(); +async function getHeaders({ + app, + installations +}: FirebaseInternalServices): Promise { const authToken = await installations.getToken(); return new Headers({ diff --git a/packages/messaging/src/models/token-details-model.ts b/packages/messaging/src/models/token-details-model.ts index 6ae682e54c6..46c29ad9f3d 100644 --- a/packages/messaging/src/models/token-details-model.ts +++ b/packages/messaging/src/models/token-details-model.ts @@ -20,14 +20,14 @@ import { TokenDetails } from '../interfaces/token-details'; import { cleanV1 } from './clean-v1-undefined'; import { DbInterface } from './db-interface'; import { ErrorCode, errorFactory } from './errors'; -import { FirebaseApp } from '@firebase/app-types'; +import { FirebaseInternalServices } from '../interfaces/internal-services'; export class TokenDetailsModel extends DbInterface { protected readonly dbName: string = 'fcm_token_details_db'; protected readonly dbVersion: number = 4; protected readonly objectStoreName: string = 'fcm_token_object_Store'; - constructor(private readonly app: FirebaseApp) { + constructor(private readonly services: FirebaseInternalServices) { super(); } @@ -57,7 +57,7 @@ export class TokenDetailsModel extends DbInterface { // Prior to version 2, we were using either 'fcm_token_details_db' // or 'undefined' as the database name due to bug in the SDK // So remove the old tokens and databases. - cleanV1(this.app); + cleanV1(this.services); } case 2: { diff --git a/packages/messaging/test/constructor.test.ts b/packages/messaging/test/constructor.test.ts index 4f3f371720c..3984e5c071d 100644 --- a/packages/messaging/test/constructor.test.ts +++ b/packages/messaging/test/constructor.test.ts @@ -22,9 +22,15 @@ import { SwController } from '../src/controllers/sw-controller'; import { WindowController } from '../src/controllers/window-controller'; import { ErrorCode } from '../src/models/errors'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { + makeFakeApp, + makeFakeInstallations, + makeFakeAnalyticsProvider +} from './testing-utils/make-fake-firebase-services'; describe('Firebase Messaging > new *Controller()', () => { + const analyticsProvider = makeFakeAnalyticsProvider(); + const installations = makeFakeInstallations(); it('should handle bad input', () => { const badInputs = [ makeFakeApp({ @@ -45,8 +51,12 @@ describe('Firebase Messaging > new *Controller()', () => { ]; badInputs.forEach(badInput => { try { - new WindowController(badInput); - new SwController(badInput); + new WindowController({ + app: badInput, + installations, + analyticsProvider + }); + new SwController({ app: badInput, installations, analyticsProvider }); assert.fail( `Bad Input should have thrown: ${JSON.stringify(badInput)}` @@ -60,7 +70,7 @@ describe('Firebase Messaging > new *Controller()', () => { it('should be able to handle good input', () => { const app = makeFakeApp(); - new WindowController(app); - new SwController(app); + new WindowController({ app, installations, analyticsProvider }); + new SwController({ app, installations, analyticsProvider }); }); }); diff --git a/packages/messaging/test/controller-delete-token.test.ts b/packages/messaging/test/controller-delete-token.test.ts index 5e6f3c47d52..cc6b81b99b7 100644 --- a/packages/messaging/test/controller-delete-token.test.ts +++ b/packages/messaging/test/controller-delete-token.test.ts @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { FirebaseApp } from '@firebase/app-types'; import { assert } from 'chai'; import { stub, restore } from 'sinon'; @@ -26,16 +25,17 @@ import { SubscriptionManager } from '../src/models/subscription-manager'; import { TokenDetailsModel } from '../src/models/token-details-model'; import { deleteDatabase } from './testing-utils/db-helper'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { makeFakeSubscription } from './testing-utils/make-fake-subscription'; import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg'; import { TokenDetails } from '../src/interfaces/token-details'; +import { FirebaseInternalServices } from '../src/interfaces/internal-services'; let FAKE_SUBSCRIPTION: PushSubscription; let EXAMPLE_TOKEN_SAVE: TokenDetails; describe('Firebase Messaging > *Controller.deleteToken()', () => { - let app: FirebaseApp; + let firebaseInternalServices: FirebaseInternalServices; let messagingService: WindowController | SwController; function configureRegistrationMocks( @@ -77,7 +77,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { }); beforeEach(() => { - app = makeFakeApp({ + firebaseInternalServices = makeFakeFirebaseInternalServices({ messagingSenderId: EXAMPLE_TOKEN_SAVE.fcmSenderId }); }); @@ -93,7 +93,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { }); it('should handle no token to delete', () => { - messagingService = new WindowController(app); + messagingService = new WindowController(firebaseInternalServices); return messagingService.deleteToken(undefined as any).then( () => { throw new Error('Expected error to be thrown.'); @@ -116,7 +116,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { async () => {} ); - messagingService = new WindowController(app); + messagingService = new WindowController(firebaseInternalServices); return messagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken); }); @@ -137,7 +137,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { async () => {} ); - messagingService = new WindowController(app); + messagingService = new WindowController(firebaseInternalServices); return messagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken).then( () => { throw new Error('Expected this to reject'); @@ -166,7 +166,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { async () => {} ); - messagingService = new serviceClass(app); + messagingService = new serviceClass(firebaseInternalServices); return messagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken); }); @@ -195,7 +195,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { async () => {} ); - messagingService = new serviceClass(app); + messagingService = new serviceClass(firebaseInternalServices); return messagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken).then( () => { throw new Error('Expected this to reject'); @@ -229,7 +229,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { throw new Error(errorMsg); }); - messagingService = new serviceClass(app); + messagingService = new serviceClass(firebaseInternalServices); return messagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken).then( () => { throw new Error('Expected this to reject'); @@ -262,7 +262,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', () => { async () => {} ); - messagingService = new serviceClass(app); + messagingService = new serviceClass(firebaseInternalServices); return messagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken); }); }); diff --git a/packages/messaging/test/controller-get-token.test.ts b/packages/messaging/test/controller-get-token.test.ts index b91e06f6f9c..95c56e378dd 100644 --- a/packages/messaging/test/controller-get-token.test.ts +++ b/packages/messaging/test/controller-get-token.test.ts @@ -17,8 +17,6 @@ import { assert, expect } from 'chai'; import { stub, restore, useFakeTimers } from 'sinon'; -import { FirebaseApp } from '@firebase/app-types'; - import { BaseController } from '../src/controllers/base-controller'; import { SwController } from '../src/controllers/sw-controller'; import { WindowController } from '../src/controllers/window-controller'; @@ -31,9 +29,10 @@ import { SubscriptionManager } from '../src/models/subscription-manager'; import { TokenDetailsModel } from '../src/models/token-details-model'; import { VapidDetailsModel } from '../src/models/vapid-details-model'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { makeFakeSubscription } from './testing-utils/make-fake-subscription'; import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg'; +import { FirebaseInternalServices } from '../src/interfaces/internal-services'; const ONE_DAY = 24 * 60 * 60 * 1000; @@ -73,7 +72,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { let EXAMPLE_TOKEN_DETAILS_CUSTOM_VAPID: TokenDetails; let EXAMPLE_EXPIRED_TOKEN_DETAILS: TokenDetails; - let app: FirebaseApp; + let firebaseInternalServices: FirebaseInternalServices; beforeEach(() => { now = Date.now(); @@ -124,7 +123,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { createTime: expiredDate }; - app = makeFakeApp({ + firebaseInternalServices = makeFakeFirebaseInternalServices({ messagingSenderId: EXAMPLE_SENDER_ID }); }); @@ -142,7 +141,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { Promise.reject('No Service Worker') ); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); try { await messagingService.getToken(); throw new Error('Expected getToken to throw '); @@ -166,7 +165,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { notificationStub.onCall(3).returns('default'); return servicesToTest.reduce(async (chain, serviceClass) => { - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); stub(serviceClass.prototype, 'getPublicVapidKey_').callsFake(() => Promise.resolve(DEFAULT_PUBLIC_VAPID_KEY) ); @@ -213,7 +212,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { 'getTokenDetailsFromSWScope' ).callsFake(() => Promise.resolve(details)); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); const token = await serviceInstance.getToken(); assert.equal(details.fcmToken, token); }); @@ -239,7 +238,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { () => Promise.resolve(EXAMPLE_TOKEN_DETAILS_CUSTOM_VAPID) ); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); const token = await serviceInstance.getToken(); assert.equal(EXAMPLE_TOKEN_DETAILS_CUSTOM_VAPID.fcmToken, token); }); @@ -279,7 +278,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { async () => {} ); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); const token = await serviceInstance.getToken(); assert.equal(EXAMPLE_FCM_TOKEN, token); }); @@ -332,7 +331,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { 'saveTokenDetails' ).callsFake(async () => {}); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); const token = await serviceInstance.getToken(); assert.equal('example-token', token); @@ -423,7 +422,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { 'getTokenDetailsFromSWScope' ).callsFake(() => Promise.resolve(details)); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); const token = await serviceInstance.getToken(); // make sure we call getToken and retrieve the new token. assert.equal('new-token', token); @@ -472,7 +471,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { Promise.resolve(subscription) ); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); const defaultVAPIDToken = await serviceInstance.getToken(); assert.equal( defaultVAPIDToken, @@ -559,7 +558,7 @@ describe('Firebase Messaging > *Controller.getToken()', () => { async () => {} ); - const serviceInstance = new serviceClass(app); + const serviceInstance = new serviceClass(firebaseInternalServices); try { await serviceInstance.getToken(); throw new Error('Expected error to be thrown.'); diff --git a/packages/messaging/test/controller-interface.test.ts b/packages/messaging/test/controller-interface.test.ts index cc7cc97a2f8..824bdaa6d3f 100644 --- a/packages/messaging/test/controller-interface.test.ts +++ b/packages/messaging/test/controller-interface.test.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import { FirebaseApp } from '@firebase/app-types'; import { expect } from 'chai'; import { stub, restore, spy } from 'sinon'; @@ -27,8 +26,9 @@ import { SubscriptionManager } from '../src/models/subscription-manager'; import { TokenDetailsModel } from '../src/models/token-details-model'; import { VapidDetailsModel } from '../src/models/vapid-details-model'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg'; +import { FirebaseInternalServices } from '../src/interfaces/internal-services'; const controllersToTest = [WindowController, SwController]; @@ -47,10 +47,10 @@ class MockBaseController extends BaseController { } describe('Firebase Messaging > *BaseController', () => { - let app: FirebaseApp; + let firebaseInternalServices: FirebaseInternalServices; beforeEach(() => { - app = makeFakeApp({ + firebaseInternalServices = makeFakeFirebaseInternalServices({ messagingSenderId: '12345' }); }); @@ -61,7 +61,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('INTERNAL.delete()', () => { it('should call delete()', async () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); const sinonSpy = spy(controller, 'delete'); await controller.INTERNAL.delete(); expect(sinonSpy.callCount).to.equal(1); @@ -70,7 +70,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('requestPermission()', () => { it(`should throw`, async () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); let thrownError; try { await controller.requestPermission(); @@ -93,7 +93,7 @@ describe('Firebase Messaging > *BaseController', () => { } }); - const controller = new controllerInTest(app); + const controller = new controllerInTest(firebaseInternalServices); return controller .getPushSubscription(reg, DEFAULT_PUBLIC_VAPID_KEY) .then( @@ -113,7 +113,7 @@ describe('Firebase Messaging > *BaseController', () => { getSubscription: async () => exampleSubscription }); - const controller = new controllerInTest(app); + const controller = new controllerInTest(firebaseInternalServices); return controller .getPushSubscription(reg, DEFAULT_PUBLIC_VAPID_KEY) .then(subscription => { @@ -136,7 +136,7 @@ describe('Firebase Messaging > *BaseController', () => { } }); - const controller = new controllerInTest(app); + const controller = new controllerInTest(firebaseInternalServices); return controller .getPushSubscription(reg, DEFAULT_PUBLIC_VAPID_KEY) .then(subscription => { @@ -148,7 +148,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('useServiceWorker()', () => { it(`should throw`, () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); let thrownError; try { controller.useServiceWorker(null as any); @@ -162,7 +162,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('usePublicVapidKey()', () => { it(`should throw`, () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); let thrownError; try { controller.usePublicVapidKey(null as any); @@ -176,7 +176,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('onMessage()', () => { it(`should throw`, () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); let thrownError; try { controller.onMessage(null as any, null as any, null as any); @@ -190,7 +190,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('onTokenRefresh()', () => { it(`should throw`, () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); let thrownError; try { controller.onTokenRefresh(null as any, null as any, null as any); @@ -204,7 +204,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('setBackgroundMessageHandler()', () => { it(`should throw`, () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); let thrownError; try { controller.setBackgroundMessageHandler(null as any); @@ -219,7 +219,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('getNotificationPermission_', () => { it('should return current permission', () => { stub(Notification as any, 'permission').value('test'); - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); const result = controller.getNotificationPermission_(); expect(result).to.equal('test'); }); @@ -227,7 +227,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('getTokenDetailsModel', () => { it('should return an instance of TokenDetailsModel', () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); const result = controller.getTokenDetailsModel(); expect(result).to.be.instanceof(TokenDetailsModel); }); @@ -235,7 +235,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('getVapidDetailsModel', () => { it('should return an instance of VapidDetailsModel', () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); const result = controller.getVapidDetailsModel(); expect(result).to.be.instanceof(VapidDetailsModel); }); @@ -243,7 +243,7 @@ describe('Firebase Messaging > *BaseController', () => { describe('getIidModel', () => { it('should return an instance of IidModel', () => { - const controller = new MockBaseController(app); + const controller = new MockBaseController(firebaseInternalServices); const result = controller.getSubscriptionManager(); expect(result).to.be.instanceof(SubscriptionManager); }); diff --git a/packages/messaging/test/get-sw-reg.test.ts b/packages/messaging/test/get-sw-reg.test.ts index eebd782e061..c50474536a4 100644 --- a/packages/messaging/test/get-sw-reg.test.ts +++ b/packages/messaging/test/get-sw-reg.test.ts @@ -21,12 +21,12 @@ import { SwController } from '../src/controllers/sw-controller'; import { WindowController } from '../src/controllers/window-controller'; import { ErrorCode } from '../src/models/errors'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg'; const EXAMPLE_SENDER_ID = '1234567890'; -const app = makeFakeApp({ +const firebaseInternalServices = makeFakeFirebaseInternalServices({ messagingSenderId: EXAMPLE_SENDER_ID }); @@ -62,7 +62,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { mockWindowRegistration(activatedRegistration); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); return messagingService .getSWRegistration_() .then(registration => { @@ -82,7 +82,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { const fakeReg = makeFakeSWReg(); mockWindowRegistration(fakeReg); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); return messagingService.getSWRegistration_().then( () => { throw new Error('Expected this error to throw due to no SW.'); @@ -97,7 +97,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { const fakeReg = makeFakeSWReg(); (self as any).registration = fakeReg; - const messagingService = new SwController(app); + const messagingService = new SwController(firebaseInternalServices); return messagingService .getSWRegistration_() .then(registration => { @@ -119,7 +119,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { throw new Error(errorMsg); }); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); return messagingService.getSWRegistration_().then( () => { throw new Error('Expect getSWRegistration_ to reject.'); @@ -140,7 +140,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { }); mockWindowRegistration(redundantRegistration); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); return messagingService.getSWRegistration_().then( () => { throw new Error('Should throw error due to redundant SW'); @@ -166,7 +166,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { const slowRedundantRegistration = makeFakeSWReg('installing', swValue); mockWindowRegistration(slowRedundantRegistration); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); return messagingService.getSWRegistration_().then( () => { throw new Error('Should throw error due to redundant SW'); @@ -192,7 +192,7 @@ describe('Firebase Messaging > *Controller.getSWReg_()', () => { const slowRedundantRegistration = makeFakeSWReg('waiting', swValue); mockWindowRegistration(slowRedundantRegistration); - const messagingService = new WindowController(app); + const messagingService = new WindowController(firebaseInternalServices); return messagingService.getSWRegistration_().then( () => { throw new Error('Should throw error due to redundant SW'); diff --git a/packages/messaging/test/index.test.ts b/packages/messaging/test/index.test.ts index d3146ec1f64..f5c17df2fdc 100644 --- a/packages/messaging/test/index.test.ts +++ b/packages/messaging/test/index.test.ts @@ -21,7 +21,7 @@ import { stub, restore, SinonStub } from 'sinon'; import { FirebaseApp } from '@firebase/app-types'; import { _FirebaseNamespace, - FirebaseServiceFactory + FirebaseService } from '@firebase/app-types/private'; import { registerMessaging } from '../index'; @@ -29,17 +29,26 @@ import { ErrorCode } from '../src/models/errors'; import { SwController } from '../src/controllers/sw-controller'; import { WindowController } from '../src/controllers/window-controller'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { + makeFakeApp, + makeFakeInstallations +} from './testing-utils/make-fake-firebase-services'; +import { + InstanceFactory, + ComponentContainer, + Component, + ComponentType +} from '@firebase/component'; describe('Firebase Messaging > registerMessaging', () => { - let registerService: SinonStub; + let registerComponent: SinonStub; let fakeFirebase: _FirebaseNamespace; beforeEach(() => { - registerService = stub(); + registerComponent = stub(); fakeFirebase = { - INTERNAL: { registerService } + INTERNAL: { registerComponent } } as any; }); @@ -47,28 +56,40 @@ describe('Firebase Messaging > registerMessaging', () => { restore(); }); - it('calls registerService', () => { + it('calls registerComponent', () => { registerMessaging(fakeFirebase); - expect(registerService.callCount).to.equal(1); + expect(registerComponent.callCount).to.equal(1); }); describe('factoryMethod', () => { - let factoryMethod: FirebaseServiceFactory; + let factoryMethod: InstanceFactory; let fakeApp: FirebaseApp; + let fakeContainer: ComponentContainer; beforeEach(() => { registerMessaging(fakeFirebase); - factoryMethod = registerService.getCall(0).args[1]; + factoryMethod = registerComponent.getCall(0).args[0].instanceFactory; fakeApp = makeFakeApp({ messagingSenderId: '1234567890' }); + fakeContainer = new ComponentContainer('test'); + fakeContainer.addComponent( + new Component('app', () => fakeApp, ComponentType.PUBLIC) + ); + fakeContainer.addComponent( + new Component( + 'installations', + () => makeFakeInstallations(), + ComponentType.PUBLIC + ) + ); }); describe('isSupported', () => { it('is a namespace export', () => { - const namespaceExports = registerService.getCall(0).args[2]; - expect(namespaceExports.isSupported).to.be.a('function'); + const component = registerComponent.getCall(0).args[0]; + expect(component.serviceProps.isSupported).to.be.a('function'); }); }); @@ -84,7 +105,7 @@ describe('Firebase Messaging > registerMessaging', () => { }); it('returns a SwController', () => { - const firebaseService = factoryMethod(fakeApp); + const firebaseService = factoryMethod(fakeContainer); expect(firebaseService).to.be.instanceOf(SwController); }); }); @@ -95,7 +116,7 @@ describe('Firebase Messaging > registerMessaging', () => { stub(window, 'navigator').value({}); try { - factoryMethod(fakeApp); + factoryMethod(fakeContainer); } catch (e) { expect(e.code).to.equal('messaging/' + ErrorCode.UNSUPPORTED_BROWSER); return; @@ -104,7 +125,7 @@ describe('Firebase Messaging > registerMessaging', () => { }); it('returns a WindowController', () => { - const firebaseService = factoryMethod(fakeApp); + const firebaseService = factoryMethod(fakeContainer); expect(firebaseService).to.be.instanceOf(WindowController); }); }); diff --git a/packages/messaging/test/subscription-manager.test.ts b/packages/messaging/test/subscription-manager.test.ts index d4dda7ae118..5c77bcb8a7b 100644 --- a/packages/messaging/test/subscription-manager.test.ts +++ b/packages/messaging/test/subscription-manager.test.ts @@ -23,10 +23,10 @@ import { SubscriptionManager } from '../src/models/subscription-manager'; import { makeFakeSubscription } from './testing-utils/make-fake-subscription'; import { fetchMock } from './testing-utils/mock-fetch'; -import { FirebaseApp } from '@firebase/app-types'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { base64ToArrayBuffer } from '../src/helpers/base64-to-array-buffer'; import { TokenDetails } from '../src/interfaces/token-details'; +import { FirebaseInternalServices } from '../src/interfaces/internal-services'; // prettier-ignore const appPubKey = new Uint8Array([ @@ -39,13 +39,13 @@ function getDefaultPublicKey(): Uint8Array { } describe('Firebase Messaging > SubscriptionManager', () => { - let app: FirebaseApp; + let firebaseInternalServices: FirebaseInternalServices; let subscription: PushSubscription; let tokenDetails: TokenDetails; let subscriptionManager: SubscriptionManager; beforeEach(() => { - app = makeFakeApp(); + firebaseInternalServices = makeFakeFirebaseInternalServices(); subscription = makeFakeSubscription(); tokenDetails = { swScope: '/example-scope', @@ -53,7 +53,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { 'BNJxw7sCGkGLOUP2cawBaBXRuWZ3lw_PmQMgreLVVvX_b' + '4emEWVURkCF8fUTHEFe2xrEgTt5ilh5xD94v0pFe_I' ), - fcmSenderId: app.options.messagingSenderId!, + fcmSenderId: firebaseInternalServices.app.options.messagingSenderId!, fcmToken: 'qwerty', endpoint: subscription.endpoint, auth: subscription.getKey('auth')!, @@ -76,7 +76,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { fetchMock.jsonOk(JSON.stringify(mockResponse)) ); const token = await subscriptionManager.getToken( - app, + firebaseInternalServices, subscription, appPubKey ); @@ -92,7 +92,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { fetchMock.jsonOk(JSON.stringify(mockResponse)) ); const token = await subscriptionManager.getToken( - app, + firebaseInternalServices, subscription, getDefaultPublicKey() ); @@ -106,7 +106,11 @@ describe('Firebase Messaging > SubscriptionManager', () => { const errorMsg = 'invalid token'; stub(window, 'fetch').returns(fetchMock.jsonError(400, errorMsg)); try { - await subscriptionManager.getToken(app, subscription, appPubKey); + await subscriptionManager.getToken( + firebaseInternalServices, + subscription, + appPubKey + ); throw new Error('Expected error to be thrown.'); } catch (e) { expect(e.message).to.include(errorMsg); @@ -116,7 +120,11 @@ describe('Firebase Messaging > SubscriptionManager', () => { it('handles fetch errors, HTML response returned', async () => { stub(window, 'fetch').returns(fetchMock.htmlError(400, 'html-response')); try { - await subscriptionManager.getToken(app, subscription, appPubKey); + await subscriptionManager.getToken( + firebaseInternalServices, + subscription, + appPubKey + ); throw new Error('Expected error to be thrown.'); } catch (e) { expect(e.code).to.include(ErrorCode.TOKEN_SUBSCRIBE_FAILED); @@ -129,7 +137,11 @@ describe('Firebase Messaging > SubscriptionManager', () => { fetchMock.jsonOk(JSON.stringify(mockInvalidResponse)) ); try { - await subscriptionManager.getToken(app, subscription, appPubKey); + await subscriptionManager.getToken( + firebaseInternalServices, + subscription, + appPubKey + ); throw new Error('Expected error to be thrown.'); } catch (e) { expect(e.message).to.include( @@ -147,7 +159,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { ); const res = await subscriptionManager.updateToken( tokenDetails, - app, + firebaseInternalServices, subscription, appPubKey ); @@ -162,7 +174,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { ); const res = await subscriptionManager.updateToken( tokenDetails, - app, + firebaseInternalServices, subscription, getDefaultPublicKey() ); @@ -180,7 +192,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { try { await subscriptionManager.updateToken( tokenDetails, - app, + firebaseInternalServices, subscription, appPubKey ); @@ -195,7 +207,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { try { await subscriptionManager.updateToken( tokenDetails, - app, + firebaseInternalServices, subscription, appPubKey ); @@ -211,7 +223,7 @@ describe('Firebase Messaging > SubscriptionManager', () => { try { await subscriptionManager.updateToken( tokenDetails, - app, + firebaseInternalServices, subscription, appPubKey ); @@ -225,7 +237,10 @@ describe('Firebase Messaging > SubscriptionManager', () => { describe('deleteToken', () => { it('deletes on valid request', async () => { stub(window, 'fetch').returns(fetchMock.jsonOk('{}')); - await subscriptionManager.deleteToken(app, tokenDetails); + await subscriptionManager.deleteToken( + firebaseInternalServices, + tokenDetails + ); }); it('handles fetch errors', async () => { @@ -234,7 +249,10 @@ describe('Firebase Messaging > SubscriptionManager', () => { stub(window, 'fetch').returns(fetchMock.jsonError(400, errorMsg)); try { - await subscriptionManager.deleteToken(app, tokenDetails); + await subscriptionManager.deleteToken( + firebaseInternalServices, + tokenDetails + ); throw new Error('Expected error to be thrown.'); } catch (e) { expect(e.code).to.include(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED); @@ -245,7 +263,10 @@ describe('Firebase Messaging > SubscriptionManager', () => { const stubbedFetch = stub(window, 'fetch'); stubbedFetch.returns(fetchMock.htmlError(404, 'html-response')); try { - await subscriptionManager.deleteToken(app, tokenDetails); + await subscriptionManager.deleteToken( + firebaseInternalServices, + tokenDetails + ); throw new Error('Expected error to be thrown.'); } catch (e) { expect(e.code).to.include(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED); diff --git a/packages/messaging/test/sw-controller.test.ts b/packages/messaging/test/sw-controller.test.ts index 5a5bec3ee8e..bed0ecafabc 100644 --- a/packages/messaging/test/sw-controller.test.ts +++ b/packages/messaging/test/sw-controller.test.ts @@ -22,23 +22,20 @@ declare const self: ServiceWorkerGlobalScope; import { expect } from 'chai'; import { stub, restore, spy, SinonSpy } from 'sinon'; - -import { FirebaseApp } from '@firebase/app-types'; import { FirebaseError } from '@firebase/util'; - -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg'; - import { SwController } from '../src/controllers/sw-controller'; import { base64ToArrayBuffer } from '../src/helpers/base64-to-array-buffer'; import { DEFAULT_PUBLIC_VAPID_KEY } from '../src/models/fcm-details'; import { VapidDetailsModel } from '../src/models/vapid-details-model'; +import { FirebaseInternalServices } from '../src/interfaces/internal-services'; const VALID_VAPID_KEY = 'BJzVfWqLoALJdgV20MYy6lrj0OfhmE16PI1qLIIYx2ZZL3FoQWJJL8L0rf7rS7tqd92j_3xN3fmejKK5Eb7yMYw'; describe('Firebase Messaging > *SwController', () => { - let app: FirebaseApp; + let firebaseInternalServices: FirebaseInternalServices; beforeEach(() => { // When trying to stub self.clients self.registration, Sinon complains that @@ -55,7 +52,7 @@ describe('Firebase Messaging > *SwController', () => { (self as any).registration = 'This is a placeholder for sinon to overwrite.'; - app = makeFakeApp({ + firebaseInternalServices = makeFakeFirebaseInternalServices({ messagingSenderId: '12345' }); }); @@ -69,7 +66,7 @@ describe('Firebase Messaging > *SwController', () => { describe('onPush', () => { it('should handle a push event with no data', async () => { - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const waitUntilSpy = spy(); swController.onPush({ waitUntil: waitUntilSpy, @@ -80,7 +77,7 @@ describe('Firebase Messaging > *SwController', () => { }); it('should handle a push event where .json() throws', async () => { - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const waitUntilSpy = spy(); swController.onPush({ waitUntil: waitUntilSpy, @@ -102,7 +99,7 @@ describe('Firebase Messaging > *SwController', () => { async () => true ); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onPush({ waitUntil: waitUntilSpy, data: { @@ -124,7 +121,7 @@ describe('Firebase Messaging > *SwController', () => { async () => true ); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onPush({ waitUntil: waitUntilSpy, data: { @@ -148,7 +145,7 @@ describe('Firebase Messaging > *SwController', () => { async () => true ); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.setBackgroundMessageHandler((() => {}) as any); swController.onPush({ waitUntil: waitUntilSpy, @@ -171,7 +168,7 @@ describe('Firebase Messaging > *SwController', () => { ); const showNotificationStub = spy(registration, 'showNotification'); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onPush({ waitUntil: waitUntilSpy, data: { @@ -209,7 +206,7 @@ describe('Firebase Messaging > *SwController', () => { icon: '/images/test-icon.png' }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onPush({ waitUntil: waitUntilSpy, data: { @@ -277,7 +274,7 @@ describe('Firebase Messaging > *SwController', () => { ] }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onPush({ waitUntil: waitUntilSpy, data: { @@ -311,7 +308,7 @@ describe('Firebase Messaging > *SwController', () => { const payloadData = {}; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.setBackgroundMessageHandler(bgMessageHandlerSpy); swController.onPush({ waitUntil: waitUntilSpy, @@ -333,7 +330,7 @@ describe('Firebase Messaging > *SwController', () => { async () => false ); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onPush({ waitUntil: waitUntilSpy, data: { @@ -349,7 +346,7 @@ describe('Firebase Messaging > *SwController', () => { describe('setBackgroundMessageHandler', () => { it('should throw on a non-function input', () => { - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); let thrownError: FirebaseError | undefined; try { swController.setBackgroundMessageHandler('' as any); @@ -378,7 +375,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.hasVisibleClients_(); expect(result).to.equal(false); }); @@ -409,7 +406,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.hasVisibleClients_(); expect(result).to.equal(false); }); @@ -444,7 +441,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.hasVisibleClients_(); expect(result).to.equal(true); }); @@ -467,7 +464,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.hasVisibleClients_(); expect(result).to.equal(false); }); @@ -487,7 +484,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.getWindowClient_('/test-url'); expect(result).to.equal(null); }); @@ -515,7 +512,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.getWindowClient_('/test-url'); expect(result).to.equal(null); }); @@ -547,7 +544,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const result = await swController.getWindowClient_(matchingClient.url); expect(result).to.equal(matchingClient); }); @@ -560,7 +557,7 @@ describe('Firebase Messaging > *SwController', () => { waitUntil: waitUntilSpy, stopImmediatePropagation: spy() }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onNotificationClick(event); @@ -574,7 +571,7 @@ describe('Firebase Messaging > *SwController', () => { waitUntil: waitUntilSpy, stopImmediatePropagation: spy() }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onNotificationClick(event); @@ -590,7 +587,7 @@ describe('Firebase Messaging > *SwController', () => { waitUntil: waitUntilSpy, stopImmediatePropagation: spy() }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onNotificationClick(event); @@ -612,7 +609,7 @@ describe('Firebase Messaging > *SwController', () => { stopImmediatePropagation: spy(), action: 'action1' }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onNotificationClick(event); @@ -631,7 +628,7 @@ describe('Firebase Messaging > *SwController', () => { waitUntil: waitUntilSpy, stopImmediatePropagation: spy() }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onNotificationClick(event); @@ -653,7 +650,7 @@ describe('Firebase Messaging > *SwController', () => { waitUntil: waitUntilSpy, stopImmediatePropagation: spy() }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onNotificationClick(event); await event.waitUntil.getCall(0).args[0]; @@ -712,7 +709,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); stub(swController, 'getWindowClient_').callsFake(async () => null); @@ -739,7 +736,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); stub(swController, 'getWindowClient_').callsFake(async () => null); const attemptToMessageClientStub = stub( @@ -782,7 +779,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); stub(swController, 'getWindowClient_').callsFake( async () => fakeWindowClient as WindowClient @@ -818,14 +815,14 @@ describe('Firebase Messaging > *SwController', () => { describe('getNotificationData_', () => { it('should return nothing for no payload', () => { - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); expect(swController.getNotificationData_(undefined as any)).to.equal( undefined ); }); it('adds message payload to data.FCM_MSG without replacing user defined data', () => { - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const msgPayload = { notification: { title: 'Hello World', @@ -852,7 +849,7 @@ describe('Firebase Messaging > *SwController', () => { describe('attemptToMessageClient_', () => { it('should reject when no window client provided', () => { - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); return swController.attemptToMessageClient_(null as any, {} as any).then( () => { throw new Error('Expected error to be thrown'); @@ -869,7 +866,7 @@ describe('Firebase Messaging > *SwController', () => { const client: any = { postMessage: spy() }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); await swController.attemptToMessageClient_(client, msg); expect(client.postMessage.callCount).to.equal(1); expect(client.postMessage.getCall(0).args[0]).to.equal(msg); @@ -884,7 +881,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const payload = {}; @@ -904,7 +901,7 @@ describe('Firebase Messaging > *SwController', () => { }; stub(self, 'clients').value(clients); - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); const attemptToMessageClientStub = stub( swController, 'attemptToMessageClient_' @@ -943,7 +940,7 @@ describe('Firebase Messaging > *SwController', () => { const onPushStub = stub(SwController.prototype, 'onPush'); const pushEvent = new Event('push'); - new SwController(app); + new SwController(firebaseInternalServices); expect(listeners['push']).to.exist; listeners['push'](pushEvent); @@ -960,7 +957,7 @@ describe('Firebase Messaging > *SwController', () => { const onSubChangeStub = stub(SwController.prototype, 'onSubChange'); const pushEvent = new Event('pushsubscriptionchange'); - new SwController(app); + new SwController(firebaseInternalServices); expect(listeners['pushsubscriptionchange']).to.exist; listeners['pushsubscriptionchange'](pushEvent); @@ -986,7 +983,7 @@ describe('Firebase Messaging > *SwController', () => { ); const pushEvent = new Event('notificationclick'); - new SwController(app); + new SwController(firebaseInternalServices); expect(listeners['notificationclick']).to.exist; listeners['notificationclick'](pushEvent); @@ -1013,7 +1010,7 @@ describe('Firebase Messaging > *SwController', () => { waitUntil: waitUntilSpy }; - const swController = new SwController(app); + const swController = new SwController(firebaseInternalServices); swController.onSubChange(event); let error: FirebaseError | undefined; @@ -1032,7 +1029,7 @@ describe('Firebase Messaging > *SwController', () => { it('should return the default key by default', async () => { const registration = makeFakeSWReg(); stub(self, 'registration').value(registration); - const controller = new SwController(app); + const controller = new SwController(firebaseInternalServices); stub(VapidDetailsModel.prototype, 'getVapidFromSWScope').callsFake( async () => undefined ); @@ -1043,7 +1040,7 @@ describe('Firebase Messaging > *SwController', () => { it('should return the default key', async () => { const registration = makeFakeSWReg(); stub(self, 'registration').value(registration); - const controller = new SwController(app); + const controller = new SwController(firebaseInternalServices); stub(VapidDetailsModel.prototype, 'getVapidFromSWScope').callsFake( async () => DEFAULT_PUBLIC_VAPID_KEY ); @@ -1054,7 +1051,7 @@ describe('Firebase Messaging > *SwController', () => { it('should return the custom key if set', async () => { const registration = makeFakeSWReg(); stub(self, 'registration').value(registration); - const controller = new SwController(app); + const controller = new SwController(firebaseInternalServices); const vapidKeyInUse = base64ToArrayBuffer(VALID_VAPID_KEY); stub(VapidDetailsModel.prototype, 'getVapidFromSWScope').callsFake( async () => vapidKeyInUse diff --git a/packages/messaging/test/testing-utils/make-fake-app.ts b/packages/messaging/test/testing-utils/make-fake-firebase-services.ts similarity index 53% rename from packages/messaging/test/testing-utils/make-fake-app.ts rename to packages/messaging/test/testing-utils/make-fake-firebase-services.ts index 5fd17133a90..d4ddebb7d35 100644 --- a/packages/messaging/test/testing-utils/make-fake-app.ts +++ b/packages/messaging/test/testing-utils/make-fake-firebase-services.ts @@ -16,6 +16,20 @@ */ import { FirebaseApp, FirebaseOptions } from '@firebase/app-types'; +import { FirebaseInstallations } from '@firebase/installations-types'; +import { FirebaseAnalyticsInternal } from '@firebase/analytics-interop-types'; +import { Provider, ComponentContainer } from '@firebase/component'; +import { FirebaseInternalServices } from '../../src/interfaces/internal-services'; + +export function makeFakeFirebaseInternalServices( + options: FirebaseOptions = {} +): FirebaseInternalServices { + return { + app: makeFakeApp(options), + installations: makeFakeInstallations(), + analyticsProvider: makeFakeAnalyticsProvider() + }; +} export function makeFakeApp(options: FirebaseOptions = {}): FirebaseApp { options = { @@ -34,12 +48,23 @@ export function makeFakeApp(options: FirebaseOptions = {}): FirebaseApp { automaticDataCollectionEnabled: true, delete: async () => {}, messaging: null as any, - installations() { - return { - getId: () => Promise.resolve('FID'), - getToken: () => Promise.resolve('authToken'), - delete: () => Promise.resolve() - }; - } + installations: null as any + }; +} + +export function makeFakeInstallations(): FirebaseInstallations { + return { + getId: () => Promise.resolve('FID'), + getToken: () => Promise.resolve('authToken'), + delete: () => Promise.resolve() }; } + +export function makeFakeAnalyticsProvider(): Provider< + FirebaseAnalyticsInternal +> { + return new Provider( + 'analytics-interop', + new ComponentContainer('test') + ); +} diff --git a/packages/messaging/test/token-details-model.test.ts b/packages/messaging/test/token-details-model.test.ts index e2f7bb3a649..19356552d4b 100644 --- a/packages/messaging/test/token-details-model.test.ts +++ b/packages/messaging/test/token-details-model.test.ts @@ -17,24 +17,22 @@ import { assert } from 'chai'; import { useFakeTimers } from 'sinon'; - import { arrayBufferToBase64 } from '../src/helpers/array-buffer-to-base64'; import { base64ToArrayBuffer } from '../src/helpers/base64-to-array-buffer'; import { TokenDetails } from '../src/interfaces/token-details'; import { ErrorCode } from '../src/models/errors'; import { TokenDetailsModel } from '../src/models/token-details-model'; - import { deleteDatabase } from './testing-utils/db-helper'; import { compareDetails } from './testing-utils/detail-comparator'; import { makeFakeSubscription } from './testing-utils/make-fake-subscription'; -import { FirebaseApp } from '@firebase/app-types'; -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; +import { FirebaseInternalServices } from '../src/interfaces/internal-services'; const BAD_INPUTS: any[] = ['', [], {}, true, null, 123]; describe('Firebase Messaging > TokenDetailsModel', () => { let clock: sinon.SinonFakeTimers; - let app: FirebaseApp; + let firebaseInternalServices: FirebaseInternalServices; let tokenDetailsModel: TokenDetailsModel; let exampleInput: TokenDetails; let fakeSubscription: PushSubscription; @@ -42,8 +40,8 @@ describe('Firebase Messaging > TokenDetailsModel', () => { beforeEach(() => { clock = useFakeTimers(); - app = makeFakeApp(); - tokenDetailsModel = new TokenDetailsModel(app); + firebaseInternalServices = makeFakeFirebaseInternalServices(); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); fakeSubscription = makeFakeSubscription(); exampleInput = { @@ -74,7 +72,9 @@ describe('Firebase Messaging > TokenDetailsModel', () => { protected readonly dbVersion = 2; } - const oldDBTokenDetailsModel = new OldDBTokenDetailsModel(app); + const oldDBTokenDetailsModel = new OldDBTokenDetailsModel( + firebaseInternalServices + ); // Old (v2) version of exampleInput // vapidKey, auth and p256dh are strings, @@ -109,7 +109,9 @@ describe('Firebase Messaging > TokenDetailsModel', () => { protected readonly dbVersion = 3; } - const oldDBTokenDetailsModel = new OldDBTokenDetailsModel(app); + const oldDBTokenDetailsModel = new OldDBTokenDetailsModel( + firebaseInternalServices + ); // Old (v3) version of exampleInput // fcmPushSet exists @@ -142,7 +144,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { describe('saveToken', () => { it('should throw on bad input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.swScope = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -159,7 +161,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { it('should throw on bad vapid key input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.vapidKey = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -176,7 +178,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { it('should throw on bad endpoint input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.endpoint = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -193,7 +195,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { it('should throw on bad auth input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.auth = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -210,7 +212,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { it('should throw on bad p256dh input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.p256dh = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -227,7 +229,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { it('should throw on bad send id input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.fcmSenderId = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -244,7 +246,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { it('should throw on bad token input', () => { const promises = BAD_INPUTS.map(badInput => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); exampleInput.fcmToken = badInput; return tokenDetailsModel.saveTokenDetails(exampleInput).then( () => { @@ -260,7 +262,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { }); it('should save valid details', () => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); return tokenDetailsModel.saveTokenDetails(exampleInput); }); }); @@ -331,7 +333,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { describe('deleteToken', () => { it('should handle no input', () => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); return tokenDetailsModel.deleteToken(undefined as any).then( () => { throw new Error('Expected this to throw an error due to no token'); @@ -343,7 +345,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { }); it('should handle empty string', () => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); return tokenDetailsModel.deleteToken('').then( () => { throw new Error('Expected this to throw an error due to no token'); @@ -355,7 +357,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { }); it('should delete current token', () => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); return tokenDetailsModel .saveTokenDetails(exampleInput) .then(() => { @@ -373,7 +375,7 @@ describe('Firebase Messaging > TokenDetailsModel', () => { }); it('should handle deleting a non-existant token', () => { - tokenDetailsModel = new TokenDetailsModel(app); + tokenDetailsModel = new TokenDetailsModel(firebaseInternalServices); return tokenDetailsModel.deleteToken('bad-token').then( () => { throw new Error('Expected this delete to throw and error.'); diff --git a/packages/messaging/test/window-controller.test.ts b/packages/messaging/test/window-controller.test.ts index a3831131446..f3dcde14870 100644 --- a/packages/messaging/test/window-controller.test.ts +++ b/packages/messaging/test/window-controller.test.ts @@ -16,10 +16,8 @@ */ import { expect } from 'chai'; import { stub, restore, spy } from 'sinon'; - -import { makeFakeApp } from './testing-utils/make-fake-app'; +import { makeFakeFirebaseInternalServices } from './testing-utils/make-fake-firebase-services'; import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg'; - import { WindowController } from '../src/controllers/window-controller'; import { base64ToArrayBuffer } from '../src/helpers/base64-to-array-buffer'; import { DEFAULT_PUBLIC_VAPID_KEY } from '../src/models/fcm-details'; @@ -29,7 +27,7 @@ const VALID_VAPID_KEY = 'BJzVfWqLoALJdgV20MYy6lrj0OfhmE16PI1qLIIYx2ZZL3FoQWJJL8L0rf7rS7tqd92j_3xN3fmejKK5Eb7yMYw'; describe('Firebase Messaging > *WindowController', () => { - const app = makeFakeApp({ + const fakeFirebaseServices = makeFakeFirebaseInternalServices({ messagingSenderId: '12345' }); @@ -49,7 +47,7 @@ describe('Firebase Messaging > *WindowController', () => { it('should resolve if the permission is already granted', () => { stub(Notification as any, 'permission').value('granted'); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); return controller.requestPermission(); }); @@ -59,7 +57,7 @@ describe('Firebase Messaging > *WindowController', () => { Promise.resolve('denied') ); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); return controller.requestPermission().then( () => { throw new Error('Expected an error.'); @@ -76,7 +74,7 @@ describe('Firebase Messaging > *WindowController', () => { Promise.resolve('default') ); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); return controller.requestPermission().then( () => { throw new Error('Expected an error.'); @@ -93,14 +91,14 @@ describe('Firebase Messaging > *WindowController', () => { Promise.resolve('granted') ); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); return controller.requestPermission(); }); }); describe('useServiceWorker()', () => { it(`should throw on invalid input`, () => { - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); let thrownError; try { controller.useServiceWorker(null as any); @@ -113,7 +111,7 @@ describe('Firebase Messaging > *WindowController', () => { it(`should only be callable once`, () => { const registration = makeFakeSWReg(); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); controller.useServiceWorker(registration); let thrownError; @@ -134,7 +132,7 @@ describe('Firebase Messaging > *WindowController', () => { const errFunc = (): void => {}; const compFunc = (): void => {}; - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); const onMessageStub = stub(controller as any, 'onMessage'); controller.onMessage(nextFunc, errFunc, compFunc); @@ -151,7 +149,7 @@ describe('Firebase Messaging > *WindowController', () => { const errFunc = (): void => {}; const compFunc = (): void => {}; - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); const onTokenRefreshStub = stub(controller as any, 'onTokenRefresh'); controller.onTokenRefresh(nextFunc, errFunc, compFunc); @@ -164,7 +162,7 @@ describe('Firebase Messaging > *WindowController', () => { describe('usePublicVapidKey()', () => { it('should throw an error when passing in an invalid value', () => { - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); let thrownError; try { @@ -177,7 +175,7 @@ describe('Firebase Messaging > *WindowController', () => { }); it('should throw an error when called twice', () => { - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); controller.usePublicVapidKey(VALID_VAPID_KEY); let thrownError; @@ -193,7 +191,7 @@ describe('Firebase Messaging > *WindowController', () => { }); it('should throw when decrypting to invalid value', () => { - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); let thrownError; try { @@ -212,14 +210,14 @@ describe('Firebase Messaging > *WindowController', () => { describe('getPublicVapidKey_()', () => { it('should return the default key by default', () => { - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); return controller.getPublicVapidKey_().then(pubKey => { expect(pubKey).to.equal(DEFAULT_PUBLIC_VAPID_KEY); }); }); it('should return the custom key if set', () => { - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); controller.usePublicVapidKey(VALID_VAPID_KEY); return controller.getPublicVapidKey_().then(pubKey => { expect(pubKey).deep.equal(base64ToArrayBuffer(VALID_VAPID_KEY)); @@ -234,7 +232,7 @@ describe('Firebase Messaging > *WindowController', () => { addEventListener: sinonSpy }); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); controller.setupSWMessageListener_(); expect(sinonSpy.args[0][0]).to.equal('message'); @@ -248,7 +246,7 @@ describe('Firebase Messaging > *WindowController', () => { addEventListener: sinonSpy }); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); controller.onMessage(onMessageSpy, null as any, null as any); controller.setupSWMessageListener_(); @@ -270,7 +268,7 @@ describe('Firebase Messaging > *WindowController', () => { addEventListener: messageCallbackSpy }); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); controller.setupSWMessageListener_(); const callback = messageCallbackSpy.args[0][1]; @@ -293,7 +291,7 @@ describe('Firebase Messaging > *WindowController', () => { addEventListener: messageCallbackSpy }); - const controller = new WindowController(app); + const controller = new WindowController(fakeFirebaseServices); // The API for the observables means it's async and so we kind have to // hope that everything is set up after a task skip @@ -339,7 +337,7 @@ describe('Firebase Messaging > *WindowController', () => { const fakeReg = makeFakeSWReg('installing', swValue); - const messagingService = new WindowController(app); + const messagingService = new WindowController(fakeFirebaseServices); const waitPromise = messagingService.waitForRegistrationToActivate_( fakeReg );