@@ -13,53 +13,94 @@ void main() {
1313 await setUpAppTest ();
1414 });
1515
16- testWidgets ('permissions screen - shows when are no permissions and pressing the button requests permissions' ,
17- (WidgetTester tester) async {
18- late PermissionsChannelObserver permissionsObserver;
19- await setUpAppTest (() {
20- permissionsObserver = PermissionsChannelObserver (tester.binding);
21- permissionsObserver.setPermission (Permission .storage, PermissionStatus .denied);
16+ group ('permissions screen' , () {
17+ testWidgets ('shows if no permissions were granted and pressing the button requests permissions' ,
18+ (WidgetTester tester) async {
19+ late PermissionsChannelObserver permissionsObserver;
20+ await setUpAppTest (() {
21+ permissionsObserver = PermissionsChannelObserver (tester.binding);
22+ permissionsObserver.setPermission (Permission .storage, PermissionStatus .denied);
23+ permissionsObserver.setPermission (Permission .audio, PermissionStatus .denied);
24+ });
25+ await tester.runAppTest (() async {
26+ expect (permissionsObserver.checkedPermissions, [Permission .storage],
27+ reason: 'Should always check the storage and audio permission on startup' );
28+ expect (find.byType (Home ), findsNothing, reason: 'Permissions are not granted yet' );
29+ final permissionGrantCompleter = Completer <PermissionStatus >();
30+ permissionsObserver.setPermissionResolvable (Permission .storage, () => permissionGrantCompleter.future);
31+ await tester.tap (find.text (l10n.grant));
32+ expect (permissionsObserver.requestedPermissions, [Permission .storage, Permission .audio]);
33+ await tester.pump ();
34+ expect (find.byType (CircularProgressIndicator ), findsOneWidget,
35+ reason: 'Indicate while waiting for the permission to be granted' );
36+ permissionGrantCompleter.complete (PermissionStatus .granted);
37+ await tester.pumpAndSettle ();
38+ expect (find.byType (Home ), findsOneWidget);
39+ });
2240 });
23- await tester.runAppTest (() async {
24- expect (permissionsObserver.checkedPermissions, [Permission .storage],
25- reason: 'Should always check the storage permission on startup' );
26- expect (find.byType (Home ), findsNothing, reason: 'Permissions are not granted yet' );
27- final permissionGrantCompleter = Completer <PermissionStatus >();
28- permissionsObserver.setPermissionResolvable (Permission .storage, () => permissionGrantCompleter.future);
29- await tester.tap (find.text (l10n.grant));
30- expect (permissionsObserver.requestedPermissions, [Permission .storage]);
31- await tester.pump ();
32- expect (find.byType (CircularProgressIndicator ), findsOneWidget,
33- reason: 'Indicate while waiting for the permission to be granted' );
34- permissionGrantCompleter.complete (PermissionStatus .granted);
35- await tester.pumpAndSettle ();
36- expect (find.byType (Home ), findsOneWidget);
41+
42+ /// On Android 13+ the storage permission is removed and reports as permanentlyDenied.
43+ /// If the user granted audio permissions, we have access to the music
44+ /// and don't want to show the permission request screen.
45+ testWidgets ('does not show when removed storage permission is permanently denied' , (WidgetTester tester) async {
46+ late PermissionsChannelObserver permissionsObserver;
47+ await setUpAppTest (() {
48+ FakeDeviceInfoControl .instance.sdkInt = 33 ;
49+ permissionsObserver = PermissionsChannelObserver (tester.binding);
50+ permissionsObserver.setPermission (Permission .storage, PermissionStatus .permanentlyDenied);
51+ permissionsObserver.setPermission (Permission .audio, PermissionStatus .granted);
52+ });
53+ await tester.runAppTest (() async {
54+ expect (Permissions .instance.granted, true );
55+ expect (permissionsObserver.checkedPermissions, [Permission .audio]);
56+ expect (find.byType (Home ), findsOneWidget, reason: 'Audio permissions was already granted' );
57+ });
3758 });
38- });
3959
40- testWidgets ('permissions screen - shows toast and opens settings when permissions are denied' ,
41- (WidgetTester tester) async {
42- late PermissionsChannelObserver permissionsObserver;
43- await setUpAppTest (() {
44- permissionsObserver = PermissionsChannelObserver (tester.binding);
45- permissionsObserver.setPermission (Permission .storage, PermissionStatus .denied);
60+ /// The audio permission is new in Android 13 and reports as permanentlyDenied on earlier versions.
61+ /// If the user granted storage permissions, we have access to the music
62+ /// and don't want to show the permission request screen.
63+ testWidgets ('does not show when non-existent audio permission is permanently denied' , (WidgetTester tester) async {
64+ late PermissionsChannelObserver permissionsObserver;
65+ await setUpAppTest (() {
66+ FakeDeviceInfoControl .instance.sdkInt = 32 ;
67+ permissionsObserver = PermissionsChannelObserver (tester.binding);
68+ permissionsObserver.setPermission (Permission .storage, PermissionStatus .granted);
69+ permissionsObserver.setPermission (Permission .audio, PermissionStatus .permanentlyDenied);
70+ });
71+ await tester.runAppTest (() async {
72+ expect (Permissions .instance.granted, true );
73+ expect (permissionsObserver.checkedPermissions, [Permission .storage]);
74+ expect (find.byType (Home ), findsOneWidget, reason: 'Storage permissions was already granted' );
75+ });
4676 });
47- await tester.runAppTest (() async {
48- permissionsObserver.setPermission (Permission .storage, PermissionStatus .permanentlyDenied);
49- permissionsObserver.isOpeningSettingsSuccessful = false ;
50- final ToastChannelObserver toastObserver = ToastChannelObserver (tester);
51- await tester.tap (find.text (l10n.grant));
52- expect (permissionsObserver.openSettingsRequests, 1 );
53- expect (toastObserver.toastMessagesLog, [l10n.allowAccessToExternalStorageManually, l10n.openAppSettingsError]);
54-
55- permissionsObserver.isOpeningSettingsSuccessful = true ;
56- await tester.tap (find.text (l10n.grant));
57- expect (permissionsObserver.openSettingsRequests, 2 );
58- expect (toastObserver.toastMessagesLog, [
59- l10n.allowAccessToExternalStorageManually,
60- l10n.openAppSettingsError,
61- l10n.allowAccessToExternalStorageManually
62- ]);
77+
78+ testWidgets ('shows toast and opens settings when permissions are denied' , (WidgetTester tester) async {
79+ late PermissionsChannelObserver permissionsObserver;
80+ await setUpAppTest (() {
81+ permissionsObserver = PermissionsChannelObserver (tester.binding);
82+ permissionsObserver.setPermission (Permission .storage, PermissionStatus .denied);
83+ permissionsObserver.setPermission (Permission .audio, PermissionStatus .denied);
84+ });
85+ await tester.runAppTest (() async {
86+ permissionsObserver.setPermission (Permission .storage, PermissionStatus .permanentlyDenied);
87+ permissionsObserver.setPermission (Permission .audio, PermissionStatus .permanentlyDenied);
88+ permissionsObserver.isOpeningSettingsSuccessful = false ;
89+ final ToastChannelObserver toastObserver = ToastChannelObserver (tester);
90+ await tester.tap (find.text (l10n.grant));
91+ await tester.pumpAndSettle ();
92+ expect (permissionsObserver.openSettingsRequests, 1 );
93+ expect (toastObserver.toastMessagesLog, [l10n.allowAccessToExternalStorageManually, l10n.openAppSettingsError]);
94+
95+ permissionsObserver.isOpeningSettingsSuccessful = true ;
96+ await tester.tap (find.text (l10n.grant));
97+ expect (permissionsObserver.openSettingsRequests, 2 );
98+ expect (toastObserver.toastMessagesLog, [
99+ l10n.allowAccessToExternalStorageManually,
100+ l10n.openAppSettingsError,
101+ l10n.allowAccessToExternalStorageManually
102+ ]);
103+ });
63104 });
64105 });
65106
0 commit comments