Skip to content

Commit 74bed6a

Browse files
committed
add tests for the new API
1 parent b38aa3b commit 74bed6a

File tree

10 files changed

+388
-61
lines changed

10 files changed

+388
-61
lines changed

packages/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"type-check": "tsc -p . --noEmit",
2323
"test:browser": "karma start --single-run",
2424
"test:browser:debug": "karma start --browsers Chrome --auto-watch",
25-
"test:node": "TS_NODE_FILES=true TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha test/**/*.test.* --opts ../../config/mocha.node.opts",
25+
"test:node": "TS_NODE_FILES=true TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha test/**/*.test.* src/**/*.test.ts --opts ../../config/mocha.node.opts",
2626
"prepare": "yarn build",
2727
"compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json"
2828
},

packages/app/src/compat/firebaseApp.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import { FirebaseAppInternalNext } from '../next/types';
2727
import { deleteApp } from '../next';
2828
import {
2929
addComponent,
30-
removeServiceInstance,
3130
addOrOverwriteComponent
3231
} from '../next/internal';
3332

@@ -93,9 +92,9 @@ export class FirebaseAppImpl implements FirebaseApp {
9392

9493
/**
9594
* Remove a service instance from the cache, so we will create a new instance for this service
96-
* when people try to get this service again.
95+
* when people try to get it again.
9796
*
98-
* NOTE: currently only firestore is using this functionality to support firestore shutdown.
97+
* NOTE: currently only firestore uses this functionality to support firestore shutdown.
9998
*
10099
* @param name The service name
101100
* @param instanceIdentifier instance identifier in case multiple instances are allowed
@@ -105,7 +104,8 @@ export class FirebaseAppImpl implements FirebaseApp {
105104
name: string,
106105
instanceIdentifier: string = DEFAULT_ENTRY_NAME
107106
): void {
108-
removeServiceInstance(this.app, name, instanceIdentifier);
107+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
108+
this.app.container.getProvider(name as any).clearInstance(instanceIdentifier);
109109
}
110110

111111
/**

packages/app/src/next/api.test.ts

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import { expect } from "chai";
2+
import { stub } from "sinon";
3+
import "../../test/setup";
4+
import { initializeApp, getApps, deleteApp, getApp, registerVersion } from './api';
5+
import { DEFAULT_ENTRY_NAME } from '../constants';
6+
import { FirebaseAppInternalNext } from './types';
7+
import { clearComponents, components, registerComponent } from './internal';
8+
import { createTestComponent } from '../../test/util';
9+
10+
describe('API tests', () => {
11+
afterEach(() => {
12+
for (const app of getApps()) {
13+
deleteApp(app).catch(() => {});
14+
}
15+
});
16+
17+
describe('initializeApp', () => {
18+
it('creats DEFAULT App', () => {
19+
const app = initializeApp({});
20+
expect(app.name).to.equal(DEFAULT_ENTRY_NAME);
21+
});
22+
23+
it('creates named App', () => {
24+
const appName = 'MyApp';
25+
const app = initializeApp({}, appName);
26+
expect(app.name).to.equal(appName);
27+
});
28+
29+
it('creates named and DEFAULT App', () => {
30+
const appName = 'MyApp';
31+
const app1 = initializeApp({});
32+
const app2 = initializeApp({}, appName);
33+
34+
expect(app1.name).to.equal(DEFAULT_ENTRY_NAME);
35+
expect(app2.name).to.equal(appName);
36+
});
37+
38+
it('throws when creating duplicate DEDAULT Apps', () => {
39+
initializeApp({});
40+
expect(() => initializeApp({})).throws(/\[DEFAULT\].*exists/i);
41+
});
42+
43+
it('throws when creating duplicate named Apps', () => {
44+
const appName = 'MyApp';
45+
initializeApp({}, appName);
46+
expect(() => initializeApp({}, appName)).throws(/'MyApp'.*exists/i);
47+
});
48+
49+
it('takes an object as the second parameter to create named App', () => {
50+
const appName = 'MyApp';
51+
const app = initializeApp({}, { name: appName });
52+
expect(app.name).to.equal(appName);
53+
});
54+
55+
it('takes an object as the second parameter to create named App', () => {
56+
const appName = 'MyApp';
57+
const app = initializeApp({}, { name: appName });
58+
expect(app.name).to.equal(appName);
59+
});
60+
61+
it('sets automaticDataCollectionEnabled', () => {
62+
const app = initializeApp({}, { automaticDataCollectionEnabled: true });
63+
expect(app.automaticDataCollectionEnabled).to.be.true;
64+
});
65+
66+
it('adds registered components to App', () => {
67+
clearComponents();
68+
const comp1 = createTestComponent('test1');
69+
const comp2 = createTestComponent('test2');
70+
registerComponent(comp1);
71+
registerComponent(comp2);
72+
73+
const app = initializeApp({}) as FirebaseAppInternalNext;
74+
expect(app.container.getProviders().length).to.equal(components.size);
75+
});
76+
});
77+
78+
describe('getApp', () => {
79+
it('retrieves DEFAULT App', () => {
80+
const app = initializeApp({});
81+
expect(getApp()).to.equal(app);
82+
});
83+
84+
it('retrives named App', () => {
85+
const appName = 'MyApp';
86+
const app = initializeApp({}, appName);
87+
expect(getApp(appName)).to.equal(app);
88+
});
89+
90+
it('throws retrieving a non existing App', () => {
91+
expect(() => getApp('RandomName')).throws(/No Firebase App 'RandomName'/);
92+
});
93+
});
94+
95+
describe('getApps', () => {
96+
it('retrives all Apps that have been created', () => {
97+
const app1 = initializeApp({});
98+
const app2 = initializeApp({}, 'App2');
99+
100+
const apps = getApps();
101+
102+
expect(apps.length).to.equal(2);
103+
expect(apps[0]).to.equal(app1);
104+
expect(apps[1]).to.equal(app2);
105+
});
106+
107+
it('does NOT return deleted Apps', () => {
108+
const app1 = initializeApp({});
109+
const app2 = initializeApp({}, 'App2');
110+
111+
deleteApp(app1).catch(() => {});
112+
113+
const apps = getApps();
114+
115+
expect(apps.length).to.equal(1);
116+
expect(apps[0]).to.equal(app2);
117+
});
118+
});
119+
120+
describe('deleteApp', () => {
121+
it('marks an App as deleted', () => {
122+
const app = initializeApp({});
123+
expect((app as FirebaseAppInternalNext).isDeleted).to.be.false;
124+
125+
deleteApp(app).catch(() => {});
126+
expect((app as FirebaseAppInternalNext).isDeleted).to.be.true;
127+
});
128+
129+
it('removes App from the cache', () => {
130+
const app = initializeApp({});
131+
expect(getApps().length).to.equal(1);
132+
133+
deleteApp(app).catch(() => {});
134+
expect(getApps().length).to.equal(0);
135+
});
136+
});
137+
138+
describe('registerVersion', () => {
139+
140+
afterEach(() => {
141+
clearComponents();
142+
});
143+
144+
it('will register an official version component without warnings', () => {
145+
const warnStub = stub(console, 'warn');
146+
const initialSize = components.size;
147+
148+
registerVersion('@firebase/analytics', '1.2.3');
149+
expect(components.get('fire-analytics-version')).to.exist;
150+
expect(components.size).to.equal(initialSize + 1);
151+
152+
expect(warnStub.called).to.be.false;
153+
});
154+
155+
it('will register an arbitrary version component without warnings', () => {
156+
const warnStub = stub(console, 'warn');
157+
const initialSize = components.size;
158+
159+
registerVersion('angularfire', '1.2.3');
160+
expect(components.get('angularfire-version')).to.exist;
161+
expect(components.size).to.equal(initialSize + 1);
162+
163+
expect(warnStub.called).to.be.false;
164+
});
165+
166+
it('will do nothing if registerVersion() is given illegal characters', () => {
167+
const warnStub = stub(console, 'warn');
168+
const initialSize = components.size;
169+
170+
registerVersion('remote config', '1.2.3');
171+
expect(warnStub.args[0][1]).to.include('library name "remote config"');
172+
expect(components.size).to.equal(initialSize);
173+
174+
registerVersion('remote-config', '1.2/3');
175+
expect(warnStub.args[1][1]).to.include('version name "1.2/3"');
176+
expect(components.size).to.equal(initialSize);
177+
});
178+
});
179+
});
File renamed without changes.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { expect } from "chai";
2+
import "../../test/setup";
3+
import { FirebaseAppImplNext } from './firebaseApp';
4+
import { ComponentContainer } from '@firebase/component';
5+
import { FirebaseAppInternalNext } from './types';
6+
7+
describe('FirebaseAppNext', () => {
8+
it('has various accessors', () => {
9+
const options = {
10+
apiKey: "APIKEY"
11+
};
12+
const app = new FirebaseAppImplNext(
13+
options,
14+
{name: 'test', automaticDataCollectionEnabled: false},
15+
new ComponentContainer('test')
16+
);
17+
18+
expect(app.automaticDataCollectionEnabled).to.be.false;
19+
expect(app.name).to.equal('test');
20+
expect(app.options).to.deep.equal(options);
21+
});
22+
23+
it('deep-copies options', () => {
24+
const options = {
25+
apiKey: "APIKEY"
26+
};
27+
const app = new FirebaseAppImplNext(
28+
options,
29+
{name: 'test', automaticDataCollectionEnabled: false},
30+
new ComponentContainer('test')
31+
);
32+
33+
expect(app.options).to.not.equal(options);
34+
expect(app.options).to.deep.equal(options);
35+
});
36+
37+
it('sets automaticDataCollectionEnabled', () => {
38+
const app = new FirebaseAppImplNext(
39+
{},
40+
{name: 'test', automaticDataCollectionEnabled: false},
41+
new ComponentContainer('test')
42+
);
43+
44+
expect(app.automaticDataCollectionEnabled).to.be.false;
45+
app.automaticDataCollectionEnabled = true;
46+
expect(app.automaticDataCollectionEnabled).to.be.true;
47+
});
48+
49+
it('throws accessing any property after being deleted', () => {
50+
const app = new FirebaseAppImplNext(
51+
{},
52+
{name: 'test', automaticDataCollectionEnabled: false},
53+
new ComponentContainer('test')
54+
);
55+
56+
expect(() => app.name).to.not.throw();
57+
(app as unknown as FirebaseAppInternalNext).isDeleted = true;
58+
59+
expect(() => {app.name;}).throws("Firebase App named 'test' already deleted");
60+
expect(() => app.options).throws("Firebase App named 'test' already deleted");
61+
expect(() => app.automaticDataCollectionEnabled).throws("Firebase App named 'test' already deleted");
62+
});
63+
});

packages/app/src/next/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './apis';
1+
export * from './api';
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { expect } from "chai";
2+
import { stub } from "sinon";
3+
import "../../test/setup";
4+
import { createTestComponent, TestService } from '../../test/util';
5+
import { initializeApp, getApps, deleteApp } from './api';
6+
import { addComponent, addOrOverwriteComponent, registerComponent, components, clearComponents } from './internal';
7+
import { FirebaseAppInternalNext } from './types';
8+
9+
declare module '@firebase/component' {
10+
interface NameServiceMapping {
11+
'test': TestService;
12+
}
13+
}
14+
15+
describe('Internal API tests', () => {
16+
17+
afterEach(() => {
18+
for (const app of getApps()) {
19+
deleteApp(app).catch(() => {});
20+
}
21+
});
22+
23+
describe('addComponent', () => {
24+
it('registers component with App', () => {
25+
const app = initializeApp({}) as FirebaseAppInternalNext;
26+
const testComp = createTestComponent('test');
27+
28+
addComponent(app, testComp);
29+
30+
expect(app.container.getProvider('test').getComponent()).to.equal(testComp);
31+
});
32+
it('does NOT throw registering duplicate components', () => {
33+
const app = initializeApp({}) as FirebaseAppInternalNext;
34+
const testComp = createTestComponent('test');
35+
36+
addComponent(app, testComp);
37+
38+
expect(() => addComponent(app, testComp)).to.not.throw();
39+
expect(app.container.getProvider('test').getComponent()).to.equal(testComp);
40+
});
41+
});
42+
43+
describe('addOrOverwriteComponent', () => {
44+
it('registers component with App', () => {
45+
const app = initializeApp({}) as FirebaseAppInternalNext;
46+
const testComp = createTestComponent('test');
47+
48+
addOrOverwriteComponent(app, testComp);
49+
50+
expect(app.container.getProvider('test').getComponent()).to.equal(testComp);
51+
});
52+
53+
it('overwrites an existing component with the same name', () => {
54+
const app = initializeApp({}) as FirebaseAppInternalNext;
55+
const testComp1 = createTestComponent('test');
56+
const testComp2 = createTestComponent('test');
57+
58+
addOrOverwriteComponent(app, testComp1);
59+
addOrOverwriteComponent(app, testComp2);
60+
61+
expect(app.container.getProvider('test').getComponent()).to.equal(testComp2);
62+
});
63+
});
64+
65+
describe('registerComponent', () => {
66+
afterEach(() => {
67+
clearComponents();
68+
});
69+
70+
it('caches a component and registers it with all Apps', () => {
71+
const app1 = initializeApp({}) as FirebaseAppInternalNext;
72+
const app2 = initializeApp({}, 'app2') as FirebaseAppInternalNext;
73+
74+
const stub1 = stub(app1.container, 'addComponent').callThrough();
75+
const stub2 = stub(app2.container, 'addComponent').callThrough();
76+
77+
const testComp = createTestComponent('test');
78+
registerComponent(testComp);
79+
80+
expect(components.get('test')).to.equal(testComp);
81+
expect(stub1).to.have.been.calledWith(testComp);
82+
expect(stub2).to.have.been.calledWith(testComp);
83+
});
84+
85+
it('returns true if registration is successful', () => {
86+
const testComp = createTestComponent('test');
87+
expect(components.size).to.equal(0);
88+
expect(registerComponent(testComp)).to.be.true;
89+
expect(components.get('test')).to.equal(testComp);
90+
});
91+
92+
it('does NOT throw when registering duplicate components and returns false', () => {
93+
const testComp1 = createTestComponent('test');
94+
const testComp2 = createTestComponent('test');
95+
expect(components.size).to.equal(0);
96+
expect(registerComponent(testComp1)).to.be.true;
97+
expect(components.get('test')).to.equal(testComp1);
98+
expect(registerComponent(testComp2)).to.be.false;
99+
expect(components.get('test')).to.equal(testComp1);
100+
});
101+
});
102+
103+
});

0 commit comments

Comments
 (0)