import assert from "node:assert/strict"; import { readFile, readdir } from "node:fs/promises"; import test from "node:test";
const ROOT=new URL("../",import.meta.url);
async function files(dir){const entries=await readdir(new URL(dir,ROOT),{withFileTypes:true});const out=[];for(const entry of entries){const rel=`${dir}${entry.name}`;if(entry.isDirectory())out.push(...await files(`${rel}/`));else out.push(rel);}return out;}
async function text(path){return readFile(new URL(path,ROOT),"utf8");}
test("Android billing boundary pins Billing 9.1.0 and registers the local plugin",async()=>{const gradle=await text("apps/pwa/android/app/build.gradle"),activity=await text("apps/pwa/android/app/src/main/java/com/makecdev/coderemotemanager/MainActivity.java");assert.match(gradle,/com\.android\.billingclient:billing:9\.1\.0/);assert.match(gradle,/generateLicenseReport/);assert.match(activity,/registerPlugin\(ProBillingPlugin\.class\).*super\.onCreate/s);});
test("purchase tokens stay outside production PWA and backend source",async()=>{const names=[...await files("apps/pwa/src/"),...await files("apps/backend/src/")].filter(name=>/\.(?:js|jsx)$/.test(name)&&!name.includes(".test."));const source=(await Promise.all(names.map(text))).join("\n");assert.doesNotMatch(source,/purchaseToken/);});
test("tracked Android source contains no fixed verifier, local, or credential endpoint",async()=>{const names=(await files("apps/pwa/android/app/src/main/")).filter(name=>/\.(?:java|xml|json)$/.test(name));const source=(await Promise.all(names.map(text))).join("\n");assert.doesNotMatch(source,/https:\/\/[A-Za-z0-9]|localhost|127\.0\.0\.1|BEGIN PRIVATE KEY|service_account/);});
test("billing verification reuses one worker instead of leaking an executor per request",async()=>{const plugin=await text("apps/pwa/android/app/src/main/java/com/makecdev/coderemotemanager/ProBillingPlugin.java");assert.match(plugin,/static final ExecutorService VERIFIER_EXECUTOR/);assert.doesNotMatch(plugin,/verify\([\s\S]*?Executors\.newSingleThreadExecutor\(\)\.execute/);});
test("restore selects only the configured Pro product",async()=>{const plugin=await text("apps/pwa/android/app/src/main/java/com/makecdev/coderemotemanager/ProBillingPlugin.java");assert.match(plugin,/purchase\.getProducts\(\)\.contains\(PRODUCT_ID\)/);assert.match(plugin,/matchingPurchase\(purchases\)/);});
