From 5dbb0bd7b14d34484c5aeff445bccdfc75f6d6a7 Mon Sep 17 00:00:00 2001 From: Diana Tkachenko Date: Wed, 12 Jun 2019 22:41:52 -0700 Subject: [PATCH 1/3] fix lint errors for database, firestore, https tests --- spec/providers/database.spec.ts | 109 ++++++++++++++----------- spec/providers/firestore.spec.ts | 132 ++++++++++++++++--------------- spec/providers/https.spec.ts | 65 +++++++-------- 3 files changed, 162 insertions(+), 144 deletions(-) diff --git a/spec/providers/database.spec.ts b/spec/providers/database.spec.ts index 5fa1307fd..911daf8a5 100644 --- a/spec/providers/database.spec.ts +++ b/spec/providers/database.spec.ts @@ -20,12 +20,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as database from '../../src/providers/database'; import { expect } from 'chai'; import { apps as appsNamespace } from '../../src/apps'; -import { applyChange } from '../../src/utils'; import * as functions from '../../src/index'; -import { Event } from '../../src/index'; +import * as database from '../../src/providers/database'; +import { applyChange } from '../../src/utils'; describe('Database Functions', () => { describe('DatabaseBuilder', () => { @@ -44,7 +43,7 @@ describe('Database Functions', () => { }); it('should allow both region and runtime options to be set', () => { - let fn = functions + const fn = functions .region('us-east1') .runWith({ timeoutSeconds: 90, @@ -60,7 +59,7 @@ describe('Database Functions', () => { describe('#onWrite()', () => { it('should return "ref.write" as the event type', () => { - let eventType = database.ref('foo').onWrite(() => null).__trigger + const eventType = database.ref('foo').onWrite(() => null).__trigger .eventTrigger.eventType; expect(eventType).to.eq( 'providers/google.firebase.database/eventTypes/ref.write' @@ -68,17 +67,17 @@ describe('Database Functions', () => { }); it('should construct a proper resource path', () => { - let resource = database.ref('foo').onWrite(() => null).__trigger + const resource = database.ref('foo').onWrite(() => null).__trigger .eventTrigger.resource; expect(resource).to.eq('projects/_/instances/subdomain/refs/foo'); }); it('should let developers choose a database instance', () => { - let func = database + const func = database .instance('custom') .ref('foo') .onWrite(() => null); - let resource = func.__trigger.eventTrigger.resource; + const resource = func.__trigger.eventTrigger.resource; expect(resource).to.eq('projects/_/instances/custom/refs/foo'); }); @@ -96,9 +95,11 @@ describe('Database Functions', () => { resource: 'projects/_/instances/subdomains/refs/users', }, }; - let handler = database.ref('/users/{id}').onWrite((change, context) => { - expect(change.after.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database + .ref('/users/{id}') + .onWrite((change, context) => { + expect(change.after.val()).to.deep.equal({ foo: 'bar' }); + }); return handler(event.data, event.context); }); @@ -106,7 +107,7 @@ describe('Database Functions', () => { describe('#onCreate()', () => { it('should return "ref.create" as the event type', () => { - let eventType = database.ref('foo').onCreate(() => null).__trigger + const eventType = database.ref('foo').onCreate(() => null).__trigger .eventTrigger.eventType; expect(eventType).to.eq( 'providers/google.firebase.database/eventTypes/ref.create' @@ -114,17 +115,17 @@ describe('Database Functions', () => { }); it('should construct a proper resource path', () => { - let resource = database.ref('foo').onCreate(() => null).__trigger + const resource = database.ref('foo').onCreate(() => null).__trigger .eventTrigger.resource; expect(resource).to.eq('projects/_/instances/subdomain/refs/foo'); }); it('should let developers choose a database instance', () => { - let func = database + const func = database .instance('custom') .ref('foo') .onCreate(() => null); - let resource = func.__trigger.eventTrigger.resource; + const resource = func.__trigger.eventTrigger.resource; expect(resource).to.eq('projects/_/instances/custom/refs/foo'); }); @@ -143,9 +144,11 @@ describe('Database Functions', () => { }, }; - let handler = database.ref('/users/{id}').onCreate((data, context) => { - expect(data.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database + .ref('/users/{id}') + .onCreate((data, context) => { + expect(data.val()).to.deep.equal({ foo: 'bar' }); + }); return handler(event.data, event.context); }); @@ -153,7 +156,7 @@ describe('Database Functions', () => { describe('#onUpdate()', () => { it('should return "ref.update" as the event type', () => { - let eventType = database.ref('foo').onUpdate(() => null).__trigger + const eventType = database.ref('foo').onUpdate(() => null).__trigger .eventTrigger.eventType; expect(eventType).to.eq( 'providers/google.firebase.database/eventTypes/ref.update' @@ -161,17 +164,17 @@ describe('Database Functions', () => { }); it('should construct a proper resource path', () => { - let resource = database.ref('foo').onUpdate(() => null).__trigger + const resource = database.ref('foo').onUpdate(() => null).__trigger .eventTrigger.resource; expect(resource).to.eq('projects/_/instances/subdomain/refs/foo'); }); it('should let developers choose a database instance', () => { - let func = database + const func = database .instance('custom') .ref('foo') .onUpdate(() => null); - let resource = func.__trigger.eventTrigger.resource; + const resource = func.__trigger.eventTrigger.resource; expect(resource).to.eq('projects/_/instances/custom/refs/foo'); }); @@ -190,7 +193,7 @@ describe('Database Functions', () => { }, }; - let handler = database + const handler = database .ref('/users/{id}') .onUpdate((change, context) => { expect(change.after.val()).to.deep.equal({ foo: 'bar' }); @@ -202,7 +205,7 @@ describe('Database Functions', () => { describe('#onDelete()', () => { it('should return "ref.delete" as the event type', () => { - let eventType = database.ref('foo').onDelete(() => null).__trigger + const eventType = database.ref('foo').onDelete(() => null).__trigger .eventTrigger.eventType; expect(eventType).to.eq( 'providers/google.firebase.database/eventTypes/ref.delete' @@ -210,17 +213,17 @@ describe('Database Functions', () => { }); it('should construct a proper resource path', () => { - let resource = database.ref('foo').onDelete(() => null).__trigger + const resource = database.ref('foo').onDelete(() => null).__trigger .eventTrigger.resource; expect(resource).to.eq('projects/_/instances/subdomain/refs/foo'); }); it('should let developers choose a database instance', () => { - let func = database + const func = database .instance('custom') .ref('foo') .onDelete(() => null); - let resource = func.__trigger.eventTrigger.resource; + const resource = func.__trigger.eventTrigger.resource; expect(resource).to.eq('projects/_/instances/custom/refs/foo'); }); @@ -239,9 +242,11 @@ describe('Database Functions', () => { }, }; - let handler = database.ref('/users/{id}').onDelete((data, context) => { - expect(data.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database + .ref('/users/{id}') + .onDelete((data, context) => { + expect(data.val()).to.deep.equal({ foo: 'bar' }); + }); return handler(event.data, event.context); }); @@ -251,12 +256,14 @@ describe('Database Functions', () => { describe('handler namespace', () => { describe('#onWrite()', () => { it('correctly sets trigger to {}', () => { - let cf = functions.handler.database.ref.onWrite(() => null); + const cf = functions.handler.database.ref.onWrite(() => null); expect(cf.__trigger).to.deep.equal({}); }); it('should be able to use the instance entry point', () => { - let func = functions.handler.database.instance.ref.onWrite(() => null); + const func = functions.handler.database.instance.ref.onWrite( + () => null + ); expect(func.__trigger).to.deep.equal({}); }); @@ -275,7 +282,7 @@ describe('Database Functions', () => { }, }; - let handler = functions.handler.database.ref.onWrite( + const handler = functions.handler.database.ref.onWrite( (change, context) => { return expect(change.after.val()).to.deep.equal({ foo: 'bar' }); } @@ -287,12 +294,14 @@ describe('Database Functions', () => { describe('#onCreate()', () => { it('correctly sets trigger to {}', () => { - let cf = functions.handler.database.ref.onCreate(() => null); + const cf = functions.handler.database.ref.onCreate(() => null); return expect(cf.__trigger).to.deep.equal({}); }); it('should be able to use the instance entry point', () => { - let func = functions.handler.database.instance.ref.onCreate(() => null); + const func = functions.handler.database.instance.ref.onCreate( + () => null + ); expect(func.__trigger).to.deep.equal({}); }); @@ -310,7 +319,7 @@ describe('Database Functions', () => { resource: 'projects/_/instances/subdomains/refs/users', }, }; - let handler = functions.handler.database.ref.onCreate( + const handler = functions.handler.database.ref.onCreate( (data, context) => { return expect(data.val()).to.deep.equal({ foo: 'bar' }); } @@ -322,12 +331,14 @@ describe('Database Functions', () => { describe('#onUpdate()', () => { it('correctly sets trigger to {}', () => { - let cf = functions.handler.database.ref.onUpdate(() => null); + const cf = functions.handler.database.ref.onUpdate(() => null); return expect(cf.__trigger).to.deep.equal({}); }); it('should be able to use the instance entry point', () => { - let func = functions.handler.database.instance.ref.onUpdate(() => null); + const func = functions.handler.database.instance.ref.onUpdate( + () => null + ); expect(func.__trigger).to.deep.equal({}); }); @@ -345,7 +356,7 @@ describe('Database Functions', () => { resource: 'projects/_/instances/subdomains/refs/users', }, }; - let handler = functions.handler.database.ref.onUpdate( + const handler = functions.handler.database.ref.onUpdate( (change, context) => { return expect(change.after.val()).to.deep.equal({ foo: 'bar' }); } @@ -357,12 +368,14 @@ describe('Database Functions', () => { describe('#onDelete()', () => { it('correctly sets trigger to {}', () => { - let cf = functions.handler.database.ref.onDelete(() => null); + const cf = functions.handler.database.ref.onDelete(() => null); return expect(cf.__trigger).to.deep.equal({}); }); it('should be able to use the instance entry point', () => { - let func = functions.handler.database.instance.ref.onDelete(() => null); + const func = functions.handler.database.instance.ref.onDelete( + () => null + ); expect(func.__trigger).to.deep.equal({}); }); @@ -381,7 +394,7 @@ describe('Database Functions', () => { }, }; - let handler = functions.handler.database.ref.onDelete( + const handler = functions.handler.database.ref.onDelete( (data, context) => { return expect(data.val()).to.deep.equal({ foo: 'bar' }); } @@ -406,14 +419,14 @@ describe('Database Functions', () => { }); it('should not throw when #run is called', () => { - let cf = database.ref('/path').onWrite(() => null); + const cf = database.ref('/path').onWrite(() => null); expect(cf.run).to.not.throw(Error); }); }); describe('resourceToInstanceAndPath', () => { it('should return the correct instance and path strings', () => { - let [instance, path] = database.resourceToInstanceAndPath( + const [instance, path] = database.resourceToInstanceAndPath( 'projects/_/instances/foo/refs/bar' ); expect(instance).to.equal('https://foo.firebaseio.com'); @@ -443,8 +456,8 @@ describe('Database Functions', () => { let subject: any; const apps = new appsNamespace.Apps(); - let populate = (data: any) => { - let [instance, path] = database.resourceToInstanceAndPath( + const populate = (data: any) => { + const [instance, path] = database.resourceToInstanceAndPath( 'projects/_/instances/other-subdomain/refs/foo' ); subject = new database.DataSnapshot(data, path, apps.admin, instance); @@ -562,7 +575,7 @@ describe('Database Functions', () => { it('should not execute for leaf or null nodes', () => { populate(23); let count = 0; - let counter = (snap: any) => count++; + const counter = (snap: any) => count++; expect(subject.forEach(counter)).to.equal(false); expect(count).to.eq(0); @@ -635,7 +648,7 @@ describe('Database Functions', () => { }); it('should return null for the root', () => { - let [instance, path] = database.resourceToInstanceAndPath( + const [instance, path] = database.resourceToInstanceAndPath( 'projects/_/instances/foo/refs/' ); const snapshot = new database.DataSnapshot( diff --git a/spec/providers/firestore.spec.ts b/spec/providers/firestore.spec.ts index e43c1f2d7..9d131d6f9 100644 --- a/spec/providers/firestore.spec.ts +++ b/spec/providers/firestore.spec.ts @@ -20,17 +20,17 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +import { expect } from 'chai'; import * as admin from 'firebase-admin'; - -import * as firestore from '../../src/providers/firestore'; import * as _ from 'lodash'; -import { expect } from 'chai'; + import * as functions from '../../src/index'; +import * as firestore from '../../src/providers/firestore'; describe('Firestore Functions', () => { function constructValue(fields: any) { return { - fields: fields, + fields, name: 'projects/pid/databases/(default)/documents/collection/123', createTime: '2017-06-02T18:48:58.920638Z', updateTime: '2017-07-02T18:48:58.920638Z', @@ -40,7 +40,7 @@ describe('Firestore Functions', () => { function makeEvent(data: any, context?: { [key: string]: any }) { context = context || {}; return { - data: data, + data, context: _.merge( { eventId: '123', @@ -59,8 +59,8 @@ describe('Firestore Functions', () => { function constructEvent(oldValue: object, value: object, eventType: string) { return { data: { - oldValue: oldValue, - value: value, + oldValue, + value, }, context: { resource: { @@ -112,18 +112,20 @@ describe('Firestore Functions', () => { }); it('should allow terse constructors', () => { - let resource = + const resource = 'projects/project1/databases/(default)/documents/users/{uid}'; - let cloudFunction = firestore.document('users/{uid}').onWrite(() => null); + const cloudFunction = firestore + .document('users/{uid}') + .onWrite(() => null); expect(cloudFunction.__trigger).to.deep.equal( expectedTrigger(resource, 'document.write') ); }); it('should allow custom namespaces', () => { - let resource = + const resource = 'projects/project1/databases/(default)/documents@v2/users/{uid}'; - let cloudFunction = firestore + const cloudFunction = firestore .namespace('v2') .document('users/{uid}') .onWrite(() => null); @@ -133,8 +135,8 @@ describe('Firestore Functions', () => { }); it('should allow custom databases', () => { - let resource = 'projects/project1/databases/myDB/documents/users/{uid}'; - let cloudFunction = firestore + const resource = 'projects/project1/databases/myDB/documents/users/{uid}'; + const cloudFunction = firestore .database('myDB') .document('users/{uid}') .onWrite(() => null); @@ -144,9 +146,9 @@ describe('Firestore Functions', () => { }); it('should allow both custom database and namespace', () => { - let resource = + const resource = 'projects/project1/databases/myDB/documents@v2/users/{uid}'; - let cloudFunction = firestore + const cloudFunction = firestore .database('myDB') .namespace('v2') .document('users/{uid}') @@ -157,7 +159,7 @@ describe('Firestore Functions', () => { }); it('should allow both region and runtime options to be set', () => { - let fn = functions + const fn = functions .region('us-east1') .runWith({ timeoutSeconds: 90, @@ -172,9 +174,9 @@ describe('Firestore Functions', () => { }); it('onCreate should have the "document.create" eventType', () => { - let resource = + const resource = 'projects/project1/databases/(default)/documents/users/{uid}'; - let eventType = firestore.document('users/{uid}').onCreate(() => null) + const eventType = firestore.document('users/{uid}').onCreate(() => null) .__trigger.eventTrigger.eventType; expect(eventType).to.eq( expectedTrigger(resource, 'document.create').eventTrigger.eventType @@ -182,9 +184,9 @@ describe('Firestore Functions', () => { }); it('onUpdate should have the "document.update" eventType', () => { - let resource = + const resource = 'projects/project1/databases/(default)/documents/users/{uid}'; - let eventType = firestore.document('users/{uid}').onUpdate(() => null) + const eventType = firestore.document('users/{uid}').onUpdate(() => null) .__trigger.eventTrigger.eventType; expect(eventType).to.eq( expectedTrigger(resource, 'document.update').eventTrigger.eventType @@ -192,9 +194,9 @@ describe('Firestore Functions', () => { }); it('onDelete should have the "document.delete" eventType', () => { - let resource = + const resource = 'projects/project1/databases/(default)/documents/users/{uid}'; - let eventType = firestore.document('users/{uid}').onDelete(() => null) + const eventType = firestore.document('users/{uid}').onDelete(() => null) .__trigger.eventTrigger.eventType; expect(eventType).to.eq( expectedTrigger(resource, 'document.delete').eventTrigger.eventType @@ -216,7 +218,7 @@ describe('Firestore Functions', () => { }); it('should not throw when #run is called', () => { - let cf = firestore.document('input').onCreate(() => null); + const cf = firestore.document('input').onCreate(() => null); expect(cf.run).to.not.throw(Error); }); }); @@ -231,7 +233,7 @@ describe('Firestore Functions', () => { }); it('constructs appropriate fields and getters for event.data on "document.write" events', () => { - let testFunction = firestore + const testFunction = firestore .document('path') .onWrite((change, context) => { expect(change.before.data()).to.deep.equal({ @@ -243,7 +245,7 @@ describe('Firestore Functions', () => { expect(change.after.get('key1')).to.equal(true); return true; // otherwise will get warning about returning undefined }); - let data = constructEvent( + const data = constructEvent( createOldValue(), createValue(), 'document.write' @@ -252,19 +254,19 @@ describe('Firestore Functions', () => { }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.create" events', () => { - let testFunction = firestore + const testFunction = firestore .document('path') .onCreate((data, context) => { expect(data.data()).to.deep.equal({ key1: true, key2: 123 }); expect(data.get('key1')).to.equal(true); return true; // otherwise will get warning about returning undefined }); - let data = constructEvent({}, createValue(), 'document.create'); - return testFunction(data.data, data.context); + const event = constructEvent({}, createValue(), 'document.create'); + return testFunction(event.data, event.context); }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.update" events', () => { - let testFunction = firestore + const testFunction = firestore .document('path') .onUpdate((change, context) => { expect(change.before.data()).to.deep.equal({ @@ -276,7 +278,7 @@ describe('Firestore Functions', () => { expect(change.after.get('key1')).to.equal(true); return true; // otherwise will get warning about returning undefined }); - let data = constructEvent( + const data = constructEvent( createOldValue(), createValue(), 'document.update' @@ -285,15 +287,15 @@ describe('Firestore Functions', () => { }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.delete" events', () => { - let testFunction = firestore + const testFunction = firestore .document('path') .onDelete((data, context) => { expect(data.data()).to.deep.equal({ key1: false, key2: 111 }); expect(data.get('key1')).to.equal(false); return true; // otherwise will get warning about returning undefined }); - let data = constructEvent(createOldValue(), {}, 'document.delete'); - return testFunction(data.data, data.context); + const event = constructEvent(createOldValue(), {}, 'document.delete'); + return testFunction(event.data, event.context); }).timeout(5000); }); @@ -307,7 +309,7 @@ describe('Firestore Functions', () => { }); it('constructs correct data type and sets trigger to {} on "document.write" events', () => { - let testFunction = functions.handler.firestore.document.onWrite( + const testFunction = functions.handler.firestore.document.onWrite( (change, context) => { expect(change.before.data()).to.deep.equal({ key1: false, @@ -320,7 +322,7 @@ describe('Firestore Functions', () => { } ); expect(testFunction.__trigger).to.deep.equal({}); - let data = constructEvent( + const data = constructEvent( createOldValue(), createValue(), 'document.write' @@ -329,7 +331,7 @@ describe('Firestore Functions', () => { }).timeout(5000); it('constructs correct data type and sets trigger to {} on "document.create" events', () => { - let testFunction = functions.handler.firestore.document.onCreate( + const testFunction = functions.handler.firestore.document.onCreate( (data, context) => { expect(data.data()).to.deep.equal({ key1: true, key2: 123 }); expect(data.get('key1')).to.equal(true); @@ -337,12 +339,12 @@ describe('Firestore Functions', () => { } ); expect(testFunction.__trigger).to.deep.equal({}); - let data = constructEvent({}, createValue(), 'document.create'); - return testFunction(data.data, data.context); + const event = constructEvent({}, createValue(), 'document.create'); + return testFunction(event.data, event.context); }).timeout(5000); it('constructs correct data type and sets trigger to {} on "document.update" events', () => { - let testFunction = functions.handler.firestore.document.onUpdate( + const testFunction = functions.handler.firestore.document.onUpdate( change => { expect(change.before.data()).to.deep.equal({ key1: false, @@ -355,7 +357,7 @@ describe('Firestore Functions', () => { } ); expect(testFunction.__trigger).to.deep.equal({}); - let data = constructEvent( + const data = constructEvent( createOldValue(), createValue(), 'document.update' @@ -364,23 +366,23 @@ describe('Firestore Functions', () => { }).timeout(5000); it('constructs correct data type and sets trigger to {} on "document.delete" events', () => { - let testFunction = functions.handler.firestore.document.onDelete( + const testFunction = functions.handler.firestore.document.onDelete( (data, context) => { expect(data.data()).to.deep.equal({ key1: false, key2: 111 }); expect(data.get('key1')).to.equal(false); return true; // otherwise will get warning about returning undefined } ); - let data = constructEvent(createOldValue(), {}, 'document.delete'); + const event = constructEvent(createOldValue(), {}, 'document.delete'); expect(testFunction.__trigger).to.deep.equal({}); - return testFunction(data.data, data.context); + return testFunction(event.data, event.context); }).timeout(5000); }); describe('SnapshotConstructor', () => { describe('#data()', () => { it('should parse int values', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { integerValue: '123' } }), }) @@ -389,7 +391,7 @@ describe('Firestore Functions', () => { }); it('should parse double values', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { doubleValue: 12.34 } }), }) @@ -398,7 +400,7 @@ describe('Firestore Functions', () => { }); it('should parse null values', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { nullValue: null } }), }) @@ -407,7 +409,7 @@ describe('Firestore Functions', () => { }); it('should parse boolean values', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { booleanValue: true } }), }) @@ -416,7 +418,7 @@ describe('Firestore Functions', () => { }); it('should parse string values', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { stringValue: 'foo' } }), }) @@ -425,14 +427,14 @@ describe('Firestore Functions', () => { }); it('should parse array values', () => { - let raw = constructValue({ + const raw = constructValue({ key: { arrayValue: { values: [{ integerValue: '1' }, { integerValue: '2' }], }, }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) @@ -441,7 +443,7 @@ describe('Firestore Functions', () => { }); it('should parse object values', () => { - let raw = constructValue({ + const raw = constructValue({ keyParent: { mapValue: { fields: { @@ -455,7 +457,7 @@ describe('Firestore Functions', () => { }, }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) @@ -466,7 +468,7 @@ describe('Firestore Functions', () => { }); it('should parse GeoPoint values', () => { - let raw = constructValue({ + const raw = constructValue({ geoPointValue: { mapValue: { fields: { @@ -480,7 +482,7 @@ describe('Firestore Functions', () => { }, }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) @@ -494,27 +496,27 @@ describe('Firestore Functions', () => { }); it('should parse reference values', () => { - let raw = constructValue({ + const raw = constructValue({ referenceVal: { referenceValue: 'projects/proj1/databases/(default)/documents/doc1/id', }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) ); - expect(snapshot.data()['referenceVal'].path).to.equal('doc1/id'); + expect(_.get(snapshot.data(), 'referenceVal').path).to.equal('doc1/id'); }); it('should parse timestamp values with precision to the millisecond', () => { - let raw = constructValue({ + const raw = constructValue({ timestampVal: { timestampValue: '2017-06-13T00:58:40.349Z', }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) @@ -527,12 +529,12 @@ describe('Firestore Functions', () => { }); it('should parse timestamp values with precision to the second', () => { - let raw = constructValue({ + const raw = constructValue({ timestampVal: { timestampValue: '2017-06-13T00:58:40Z', }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) @@ -546,12 +548,12 @@ describe('Firestore Functions', () => { it('should parse binary values', () => { // Format defined in https://developers.google.com/discovery/v1/type-format - let raw = constructValue({ + const raw = constructValue({ binaryVal: { bytesValue: 'Zm9vYmFy', }, }); - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: raw, }) @@ -609,7 +611,7 @@ describe('Firestore Functions', () => { describe('Handle empty and non-existent documents', () => { it('constructs non-existent DocumentSnapshot when whole document deleted', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent( { value: {}, // value is empty when the whole document is deleted @@ -627,7 +629,7 @@ describe('Firestore Functions', () => { }); it('constructs existent DocumentSnapshot with empty data when all fields of document deleted', () => { - let snapshot = firestore.snapshotConstructor( + const snapshot = firestore.snapshotConstructor( makeEvent({ value: { // value is not empty when document still exists diff --git a/spec/providers/https.spec.ts b/spec/providers/https.spec.ts index ec1a191e5..8a78db540 100644 --- a/spec/providers/https.spec.ts +++ b/spec/providers/https.spec.ts @@ -34,14 +34,14 @@ import * as mocks from '../fixtures/credential/key.json'; describe('CloudHttpsBuilder', () => { describe('#onRequest', () => { it('should return a Trigger with appropriate values', () => { - let result = https.onRequest((req, resp) => { + const result = https.onRequest((req, resp) => { resp.send(200); }); expect(result.__trigger).to.deep.equal({ httpsTrigger: {} }); }); it('should allow both region and runtime options to be set', () => { - let fn = functions + const fn = functions .region('us-east1') .runWith({ timeoutSeconds: 90, @@ -59,7 +59,7 @@ describe('CloudHttpsBuilder', () => { describe('handler namespace', () => { describe('#onRequest', () => { it('should return an empty trigger', () => { - let result = functions.handler.https.onRequest((req, res) => { + const result = functions.handler.https.onRequest((req, res) => { res.send(200); }); expect(result.__trigger).to.deep.equal({}); @@ -68,7 +68,7 @@ describe('handler namespace', () => { describe('#onCall', () => { it('should return an empty trigger', () => { - let result = functions.handler.https.onCall(() => null); + const result = functions.handler.https.onCall(() => null); expect(result.__trigger).to.deep.equal({}); }); }); @@ -164,6 +164,7 @@ async function runTest(test: CallTest): Promise { } // MockRequest mocks an https.Request. +// tslint:disable-next-line class MockRequest { public method: 'POST' | 'GET' | 'OPTIONS' = 'POST'; @@ -180,7 +181,7 @@ class MockRequest { } // Creates a mock request with the given data and content-type. -function request( +function mockRequest( data: any, contentType: string = 'application/json', context: { @@ -245,7 +246,7 @@ describe('callable.FunctionBuilder', () => { let app: firebase.app.App; before(() => { - let credential = { + const credential = { getAccessToken: () => { return Promise.resolve({ expires_in: 1000, @@ -260,7 +261,7 @@ describe('callable.FunctionBuilder', () => { }; app = firebase.initializeApp({ projectId: 'aProjectId', - credential: credential, + credential, }); Object.defineProperty(appsNamespace(), 'admin', { get: () => app }); }); @@ -283,7 +284,7 @@ describe('callable.FunctionBuilder', () => { it('should handle success', () => { return runTest({ - httpRequest: request({ foo: 'bar' }), + httpRequest: mockRequest({ foo: 'bar' }), expectedData: { foo: 'bar' }, callableFunction: (data, context) => ({ baz: 'qux' }), expectedHttpResponse: { @@ -296,7 +297,7 @@ describe('callable.FunctionBuilder', () => { it('should handle null data and return', () => { return runTest({ - httpRequest: request(null), + httpRequest: mockRequest(null), expectedData: null, callableFunction: (data, context) => null, expectedHttpResponse: { @@ -309,7 +310,7 @@ describe('callable.FunctionBuilder', () => { it('should handle void return', () => { return runTest({ - httpRequest: request(null), + httpRequest: mockRequest(null), expectedData: null, callableFunction: (data, context) => { return; @@ -323,7 +324,7 @@ describe('callable.FunctionBuilder', () => { }); it('should reject bad method', () => { - let req = request(null); + const req = mockRequest(null); req.method = 'GET'; return runTest({ httpRequest: req, @@ -343,7 +344,7 @@ describe('callable.FunctionBuilder', () => { it('should ignore charset', () => { return runTest({ - httpRequest: request(null, 'application/json; charset=utf-8'), + httpRequest: mockRequest(null, 'application/json; charset=utf-8'), expectedData: null, callableFunction: (data, context) => { return; @@ -358,7 +359,7 @@ describe('callable.FunctionBuilder', () => { it('should reject bad content type', () => { return runTest({ - httpRequest: request(null, 'text/plain'), + httpRequest: mockRequest(null, 'text/plain'), expectedData: null, callableFunction: (data, context) => { return; @@ -374,7 +375,7 @@ describe('callable.FunctionBuilder', () => { }); it('should reject extra body fields', () => { - const req = request(null); + const req = mockRequest(null); req.body.extra = 'bad'; return runTest({ httpRequest: req, @@ -394,10 +395,10 @@ describe('callable.FunctionBuilder', () => { it('should handle unhandled error', () => { return runTest({ - httpRequest: request(null), + httpRequest: mockRequest(null), expectedData: null, callableFunction: (data, context) => { - throw 'ceci n\'est pas une error'; + throw new Error("ceci n'est pas une error"); }, expectedHttpResponse: { status: 500, @@ -409,7 +410,7 @@ describe('callable.FunctionBuilder', () => { it('should handle unknown error status', () => { return runTest({ - httpRequest: request(null), + httpRequest: mockRequest(null), expectedData: null, callableFunction: (data, context) => { throw new https.HttpsError('THIS_IS_NOT_VALID' as any, 'nope'); @@ -424,7 +425,7 @@ describe('callable.FunctionBuilder', () => { it('should handle well-formed error', () => { return runTest({ - httpRequest: request(null), + httpRequest: mockRequest(null), expectedData: null, callableFunction: (data, context) => { throw new https.HttpsError('not-found', 'i am error'); @@ -442,7 +443,7 @@ describe('callable.FunctionBuilder', () => { const projectId = appsNamespace().admin.options.projectId; const idToken = generateIdToken(projectId); await runTest({ - httpRequest: request(null, 'application/json', { + httpRequest: mockRequest(null, 'application/json', { authorization: 'Bearer ' + idToken, }), expectedData: null, @@ -467,7 +468,7 @@ describe('callable.FunctionBuilder', () => { it('should reject bad auth', async () => { await runTest({ - httpRequest: request(null, 'application/json', { + httpRequest: mockRequest(null, 'application/json', { authorization: 'Bearer FAKE', }), expectedData: null, @@ -489,7 +490,7 @@ describe('callable.FunctionBuilder', () => { it('should handle instance id', async () => { await runTest({ - httpRequest: request(null, 'application/json', { + httpRequest: mockRequest(null, 'application/json', { instanceIdToken: 'iid-token', }), expectedData: null, @@ -507,13 +508,13 @@ describe('callable.FunctionBuilder', () => { }); it('should expose raw request', async () => { - const mockRequest = request(null, 'application/json', {}); + const mockReq = mockRequest(null, 'application/json', {}); await runTest({ - httpRequest: mockRequest, + httpRequest: mockReq, expectedData: null, callableFunction: (data, context) => { expect(context.rawRequest).to.not.be.undefined; - expect(context.rawRequest).to.equal(mockRequest); + expect(context.rawRequest).to.equal(mockReq); return null; }, expectedHttpResponse: { @@ -525,7 +526,7 @@ describe('callable.FunctionBuilder', () => { }); it('should allow both region and runtime options to be set', () => { - let fn = functions + const fn = functions .region('us-east1') .runWith({ timeoutSeconds: 90, @@ -539,8 +540,8 @@ describe('callable.FunctionBuilder', () => { }); it('has a .run method', () => { - const cf = https.onCall((data, context) => { - return { data, context }; + const cf = https.onCall((d, c) => { + return { data: d, context: c }; }); const data = 'data'; @@ -559,10 +560,12 @@ describe('callable.FunctionBuilder', () => { describe('callable CORS', () => { it('handles OPTIONS preflight', async () => { const func = https.onCall((data, context) => { - throw "This shouldn't have gotten called for an OPTIONS preflight."; + throw new Error( + "This shouldn't have gotten called for an OPTIONS preflight." + ); }); - const request = new MockRequest( + const req = new MockRequest( {}, { 'Access-Control-Request-Method': 'POST', @@ -570,9 +573,9 @@ describe('callable CORS', () => { Origin: 'example.com', } ); - request.method = 'OPTIONS'; + req.method = 'OPTIONS'; - const response = await runHandler(func, request as any); + const response = await runHandler(func, req as any); expect(response.status).to.equal(204); expect(response.body).to.be.undefined; From e4daf8d5198f5a24fd02d489775601d5f5947348 Mon Sep 17 00:00:00 2001 From: Diana Tkachenko Date: Fri, 14 Jun 2019 18:55:25 -0700 Subject: [PATCH 2/3] consistency changes and missed lint errors, separate out mockrequest class --- spec/fixtures/mockrequest.ts | 82 +++++++++++++++++++++++++ spec/providers/database.spec.ts | 2 +- spec/providers/firestore.spec.ts | 20 +++--- spec/providers/https.spec.ts | 102 +++++-------------------------- 4 files changed, 107 insertions(+), 99 deletions(-) create mode 100644 spec/fixtures/mockrequest.ts diff --git a/spec/fixtures/mockrequest.ts b/spec/fixtures/mockrequest.ts new file mode 100644 index 000000000..8b0feb805 --- /dev/null +++ b/spec/fixtures/mockrequest.ts @@ -0,0 +1,82 @@ +import * as jwt from 'jsonwebtoken'; +import * as _ from 'lodash'; +import * as nock from 'nock'; +import * as mocks from '../fixtures/credential/key.json'; + +// MockRequest mocks an https.Request. +export class MockRequest { + public method: 'POST' | 'GET' | 'OPTIONS' = 'POST'; + + constructor( + readonly body: any, + readonly headers: { [name: string]: string } + ) { + // This block intentionally left blank. + } + + public header(name: string): string { + return this.headers[name.toLowerCase()]; + } +} + +// Creates a mock request with the given data and content-type. +export function mockRequest( + data: any, + contentType: string = 'application/json', + context: { + authorization?: string; + instanceIdToken?: string; + } = {} +) { + const body: any = {}; + if (!_.isUndefined(data)) { + body.data = data; + } + + const headers = { + 'content-type': contentType, + 'authorization': context.authorization, + 'firebase-instance-id-token': context.instanceIdToken, + 'origin': 'example.com', + }; + + return new MockRequest(body, headers); +} + +export const expectedResponseHeaders = { + 'Access-Control-Allow-Origin': 'example.com', + 'Vary': 'Origin', +}; + +/** + * Mocks out the http request used by the firebase-admin SDK to get the key for + * verifying an id token. + */ +export function mockFetchPublicKeys(): nock.Scope { + const mockedResponse = { [mocks.key_id]: mocks.public_key }; + const headers = { + 'cache-control': 'public, max-age=1, must-revalidate, no-transform', + }; + + return nock('https://www.googleapis.com:443') + .get('/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com') + .reply(200, mockedResponse, headers); +} + +/** + * Generates a mocked Firebase ID token. + */ +export function generateIdToken(projectId: string): string { + const claims = {}; + const options = { + audience: projectId, + expiresIn: 60 * 60, // 1 hour in seconds + issuer: 'https://securetoken.google.com/' + projectId, + subject: mocks.user_id, + algorithm: 'RS256', + header: { + kid: mocks.key_id, + }, + }; + return jwt.sign(claims, mocks.private_key, options); +} diff --git a/spec/providers/database.spec.ts b/spec/providers/database.spec.ts index 911daf8a5..25293ac11 100644 --- a/spec/providers/database.spec.ts +++ b/spec/providers/database.spec.ts @@ -50,7 +50,7 @@ describe('Database Functions', () => { memory: '256MB', }) .database.ref('/') - .onCreate(snap => snap); + .onCreate((snap) => snap); expect(fn.__trigger.regions).to.deep.equal(['us-east1']); expect(fn.__trigger.availableMemoryMb).to.deep.equal(256); diff --git a/spec/providers/firestore.spec.ts b/spec/providers/firestore.spec.ts index 9d131d6f9..42cdf97f7 100644 --- a/spec/providers/firestore.spec.ts +++ b/spec/providers/firestore.spec.ts @@ -166,7 +166,7 @@ describe('Firestore Functions', () => { memory: '256MB', }) .firestore.document('doc') - .onCreate(snap => snap); + .onCreate((snap) => snap); expect(fn.__trigger.regions).to.deep.equal(['us-east1']); expect(fn.__trigger.availableMemoryMb).to.deep.equal(256); @@ -245,12 +245,12 @@ describe('Firestore Functions', () => { expect(change.after.get('key1')).to.equal(true); return true; // otherwise will get warning about returning undefined }); - const data = constructEvent( + const event = constructEvent( createOldValue(), createValue(), 'document.write' ); - return testFunction(data.data, data.context); + return testFunction(event.data, event.context); }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.create" events', () => { @@ -278,12 +278,12 @@ describe('Firestore Functions', () => { expect(change.after.get('key1')).to.equal(true); return true; // otherwise will get warning about returning undefined }); - const data = constructEvent( + const event = constructEvent( createOldValue(), createValue(), 'document.update' ); - return testFunction(data.data, data.context); + return testFunction(event.data, event.context); }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.delete" events', () => { @@ -322,12 +322,12 @@ describe('Firestore Functions', () => { } ); expect(testFunction.__trigger).to.deep.equal({}); - const data = constructEvent( + const event = constructEvent( createOldValue(), createValue(), 'document.write' ); - return testFunction(data.data, data.context); + return testFunction(event.data, event.context); }).timeout(5000); it('constructs correct data type and sets trigger to {} on "document.create" events', () => { @@ -345,7 +345,7 @@ describe('Firestore Functions', () => { it('constructs correct data type and sets trigger to {} on "document.update" events', () => { const testFunction = functions.handler.firestore.document.onUpdate( - change => { + (change) => { expect(change.before.data()).to.deep.equal({ key1: false, key2: 111, @@ -357,12 +357,12 @@ describe('Firestore Functions', () => { } ); expect(testFunction.__trigger).to.deep.equal({}); - const data = constructEvent( + const event = constructEvent( createOldValue(), createValue(), 'document.update' ); - return testFunction(data.data, data.context); + return testFunction(event.data, event.context); }).timeout(5000); it('constructs correct data type and sets trigger to {} on "document.delete" events', () => { diff --git a/spec/providers/https.spec.ts b/spec/providers/https.spec.ts index 8a78db540..546568cb8 100644 --- a/spec/providers/https.spec.ts +++ b/spec/providers/https.spec.ts @@ -23,13 +23,18 @@ import { expect } from 'chai'; import * as express from 'express'; import * as firebase from 'firebase-admin'; -import * as jwt from 'jsonwebtoken'; import * as _ from 'lodash'; -import * as nock from 'nock'; import { apps as appsNamespace } from '../../src/apps'; import * as functions from '../../src/index'; import * as https from '../../src/providers/https'; import * as mocks from '../fixtures/credential/key.json'; +import { + expectedResponseHeaders, + generateIdToken, + mockFetchPublicKeys, + MockRequest, + mockRequest, +} from '../fixtures/mockrequest'; describe('CloudHttpsBuilder', () => { describe('#onRequest', () => { @@ -163,85 +168,6 @@ async function runTest(test: CallTest): Promise { expect(response.status).to.equal(test.expectedHttpResponse.status); } -// MockRequest mocks an https.Request. -// tslint:disable-next-line -class MockRequest { - public method: 'POST' | 'GET' | 'OPTIONS' = 'POST'; - - constructor( - readonly body: any, - readonly headers: { [name: string]: string } - ) { - // This block intentionally left blank. - } - - public header(name: string): string { - return this.headers[name.toLowerCase()]; - } -} - -// Creates a mock request with the given data and content-type. -function mockRequest( - data: any, - contentType: string = 'application/json', - context: { - authorization?: string; - instanceIdToken?: string; - } = {} -) { - const body: any = {}; - if (!_.isUndefined(data)) { - body.data = data; - } - - const headers = { - 'content-type': contentType, - authorization: context.authorization, - 'firebase-instance-id-token': context.instanceIdToken, - origin: 'example.com', - }; - - return new MockRequest(body, headers); -} - -const expectedResponseHeaders = { - 'Access-Control-Allow-Origin': 'example.com', - Vary: 'Origin', -}; - -/** - * Mocks out the http request used by the firebase-admin SDK to get the key for - * verifying an id token. - */ -function mockFetchPublicKeys(): nock.Scope { - const mockedResponse = { [mocks.key_id]: mocks.public_key }; - const headers = { - 'cache-control': 'public, max-age=1, must-revalidate, no-transform', - }; - - return nock('https://www.googleapis.com:443') - .get('/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com') - .reply(200, mockedResponse, headers); -} - -/** - * Generates a mocked Firebase ID token. - */ -export function generateIdToken(projectId: string): string { - const claims = {}; - const options = { - audience: projectId, - expiresIn: 60 * 60, // 1 hour in seconds - issuer: 'https://securetoken.google.com/' + projectId, - subject: mocks.user_id, - algorithm: 'RS256', - header: { - kid: mocks.key_id, - }, - }; - return jwt.sign(claims, mocks.private_key, options); -} - describe('callable.FunctionBuilder', () => { let app: firebase.app.App; @@ -273,7 +199,7 @@ describe('callable.FunctionBuilder', () => { describe('#onCall', () => { it('should return a Trigger with appropriate values', () => { - const result = https.onCall(data => { + const result = https.onCall((data) => { return 'response'; }); expect(result.__trigger).to.deep.equal({ @@ -570,7 +496,7 @@ describe('callable CORS', () => { { 'Access-Control-Request-Method': 'POST', 'Access-Control-Request-Headers': 'origin', - Origin: 'example.com', + 'Origin': 'example.com', } ); req.method = 'OPTIONS'; @@ -582,7 +508,7 @@ describe('callable CORS', () => { expect(response.headers).to.deep.equal({ 'Access-Control-Allow-Methods': 'POST', 'Content-Length': '0', - Vary: 'Origin, Access-Control-Request-Headers', + 'Vary': 'Origin, Access-Control-Request-Headers', }); }); }); @@ -614,7 +540,7 @@ describe('callable', () => { expect( https.decode({ '@type': 'type.googleapis.com/google.protobuf.Int64Value', - value: '-9223372036854775000', + 'value': '-9223372036854775000', }) ).to.equal(-9223372036854775000); }); @@ -627,7 +553,7 @@ describe('callable', () => { expect( https.decode({ '@type': 'type.googleapis.com/google.protobuf.UInt64Value', - value: '9223372036854800000', + 'value': '9223372036854800000', }) ).to.equal(9223372036854800000); }); @@ -662,7 +588,7 @@ describe('callable', () => { [ 3, { - value: '1099511627776', + 'value': '1099511627776', '@type': 'type.googleapis.com/google.protobuf.Int64Value', }, ], @@ -695,7 +621,7 @@ describe('callable', () => { 1, 2, { - value: '1099511627776', + 'value': '1099511627776', '@type': 'type.googleapis.com/google.protobuf.Int64Value', }, ], From eaa06c4ea175b06181e43b83837f6f4c2116db25 Mon Sep 17 00:00:00 2001 From: Diana Tkachenko Date: Fri, 14 Jun 2019 19:07:33 -0700 Subject: [PATCH 3/3] format strings --- spec/fixtures/mockrequest.ts | 6 +++--- spec/providers/https.spec.ts | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/fixtures/mockrequest.ts b/spec/fixtures/mockrequest.ts index 8b0feb805..2139c71ce 100644 --- a/spec/fixtures/mockrequest.ts +++ b/spec/fixtures/mockrequest.ts @@ -35,9 +35,9 @@ export function mockRequest( const headers = { 'content-type': contentType, - 'authorization': context.authorization, + authorization: context.authorization, 'firebase-instance-id-token': context.instanceIdToken, - 'origin': 'example.com', + origin: 'example.com', }; return new MockRequest(body, headers); @@ -45,7 +45,7 @@ export function mockRequest( export const expectedResponseHeaders = { 'Access-Control-Allow-Origin': 'example.com', - 'Vary': 'Origin', + Vary: 'Origin', }; /** diff --git a/spec/providers/https.spec.ts b/spec/providers/https.spec.ts index 546568cb8..f858d5923 100644 --- a/spec/providers/https.spec.ts +++ b/spec/providers/https.spec.ts @@ -324,7 +324,7 @@ describe('callable.FunctionBuilder', () => { httpRequest: mockRequest(null), expectedData: null, callableFunction: (data, context) => { - throw new Error("ceci n'est pas une error"); + throw new Error(`ceci n'est pas une error`); }, expectedHttpResponse: { status: 500, @@ -487,7 +487,7 @@ describe('callable CORS', () => { it('handles OPTIONS preflight', async () => { const func = https.onCall((data, context) => { throw new Error( - "This shouldn't have gotten called for an OPTIONS preflight." + `This shouldn't have gotten called for an OPTIONS preflight.` ); }); @@ -496,7 +496,7 @@ describe('callable CORS', () => { { 'Access-Control-Request-Method': 'POST', 'Access-Control-Request-Headers': 'origin', - 'Origin': 'example.com', + Origin: 'example.com', } ); req.method = 'OPTIONS'; @@ -508,7 +508,7 @@ describe('callable CORS', () => { expect(response.headers).to.deep.equal({ 'Access-Control-Allow-Methods': 'POST', 'Content-Length': '0', - 'Vary': 'Origin, Access-Control-Request-Headers', + Vary: 'Origin, Access-Control-Request-Headers', }); }); }); @@ -540,7 +540,7 @@ describe('callable', () => { expect( https.decode({ '@type': 'type.googleapis.com/google.protobuf.Int64Value', - 'value': '-9223372036854775000', + value: '-9223372036854775000', }) ).to.equal(-9223372036854775000); }); @@ -553,7 +553,7 @@ describe('callable', () => { expect( https.decode({ '@type': 'type.googleapis.com/google.protobuf.UInt64Value', - 'value': '9223372036854800000', + value: '9223372036854800000', }) ).to.equal(9223372036854800000); }); @@ -588,7 +588,7 @@ describe('callable', () => { [ 3, { - 'value': '1099511627776', + value: '1099511627776', '@type': 'type.googleapis.com/google.protobuf.Int64Value', }, ], @@ -621,7 +621,7 @@ describe('callable', () => { 1, 2, { - 'value': '1099511627776', + value: '1099511627776', '@type': 'type.googleapis.com/google.protobuf.Int64Value', }, ],