JestでFirestoreセキュリティルールのテストを書く

公開日時

先日の記事でセキュリティルールのtestについて学んだので、個人プロジェクトで実践することにした。

YouTube動画ではmochaを使っていたが、今回はJestでテストを書くことにした。

firebase emulators:exec --only firestore "yarn test"

FIRESTORE INTERNAL ASSERTION FAILEDエラー

上記を実行したところ↓のエラーが発生した。

FIRESTORE INTERNAL ASSERTION FAILED: Unexpected state

上記の記事を参考に jest.config.jstestEnvironment を変更したところエラーはでなくなった。

// testEnvironment: 'jsdom',
testEnvironment: 'node',

テスト実行が終了しない

エラーが解消したので再度テストを実行したところ、テストが完了してもコマンドが終了しない減少が起きた。

This usually means that there are asynchronous operations that weren't stopped in your tests.
Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

ターミナルに上記のメッセージが表示されていたので --detectOpenHandles を付与してテストを再実行したものの何も検知できず。

firebase.appの終了処理をやる必要がありそうだなと思い、ドキュメントを読み直していたところ↓を見つけた。

apps() => [FirebaseApp]。このメソッドは、現在初期化されているテストと管理アプリをすべて返します。テスト間またはテスト後にアプリを消去するには、このメソッドを次のように使用します。

Promise.all(firebase.apps().map(app => app.delete()))

ということで、 afterAll でテスト後にFirebaseAppを消去するようにしたところ、正しくテストが終了できるようになった。

afterAll(async () => {
  await firebase.clearFirestoreData({ projectId: MY_PROJECT_ID })

  firebase.apps().map((app) => app.delete())
})

Github Actions

最後にGithub Actionsを使ってpushの度にテストが実行されるようにしておく。

    steps:
      - uses: actions/checkout@v2
      - run: yarn
      - run: yarn run firebase emulators:exec --only firestore "yarn test"

これで安心してFirestoreを使ったサービスの開発ができるようになった。

CIでのテスト実行については↓のYouTube動画も参考になる。

参考


Related #firebase

SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92

クロスオリジン分離対応を実施

Firebase Emulator Suiteで起動しているFunctionsから本番のFirestoreにアクセスする

functionsのみエミュレータを使うようにするとできる

Firebase Functions呼び出し時に Error: function terminated. が発生した場合

firebase functions:logで詳細を確認できる

Cloud BuildでFirebase Hostingのデプロイを行う

リポジトリへのpush以外をトリガーにしたい場合に使用

Firebase FunctionsでonCallで実装しているにも関わらずCORSエラーが発生した場合

Cloud Functions(GCP)の管理画面を確認してみる

Local Emulator Suiteを使ってFirestoreのローカル開発を行う際に初期データ(seeds)を用意する

ローカル管理画面でDeveloperToolsを開くとwindow.firestoreが使える