From c82b8677ddf3e8cedfadceda426b3829935e0d95 Mon Sep 17 00:00:00 2001 From: Dinesh Date: Sat, 16 Dec 2023 19:34:47 +0530 Subject: [PATCH 1/4] Code changes to allow cancelling updates in manage page --- .../lib/src/manage/manage_page.dart | 15 +++++++++++ .../lib/src/snapd/updates_model.dart | 21 +++++++++++++++ .../app_center/test/manage_page_test.dart | 27 +++++++++++++++++++ packages/app_center/test/test_utils.dart | 1 + 4 files changed, 64 insertions(+) diff --git a/packages/app_center/lib/src/manage/manage_page.dart b/packages/app_center/lib/src/manage/manage_page.dart index cf3130b0d..87ce1fe57 100644 --- a/packages/app_center/lib/src/manage/manage_page.dart +++ b/packages/app_center/lib/src/manage/manage_page.dart @@ -303,6 +303,21 @@ class _ActionButtons extends ConsumerWidget { ], ), ), + const SizedBox(width: 8), + PushButton.outlined( + onPressed: updatesModel.refreshableSnapNames.isNotEmpty && + !updatesModel.state.isLoading && + updatesModel.activeChangeId != null + ? () => ref + .read(updatesModelProvider) + .cancelChange(updatesModel.activeChangeId!) + : null, + child: Text( + l10n.snapActionCancelLabel, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), ], ); } diff --git a/packages/app_center/lib/src/snapd/updates_model.dart b/packages/app_center/lib/src/snapd/updates_model.dart index 25a7d1d3b..aa078b416 100644 --- a/packages/app_center/lib/src/snapd/updates_model.dart +++ b/packages/app_center/lib/src/snapd/updates_model.dart @@ -63,4 +63,25 @@ class UpdatesModel extends ChangeNotifier { _activeChangeId = null; await refresh(); } + + Future cancelChange(String changeId) async { + if (changeId.isEmpty) return; + + try { + final changeDetails = await snapd.getChange(changeId); + + // If the change is already completed, ignore silently. + // Otherwise an erorr will be displayed to user, which might be confusing. + if (changeDetails.ready) { + return; + } + + final abortChange = await snapd.abortChange(changeId); + await snapd.waitChange(abortChange.id); + _activeChangeId = null; + notifyListeners(); + } on SnapdException catch (e) { + _handleError(e); + } + } } diff --git a/packages/app_center/test/manage_page_test.dart b/packages/app_center/test/manage_page_test.dart index 5e4c5e0c2..4183ac72e 100644 --- a/packages/app_center/test/manage_page_test.dart +++ b/packages/app_center/test/manage_page_test.dart @@ -188,6 +188,33 @@ void main() { ); }); + testWidgets('cancel refresh all', (tester) async { + final mockUpdatesModel = createMockUpdatesModel( + refreshableSnapNames: refreshableSnaps.map((snap) => snap.name), + isBusy: true, + ); + + await tester.pumpApp( + (_) => ProviderScope( + overrides: [ + launchProvider.overrideWith((_, __) => createMockSnapLauncher()), + manageModelProvider.overrideWith( + (_) => createMockManageModel( + refreshableSnaps: refreshableSnaps, + ), + ), + updatesModelProvider.overrideWith((_) => mockUpdatesModel), + ], + child: const ManagePage(), + ), + ); + await tester.pump(); + + final cancelButton = find.buttonWithText(tester.l10n.snapActionCancelLabel); + expect(cancelButton, findsOneWidget); + expect(cancelButton, isEnabled); + }); + testWidgets('error dialog', (tester) async { await tester.pumpApp( (_) => ProviderScope( diff --git a/packages/app_center/test/test_utils.dart b/packages/app_center/test/test_utils.dart index 96983cd1a..8b2a9d4ba 100644 --- a/packages/app_center/test/test_utils.dart +++ b/packages/app_center/test/test_utils.dart @@ -230,6 +230,7 @@ MockUpdatesModel createMockUpdatesModel({ when(model.activeChangeId).thenReturn(isBusy ? 'changeId' : null); when(model.errorStream) .thenAnswer((_) => errorStream ?? const Stream.empty()); + when(model.activeChangeId).thenReturn('activeChangeId'); return model; } From 3d8d81365aedfeb87f46759e2077566e448b5844 Mon Sep 17 00:00:00 2001 From: Dinesh Date: Thu, 28 Dec 2023 22:09:08 +0530 Subject: [PATCH 2/4] Update packages/app_center/lib/src/snapd/updates_model.dart Co-authored-by: Lukas Klingsbo --- packages/app_center/lib/src/snapd/updates_model.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/app_center/lib/src/snapd/updates_model.dart b/packages/app_center/lib/src/snapd/updates_model.dart index aa078b416..5f37dd6c2 100644 --- a/packages/app_center/lib/src/snapd/updates_model.dart +++ b/packages/app_center/lib/src/snapd/updates_model.dart @@ -71,7 +71,8 @@ class UpdatesModel extends ChangeNotifier { final changeDetails = await snapd.getChange(changeId); // If the change is already completed, ignore silently. - // Otherwise an erorr will be displayed to user, which might be confusing. + // If it wouldn't be ignored, an error would be displayed to the user, + // which might be confusing. if (changeDetails.ready) { return; } From c7688a338e7ed82c3051460edf57872388a75fd8 Mon Sep 17 00:00:00 2001 From: Dinesh Date: Thu, 28 Dec 2023 22:22:15 +0530 Subject: [PATCH 3/4] fix mock, and refactor per code review suggestion --- packages/app_center/lib/src/manage/manage_page.dart | 7 ++++--- packages/app_center/test/test_utils.mocks.dart | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/app_center/lib/src/manage/manage_page.dart b/packages/app_center/lib/src/manage/manage_page.dart index 0cdf57827..1f5cbce8e 100644 --- a/packages/app_center/lib/src/manage/manage_page.dart +++ b/packages/app_center/lib/src/manage/manage_page.dart @@ -234,6 +234,9 @@ class _ActionButtons extends ConsumerWidget { error: (_, __) => ('', const SizedBox.shrink()), ); + final updatesInprogress = updatesModel.refreshableSnapNames.isNotEmpty && + !updatesModel.state.isLoading && + updatesModel.activeChangeId != null; return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -306,9 +309,7 @@ class _ActionButtons extends ConsumerWidget { ), const SizedBox(width: 8), PushButton.outlined( - onPressed: updatesModel.refreshableSnapNames.isNotEmpty && - !updatesModel.state.isLoading && - updatesModel.activeChangeId != null + onPressed: updatesInprogress ? () => ref .read(updatesModelProvider) .cancelChange(updatesModel.activeChangeId!) diff --git a/packages/app_center/test/test_utils.mocks.dart b/packages/app_center/test/test_utils.mocks.dart index 41e3e0160..488cc2c30 100644 --- a/packages/app_center/test/test_utils.mocks.dart +++ b/packages/app_center/test/test_utils.mocks.dart @@ -1452,6 +1452,16 @@ class MockUpdatesModel extends _i1.Mock implements _i6.UpdatesModel { returnValueForMissingStub: _i14.Future.value(), ) as _i14.Future); + @override + _i14.Future cancelChange(String? changeId) => (super.noSuchMethod( + Invocation.method( + #cancelChange, + [changeId], + ), + returnValue: _i14.Future.value(), + returnValueForMissingStub: _i14.Future.value(), + ) as _i14.Future); + @override void addListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( From 1736eb66b30e29c71d65df2235421b0ef3feb3d4 Mon Sep 17 00:00:00 2001 From: Dinesh Date: Fri, 29 Dec 2023 23:42:35 +0530 Subject: [PATCH 4/4] fix failing test --- packages/app_center/test/manage_page_test.dart | 1 + packages/app_center/test/test_utils.dart | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app_center/test/manage_page_test.dart b/packages/app_center/test/manage_page_test.dart index ec021be00..3f38b73fc 100644 --- a/packages/app_center/test/manage_page_test.dart +++ b/packages/app_center/test/manage_page_test.dart @@ -250,6 +250,7 @@ void main() { refreshableSnaps: refreshableSnaps, ), ), + snapModelProvider.overrideWith((_, __) => snapModel), updatesModelProvider.overrideWith((_) => mockUpdatesModel), ], child: const ManagePage(), diff --git a/packages/app_center/test/test_utils.dart b/packages/app_center/test/test_utils.dart index 8b2a9d4ba..96983cd1a 100644 --- a/packages/app_center/test/test_utils.dart +++ b/packages/app_center/test/test_utils.dart @@ -230,7 +230,6 @@ MockUpdatesModel createMockUpdatesModel({ when(model.activeChangeId).thenReturn(isBusy ? 'changeId' : null); when(model.errorStream) .thenAnswer((_) => errorStream ?? const Stream.empty()); - when(model.activeChangeId).thenReturn('activeChangeId'); return model; }