エミュレータ環境でFirestoreのセキュリティルールをテストするまでの準備
October 24, 2021
もう一度同じ作業をすることになった時のために。自分用の備忘録です。
環境準備 #
(Firebase CLI でプロジェクト作成は済んでいるものとしてスタート)
ディレクトリを作成する #
firestore.rules
の隣に tests
ディレクトリを作成する。
├ firestore.rules
└ tests/
以降は tests
ディレクトリの中で作業する。
パッケージをインストールする #
package.json
を作成して以下を記載する。
{
"private": true,
"scripts": {
"test": "jest",
"test:watch": "jest --watchAll"
},
"devDependencies": {
"@firebase/testing": "^0.20.11",
"@types/jest": "^27.0.1",
"jest": "^27.1.0",
"ts-jest": "^27.0.5",
"typescript": "^4.4.2"
}
}
パッケージをインストールする。
npm install
この記事を参考に作業しているタイミングでは、(記事作成時点の)上記からパッケージに更新が入っていると思うので最新版にしておく。
以下を実施し更新の有無を確認する。
npx npm-check-updates
更新点があれば以下を実施する。
npx npm-check-updates -u -i
npm install
tsconfig.json を作成する #
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"strict": true,
"esModuleInterop": true
}
}
jest.config.js を作成する #
jest.config.js
module.exports = {
verbose: true,
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js', 'ts'],
transform: { '^.+\\.ts$': 'ts-jest' },
};
テスト実施 #
テストファイルを作成する #
__tests__
ディレクトリを作成後、配下に example.test.ts
を作成し以下を記載する。
example.test.ts
import fs from 'fs/promises';
import * as firebase from '@firebase/testing';
const PROJECT_ID = 'firestore-testing';
const RULES_FILE = '../firestore.rules';
beforeAll(async () => {
const rules = await fs.readFile(RULES_FILE, 'utf8');
await firebase.loadFirestoreRules({ projectId: PROJECT_ID, rules });
});
afterEach(async () => {
await firebase.clearFirestoreData({ projectId: PROJECT_ID });
});
afterAll(async () => {
await Promise.all(firebase.apps().map((app) => app.delete()));
});
const createAuthApp = (auth?: object) => {
return firebase.initializeTestApp({ projectId: PROJECT_ID, auth: auth }).firestore();
};
const authedDB = createAuthApp({ uid: 'alice', email: '[email protected]' });
const unAuthedDB = createAuthApp();
const authedUser = authedDB.collection('users');
const unAuthedUser = unAuthedDB.collection('users');
describe('/users/{id}', () => {
test('list succeeds', async () => {
await firebase.assertSucceeds(authedUser.get());
});
test('list fails', async () => {
await firebase.assertFails(unAuthedUser.get());
});
test('get succeeds', async () => {
await firebase.assertSucceeds(authedUser.doc('01234567890123456789').get());
});
test('get fails', async () => {
await firebase.assertFails(unAuthedUser.doc('01234567890123456789').get());
});
});
セキュリティルールを編集する #
確認のために firestore.rules
を以下の内容にする。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{id} {
allow list: if request.auth != null;
allow get: if request.auth != null;
}
}
}
テストを実行する #
npm test
テストが実施されて以下の表示になれば成功。
PASS __tests__/example.test.ts (*.** s)
/users/{id}
✓ list succeeds (** ms)
✓ list fails (** ms)
✓ get succeeds (** ms)
✓ get fails (** ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: *.*** s
Ran all test suites.
以上 #
最終的なディレクトリ構成は以下。
├ firestore.rules
└ tests/
├ package.json
├ package-lock.json
├ node_modules/
├ tsconfig.json
├ jest.config.js
└ __tests__
└ example.test.ts