# Testing Rules With the Emulator Suite — Firebase

Source: https://www.skillbyai.com/en/firebase/ru-test

> Prove allow and deny cases.

## Unit tests against the emulator

The **Firebase Local Emulator Suite** runs Firestore, Auth, Storage, Functions and other emulators locally. The `@firebase/rules-unit-testing` library loads your rules into the emulator and gives you contexts for an authenticated user, an unauthenticated user, or a context that bypasses rules for seeding data. Wrap operations in `assertSucceeds` and `assertFails` and write tests for both: that owners can write and that strangers cannot. Run them in CI with `firebase emulators:exec` so every rules change is checked. The console's Rules Playground is handy for quick experiments but is not a substitute for tests.

## A rules test

TypeScript with a test runner such as Vitest or Jest.

```typescript
import { readFileSync } from "node:fs";
import {
  initializeTestEnvironment, assertFails, assertSucceeds, RulesTestEnvironment,
} from "@firebase/rules-unit-testing";
import { doc, getDoc, setDoc, serverTimestamp } from "firebase/firestore";

let env: RulesTestEnvironment;

beforeAll(async () => {
  env = await initializeTestEnvironment({
    projectId: "demo-rules-test",
    firestore: { rules: readFileSync("firestore.rules", "utf8") },
  });
});
afterAll(() => env.cleanup());

test("users can create only their own profile", async () => {
  const alice = env.authenticatedContext("alice").firestore();
  await assertSucceeds(setDoc(doc(alice, "profiles/alice"),
    { displayName: "Alice", createdAt: serverTimestamp() }));
  await assertFails(setDoc(doc(alice, "profiles/bob"),
    { displayName: "Not Bob", createdAt: serverTimestamp() }));
});

test("signed-out users cannot read profiles", async () => {
  const anon = env.unauthenticatedContext().firestore();
  await assertFails(getDoc(doc(anon, "profiles/alice")));
});

// shell, not run here:
// firebase emulators:exec --only firestore "npm test"
```

## Use a demo- project id

Project ids starting with `demo-` tell the emulators that no real project exists, so tests cannot accidentally reach production resources.

**Quiz:** Which helper asserts that an operation is denied by rules?

- [x] assertFails
- [ ] assertSucceeds
- [ ] withSecurityRulesDisabled
- [ ] onSnapshot

*Answer:* assertFails. Test denials as carefully as approvals.
