firebase / emulators-codelab

Apache License 2.0
46 stars 38 forks source link

Firestore rules encoding fix #5

Closed KayO-GH closed 4 years ago

KayO-GH commented 4 years ago

Browser: No browser involved Browser version: Operating system: Ubuntu Linux Operating system version: 18.04.4 LTS package.json dependencies:

"dependencies": {
    "file-system": "^2.2.2",
    "firebase-admin": "^8.12.1",
    "firebase-functions": "^3.7.0"
  },
  "devDependencies": {
    "@firebase/testing": "^0.20.5",
    "eslint": "^5.12.0",
    "eslint-plugin-promise": "^4.0.1",
    "firebase-functions-test": "^0.2.1",
    "mocha": "^8.0.1"
  },

What steps will reproduce the problem:

  1. cd into either codelab-initial-state or codelab-final-state
  2. Update npm dependencies & dev-dependencies to latest in the functions directory. cd out of functions when done.
  3. run firebase emulators:start
  4. run npm --prefix=functions test

What is the expected result?

> functions@ test .../emulators-codelab/codelab-initial-state/functions
> mocha

  shopping carts
    1) can be created by the cart owner

  shopping carts
    2) can be read, updated, and deleted by the cart owner

  shopping cart items
    3) can be read by the cart owner
    4) can be added by the cart owner

  adding an item to the cart recalculates the cart total. 
    - should sum the cost of their items

  0 passing (550ms)
  1 pending
  4 failing

What happens instead of that?

> functions@ test .../emulators-codelab/codelab-initial-state/functions
> mocha

body {"error":{"code":400,"message":"Payload isn't valid for request.","status":"INVALID_ARGUMENT"}}
  1) "before all" hook in "{root}"

  0 passing (147ms)
  1 failing

  1) "before all" hook in "{root}":
     Payload isn't valid for request.

npm ERR! Test failed.  See above for more details.

Fix explained: Depending on the version of dependencies (or dev-dependencies, more accurately) the rulesContent is passed as a buffer instead of a string in the before hook of test,js.

before(async () => {
  /* explanatory comments */
  const rulesContent = fs.readFileSync(path.resolve(__dirname, "../firestore.rules")); // returns a buffer
  console.log(rulesContent);
  await firebase.loadFirestoreRules({
    projectId: TEST_FIREBASE_PROJECT_ID,
    rules: rulesContent, // expects a string
  });
});

This led to the npm --prefix=functions test failing in the first before hook with the status: "INVALID_ARGUMENT". (The instruction is given in this codelab under "3. Run the emulators and tests" with no mention of this issue.)

To fix this, I have added "utf8" explicitly as a second parameter to fs.readFileSync() in both the initial and final states.

///
 const rulesContent = 
    fs.readFileSync(
      path.resolve(__dirname, "../firestore.rules"), 
      "utf8" // explicit encoding to utf-8
    );
///

The change does not affect the old code negatively.

samtstern commented 4 years ago

@KayO-GH thank you for the fix and the excellent PR description. Merging!