Skip to content

Commit 4845858

Browse files
authored
Merge pull request #101 from FirebasePrivate/v0.5
Merge V0.5
2 parents 84424f4 + 587e95c commit 4845858

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1879
-2208
lines changed

.npmignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
.tmp
22
coverage
33
.vscode
4+
tsconfig.*
5+
tslint.*
46

5-
# The SDK's internal unit tests might confuse users looking for the testing/ module.
7+
# Don't include the raw typescript
8+
src
69
spec
10+
# TODO(rjh) add back once testing isn't just a joke
11+
testing

CONTRIBUTING.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# How to contribute
2+
3+
We'd love to accept your patches and contributions to this project. There are
4+
just a few small guidelines you need to follow.
5+
6+
## Contributor License Agreement
7+
8+
Contributions to this project must be accompanied by a Contributor License
9+
Agreement. You (or your employer) retain the copyright to your contribution,
10+
this simply gives us permission to use and redistribute your contributions as
11+
part of the project. Head over to <https://cla.developers.google.com/> to see
12+
your current agreements on file or to sign a new one.
13+
14+
You generally only need to submit a CLA once, so if you've already submitted one
15+
(even if it was for a different project), you probably don't need to do it
16+
again.
17+
18+
## Code reviews
19+
20+
All submissions, including submissions by project members, require review. We
21+
use GitHub pull requests for this purpose. Consult [GitHub Help] for more
22+
information on using pull requests.
23+
24+
[GitHub Help]: https://help.github.com/articles/about-pull-requests/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 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.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ In your Firebase project's `functions` directory, run:
1515
var functions = require('firebase-functions');
1616
var notifyUsers = require('./notify-users');
1717

18-
exports.newPost = functions.database()
19-
.path('/posts/{postId}')
18+
exports.newPost = functions.database
19+
.ref('/posts/{postId}')
2020
.onWrite(function(event) {
2121
// only execute function on creation
2222
if (!event.data.previous.exists()) {

package.json

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "firebase-functions",
3-
"version": "0.4.1",
3+
"version": "0.5.0",
44
"description": "Node helpers for Firebase Functions.",
55
"main": "lib/index.js",
66
"scripts": {
77
"build": "node_modules/.bin/tsc",
8-
"build:pack": "npm prune --production && npm install typescript && node_modules/.bin/tsc && npm pack && npm install",
8+
"build:pack": "npm prune --production && rm -rf lib && npm install typescript && node_modules/.bin/tsc && npm pack && npm install",
99
"lint": "node_modules/.bin/tslint src/{**/*,*}.ts spec/{**/*,*}.ts",
10-
"pretest": "node_modules/.bin/tsc spec/index.spec.ts --target es5 --outDir .tmp && cp -r spec/fixtures .tmp/spec",
10+
"pretest": "node_modules/.bin/tsc -p tsconfig.spec.json && cp -r spec/fixtures .tmp/spec",
1111
"test": "npm run lint && mocha .tmp/spec/index.spec.js",
1212
"posttest": "rm -rf .tmp"
1313
},
@@ -29,34 +29,37 @@
2929
"@types/chai": "^3.4.32",
3030
"@types/chai-as-promised": "0.0.28",
3131
"@types/mocha": "^2.2.31",
32+
"@types/mock-require": "^1.3.3",
3233
"@types/nock": "^0.54.32",
34+
"@types/node": "^6.0.38",
35+
"@types/request": "0.0.30",
3336
"@types/sinon": "^1.16.29",
3437
"chai": "^3.5.0",
3538
"chai-as-promised": "^5.2.0",
36-
"firebase": "^3.3",
39+
"firebase-admin": "^4.0.5",
3740
"istanbul": "^0.4.2",
3841
"mocha": "^2.4.5",
42+
"mock-require": "^2.0.1",
3943
"nock": "^8.0.0",
4044
"sinon": "^1.17.4",
4145
"tslint": "^3.15.1",
42-
"typescript": "^2.0.0"
46+
"typescript": "^2.0.3"
4347
},
4448
"peerDependencies": {
45-
"firebase": "^3.3"
49+
"firebase-admin": "^4.0.5"
4650
},
4751
"dependencies": {
48-
"@types/bluebird": "^3.0.32",
49-
"@types/jsonwebtoken": "^7.1.32",
5052
"@types/express": "^4.0.33",
53+
"@types/jsonwebtoken": "^7.1.32",
5154
"@types/lodash": "^4.14.34",
52-
"@types/node": "^6.0.38",
53-
"@types/request": "0.0.30",
5455
"@types/request-promise": "^3.0.30",
55-
"bluebird": "^3.4.6",
56+
"@types/sha1": "^1.1.0",
57+
"express": "^4.0.33",
5658
"jsonwebtoken": "^7.1.9",
5759
"lodash": "^4.6.1",
5860
"request": "^2.74.0",
59-
"request-promise": "^4.1.1"
61+
"request-promise": "^4.1.1",
62+
"sha1": "^1.1.1"
6063
},
6164
"typings": "lib/index.d.ts"
6265
}

spec/apps.spec.ts

Lines changed: 142 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,45 @@
1-
import { expect } from 'chai';
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2015 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.
222

3-
import { FakeEnv } from './support/helpers';
4-
import Apps from '../src/apps';
5-
import * as firebase from 'firebase';
23+
import { expect } from 'chai';
24+
import { fakeConfig } from './support/helpers';
25+
import {apps as appsNamespace, apps} from '../src/apps';
26+
import * as firebase from 'firebase-admin';
27+
import * as _ from 'lodash';
28+
import * as sinon from 'sinon';
629

730
describe('apps', () => {
8-
let apps;
31+
let apps: appsNamespace.Apps;
32+
let claims;
933
beforeEach(() => {
10-
apps = new Apps(new FakeEnv());
34+
apps = new appsNamespace.Apps(fakeConfig());
35+
// mock claims intentionally contains dots, square brackets, and nested paths
36+
claims = {'token': {'firebase': {'identities':{'google.com':['111']}}}};
37+
});
38+
39+
afterEach(() => {
40+
_.forEach(firebase.apps, app => {
41+
app.delete();
42+
});
1143
});
1244

1345
it('should load the admin app for admin impersonation', function () {
@@ -19,16 +51,116 @@ describe('apps', () => {
1951
});
2052

2153
it('should create a user app for user impersonation', function () {
22-
const claims = { uid: 'inlined', team: 'firebase' };
23-
const key = JSON.stringify(claims);
54+
const auth = { admin: false, variable: claims };
55+
const key = apps._appName(auth);
2456
expect(function () {
2557
return firebase.app(key);
2658
}).to.throw(Error);
2759

28-
const userApp = apps.forMode({ admin: false, variable: claims });
60+
const userApp = apps.forMode(auth);
2961
expect(firebase.app(key)).to.equal(userApp);
3062

31-
const userAppAgain = apps.forMode({ admin: false, variable: claims });
63+
const userAppAgain = apps.forMode(auth);
3264
expect(userApp).to.equal(userAppAgain);
3365
});
66+
67+
it('should retain/release ref counters appropriately without auth', function() {
68+
apps.retain({});
69+
expect(apps['_refCounter']).to.deep.equal({
70+
__admin__: 1,
71+
__noauth__: 1,
72+
});
73+
apps.release({});
74+
expect(apps['_refCounter']).to.deep.equal({
75+
__admin__: 0,
76+
__noauth__: 0,
77+
});
78+
});
79+
80+
it('should retain/release ref counters appropriately with admin auth', function() {
81+
apps.retain({auth: {admin: true}});
82+
expect(apps['_refCounter']).to.deep.equal({
83+
__admin__: 2,
84+
});
85+
apps.release({auth: {admin: true}});
86+
expect(apps['_refCounter']).to.deep.equal({
87+
__admin__: 0,
88+
});
89+
});
90+
91+
it('should retain/release ref counters appropriately with user auth', function() {
92+
const payload = {auth: {admin: false, variable: claims}};
93+
const userAppName = apps._appName(payload.auth);
94+
apps.retain(payload);
95+
expect(apps['_refCounter']).to.deep.equal({
96+
__admin__: 1,
97+
[userAppName]: 1,
98+
});
99+
apps.release(payload);
100+
expect(apps['_refCounter']).to.deep.equal({
101+
__admin__: 0,
102+
[userAppName]: 0,
103+
});
104+
});
105+
106+
describe('#_waitToDestroyApp', () => {
107+
let clock;
108+
let noauthApp;
109+
let deleteNoauth;
110+
111+
beforeEach(() => {
112+
clock = sinon.useFakeTimers();
113+
noauthApp = apps.forMode({ admin: false });
114+
deleteNoauth = noauthApp.delete.bind(noauthApp);
115+
sinon.spy(noauthApp, 'delete');
116+
});
117+
118+
afterEach(() => {
119+
clock.restore();
120+
noauthApp.delete.restore();
121+
});
122+
123+
it('should delete app after 2 minutes and not earlier', function() {
124+
apps['_refCounter'] = { '__noauth__': 0 };
125+
apps._waitToDestroyApp('__noauth__');
126+
clock.tick(appsNamespace.garbageCollectionInterval - 1);
127+
expect(noauthApp.delete.called).to.be.false;
128+
clock.tick(1);
129+
130+
// Technically the delete happens on the next tick *after* 2 min
131+
return Promise.resolve().then(() => {
132+
expect(noauthApp.delete.called).to.be.true;
133+
});
134+
});
135+
136+
it('should exit right away if app was already deleted', function() {
137+
return deleteNoauth().then(() => {
138+
let spy = sinon.spy(appsNamespace, 'delay');
139+
apps._waitToDestroyApp('__noauth__');
140+
spy.restore();
141+
expect(spy.called).to.be.false;
142+
});
143+
});
144+
145+
it('should not delete app if it gets deleted while function is waiting', function() {
146+
apps._waitToDestroyApp('__noauth__');
147+
deleteNoauth();
148+
clock.tick(appsNamespace.garbageCollectionInterval);
149+
return Promise.resolve().then(() => {
150+
expect(noauthApp.delete.called).to.be.false;
151+
});
152+
});
153+
154+
it('should not delete app if ref count rises above 0', function() {
155+
apps['_refCounter'] = {
156+
'__admin__': 0,
157+
'__noauth__': 1,
158+
};
159+
apps._waitToDestroyApp('__noauth__');
160+
clock.tick(appsNamespace.garbageCollectionInterval);
161+
return Promise.resolve().then(() => {
162+
expect(noauthApp.delete.called).to.be.false;
163+
});
164+
});
165+
});
34166
});

spec/builder.spec.ts

Lines changed: 0 additions & 89 deletions
This file was deleted.

0 commit comments

Comments
 (0)