firebase / firebase/firebase-js-sdk
assertFails in rules-unit-testing resolves when it should reject
- Dominant language
- TypeScript
- Stars
- 5.1k
- Forks
- 1k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 37
Description
### Operating System
macOS sonoma 14.4.1
### Environment (if applicable)
nodejs v22.1.0
### Firebase SDK Version
4.0.1
### Firebase SDK Product(s)
Database
### Project Tooling
node with jest
### Detailed Problem Description
the documentation for assertFails says it should return a promise that rejects if the promise passed to it resolves
https://firebase.google.com/docs/reference/emulator-suite/rules-unit-testing/rules-unit-testing.md#assertfails
I tested a asserFails on a get() call on rtdb and found that this is not the case, instead it resolved when the promised it was passed resolved. I tested using the same approach as this line in the quickstart example code here: https://github.com/firebase/quickstart-testing/blob/6ac0acf396e87e2588223151e8f0b4cf307a5e84/unit-test-security-rules-v9/test/database.spec.ts#L86
### Steps and code to reproduce issue
`const {
assertFails,
assertSucceeds,
initializeTestEnvironment
} = require("@firebase/rules-unit-testing");
const { log } = require("console");
const fs = require('fs');
// import { describe, expect, test, beforeAll, beforeEach, afterAll } from 'vitest';
let testEnv;
beforeAll(async () => {
testEnv = await initializeTestEnvironment({
projectId: "XXXXX",
database: {
host: 'localhost',
port: '9000',
rules: fs.readFileSync("../database.rules.json", "utf8"),
},
});
});
afterAll(async () => {
return testEnv.cleanup();
});
beforeEach(async () => {
return testEnv.clearDatabase();
});
test("can't read or write to gameLobby if unauthenticated", async () => { // test for "auth != null" rule
let loggedOutDb = testEnv.unauthenticatedContext().database();
let errorResult = await assertFails(loggedOutDb.ref('/gameLobby').set({foo: "bar"})); // this works as expected
await expect(errorResult.code).toBe('PERMISSION_DENIED');
return expect(assertFails(loggedOutDb.ref('/gameLobby').get())).resolves; // this passes whether or not your rules allow or block the read.
});
`
Contributor guide
Assessment
This issue has not been assessed yet.