CarboAny / src /lib /distributionEngine.test.ts
Esketch's picture
deploy: [P4] Strangler Pattern API Adapter Release (Orphan Clean Build v2)
daaf9d7
Raw
History Blame Contribute Delete
2.92 kB
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);
});
});