在玩笑测试中绕过 Firestore 安全规则
Bypassing Firestore Security Rules in jest tests
目前正在处理 React/Typescript/Firebase Firestore 项目。在为从 UI 调用的某些 actions/functions 编写 Jest 测试时,我 运行 遇到了以下问题:
在测试文件中,我可以使用 v9 api 设置 firestore 客户端并使其与模拟器对话
const app = initializeApp(config.firebase);
const firestore = getFirestore(app);
connectFirestoreEmulator(firestore, "localhost", 8080);
此外,我还了解了如何设置管理客户端并使其与模拟器通信
process.env.FIRESTORE_EMULATOR_HOST = "localhost:8080";
const serviceAccount = require("../../../my-key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
...config.firebase
});
测试本身看起来像这样:
describe("createCompanyAndRating action", () => {
test("call createCompanyAndRating and make sure it creates a proper rating entity", async () => {
// omitted: set testRatingFormState and other test data that are passed as args and
// pass in the firestore db client
const {
ratingId,
companyId,
} = await createCompanyAndRating({
ratingFormState: testRatingFormState,
visitorId: testVisitorId,
firestore,
});
// verify result by fetching the rating entity from the emulator db using the admin client
const ratingPath = `companies/${companyId}/ratings/${ratingId}`;
const ratingSnap = await admin.firestore().doc(ratingPath).withConverter(ratingConverter).get();
const rating: Rating | undefined = ratingSnap.data();
// omitted: verify result with some Jest expect-statetments...
});
})
我现在的问题是 Firestore 安全规则适用,只有经过身份验证的用户才能在 createCompanyAndRating 函数中使用的集合中编写文档,因此在调用该函数时测试已经抛出错误。
在这种情况下,我对测试安全规则本身不感兴趣。
- 有没有办法绕过测试的安全规则?
- 如果是,我该如何设置 firestore 客户端?
- 是否有可能在测试中以某种方式冒充用户?
此外,请注意我无法将管理客户端传递给 createCompanyAndRating 函数,因为管理客户端 API 与我依赖的 v9 firebase API 不同在 createCompanyAndRating 函数实现中(尝试过但没有成功,不仅仅是因为一些类型错误)。
也许我的整个方法有点误入歧途,我应该专注于测试 createCompanyAndRating 函数的内部结构,我在其中做了很多可以在没有数据库交互的情况下进行测试的工厂工作。
无论如何,help/guidance非常感谢。
感谢您确认我找对了地方(即@firebase/rules-unit-testing)。终于弄清楚问题出在哪里,在 createCompanyAndRating 中错过了一个“等待”,所以 firestore 管理实例没有获取数据(我虽然这是一个管理配置问题......)谢谢!
目前正在处理 React/Typescript/Firebase Firestore 项目。在为从 UI 调用的某些 actions/functions 编写 Jest 测试时,我 运行 遇到了以下问题:
在测试文件中,我可以使用 v9 api 设置 firestore 客户端并使其与模拟器对话
const app = initializeApp(config.firebase);
const firestore = getFirestore(app);
connectFirestoreEmulator(firestore, "localhost", 8080);
此外,我还了解了如何设置管理客户端并使其与模拟器通信
process.env.FIRESTORE_EMULATOR_HOST = "localhost:8080";
const serviceAccount = require("../../../my-key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
...config.firebase
});
测试本身看起来像这样:
describe("createCompanyAndRating action", () => {
test("call createCompanyAndRating and make sure it creates a proper rating entity", async () => {
// omitted: set testRatingFormState and other test data that are passed as args and
// pass in the firestore db client
const {
ratingId,
companyId,
} = await createCompanyAndRating({
ratingFormState: testRatingFormState,
visitorId: testVisitorId,
firestore,
});
// verify result by fetching the rating entity from the emulator db using the admin client
const ratingPath = `companies/${companyId}/ratings/${ratingId}`;
const ratingSnap = await admin.firestore().doc(ratingPath).withConverter(ratingConverter).get();
const rating: Rating | undefined = ratingSnap.data();
// omitted: verify result with some Jest expect-statetments...
});
})
我现在的问题是 Firestore 安全规则适用,只有经过身份验证的用户才能在 createCompanyAndRating 函数中使用的集合中编写文档,因此在调用该函数时测试已经抛出错误。
在这种情况下,我对测试安全规则本身不感兴趣。
- 有没有办法绕过测试的安全规则?
- 如果是,我该如何设置 firestore 客户端?
- 是否有可能在测试中以某种方式冒充用户?
此外,请注意我无法将管理客户端传递给 createCompanyAndRating 函数,因为管理客户端 API 与我依赖的 v9 firebase API 不同在 createCompanyAndRating 函数实现中(尝试过但没有成功,不仅仅是因为一些类型错误)。
也许我的整个方法有点误入歧途,我应该专注于测试 createCompanyAndRating 函数的内部结构,我在其中做了很多可以在没有数据库交互的情况下进行测试的工厂工作。
无论如何,help/guidance非常感谢。
感谢您确认我找对了地方(即@firebase/rules-unit-testing)。终于弄清楚问题出在哪里,在 createCompanyAndRating 中错过了一个“等待”,所以 firestore 管理实例没有获取数据(我虽然这是一个管理配置问题......)谢谢!