// First integration test against a real `fai serve` subprocess. // // What this test covers (the regression bait): // // When the operator opens a flow that references `system.approval` // or any other built-in / federated capability, the missing-deps // check in Studio's Flows page must consider those caps already // available — otherwise the Run button stays disabled forever // and the operator's only recourse is to install a module that // doesn't exist. // // Why this test as the canonical first scaffold: // // It's the exact bug class that survived three commits of the // May-2026 trust pass before someone noticed. A real-Hub test // for it makes regressions impossible to ship. // // Cost: ~2 seconds (Hub start) + ~0.1 seconds (gRPC). Acceptable. // // Run manually with: // // flutter test test/integration/ // // CI does not yet run these by default — they need a built `fai` // binary in PATH or in ../fai_platform/target/release/. Wire that // in via .forgejo/workflows/ci.yml once the platform CI publishes // a Linux binary as an artifact for downstream jobs to consume. import 'package:flutter_test/flutter_test.dart'; import 'hub_fixture.dart'; void main() { group('Hub capability listing', () { late HubFixture? fixture; setUp(() async { fixture = await HubFixture.start(); }); tearDown(() async { await fixture?.dispose(); }); test('system.approval shows up as a builtin capability', () async { final f = fixture; if (f == null) return; // skipped — no binary final caps = await f.client.listCapabilities(); final approval = caps.where( (c) => c.capability == 'system.approval', ).toList(); expect(approval, isNotEmpty, reason: 'system.approval must appear in list_capabilities ' 'so Studio does not try to install it through the store'); expect(approval.first.kind, 'builtin', reason: 'kind=builtin lets Studio gate the Install button correctly'); }); test('every capability carries a kind tag', () async { final f = fixture; if (f == null) return; final caps = await f.client.listCapabilities(); expect(caps, isNotEmpty, reason: 'a fresh hub has at least the system.approval builtin'); for (final c in caps) { expect(['wasm', 'builtin', 'federated'], contains(c.kind), reason: 'cap ${c.capability} has unrecognised kind="${c.kind}" — ' 'Studio gates the Install button on this string, so the wire ' 'value must stay in the known set'); } }); }); }