From b7f35a0b76bb2afd682b806d2b25568611612557 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Tue, 20 Mar 2018 11:59:03 -0700 Subject: Initial Firebase Functions (#948) --- Functions/Backend/index.js | 95 ++++++++++++++++++++++++++++++++++++++++++ Functions/Backend/package.json | 12 ++++++ Functions/Backend/start.sh | 41 ++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 Functions/Backend/index.js create mode 100644 Functions/Backend/package.json create mode 100755 Functions/Backend/start.sh (limited to 'Functions/Backend') diff --git a/Functions/Backend/index.js b/Functions/Backend/index.js new file mode 100644 index 0000000..0245f1b --- /dev/null +++ b/Functions/Backend/index.js @@ -0,0 +1,95 @@ +const assert = require('assert'); +const functions = require('firebase-functions'); + +exports.dataTest = functions.https.onRequest((request, response) => { + assert.deepEqual(request.body, { + data: { + bool: true, + int: 2, + long: { + value: '3', + '@type': 'type.googleapis.com/google.protobuf.Int64Value', + }, + string: 'four', + array: [5, 6], + 'null': null, + } + }); + response.send({ + data: { + message: 'stub response', + code: 42, + long: { + value: '420', + '@type': 'type.googleapis.com/google.protobuf.Int64Value', + }, + } + }); +}); + +exports.scalarTest = functions.https.onRequest((request, response) => { + assert.deepEqual(request.body, { data: 17 }); + response.send({ data: 76 }); +}); + +exports.tokenTest = functions.https.onRequest((request, response) => { + assert.equal('Bearer token', request.get('Authorization')); + assert.deepEqual(request.body, { data: {} }); + response.send({ data: {} }); +}); + +exports.instanceIdTest = functions.https.onRequest((request, response) => { + assert.equal(request.get('Firebase-Instance-ID-Token'), 'iid'); + assert.deepEqual(request.body, { data: {} }); + response.send({ data: {} }); +}); + +exports.nullTest = functions.https.onRequest((request, response) => { + assert.deepEqual(request.body, { data: null }); + response.send({ data: null }); +}); + +exports.missingResultTest = functions.https.onRequest((request, response) => { + assert.deepEqual(request.body, { data: null }); + response.send({}); +}); + +exports.unhandledErrorTest = functions.https.onRequest((request, response) => { + // Fail in a way that the client shouldn't see. + throw 'nope'; +}); + +exports.unknownErrorTest = functions.https.onRequest((request, response) => { + // Send an http error with a body with an explicit code. + response.status(400).send({ + error: { + status: 'THIS_IS_NOT_VALID', + message: 'this should be ignored', + }, + }); +}); + +exports.explicitErrorTest = functions.https.onRequest((request, response) => { + // Send an http error with a body with an explicit code. + // Note that eventually the SDK will have a helper to automatically return + // the appropriate http status code for an error. + response.status(400).send({ + error: { + status: 'OUT_OF_RANGE', + message: 'explicit nope', + details: { + start: 10, + end: 20, + long: { + value: '30', + '@type': 'type.googleapis.com/google.protobuf.Int64Value', + }, + }, + }, + }); +}); + +exports.httpErrorTest = functions.https.onRequest((request, response) => { + // Send an http error with no body. + response.status(400).send(); +}); diff --git a/Functions/Backend/package.json b/Functions/Backend/package.json new file mode 100644 index 0000000..c227bb1 --- /dev/null +++ b/Functions/Backend/package.json @@ -0,0 +1,12 @@ +{ + "name": "functions", + "description": "Cloud Functions for Firebase", + "dependencies": { + "firebase-admin": "~4.2.1", + "firebase-functions": "^0.5.7" + }, + "private": true, + "devDependencies": { + "@google-cloud/functions-emulator": "^1.0.0-alpha.21" + } +} diff --git a/Functions/Backend/start.sh b/Functions/Backend/start.sh new file mode 100755 index 0000000..aaa2b73 --- /dev/null +++ b/Functions/Backend/start.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# +# Sets up a project with the functions CLI and starts a backend to run +# integration tests against. + +set -e + +# Get the absolute path to the directory containing this script. +SCRIPT_DIR="$(cd $(dirname ${BASH_SOURCE[0]}) && pwd)" +TEMP_DIR="$(mktemp -d -t firebase-functions)" +echo "Creating functions in ${TEMP_DIR}" + +# Set up the functions directory. +cp "${SCRIPT_DIR}/index.js" "${TEMP_DIR}/" +cp "${SCRIPT_DIR}/package.json" "${TEMP_DIR}/" +cd "${TEMP_DIR}" +npm install + +# Start the server. +FUNCTIONS_BIN="./node_modules/.bin/functions" +"${FUNCTIONS_BIN}" config set projectId functions-integration-test +"${FUNCTIONS_BIN}" config set supervisorPort 5005 +"${FUNCTIONS_BIN}" config set region us-central1 +"${FUNCTIONS_BIN}" config set verbose true +"${FUNCTIONS_BIN}" restart +"${FUNCTIONS_BIN}" deploy dataTest --trigger-http +"${FUNCTIONS_BIN}" deploy scalarTest --trigger-http +"${FUNCTIONS_BIN}" deploy tokenTest --trigger-http +"${FUNCTIONS_BIN}" deploy instanceIdTest --trigger-http +"${FUNCTIONS_BIN}" deploy nullTest --trigger-http +"${FUNCTIONS_BIN}" deploy missingResultTest --trigger-http +"${FUNCTIONS_BIN}" deploy unhandledErrorTest --trigger-http +"${FUNCTIONS_BIN}" deploy unknownErrorTest --trigger-http +"${FUNCTIONS_BIN}" deploy explicitErrorTest --trigger-http +"${FUNCTIONS_BIN}" deploy httpErrorTest --trigger-http + +# Wait for the user to tell us to stop the server. +echo "Functions emulator now running in ${TEMP_DIR}." +read -n 1 -p "*** Press any key to stop the server. ***" +echo "\nStopping the emulator..." +"${FUNCTIONS_BIN}" stop -- cgit v1.2.3