firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.82k stars 884 forks source link

FR: Immutability when testing Firestore Security Rules #2895

Open akauppi opened 4 years ago

akauppi commented 4 years ago

Environment

Problem

It's good to be able to test one's Security Rules, locally. The Firestore emulator and the @firebase/testing package provide means for this.

However, when running tests and if the access is allowed, the underlying data actually changes. This is normal from an implementation aspect, since the assertFails and assertSucceeds are only thin wrappers around the promise from Firebase client.

The problem with changing underlying data is that it makes the test setup stateful. It becomes way harder to reason what should pass and what not. Also, this presents a different mental model to the online Security Rules Playground, where allowed rule access does not change the data.

If we agree that immutability of data is good when testing Security Rules, there are two ways to approach that.

1. Cloaking

I've implemented an immutability facade in the project I'm working on. It's based on storing the document being targeted, and restoring it if write access is allowed. There are mutexes involved, in case multiple tests would access the same document at the same time.

This approach is a bit complex, but hidden from the tests themselves. It helped me reason about my Security Tests and to get them to pass.

The problem is that my current mutexes don't go far enough. Jest runs each suite in a separate JavaScript context and therefore I would need to mutex across all of those.

2. Foundation

The @firebase/testing module could help one reach the above, by providing means to make a certain connection to Firestore "dry-run". It would act as normal, on the protocol level, but if allowed, a transaction would not change the data within the Firestore emulator.

This would be beautiful. It would mean that one can build an immutable Security Rules testing structure, and I would not need to think, how to mutex-guard tests running in separate Jest contexts.

Suggestion

My current approach is to open a discussion about this, both with fellow developers and Firebase authors. If we see joint value in the immutable approach, we could make a roadmap on how to reach there.

akauppi commented 3 years ago

firebase-jest-testing now allows testing Security Rules immutably, and with good performance.

It needs to use locking to achieve this, but this does not show to the user, nor slow down the testing.