Cloud Functions 도메인 함수 — POP 원장 · 퀘스트 · 이클립스 · 행성 성장 · 캠페인 · 결제 · 알림 · 브리핑 · INSIDE · 추천 · 번역 · 서버 테스트
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { afterAll, beforeAll, expect, it, vi } from 'vitest';
|
||||
import { DocumentReference, getFirestore } from 'firebase-admin/firestore';
|
||||
import { fnPlanetEvolutionRecord } from '../src/fandom/evolution.js';
|
||||
import { bootAdmin, shutdownAdmin } from './support.js';
|
||||
|
||||
const id = 'test-evolution-history';
|
||||
beforeAll(() => { bootAdmin(); });
|
||||
afterAll(async () => {
|
||||
vi.restoreAllMocks();
|
||||
await getFirestore().recursiveDelete(getFirestore().doc(`fandoms/${id}`));
|
||||
await shutdownAdmin();
|
||||
});
|
||||
|
||||
async function event(beforeStage: unknown, afterStage: unknown, eventId: string) {
|
||||
const db = getFirestore();
|
||||
const ref = db.doc(`fandoms/${id}`);
|
||||
await ref.set({ ...(beforeStage === undefined ? {} : { stage: beforeStage }) });
|
||||
const before = (await db.collection('fandoms').where('__name__', '==', id).get()).docs[0]!;
|
||||
await ref.set({ stage: afterStage });
|
||||
const after = (await db.collection('fandoms').where('__name__', '==', id).get()).docs[0]!;
|
||||
return {
|
||||
specversion: '1.0' as const, id: eventId, source: 'firestore',
|
||||
type: 'google.cloud.firestore.document.v1.updated', time: new Date().toISOString(),
|
||||
data: { before, after }, params: { fandomId: id },
|
||||
location: 'asia-northeast3', project: 'demo-fanuzu', database: '(default)',
|
||||
namespace: '', document: ref.path,
|
||||
};
|
||||
}
|
||||
|
||||
it('저장 실패를 재시도하고 동시 재전달에도 확정 진화를 한 번만 남긴다', async () => {
|
||||
const input = await event(1, 3, 'confirmed/event');
|
||||
const create = vi.spyOn(DocumentReference.prototype, 'create').mockRejectedValueOnce(new Error('write failed'));
|
||||
try {
|
||||
await expect(fnPlanetEvolutionRecord.run(input)).rejects.toThrow('write failed');
|
||||
} finally {
|
||||
create.mockRestore();
|
||||
}
|
||||
await Promise.all([fnPlanetEvolutionRecord.run(input), fnPlanetEvolutionRecord.run(input)]);
|
||||
const records = await getFirestore().collection(`fandoms/${id}/stateHistory`).get();
|
||||
expect(records.size).toBe(1);
|
||||
const record = records.docs[0]!;
|
||||
expect(record.get('kind')).toBe('evolution');
|
||||
expect(record.get('fromStage')).toBe(1);
|
||||
expect(record.get('toStage')).toBe(3);
|
||||
expect(record.get('occurredAt').isEqual(input.data.after.updateTime)).toBe(true);
|
||||
expect(record.get('participantIds')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('동일 Stage·하락·누락·범위 밖 수치를 진화로 기록하지 않는다', async () => {
|
||||
const history = getFirestore().collection(`fandoms/${id}/stateHistory`);
|
||||
const count = (await history.get()).size;
|
||||
for (const [before, after] of [[3, 3], [3, 2], [undefined, 3], [-1, 1], [6, 7], [1, '2']]) {
|
||||
await fnPlanetEvolutionRecord.run(await event(before, after, `skip-${before}-${after}`));
|
||||
}
|
||||
expect((await history.get()).size).toBe(count);
|
||||
});
|
||||
Reference in New Issue
Block a user