chain-studio/test/install_confirm_test.dart
flemming-it 039f11b6bc
Some checks failed
Security / Security check (push) Failing after 2s
feat(store): trust gate before every module install
One-click installs showed no trust signal at all (top security
finding of the usertest panel). Every install path — store card,
detail sheet, and the flow list's quick fix — now routes through
one confirmation dialog showing what the hub actually knows
before download: origin store, version, license, maturity, and
required services/capabilities, plus the sandbox model and an
honest note that per-entry signature status is not in the store
index yet (verification happens hub-side at install). Widget
tests cover content and confirm/cancel semantics.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-07-17 23:44:14 +02:00

84 lines
2.6 KiB
Dart

// Install trust gate — every install path routes through this
// dialog, so it must show provenance (source, version, license,
// maturity) and the honest signature note, and only proceed on
// an explicit confirmation.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:chain_studio/data/hub.dart';
import 'package:chain_studio/l10n/app_localizations.dart';
import 'package:chain_studio/widgets/chain_install_confirm.dart';
const _item = StoreItem(
name: 'text.extract',
taglineEn: '',
taglineDe: '',
descriptionEn: '',
descriptionDe: '',
category: 'text',
tags: [],
requiresCapabilities: [],
requiresServices: ['judge-ner'],
license: 'Apache-2.0',
repository: '',
bestVersion: '0.1.0',
status: 'alpha',
installed: false,
featured: false,
iconUrl: '',
screenshotUrls: [],
docsUrl: '',
kind: 'native',
provider: 'fai',
source: 'bundled',
);
Widget _host({required void Function(bool) onResult}) => MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: const Locale('de'),
home: Builder(
builder: (context) => Center(
child: ElevatedButton(
onPressed: () async {
onResult(await ChainInstallConfirmDialog.show(context, _item));
},
child: const Text('go'),
),
),
),
);
void main() {
testWidgets('shows provenance, maturity, and the signature note',
(tester) async {
await tester.pumpWidget(_host(onResult: (_) {}));
await tester.tap(find.text('go'));
await tester.pumpAndSettle();
expect(find.text('„text.extract" installieren?'), findsOneWidget);
expect(find.text('v0.1.0'), findsOneWidget);
expect(find.text('Mitgelieferter Store-Index'), findsOneWidget);
expect(find.text('Apache-2.0'), findsOneWidget);
expect(find.text('experimentell'), findsOneWidget);
expect(find.text('judge-ner'), findsOneWidget);
expect(find.textContaining('Signaturen prüft der Hub'), findsOneWidget);
});
testWidgets('cancel returns false, install returns true', (tester) async {
bool? result;
await tester.pumpWidget(_host(onResult: (r) => result = r));
await tester.tap(find.text('go'));
await tester.pumpAndSettle();
await tester.tap(find.text('Abbrechen'));
await tester.pumpAndSettle();
expect(result, isFalse);
await tester.tap(find.text('go'));
await tester.pumpAndSettle();
await tester.tap(find.text('Installieren'));
await tester.pumpAndSettle();
expect(result, isTrue);
});
}