feat(approvals,runs): explain approvals in place + one-click hub update (0.81.0)
Approvals: the pending card now shows its full origin — flow, step, run id (previously dropped at the Dart mapping layer), project, and requested-at — under an ORIGIN heading, led by a one-line intro strip that says what the inbox is and what Approve/Reject do. Approve/Reject buttons carry tooltips; the history dialog gains project + run id. Fixes the approvals doc drift (title/details/reviewer -> prompt/show/timeout_seconds). Guard: approvals_origin_test renders the card via the hermetic fake hub and pins every origin fact. Runs: the "hub too old" state now leads with an in-place update button (same `chain update apply` path as the Diagnose page), the Diagnose deeplink demoted to secondary, with a CLI-absent fallback. Guard: two new RunsLoadErrorView widget tests. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
14f824b8ef
commit
28f6fe1a9a
16 changed files with 613 additions and 115 deletions
|
|
@ -135,6 +135,53 @@ void main() {
|
|||
expect(doctorOpened, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('too-old hub leads with an in-place update button, '
|
||||
'doctor demoted to secondary', (tester) async {
|
||||
var updateTriggered = false;
|
||||
await tester.pumpWidget(
|
||||
_host(
|
||||
RunsLoadErrorView(
|
||||
error: const _FakeGrpcError(12, 'unimplemented'),
|
||||
issue: RunsLoadIssue.unsupported,
|
||||
onOpenGuide: () {},
|
||||
onOpenDoctor: () {},
|
||||
onUpdateHub: () => updateTriggered = true,
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
// Primary CTA is the fix, not the detour.
|
||||
expect(find.text('Hub jetzt aktualisieren'), findsOneWidget);
|
||||
expect(find.text('Diagnose öffnen'), findsOneWidget);
|
||||
await tester.tap(find.text('Hub jetzt aktualisieren'));
|
||||
expect(updateTriggered, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('while updating, the button shows progress and is disabled', (
|
||||
tester,
|
||||
) async {
|
||||
var updateTriggered = false;
|
||||
await tester.pumpWidget(
|
||||
_host(
|
||||
RunsLoadErrorView(
|
||||
error: const _FakeGrpcError(12, 'unimplemented'),
|
||||
issue: RunsLoadIssue.unsupported,
|
||||
onOpenGuide: () {},
|
||||
onOpenDoctor: () {},
|
||||
onUpdateHub: () => updateTriggered = true,
|
||||
updating: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
// The spinner animates forever, so pump one frame rather than
|
||||
// pumpAndSettle (which would time out waiting for it to stop).
|
||||
await tester.pump();
|
||||
expect(find.text('Hub wird aktualisiert…'), findsOneWidget);
|
||||
// Disabled while in flight — a tap must not re-fire.
|
||||
await tester.tap(find.byType(FilledButton), warnIfMissed: false);
|
||||
expect(updateTriggered, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('a genuinely unreachable hub still says unreachable', (
|
||||
tester,
|
||||
) async {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue