firebase/quickstart-testing

Testing firestore rules against emulator fails with reason: Unexpected token < in JSON at position 0

Wizzel1 opened this issue · 2 comments

Hi, I am trying to setup firestore rules unit tests.

Since I am using typescript and jest for testing, I have edited your provided example a bit. This is what I have currently:

import { readFileSync } from 'fs-extra'
import * as firebase from '@firebase/rules-unit-testing'
import { getDoc, setDoc, setLogLevel } from 'firebase/firestore'

describe(' Firestore Rules', () => {
    let testEnv: firebase.RulesTestEnvironment;

    beforeAll(async () => {
        testEnv = await firebase.initializeTestEnvironment({
            firestore: { rules: readFileSync('../firestore.rules', 'utf8') },
            projectId: 'podsuite',
            hub: { host: 'localhost', port: 4000 },
        });
    });

    afterAll(async () => {
        await testEnv.cleanup();
    });

    beforeEach(async () => {
        await testEnv.clearFirestore();
    });


    test('noone should have access to user document', async function () {
        // Setup: Create documents in DB for testing (bypassing Security Rules).
        await testEnv.withSecurityRulesDisabled(async (context) => {
            const testdoc = context.firestore().collection('users').doc('user1234');
            await setDoc(testdoc, { test: 'test1' });
        });

        const unauthedDb = testEnv.unauthenticatedContext().firestore();

        // Then test security rules by trying to read it using the client SDK.
        const testdoc = unauthedDb.collection('users').doc('user1234');

        await firebase.assertFails(getDoc(testdoc));

    });
});

My emulator runs on http://localhost:4000/
These are my rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
       allow read, write: if false;
    }

    match /users/{userId}/salesItems/{documentId} {
      allow read: if true;
      allow write: if false;
    }

    match /users/{userId}/overviews/{documentId} {
      allow read: if true;
      allow write: if false;
    }
  }
}

When I run npm test I am getting an error :

 FAIL  src/tests/rules.test.ts
  ●  Firestore Rules › noone should have access to user document

    FetchError: invalid json response body at http://localhost:4000/emulators reason: Unexpected token < in JSON at position 0

      at node_modules/@firebase/rules-unit-testing/node_modules/node-fetch/lib/index.js:272:32

What is wrong?

I received the same error message while writing my test suite.
When initializing the test environment you set the hub port to 4000. This is the UI port. You have to pass the port of the emulator hub (by default 4400).

Changing your code to the following should allow the tests to connect to the emulators:

 testEnv = await firebase.initializeTestEnvironment({
            firestore: { rules: readFileSync('../firestore.rules', 'utf8') },
            projectId: 'podsuite',
            hub: { host: 'localhost', port: 4400 },
        });

@andipaetzold Thanks for taking the time to comment. I will try that ASAP