Skip to content

Commit a682347

Browse files
authored
Add functionality for firebase-functions-test (firebase#1)
1 parent 07854ca commit a682347

23 files changed

+1332
-0
lines changed

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
npm-debug.log
3+
lib
4+
.npmrc
5+
.vscode
6+
*.tgz
7+
.tmp

.npmignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.tmp
2+
coverage
3+
.vscode
4+
.idea
5+
tsconfig.*
6+
tslint.*
7+
.travis.yml
8+
.github
9+
10+
# Don't include the raw typescript
11+
src
12+
spec
13+
*.tgz

.travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- '6.11.5'
4+
- stable
5+
sudo: false

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# firebase-functions-fake

package.json

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "firebase-functions-test",
3+
"version": "0.1.0",
4+
"description": "A testing companion to firebase-functions.",
5+
"main": "lib/index.js",
6+
"scripts": {
7+
"build": "npm i && node_modules/.bin/tsc -p tsconfig.release.json",
8+
"build:pack": "npm prune --production && rm -rf lib && npm install && node_modules/.bin/tsc -p tsconfig.release.json && npm pack && npm install",
9+
"build:release": "npm install --production && npm install typescript firebase-functions && node_modules/.bin/tsc -p tsconfig.release.json",
10+
"lint": "node_modules/.bin/tslint src/{**/*,*}.ts spec/{**/*,*}.ts",
11+
"pretest": "node_modules/.bin/tsc",
12+
"test": "mocha .tmp/spec/index.spec.js",
13+
"posttest": "npm run lint && rm -rf .tmp"
14+
},
15+
"author": "Firebase Team",
16+
"dependencies": {
17+
"@types/lodash": "^4.14.104",
18+
"firebase-admin": "^5.11.0",
19+
"lodash": "^4.17.5"
20+
},
21+
"devDependencies": {
22+
"@types/chai": "^4.1.2",
23+
"@types/mocha": "^5.0.0",
24+
"chai": "^4.1.2",
25+
"firebase-functions": "https://storage.googleapis.com/functions-dev-preview/firebase-functions-1.0.0-rc4.tgz",
26+
"mocha": "^5.0.5",
27+
"sinon": "^4.4.9",
28+
"tslint": "^5.8.0",
29+
"typescript": "^2.4.1"
30+
},
31+
"peerDependencies": {
32+
"firebase-functions": "https://storage.googleapis.com/functions-dev-preview/firebase-functions-1.0.0-rc4.tgz"
33+
},
34+
"engines": {
35+
"node": ">=6.0.0"
36+
},
37+
"typings": "lib/index.d.ts"
38+
}

spec/app.spec.ts

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2018 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import { expect } from 'chai';
24+
import * as sinon from 'sinon';
25+
import * as firebase from 'firebase-admin';
26+
27+
import { testApp } from '../src/app';
28+
import { FirebaseFunctionsTest } from '../src/lifecycle';
29+
30+
describe('app', () => {
31+
let appInstance;
32+
let test = new FirebaseFunctionsTest();
33+
before(() => {
34+
test.init();
35+
appInstance = testApp();
36+
});
37+
38+
after(() => {
39+
test.cleanup();
40+
});
41+
42+
describe('#getApp', () => {
43+
const spy = sinon.spy(firebase, 'initializeApp');
44+
45+
afterEach(() => {
46+
spy.resetHistory();
47+
appInstance.deleteApp();
48+
});
49+
50+
it('should initialize a new app if appSingleton does not exist', () => {
51+
appInstance.getApp();
52+
expect(spy.called).to.be.true;
53+
});
54+
55+
it('should only initialize app once', () => {
56+
appInstance.getApp();
57+
appInstance.getApp();
58+
expect(spy.calledOnce).to.be.true;
59+
});
60+
});
61+
62+
describe('#deleteApp', () => {
63+
it('deletes appSingleton if it exists', () => {
64+
const spy = sinon.spy();
65+
appInstance.appSingleton = {
66+
delete: spy,
67+
};
68+
appInstance.deleteApp();
69+
expect(spy.called).to.be.true;
70+
expect(appInstance.appSingleton).to.equal(undefined);
71+
});
72+
73+
it('does not throw an error if there are no apps to delete', () => {
74+
delete appInstance.appSingleton;
75+
expect(() => appInstance.deleteApp).to.not.throw(Error);
76+
});
77+
});
78+
});

spec/index.spec.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2018 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import * as chai from 'chai';
24+
import * as chaiAsPromised from 'chai-as-promised';
25+
chai.use(chaiAsPromised);
26+
27+
import 'mocha';
28+
import './lifecycle.spec';
29+
import './main.spec';
30+
import './app.spec';
31+
// import './providers/analytics.spec';
32+
// import './providers/auth.spec';
33+
// import './providers/database.spec';
34+
// import './providers/firestore.spec';
35+
// import './providers/https.spec';
36+
// import './providers/pubsub.spec';
37+
// import './providers/storage.spec';
38+
// import './providers/crashlytics.spec';

spec/lifecycle.spec.ts

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2018 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import { expect } from 'chai';
24+
25+
import { FirebaseFunctionsTest } from '../src/lifecycle';
26+
import { mockConfig } from '../src/main';
27+
import { afterEach } from 'mocha';
28+
29+
describe('lifecycle', () => {
30+
describe('#init', () => {
31+
let test = new FirebaseFunctionsTest();
32+
afterEach(() => {
33+
test.cleanup();
34+
});
35+
36+
it('sets env variables appropriately if SDK initialized without parameters', () => {
37+
test.init();
38+
expect(process.env.FIREBASE_CONFIG).to.equal(JSON.stringify({
39+
databaseURL: 'https://not-a-project.firebaseio.com',
40+
storageBucket: 'not-a-project.appspot.com',
41+
projectId: 'not-a-project',
42+
}));
43+
expect(process.env.GCLOUD_PROJECT).to.equal('not-a-project');
44+
expect(process.env.GOOGLE_APPLICATION_CREDENTIALS).to.be.undefined;
45+
});
46+
47+
it('sets env variables appropriately if SDK initialized with parameters', () => {
48+
let firebaseConfig = {
49+
databaseURL: 'https://my-project.firebaseio.com',
50+
storageBucket: 'my-project.appspot.com',
51+
projectId: 'my-project',
52+
};
53+
test.init(firebaseConfig, 'path/to/key.json');
54+
55+
expect(process.env.FIREBASE_CONFIG).to.equal(JSON.stringify(firebaseConfig));
56+
expect(process.env.GCLOUD_PROJECT).to.equal('my-project');
57+
expect(process.env.GOOGLE_APPLICATION_CREDENTIALS).to.equal('path/to/key.json');
58+
});
59+
});
60+
61+
describe('#cleanUp', () => {
62+
afterEach(() => {
63+
delete process.env.FIREBASE_CONFIG;
64+
delete process.env.GCLOUD_PROJECT;
65+
delete process.env.GOOGLE_APPLICATION_CREDENTIALS;
66+
delete process.env.CLOUD_RUNTIME_CONFIG;
67+
});
68+
69+
it('deletes all the env variables if they did not previously exist', () => {
70+
let test = new FirebaseFunctionsTest();
71+
test.init();
72+
mockConfig({ foo: {bar: 'faz '}});
73+
test.cleanup();
74+
expect(process.env.FIREBASE_CONFIG).to.be.undefined;
75+
expect(process.env.GCLOUD_PROJECT).to.be.undefined;
76+
expect(process.env.GOOGLE_APPLICATION_CREDENTIALS).to.be.undefined;
77+
expect(process.env.CLOUD_RUNTIME_CONFIG).to.be.undefined;
78+
});
79+
80+
it('restores env variables if they had previous values', () => {
81+
process.env.FIREBASE_CONFIG = 'oldFb';
82+
process.env.GCLOUD_PROJECT = 'oldGc';
83+
process.env.GOOGLE_APPLICATION_CREDENTIALS = 'oldGac';
84+
process.env.CLOUD_RUNTIME_CONFIG = 'oldCrc';
85+
let test = new FirebaseFunctionsTest();
86+
87+
test.init();
88+
mockConfig({ foo: { bar: 'faz ' } });
89+
test.cleanup();
90+
91+
expect(process.env.FIREBASE_CONFIG).to.equal('oldFb');
92+
expect(process.env.GCLOUD_PROJECT).to.equal('oldGc');
93+
expect(process.env.GOOGLE_APPLICATION_CREDENTIALS).to.equal('oldGac');
94+
expect(process.env.CLOUD_RUNTIME_CONFIG).to.equal('oldCrc');
95+
});
96+
});
97+
});

0 commit comments

Comments
 (0)