open-standards/wai/quantum-studio/test/hardware.test.mjs
Transaction Science 24adcdc918 Quantum Studio and the desktop app: Your hardware, with a cost dialog
- Desktop: providers_list, provider_estimate and run_on_provider
  commands; the app reads the credential from the keychain, seals the
  counts with the user's key, and refuses a run that is not free unless
  the page confirms it.
- Studio: a "Your hardware" switch. In the desktop app it lists the
  person's providers, asks for the estimate first and shows a dialog
  before a run that is not free; in a browser tab it says such runs go
  through the desktop app or the command line, since a tab must not hold
  a provider's credential.
- Tests: test/hardware.test.mjs (the switch's logic without a browser),
  a check in the browser test, and a desktop test of the estimate, the
  refusal and the sealed run. The Studio workflow runs the first and
  pins the last, and follows wai-quantum-qpu.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 19:51:08 -04:00

70 lines
3.8 KiB
JavaScript

// The "Your hardware" logic, without a browser: a run that is not free asks
// the person first, a free one does not, a "no" sends nothing, and the
// dialog's words carry the estimate.
//
// node test/hardware.test.mjs
import { HardwareEngine, NOTE, confirmText, costText, needsConfirmation } from '../src/hardware.js';
let fails = 0;
const check = (ok, what) => { console.log(`${ok ? 'PASS' : 'FAIL'} ${what}`); if (!ok) fails += 1; };
const plan = (free, estimate) => ({ free, estimate, provider: { name: 'lab', device: 'reference:line-5', provenance: 'simulator:x' }, plan: { shots: 100, compile: { native_gates: 12, basis: 'rzsxxcz', swaps: 0 } } });
const priced = plan(false, { free: false, amount: '0.3', currency: 'USD', unit: 'shot', seconds: 4 });
check(needsConfirmation(priced) && !needsConfirmation(plan(true, { free: true })), 'a run not stated free needs a confirmation, a free one does not');
check(needsConfirmation(plan(undefined, { unknown: 'no estimate' })), 'an unknown cost needs a confirmation');
check(costText(priced) === '0.3 USD (billed by the shot), about 4 s', `the cost in words (${costText(priced)})`);
check(costText(plan(false, { unknown: 'the provider gives no estimate' })) === 'cost unknown: the provider gives no estimate', 'an unknown cost says so');
const words = confirmText(priced).join(' ');
check(/Run on lab \(reference:line-5/.test(words) && /not free: 0\.3 USD/.test(words) && /12 native gates in rzsxxcz/.test(words) && /spends your account/.test(words), `the dialog's words (${words})`);
check(/desktop app or the command line/.test(NOTE) && /must not hold the credentials/.test(NOTE), 'the browser note');
// The engine against fake desktop commands.
function fake(p) {
const calls = [];
const invoke = async (cmd, args) => {
calls.push([cmd, args]);
if (cmd === 'providers_list') return JSON.stringify({ providers: [{ name: 'lab', kind: 'process' }] });
if (cmd === 'provider_estimate') return JSON.stringify(p);
if (cmd === 'run_on_provider') return JSON.stringify({ status: 'done', method: 'provider', request: JSON.parse(args.request), result: { counts: { '00': 50, '11': 50 } } });
return JSON.stringify({ error: `no command ${cmd}` });
};
return { calls, invoke };
}
{
const f = fake(plan(true, { free: true }));
let asked = 0;
const e = new HardwareEngine(f.invoke, async () => { asked += 1; return true; });
check((await e.providers()).length === 1, 'the providers are listed');
e.select('lab');
const body = await e.run({ qasm: 'OPENQASM 3.0; qubit[2] q;', shots: 100 });
const run = f.calls.find((c) => c[0] === 'run_on_provider');
check(asked === 0 && run[1].confirmCost === false && body.request.provider === 'lab', 'a free run is not asked about, and names its provider');
}
{
const f = fake(priced);
const e = new HardwareEngine(f.invoke, async () => false);
e.select('lab');
let err = '';
try { await e.run({ qasm: 'q', shots: 100 }); } catch (x) { err = x.message; }
check(err === 'cancelled' && !f.calls.some((c) => c[0] === 'run_on_provider'), 'a run not free, declined, sends nothing');
}
{
const f = fake(priced);
let shown = null;
const e = new HardwareEngine(f.invoke, async (p) => { shown = p; return true; });
e.select('lab');
await e.run({ qasm: 'q', shots: 100 });
const run = f.calls.find((c) => c[0] === 'run_on_provider');
check(shown === null ? false : shown.estimate.amount === '0.3', 'the dialog is shown the estimate');
check(run && run[1].confirmCost === true, 'a run not free, accepted, is sent confirmed');
}
{
const e = new HardwareEngine(fake(priced).invoke, async () => true);
let err = '';
try { await e.run({ qasm: 'q' }); } catch (x) { err = x.message; }
check(/choose one of your providers/.test(err), 'no provider chosen, no run');
}
if (fails) { console.error(`${fails} failed`); process.exit(1); }
console.log('hardware: every check held');