// apps/desktop/tests/unit/AdMediationEngine.spec.ts // Comprehensive Real Service Test Suite for 10+ Multi-Ad Network Mediation & Settlement import { describe, it, expect, beforeEach } from 'vitest' import { getAdMediationEngine, AdMediationEngine } from '../../src/main/services/ads/AdMediationEngine' import { getAdSettlementService, AdSettlementService } from '../../src/main/services/ads/AdSettlementService' import { EthicalAdsAdapter } from '../../src/main/services/ads/EthicalAdsAdapter' import { CarbonAdsAdapter } from '../../src/main/services/ads/CarbonAdsAdapter' import { PlaywireAdapter } from '../../src/main/services/ads/PlaywireAdapter' import { UnityAdsAdapter } from '../../src/main/services/ads/UnityAdsAdapter' import { AppLovinAdapter } from '../../src/main/services/ads/AppLovinAdapter' import { GoogleAdManagerAdapter } from '../../src/main/services/ads/GoogleAdManagerAdapter' import { InMobiAdapter } from '../../src/main/services/ads/InMobiAdapter' import { PubMaticAdapter } from '../../src/main/services/ads/PubMaticAdapter' import { MintegralAdapter } from '../../src/main/services/ads/MintegralAdapter' import { DirectHouseSponsorAdapter } from '../../src/main/services/ads/DirectHouseSponsorAdapter' describe('10+ Multi-Ad Network Adapters & Real Service Tests', () => { it('1. EthicalAds Adapter bids on developer dock slots', async () => { const adapter = new EthicalAdsAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(3.0) expect(bid.creative?.networkId).toBe('ethical_ads') expect(bid.creative?.title).toContain('MongoDB') }) it('2. Carbon Ads Adapter provides tech native single-unit creatives', async () => { const adapter = new CarbonAdsAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(3.5) expect(bid.creative?.networkId).toBe('carbon_ads') expect(bid.creative?.title).toContain('Linear') }) it('3. Playwire RAMP Adapter participates in desktop header bidding', async () => { const adapter = new PlaywireAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(4.5) expect(bid.creative?.networkId).toBe('playwire') }) it('4. Unity LevelPlay Adapter delivers high-yield rewarded video ads', async () => { const adapter = new UnityAdsAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'rewarded_video_quota', format: 'rewarded_video' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(6.0) expect(bid.creative?.networkId).toBe('unity_ads') expect(bid.creative?.rewardTokens).toBe(50) }) it('5. AppLovin MAX Adapter provides competitive in-app bidding', async () => { const adapter = new AppLovinAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'rewarded_video_quota', format: 'rewarded_video' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(5.5) expect(bid.creative?.networkId).toBe('applovin_max') }) it('6. Google Ad Manager 360 Adapter offers reliable global demand', async () => { const adapter = new GoogleAdManagerAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(2.0) expect(bid.creative?.networkId).toBe('google_ad_manager') }) it('7. InMobi Adapter handles programmatic exchange bids', async () => { const adapter = new InMobiAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(2.8) expect(bid.creative?.networkId).toBe('inmobi') }) it('8. PubMatic OpenWrap SSP Adapter responds with Prebid bids', async () => { const adapter = new PubMaticAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(3.0) expect(bid.creative?.networkId).toBe('pubmatic') }) it('9. Mintegral Adapter delivers APAC/global video demand', async () => { const adapter = new MintegralAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'rewarded_video_quota', format: 'rewarded_video' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(4.0) expect(bid.creative?.networkId).toBe('mintegral') }) it('10. Direct House Sponsor Adapter provides 100% margin premium AI ads', async () => { const adapter = new DirectHouseSponsorAdapter() await adapter.init() const bid = await adapter.requestBid({ placement: 'bottom_dock_banner', format: 'banner_dock' }) expect(bid.hasBid).toBe(true) expect(bid.bidEcpm).toBeGreaterThanOrEqual(12.0) expect(bid.creative?.networkId).toBe('direct_sponsor') }) }) describe('AdMediationEngine Header Bidding Auction & Telemetry', () => { let engine: AdMediationEngine beforeEach(() => { engine = getAdMediationEngine() }) it('executes parallel header bidding auction across all active networks', async () => { const auctionResult = await engine.runAuction({ placement: 'bottom_dock_banner', format: 'banner_dock', floorEcpm: 2.0, auctionTimeoutMs: 800, }) expect(auctionResult).toBeDefined() expect(auctionResult.winner).toBeDefined() expect(auctionResult.winningBidEcpm).toBeGreaterThanOrEqual(2.0) expect(auctionResult.participatingBids.length).toBeGreaterThanOrEqual(6) expect(auctionResult.totalAuctionLatencyMs).toBeLessThanOrEqual(1200) }) it('records ad impression and triggers adapter beacon', () => { expect(() => { engine.recordImpression({ adId: 'test_ad_001', format: 'banner_dock', network: 'ethical_ads', earnedEcpm: 4.2, }) }).not.toThrow() }) it('records ad click-through tracking event', () => { expect(() => { engine.recordClick('test_ad_001', 'ethical_ads') }).not.toThrow() }) it('dispenses +50 tokens upon rewarded video completion and enforces cooldown', async () => { const rewardRes = await engine.claimReward('test_video_ad', 'unity_ads') expect(rewardRes.success).toBe(true) expect(rewardRes.tokensAdded).toBe(50) // Immediate second claim should be rejected by cooldown const cooldownRes = await engine.claimReward('test_video_ad_2', 'unity_ads') expect(cooldownRes.success).toBe(false) expect(cooldownRes.tokensAdded).toBe(0) expect(cooldownRes.nextAvailableAt).toBeDefined() }) }) describe('AdSettlementService Revenue Ledger & Tax Withholding', () => { let settlement: AdSettlementService beforeEach(() => { settlement = getAdSettlementService() }) it('retrieves registered publisher account metadata for yunchanpaca@gmail.com', () => { const account = settlement.getPublisherAccount() expect(account.accountEmail).toBe('yunchanpaca@gmail.com') expect(account.payoutBank).toContain('KB국민은행') expect(account.networksConfigured).toBe(10) }) it('generates revenue statistics and computes Korean 3.3% withholding tax', () => { const stats = settlement.getRevenueStats('2026-08') expect(stats.totalRevenueUsd).toBeGreaterThan(0) expect(stats.avgEcpm).toBeGreaterThan(0) expect(stats.settlements.length).toBeGreaterThanOrEqual(5) const first = stats.settlements[0] expect(first.withholdingTaxRate).toBe(0.033) expect(first.netPayoutKrw).toBe(Math.round(first.netRevenueUsd * 1350)) }) it('processes payout request and updates status to paid', () => { const res = settlement.requestPayout('stl_202607_direct_sponsor') expect(res.success).toBe(true) expect(res.settlement?.payoutStatus).toBe('paid') expect(res.message).toContain('KB국민은행') }) })