// Login ads are a flat 30-day slot, not a daily meter. // // The old model charged 100 credits for every day a campaign was shown, with no end date. // That produced 74-day queues, and every new campaign added 100/day of charges while adding // no inventory — on 18 Sep, 15 campaigns were charged 1,500 credits against a platform that // had produced 367 login impressions in its whole life. import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); const ads = require('../ads.js'); const ok = [], bad = []; const t = (n, c, extra) => { (c ? ok : bad).push(n + (c || !extra ? '' : ' -> ' + extra)); }; const r = ads.rates(); t('a slot price is configured', Number(r.loginSlotCredits) > 0, String(r.loginSlotCredits)); t('a slot length is configured', Number(r.loginSlotDays) > 0, String(r.loginSlotDays)); t('the slot is 3,000 credits for 30 days', r.loginSlotCredits === 3000 && r.loginSlotDays === 30, r.loginSlotCredits + ' / ' + r.loginSlotDays); // the price matches what 30 days used to cost, so nobody pays more than before t('same total as 30 days at the old daily rate', r.loginSlotCredits === 30 * r.loginCreditsPerDay, r.loginSlotCredits + ' vs ' + (30 * r.loginCreditsPerDay)); // the source guarantees that matter, checked directly — these are the behaviours that stop // a slot draining against days when the gate produced nothing const src = require('fs').readFileSync(new URL('../ads.js', import.meta.url), 'utf8'); t('buying a slot charges the whole price up front', /Login-ad slot \(/.test(src) && /chargeCredits\(campaign\.id, v\.c\.budget, 'Login-ad slot/.test(src)); t('a slot gets an end date at purchase', /out\.expires = Date\.now\(\) \+ days \* 86400000/.test(src)); t('the MySQL daily meter skips slot campaigns', /expires IS NULL AND \(last_day_charged/.test(src)); t('the JSON daily meter skips slot campaigns', /if \(c\.expires\) continue; \/\/ slot buy/.test(src)); t('a short budget is refused with the slot price named', /A login-ad slot is ' \+ cost \+ ' credits for ' \+ days \+ ' days/.test(src)); console.log('PASS ' + ok.length); for (const b of bad) console.log('FAIL ' + b); process.exit(bad.length ? 1 : 0);