Cloud Functions 도메인 함수 — POP 원장 · 퀘스트 · 이클립스 · 행성 성장 · 캠페인 · 결제 · 알림 · 브리핑 · INSIDE · 추천 · 번역 · 서버 테스트
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { afterAll, beforeAll, expect, it } from 'vitest';
|
||||
import { getFirestore, Timestamp } from 'firebase-admin/firestore';
|
||||
import { fnPlanetHistory } from '../src/fandom/history.js';
|
||||
import { bootAdmin, shutdownAdmin } from './support.js';
|
||||
|
||||
const fandomId = 'history-test';
|
||||
const uid = 'history-reader';
|
||||
const call = (data: Record<string, unknown>, user = uid) =>
|
||||
fnPlanetHistory.run({ data, ...(user ? { auth: { uid: user, token: {} } } : {}) } as never);
|
||||
beforeAll(async () => {
|
||||
bootAdmin();
|
||||
const db = getFirestore();
|
||||
for (let i = 1; i <= 22; i++) {
|
||||
await db.doc(`fandoms/${fandomId}/stateHistory/${i}`).set({
|
||||
kind: 'evolution', fromStage: 1, toStage: 2,
|
||||
occurredAt: Timestamp.fromMillis(i * 1000), sourceEventId: 'private-source',
|
||||
settings: { private: true },
|
||||
});
|
||||
}
|
||||
await db.doc(`users/${uid}/growthEvents/one`).set({
|
||||
fandomIdAtPayout: fandomId, amount: 10, sourceType: 'zap', reversalOf: null,
|
||||
createdAt: Timestamp.fromMillis(10_000),
|
||||
});
|
||||
});
|
||||
afterAll(async () => {
|
||||
const db = getFirestore();
|
||||
await db.recursiveDelete(db.doc(`fandoms/${fandomId}`));
|
||||
await db.recursiveDelete(db.doc(`users/${uid}`));
|
||||
await shutdownAdmin();
|
||||
});
|
||||
|
||||
it('자신의 과거 기여만 확인하며 다른 사용자 ID나 내부 기록을 노출하지 않는다', async () => {
|
||||
const result = await call({ fandomId });
|
||||
expect(result.items).toHaveLength(20);
|
||||
expect(result.items[0]!.participationConfirmed).toBe(true);
|
||||
expect(result.items.at(-1)!.participationConfirmed).toBe(false);
|
||||
expect(JSON.stringify(result)).not.toContain('private');
|
||||
const stranger = await call({ fandomId, uid }, 'other-user');
|
||||
expect(stranger.items.every((item) => item.participationConfirmed === false)).toBe(true);
|
||||
});
|
||||
|
||||
it('커서 페이지가 겹치지 않으며 인증·경로·커서 오류를 거부한다', async () => {
|
||||
const first = await call({ fandomId });
|
||||
const second = await call({ fandomId, cursor: first.nextCursor });
|
||||
expect(second.items).toHaveLength(2);
|
||||
expect(second.nextCursor).toBeNull();
|
||||
expect(new Set([...first.items, ...second.items].map((item) => item.id)).size).toBe(22);
|
||||
await expect(call({ fandomId }, '')).rejects.toThrow();
|
||||
await expect(call({ fandomId: '../users/private' })).rejects.toThrow();
|
||||
await expect(call({ fandomId, cursor: 'missing' })).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('수량이 잘못된 기록은 개인 참여 증거로 쓰지 않는다', async () => {
|
||||
await getFirestore().doc(`users/${uid}/growthEvents/one`).update({ amount: '10' });
|
||||
const result = await call({ fandomId });
|
||||
expect(result.items.every((item) => item.participationConfirmed === false)).toBe(true);
|
||||
});
|
||||
|
||||
it('내 활동은 호출자와 지급 당시 팬덤으로 제한하고 다른 팬덤 커서를 거부한다', async () => {
|
||||
const events = getFirestore().collection(`users/${uid}/growthEvents`);
|
||||
await events.doc('one').update({ amount: 10 });
|
||||
for (const [index, sourceType] of ['quest_reward', 'company_ad_bonus', 'zap', 'funding'].entries()) {
|
||||
await events.doc(`activity-${index}`).set({
|
||||
fandomIdAtPayout: fandomId, sourceType, amount: 10 + index, reversalOf: null,
|
||||
createdAt: Timestamp.fromMillis(30_000 + index), sourceEventId: 'private-ledger',
|
||||
});
|
||||
}
|
||||
await events.doc('other-fandom').set({ fandomIdAtPayout: 'other-fandom', sourceType: 'zap',
|
||||
amount: 999, createdAt: Timestamp.fromMillis(40_000) });
|
||||
const result = await call({ fandomId, scope: 'personal' });
|
||||
expect(result.items).toHaveLength(5);
|
||||
expect(result.items[0]!.kind).toBe('funding');
|
||||
expect(result.items[0]!.amount).toBe(13);
|
||||
expect(JSON.stringify(result)).not.toContain('private-ledger');
|
||||
expect((await call({ fandomId, scope: 'personal', uid }, 'other-user')).items).toEqual([]);
|
||||
await expect(call({ fandomId, scope: 'personal', cursor: 'other-fandom' })).rejects.toThrow();
|
||||
await expect(call({ fandomId, scope: 'all-users' })).rejects.toThrow();
|
||||
});
|
||||
Reference in New Issue
Block a user