Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/node-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ jobs:
matrix:
node-version:
- 8.x
- 12.x
script:
- npm run test:hosting
- npm run test:client-integration
Expand All @@ -80,7 +81,7 @@ jobs:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 8.x
node-version: ${{ matrix.node_version }}

- name: Cache npm
uses: actions/cache@v1
Expand All @@ -98,6 +99,8 @@ jobs:
- run: npm ci
- run: echo ${{ secrets.service_account_json_base64 }} | base64 -d > ./scripts/service-account.json
- run: ${{ matrix.script }}
env:
NODE_VERSION: ${{ matrix.node-version }}

- name: Print debug logs
if: failure()
Expand Down
4 changes: 2 additions & 2 deletions scripts/extensions-emulator-tests/run.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/bash
set -e # Immediately exit on failure

# Globally link the CLI for the testing framework.
npm link
# Globally link the CLI for the testing framework
./scripts/npm-link.sh

cd scripts/extensions-emulator-tests/greet-the-world
npm i
Expand Down
4 changes: 2 additions & 2 deletions scripts/hosting-tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ TEMP_DIR="$(mktemp -d)"
echo "Created temp directory: ${TEMP_DIR}"

echo "Installing firebase-tools..."
npm link
./scripts/npm-link.sh
echo "Installed firebase-tools: $(which firebase)"

echo "Initializing temp directory..."
Expand Down Expand Up @@ -121,4 +121,4 @@ sleep 5
CHANNEL_URL=$(cat output.json | jq -r ".result.customtarget.url")
VALUE="$(curl ${CHANNEL_URL}/${TARGET_FILE})"
test "${DATE}" = "${VALUE}" || (echo "Expected ${VALUE} to equal ${DATE}." && false)
echo "Tested hosting channel deployment by target."
echo "Tested hosting channel deployment by target."
13 changes: 13 additions & 0 deletions scripts/integration-helpers/framework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const FIREBASE_PROJECT_ZONE = "us-central1";
const RTDB_FUNCTION_LOG = "========== RTDB FUNCTION ==========";
const FIRESTORE_FUNCTION_LOG = "========== FIRESTORE FUNCTION ==========";
const PUBSUB_FUNCTION_LOG = "========== PUBSUB FUNCTION ==========";
const AUTH_FUNCTION_LOG = "========== AUTH FUNCTION ==========";
const ALL_EMULATORS_STARTED_LOG = "All emulators ready";

interface ConnectionInfo {
Expand All @@ -24,6 +25,7 @@ export interface FrameworkOptions {
firestore: ConnectionInfo;
functions: ConnectionInfo;
pubsub: ConnectionInfo;
auth: ConnectionInfo;
};
}

Expand All @@ -36,10 +38,13 @@ export class TriggerEndToEndTest {
functionsEmulatorPort = 0;
pubsubEmulatorHost = "localhost";
pubsubEmulatorPort = 0;
authEmulatorHost = "localhost";
authEmulatorPort = 0;
allEmulatorsStarted = false;
rtdbTriggerCount = 0;
firestoreTriggerCount = 0;
pubsubTriggerCount = 0;
authTriggerCount = 0;
rtdbFromFirestore = false;
firestoreFromRtdb = false;
rtdbFromRtdb = false;
Expand All @@ -52,6 +57,7 @@ export class TriggerEndToEndTest {
this.firestoreEmulatorPort = config.emulators.firestore?.port;
this.functionsEmulatorPort = config.emulators.functions?.port;
this.pubsubEmulatorPort = config.emulators.pubsub?.port;
this.authEmulatorPort = config.emulators.auth?.port;
}
}

Expand Down Expand Up @@ -87,6 +93,9 @@ export class TriggerEndToEndTest {
if (data.includes(PUBSUB_FUNCTION_LOG)) {
this.pubsubTriggerCount++;
}
if (data.includes(AUTH_FUNCTION_LOG)) {
this.authTriggerCount++;
}
});

this.cliProcess = cli;
Expand Down Expand Up @@ -139,6 +148,10 @@ export class TriggerEndToEndTest {
return this.invokeHttpFunction("writeToPubsub");
}

writeToAuth(): Promise<request.Response> {
return this.invokeHttpFunction("writeToAuth");
}

writeToScheduledPubsub(): Promise<request.Response> {
return this.invokeHttpFunction("writeToScheduledPubsub");
}
Expand Down
10 changes: 10 additions & 0 deletions scripts/npm-link.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -e

if [ "$CI" = "true" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't care what CI is set to (just that it isn't empty), you could use -z:

if [ ! -z "$CI" ]; then

echo "Running sudo npm link..."
sudo npm link
else
echo "Running npm link..."
npm link
fi
3 changes: 3 additions & 0 deletions scripts/triggers-end-to-end-tests/firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
},
"pubsub": {
"port": 8085
},
"auth": {
"port": 9099
}
}
}
17 changes: 17 additions & 0 deletions scripts/triggers-end-to-end-tests/functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { PubSub } = require("@google-cloud/pubsub");
const RTDB_FUNCTION_LOG = "========== RTDB FUNCTION ==========";
const FIRESTORE_FUNCTION_LOG = "========== FIRESTORE FUNCTION ==========";
const PUBSUB_FUNCTION_LOG = "========== PUBSUB FUNCTION ==========";
const AUTH_FUNCTION_LOG = "========== AUTH FUNCTION ==========";

/*
* We install onWrite triggers for START_DOCUMENT_NAME in both the firestore and
Expand Down Expand Up @@ -73,6 +74,16 @@ exports.writeToScheduledPubsub = functions.https.onRequest(async (req, res) => {
res.json({ published: "ok" });
});

exports.writeToAuth = functions.https.onRequest(async (req, res) => {
const time = new Date().getTime();
await admin.auth().createUser({
uid: `uid${time}`,
email: `user${time}@example.com`,
});

res.json({ created: "ok" });
});

exports.firestoreReaction = functions.firestore
.document(START_DOCUMENT_NAME)
.onWrite(async (/* change, ctx */) => {
Expand Down Expand Up @@ -121,3 +132,9 @@ exports.pubsubScheduled = functions.pubsub.schedule("every mon 07:00").onRun((co
console.log("Resource", JSON.stringify(context.resource));
return true;
});

exports.authReaction = functions.auth.user().onCreate((user, ctx) => {
console.log(AUTH_FUNCTION_LOG);
console.log("User", JSON.stringify(user));
return true;
});
17 changes: 17 additions & 0 deletions scripts/triggers-end-to-end-tests/functions/package.12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {},
"engines": {
"node": "12"
},
"dependencies": {
"@google-cloud/pubsub": "^1.1.5",
"firebase-admin": "^9.3.0",
"firebase-functions": "^3.11.0"
},
"devDependencies": {
"firebase-functions-test": "^0.2.0"
},
"private": true
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"scripts": {},
"engines": {
"node": "12"
"node": "8"
},
"dependencies": {
"@google-cloud/pubsub": "^1.1.5",
Expand Down
15 changes: 14 additions & 1 deletion scripts/triggers-end-to-end-tests/run.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
#!/bin/bash

source scripts/set-default-credentials.sh
./scripts/npm-link.sh

npm link
echo "NODE_VERSION=$NODE_VERSION"
(
cd scripts/triggers-end-to-end-tests/functions
if [ "$NODE_VERSION" = "8" ]; then
cp package{.8,}.json
else
cp package{.12,}.json
fi

npm install
)

mocha \
--require ts-node/register \
--require source-map-support/register \
--require src/test/helpers/mocha-bootstrap.js \
--exit \
scripts/triggers-end-to-end-tests/tests.ts

rm scripts/triggers-end-to-end-tests/functions/package.json
48 changes: 48 additions & 0 deletions scripts/triggers-end-to-end-tests/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import * as path from "path";
import { CLIProcess } from "../integration-helpers/cli";
import { FrameworkOptions, TriggerEndToEndTest } from "../integration-helpers/framework";

const NODE_VERSION = Number.parseInt(process.env.NODE_VERSION || "8");

const FIREBASE_PROJECT = process.env.FBTOOLS_TARGET_PROJECT || "";
const ADMIN_CREDENTIAL = {
getAccessToken: () => {
Expand Down Expand Up @@ -213,6 +215,52 @@ describe("pubsub emulator function triggers", () => {
});
});

describe("auth emulator function triggers", () => {
let test: TriggerEndToEndTest;

before(async function() {
// eslint-disable-next-line no-invalid-this
this.timeout(TEST_SETUP_TIMEOUT);

expect(FIREBASE_PROJECT).to.exist.and.not.be.empty;

const config = readConfig();
test = new TriggerEndToEndTest(FIREBASE_PROJECT, __dirname, config);
await test.startEmulators(["--only", "functions,auth"]);
});

after(async function() {
// eslint-disable-next-line no-invalid-this
this.timeout(EMULATORS_SHUTDOWN_DELAY_MS);
await test.stopEmulators();
});

it("should write to the auth emulator", async function() {
// eslint-disable-next-line no-invalid-this
this.timeout(EMULATOR_TEST_TIMEOUT);

// This test only works on Node 10+
if (NODE_VERSION < 10) {
// eslint-disable-next-line no-invalid-this
this.skip();
}

const response = await test.writeToAuth();
expect(response.statusCode).to.equal(200);
await new Promise((resolve) => setTimeout(resolve, EMULATORS_WRITE_DELAY_MS));
});

it("should have have triggered cloud functions", function() {
// This test only works on Node 10+
if (NODE_VERSION < 10) {
// eslint-disable-next-line no-invalid-this
this.skip();
}

expect(test.authTriggerCount).to.equal(1);
});
});

describe("import/export end to end", () => {
it("should be able to import/export firestore data", async function() {
// eslint-disable-next-line no-invalid-this
Expand Down