Skip to content

Commit 97d3823

Browse files
authored
Add emulator-based integration tests. (#1155)
* Add emulator-based integration tests. * Move emulator stuff out of package.json. * Update CONTRIBUTING.md too. * Add npx. * Skip new unsupported tests. * Inline commands in ci.yml.
1 parent 738eba7 commit 97d3823

File tree

4 files changed

+58
-10
lines changed

4 files changed

+58
-10
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,17 @@ jobs:
1717
uses: actions/setup-node@v1
1818
with:
1919
node-version: ${{ matrix.node-version }}
20-
- name: Install, build and test
20+
- name: Install and build
2121
run: |
2222
npm ci
2323
npm run build
2424
npm run build:tests
25-
npm test
26-
npm run api-extractor
25+
- name: Lint and run unit tests
26+
run: npm test
27+
- name: Run api-extractor
28+
run: npm run api-extractor
29+
- name: Run emulator-based integration tests
30+
run: |
31+
npm install -g firebase-tools
32+
firebase emulators:exec --project fake-project-id --only auth,database,firestore \
33+
'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register'

CONTRIBUTING.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ There are two test suites: unit and integration. The unit test suite is intended
123123
development, and the integration test suite is intended to be run before packaging up release
124124
candidates.
125125

126+
#### Unit Tests
127+
126128
To run the unit test suite:
127129

128130
```bash
@@ -135,7 +137,26 @@ If you wish to skip the linter, and only run the unit tests:
135137
$ npm run test:unit
136138
```
137139

138-
The integration tests run against an actual Firebase project. Create a new
140+
#### Integration Tests with Emulator Suite
141+
142+
Some of the integration tests work with the Emulator Suite and you can run them
143+
without an actual Firebase project.
144+
145+
First, make sure to [install Firebase CLI](https://firebase.google.com/docs/cli#install_the_firebase_cli).
146+
And then:
147+
148+
```bash
149+
firebase emulators:exec --project fake-project-id --only auth,database,firestore \
150+
'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register'
151+
```
152+
153+
Currently, only the Auth, Database, and Firestore test suites work. Some test
154+
cases will be automatically skipped due to lack of emulator support. The section
155+
below covers how to run the full test suite against an actual Firebase project.
156+
157+
#### Integration Tests with an actual Firebase project
158+
159+
Other integration tests require an actual Firebase project. Create a new
139160
project in the [Firebase Console](https://console.firebase.google.com), if you
140161
do not already have one suitable for running the tests against. Then obtain the
141162
following credentials from the project:

test/integration/auth.spec.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,10 @@ describe('admin.auth', () => {
683683
});
684684
});
685685

686-
it('can link/unlink with a federated provider', async () => {
686+
it('can link/unlink with a federated provider', async function () {
687+
if (authEmulatorHost) {
688+
return this.skip(); // Not yet supported in Auth Emulator.
689+
}
687690
const googleFederatedUid = 'google_uid_' + generateRandomString(10);
688691
let userRecord = await admin.auth().updateUser(updateUser.uid, {
689692
providerToLink: {
@@ -707,7 +710,10 @@ describe('admin.auth', () => {
707710
expect(providerIds).to.not.deep.include('google.com');
708711
});
709712

710-
it('can unlink multiple providers at once, incl a non-federated provider', async () => {
713+
it('can unlink multiple providers at once, incl a non-federated provider', async function () {
714+
if (authEmulatorHost) {
715+
return this.skip(); // Not yet supported in Auth Emulator.
716+
}
711717
await deletePhoneNumberUser('+15555550001');
712718

713719
const googleFederatedUid = 'google_uid_' + generateRandomString(10);

test/integration/database.spec.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import * as admin from '../../lib/index';
1818
import * as chai from 'chai';
1919
import * as chaiAsPromised from 'chai-as-promised';
20-
import { defaultApp, nullApp, nonNullApp, cmdArgs, databaseUrl } from './setup';
20+
import { defaultApp, nullApp, nonNullApp, cmdArgs, databaseUrl, isEmulator } from './setup';
2121

2222
// eslint-disable-next-line @typescript-eslint/no-var-requires
2323
const chalk = require('chalk');
@@ -64,7 +64,13 @@ describe('admin.database', () => {
6464
.should.eventually.be.fulfilled;
6565
});
6666

67-
it('App with null auth overrides is blocked by security rules', () => {
67+
it('App with null auth overrides is blocked by security rules', function () {
68+
if (isEmulator) {
69+
// RTDB emulator has open security rules by default and won't block this.
70+
// TODO(https://github.com/firebase/firebase-admin-node/issues/1149):
71+
// remove this once updating security rules through admin is in place.
72+
return this.skip();
73+
}
6874
return nullApp.database().ref('blocked').set(admin.database.ServerValue.TIMESTAMP)
6975
.should.eventually.be.rejectedWith('PERMISSION_DENIED: Permission denied');
7076
});
@@ -157,13 +163,21 @@ describe('admin.database', () => {
157163
});
158164
});
159165

160-
it('admin.database().getRules() returns currently defined rules as a string', () => {
166+
it('admin.database().getRules() returns currently defined rules as a string', function () {
167+
if (isEmulator) {
168+
// https://github.com/firebase/firebase-admin-node/issues/1149
169+
return this.skip();
170+
}
161171
return admin.database().getRules().then((result) => {
162172
return expect(result).to.be.not.empty;
163173
});
164174
});
165175

166-
it('admin.database().getRulesJSON() returns currently defined rules as an object', () => {
176+
it('admin.database().getRulesJSON() returns currently defined rules as an object', function () {
177+
if (isEmulator) {
178+
// https://github.com/firebase/firebase-admin-node/issues/1149
179+
return this.skip();
180+
}
167181
return admin.database().getRulesJSON().then((result) => {
168182
return expect(result).to.be.not.undefined;
169183
});

0 commit comments

Comments
 (0)