캠페인 성공 알림 · 운영 퀘스트 참여 인원 · Music Shake 하루 1회 · 함수 배포 전 빌드

This commit is contained in:
Sn-Kinos
2026-10-08 16:01:12 +09:00
parent 93150a0d5b
commit f7075f0e6f
14 changed files with 243 additions and 18 deletions
@@ -7,7 +7,7 @@ import { fundCampaign } from '../src/fandom/fandom.js';
import { createCampaign, retryFeeRefunds, withdrawCampaign } from '../src/campaign/create.js';
import {
MAX_AUTO_REFUND_ATTEMPTS, cancelCampaign, fnCampaignAdminReview, fnCampaignReportSubmit, refundCampaign,
retryPendingRefunds, settleDueCampaigns, submitCampaignReport,
notifySuccess, retryPendingRefunds, settleDueCampaigns, submitCampaignReport,
} from '../src/campaign/settle.js';
/**
@@ -313,6 +313,17 @@ describe('정산 분기', () => {
expect(short.get('status')).toBe('fail');
expect(short.get('refundState')).toBe('pending');
expect(short.get('refundDueAt').toMillis() - Date.now()).toBeGreaterThan(71 * 3600_000);
// B-3 8-10 성공 알림 — 개설자 · 후원자 한 건씩(kind campaign · essential), 실패 캠페인은 성공 알림 없음.
for (const uid of [CREATOR, A, B]) expect(await notes(uid)).toEqual(['campaignSuccess_cmp-ok']);
const note = await db().doc(`users/${A}/notifications/campaignSuccess_cmp-ok`).get();
expect(note.data()).toMatchObject({ eventType: 'campaign', type: 'essential', campaignId: 'cmp-ok' });
expect(note.get('title')).toBe('후원하신 「캠페인 cmp-ok」 캠페인이 목표를 달성했습니다');
expect((await db().doc(`users/${CREATOR}/notifications/campaignSuccess_cmp-ok`).get()).get('title'))
.toBe('개설하신 「캠페인 cmp-ok」 캠페인이 목표를 달성했습니다');
// 재호출은 같은 문서 — 중복 알림 0건.
await notifySuccess('cmp-ok');
expect(await notes(A)).toEqual(['campaignSuccess_cmp-ok']);
});
it('「응원 중」(donorCount)은 고유 후원자 수다 — 같은 사람의 두 번째 후원은 늘리지 않는다', async () => {
@@ -467,7 +478,7 @@ describe('결과보고 — 운영 전용 (B-35)', () => {
const doc = await db().doc('campaigns/cmp-rep/reports/main').get();
expect(doc.get('receiptPaths')).toEqual(['campaignReports/cmp-rep/r1.png']);
expect(doc.get('budgetTotal')).toBe(500);
expect(await notes(A)).toEqual(['campaignReport_cmp-rep_main']);
expect(await notes(A)).toEqual(['campaignReport_cmp-rep_main', 'campaignSuccess_cmp-rep']);
// 게시 뒤 알림 전에 죽은 경우.
await db().recursiveDelete(db().collection(`users/${A}/notifications`));