This is my first question asked on stackoverflow, so please let me know if I am missing some aspect of the question that is preferred or required.
My goal is to understand why the mocha test shown below is passing when the created document is missing fields required by the firestore rules listed below.
Mocha Test Code (Note that the project ID is checked and working but omitted here)
const assert = require("assert");
const firebase = require("@firebase/rules-unit-testing");
const { firestore } = require("firebase-admin");
const { debug } = require("console");
const MY_PROJECT_ID = "####";
const myID = "user_abc";
const theirID = "user_def";
const myAuth = {uid: myID, email: "abc@gmail.com"};
const theirAuth = {uid: theirID};
function getFirestore(auth) {
return firebase.initializeTestApp({projectId: MY_PROJECT_ID, auth: auth}).firestore();
}
function getAdminFirestore() {
return firebase.initializeAdminApp({projectId: MY_PROJECT_ID}).firestore();
}
beforeEach(async ()=>{
await firebase.clearFirestoreData({projectId:MY_PROJECT_ID});
});
describe("Our Social App", () => {
it("Can overwrite an existing post with allowed fields", async()=>{
const postPath = "/posts/post_123";
const admin = getAdminFirestore();
await admin.doc(postPath).set({authorID:myID, content:"content",
visibility:"private",
headline:"headline"});
const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
await firebase.assertSucceeds(docRef.set({}));
});
});
after(async ()=>{
await firebase.clearFirestoreData({projectId:MY_PROJECT_ID});
});
Firestore Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function documentFieldsCheckOut(requiredFields, allowedFields){
let requiredAndAllowed = requiredFields.concat(allowedFields);
return request.resource.data.keys().hasAll(requiredFields) &&
request.resource.data.keys().hasOnly(requiredAndAllowed);
}
function updateHasOnlyAllowedFields(allowedFields){
return debug(request.resource.data.keys()).hasOnly(allowedFields);
}
match /{document=**} {
allow read, write: if false;
}
match /posts/{postID} {
allow update: if ((resource.data.authorID == request.auth.uid) || userIsModerator())
&& updateHasOnlyAllowedFields(["visibility", "content"]);
allow create: if (request.resource.data.authorID == request.auth.uid) &&
documentFieldsCheckOut(["authorID", "content", "visibility", "headline"],
["photo", "location", "tags"]);
}
}
}
Note: Commenting out await admin.doc(postPath).set({authorID:myID, content:"content", visibility:"private", headline:"headline"}); causes the test to fail as expected.
Additionally, changing the .set to .update in await firebase.assertSucceeds(docRef.set({})); also causes the test to fail as expected.