wallet-optimization.test.cjs (2815B)
1 const { test } = require('node:test'); 2 const assert = require('node:assert/strict'); 3 const { readFileSync } = require('node:fs'); 4 const vm = require('node:vm'); 5 6 function app() { 7 const context = { window: {}, localStorage: { getItem: () => null }, setTimeout, clearTimeout, URLSearchParams }; 8 vm.runInNewContext(readFileSync(require.resolve('../www/assets/iuna-ui.js'), 'utf8'), context); 9 const app = context.window.iunaApp(); 10 app.status = { wallet_address: 'wallet', wallet_locked: false }; 11 app.refresh = async () => {}; 12 app.optimizePlan = { address: 'wallet', before: 5, after: 3, fee: 200, rate: 1, mergeRoots: false, 13 batches: [{ fee: 100, utxos: ['one', 'two'] }, { fee: 100, utxos: ['three', 'four'] }] }; 14 return app; 15 } 16 17 test('does not submit before approval and queues each batch after confirmation', async () => { 18 const ui = app(); 19 ui.optimizeOpen = true; 20 const events = []; 21 ui.submitForm = async (_path, fields) => { 22 events.push(`submit:${fields.utxos}`); 23 assert.equal(fields.max_fee, 100); 24 assert.equal(fields.address, 'wallet'); 25 return { signature: `tx${events.length}` }; 26 }; 27 ui.showFlash = () => {}; 28 assert.equal(events.length, 0); 29 await ui.runOptimization(); 30 assert.equal(events.length, 2); 31 assert.equal(ui.optimizePlan, null); 32 assert.equal(ui.optimizeOpen, false); 33 assert.match(ui.optimizeMessage, /submitted/); 34 }); 35 36 test('runs all approved batches as one action', async () => { 37 const ui = app(); 38 let submissions = 0; 39 ui.submitForm = async () => { submissions++; return { signature: `tx${submissions}` }; }; 40 ui.showFlash = () => {}; 41 await ui.runOptimization(); 42 assert.equal(submissions, 2); 43 assert.equal(ui.optimizePlan, null); 44 }); 45 46 test('uncertain submission stops and requires a fresh preview', async () => { 47 const ui = app(); 48 let submissions = 0; 49 ui.submitForm = async () => { submissions++; throw new Error('timeout'); }; 50 await ui.runOptimization(); 51 await ui.runOptimization(); 52 assert.equal(submissions, 1); 53 assert.equal(ui.optimizePlan, null); 54 assert.match(ui.optimizeError, /Check wallet activity/); 55 }); 56 57 test('wallet switch and wallet lock stop further submissions', async () => { 58 for (const status of [{ wallet_address: 'other' }, { wallet_address: 'wallet', wallet_locked: true }]) { 59 const ui = app(); 60 ui.status = status; 61 ui.submitForm = async () => assert.fail('must not submit'); 62 await ui.runOptimization(); 63 assert.match(ui.optimizeError, /Wallet locked or changed/); 64 } 65 }); 66 67 test('broadcast failure stops without silently retrying', async () => { 68 const ui = app(); 69 ui.submitForm = async () => ({ signature: 'accepted', broadcast_error: 'offline' }); 70 await ui.runOptimization(); 71 assert.match(ui.optimizeError, /queued locally/); 72 assert.equal(ui.optimizePlan, null); 73 });