Files
fanuzu/app/firebase/functions/test/eclipse_target.test.ts
T

49 lines
3.0 KiB
TypeScript

import { afterAll, beforeAll, expect, it } from 'vitest';
import { getFirestore, Timestamp } from 'firebase-admin/firestore';
import { eclipseTarget } from '../src/fandom/eclipse_target.js';
import { bootAdmin, shutdownAdmin } from './support.js';
beforeAll(bootAdmin);
afterAll(async () => {
await getFirestore().recursiveDelete(getFirestore().doc('fandoms/test-eclipse-target'));
await shutdownAdmin();
});
it('생성일·0명·누락·최근 7일·목표율을 구분해 고유 참여자 목표를 산출한다', async () => {
const ref = getFirestore().doc('fandoms/test-eclipse-target');
const created = (date: string) => Timestamp.fromDate(new Date(`${date}T00:00:00+09:00`));
const stats = ref.collection('fandomDailyStats');
expect(await eclipseTarget(ref, created('2026-09-22'), '2026-09-22')).toEqual({
target: 1, averageDau: null, dauDays: [],
});
expect(await eclipseTarget(ref, undefined, '2026-09-22')).toMatchObject({ result: 'cancelled_error' });
expect(await eclipseTarget(ref, created('2026-09-23'), '2026-09-22')).toMatchObject({ result: 'cancelled_error' });
expect(await eclipseTarget(ref, created('2026-09-21'), '2026-09-22')).toMatchObject({ result: 'cancelled_error' });
await stats.doc('2026-09-21').set({ dau: 0, active30: 10000 });
expect(await eclipseTarget(ref, created('2026-09-21'), '2026-09-22')).toMatchObject({ target: 1, averageDau: 0 });
await stats.doc('2026-09-20').set({ dau: 30 });
await stats.doc('2026-09-19').set({ dau: 60 });
expect(await eclipseTarget(ref, created('2026-09-19'), '2026-09-22')).toEqual({
target: 2, averageDau: 30, dauDays: ['2026-09-21', '2026-09-20', '2026-09-19'],
});
expect(await eclipseTarget(ref, created('2026-09-19'), '2026-09-22', 0.1)).toMatchObject({ target: 3 });
for (const rate of [0, -1, Number.NaN, Number.POSITIVE_INFINITY, 1.1]) {
expect(await eclipseTarget(ref, created('2026-09-19'), '2026-09-22', rate)).toMatchObject({ result: 'cancelled_error' });
}
for (let d = 15; d <= 21; d++) await stats.doc(`2026-09-${d}`).set({ dau: 30 });
await stats.doc('2026-09-14').set({ dau: 100000 });
await stats.doc('2026-09-22').set({ dau: 100000 });
expect(await eclipseTarget(ref, created('2026-09-01'), '2026-09-22')).toMatchObject({ target: 2, averageDau: 30 });
// C-21 집계 기간은 운영값 — 8일로 늘리면 14일의 값이 분모에 들어온다.
expect(await eclipseTarget(ref, created('2026-09-01'), '2026-09-22', 0.05, 8)).toMatchObject({
target: Math.ceil((30 * 7 + 100000) / 8 * 0.05), averageDau: (30 * 7 + 100000) / 8,
});
expect(await eclipseTarget(ref, created('2026-09-01'), '2026-09-22', 0.05, 0)).toMatchObject({ result: 'cancelled_error' });
for (const invalid of [-1, 0.5, '30', null]) {
await stats.doc('2026-09-20').set({ dau: invalid });
expect(await eclipseTarget(ref, created('2026-09-01'), '2026-09-22')).toMatchObject({ result: 'cancelled_error' });
}
await stats.doc('2026-09-20').delete();
expect(await eclipseTarget(ref, created('2026-09-01'), '2026-09-22')).toMatchObject({ result: 'cancelled_error' });
});