File size: 2,918 Bytes
5c98911 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import { describe, it, expect, vi } from 'vitest';
import { distributeCampaignBudget } from './distributionEngine';
// Supabase Mocking representing both contributions view and distribution rules table
vi.mock('./supabase', () => ({
supabase: {
from: vi.fn((table: string) => {
if (table === 'distribution_rules') {
return {
select: vi.fn(() => ({
eq: vi.fn(() => ({
maybeSingle: vi.fn(() => Promise.resolve({
data: {
id: 'rule-001',
campaign_id: 'camp-123',
citizen_reward_ratio: 0.70, // 70% Citizen Reward
sme_donation_ratio: 0.20, // 20% SME Donation
platform_fee_ratio: 0.10, // 10% Platform Fee
rule_type: 'CUSTOM',
description: 'ํ
์คํธ์ฉ ๋์ ๋น์จ'
},
error: null
}))
}))
}))
};
}
// Default fallback is my_nature_contributions_view
return {
select: vi.fn(() => ({
eq: vi.fn(() => ({
gt: vi.fn(() => Promise.resolve({
data: [
{ user_id: 'user_1', display_name: '์ฐธ์ฌ์A', co2_grams: 600 },
{ user_id: 'user_2', display_name: '์ฐธ์ฌ์B', co2_grams: 400 },
],
error: null
}))
}))
}))
};
})
}
}));
// Ledger Mocking
vi.mock('./ledger', () => ({
appendLedgerEntry: vi.fn(() => Promise.resolve({ transactionId: 'test-tx-id' }))
}));
describe('Distribution Engine v1.2 Unit Tests', () => {
it('1์ฐจ ๋ถ๋ฐฐ (๊ณ ์ ํ๋ผ๋ฏธํฐ): ์์๋ฃ 10% ์ ์ธ ํ ๊ธฐ์ฌ๋(6:4)์ ๋ฐ๋ผ ํฌ์ธํธ๊ฐ ๋ฐฐ๋ถ๋์ด์ผ ํ๋ค', async () => {
const params = {
campaignId: 'camp-123',
budgetAmount: 100000, // 10๋ง์
platformFeeRate: 0.1, // 10% ์์๋ฃ
};
const result = await distributeCampaignBudget(params);
// 1. ํ๋ซํผ ์์๋ฃ ํ์ธ: 100,000 * 0.1 = 10,000
expect(result.platformFee).toBe(10000);
// 2. ์ด ๋ถ๋ฐฐ์ก ํ์ธ: 100,000 * 0.70 (rules๊ฐ ๋์ ์ผ๋ก ๋ถ๋ ค์ ธ 70%๋ก ์ ์ฐ๋จ)
expect(result.totalDistributed).toBe(70000);
expect(result.recipientCount).toBe(2);
});
it('1์ฐจ ๋ถ๋ฐฐ (๋์ ๋น์จ): DB distribution_rules์ ์ ์๋ ์๋ฏผ ์ง๋ถ(70%)๊ณผ ํ๋ซํผ ์ง๋ถ(10%)์ด ์ ์ ๋ฐ์๋์ด์ผ ํ๋ค', async () => {
const params = {
campaignId: 'camp-123',
budgetAmount: 100000, // 10๋ง์
};
const result = await distributeCampaignBudget(params);
// 1. ๋์ ํ๋ซํผ ์์๋ฃ ํ์ธ: 100,000 * 0.10 = 10,000
expect(result.platformFee).toBe(10000);
// 2. ๋์ ์ด ์๋ฏผ ๋ถ๋ฐฐ์ก ํ์ธ: 100,000 * 0.70 = 70,000
expect(result.totalDistributed).toBe(70000);
expect(result.recipientCount).toBe(2);
});
});
|