Files
fanuzu/app/firebase/test/support/environment.mjs
T

90 lines
2.4 KiB
JavaScript

import { readFileSync } from 'node:fs';
import { initializeTestEnvironment } from '@firebase/rules-unit-testing';
import { doc, setDoc } from 'firebase/firestore';
export const projectId = process.env.GCLOUD_PROJECT ?? 'demo-fancake';
function emulatorAddress() {
const value = process.env.FIRESTORE_EMULATOR_HOST ?? '127.0.0.1:8080';
const separator = value.lastIndexOf(':');
if (separator < 1) {
throw new Error(`Invalid FIRESTORE_EMULATOR_HOST: ${value}`);
}
const host = value.slice(0, separator);
const port = Number(value.slice(separator + 1));
if (!Number.isInteger(port)) {
throw new Error(`Invalid Firestore emulator port: ${value}`);
}
return { host, port };
}
export async function createTestEnvironment() {
const rules = readFileSync(new URL('../../firestore.rules', import.meta.url), 'utf8');
return initializeTestEnvironment({
projectId,
firestore: {
...emulatorAddress(),
rules,
},
});
}
function storageAddress() {
const value = process.env.FIREBASE_STORAGE_EMULATOR_HOST ?? '127.0.0.1:9199';
const separator = value.lastIndexOf(':');
if (separator < 1) {
throw new Error(`Invalid FIREBASE_STORAGE_EMULATOR_HOST: ${value}`);
}
const host = value.slice(0, separator);
const port = Number(value.slice(separator + 1));
if (!Number.isInteger(port)) {
throw new Error(`Invalid Storage emulator port: ${value}`);
}
return { host, port };
}
/// Storage 규칙 전용 환경. Firestore 와 나눠 둔 이유는 에뮬레이터가 서로 다른
/// 포트에 뜨고, 한쪽만 켠 실행에서도 남은 하나가 돌아야 하기 때문이다.
export async function createStorageTestEnvironment() {
const rules = readFileSync(new URL('../../storage.rules', import.meta.url), 'utf8');
return initializeTestEnvironment({
projectId,
storage: {
...storageAddress(),
rules,
},
});
}
export async function seedDocuments(testEnvironment, documents) {
await testEnvironment.withSecurityRulesDisabled(async (context) => {
const firestore = context.firestore();
await Promise.all(
Object.entries(documents).map(([path, data]) => setDoc(doc(firestore, path), data)),
);
});
}
export function userDocument(uid, overrides = {}) {
return {
uid,
displayName: uid,
fandomId: 'fandom-a',
totalContributedPop: 0,
status: 'active',
updatedAt: '2026-08-08T00:00:00Z',
...overrides,
};
}