fix(mobile): preserve diagnostics revocation

Co-authored-by: npub1ft62tztwwm2x9xamk25smmuaj4sfckdkldksruf2x2jwqalffkrq0g7arr <4af4a5896e76d4629bbbb2a90def9d95609c59b6fb6d01f12a32a4e077e94d86@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1ft62tztwwm2x9xamk25smmuaj4sfckdkldksruf2x2jwqalffkrq0g7arr <4af4a5896e76d4629bbbb2a90def9d95609c59b6fb6d01f12a32a4e077e94d86@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
npub1ft62tztwwm2x9xamk25smmuaj4sfckdkldksruf2x2jwqalffkrq0g7arr
2026-07-19 14:17:34 -07:00
parent bdfc94b217
commit 63a9348629
4 changed files with 22 additions and 5 deletions
@@ -117,8 +117,8 @@ class SettingsPage extends HookConsumerWidget {
title: 'Share Crash Reports',
subtitle: diagnostics.isConfigured
? 'Send crash details to help improve Buzz. Reports '
'exclude message text, screenshots, and personal '
'information.'
'do not include screenshots, view hierarchy, '
'breadcrumbs, or performance traces.'
: 'Crash reporting is unavailable in this build.',
subtitleMaxLines: 4,
trailing: Switch.adaptive(
@@ -70,6 +70,7 @@ class DiagnosticsController extends ChangeNotifier {
}
final previousConsent = _consentGranted;
var consentPersisted = false;
_consentGranted = granted;
notifyListeners();
try {
@@ -80,8 +81,15 @@ class DiagnosticsController extends ChangeNotifier {
if (!persisted) {
throw StateError('Failed to persist diagnostics consent');
}
consentPersisted = true;
await _applyCurrentConsent();
} on Object {
// A persisted revocation must survive teardown failure. Otherwise the
// next launch could initialize crash reporting against the user's
// explicit choice.
if (!granted && consentPersisted) {
rethrow;
}
_consentGranted = previousConsent;
final rolledBack = await _preferences.setBool(
diagnosticsConsentPreferenceKey,
@@ -56,6 +56,15 @@ void main() {
expect(find.text('DIAGNOSTICS'), findsOneWidget);
expect(find.text('Share Crash Reports'), findsOneWidget);
expect(
find.text(
'Send crash details to help improve Buzz. Reports do not include '
'screenshots, view hierarchy, breadcrumbs, or performance traces.',
),
findsOneWidget,
);
expect(find.textContaining('personal information'), findsNothing);
expect(find.textContaining('message text'), findsNothing);
final toggle = tester.widget<Switch>(find.byType(Switch));
expect(toggle.value, isFalse);
@@ -174,7 +174,7 @@ void main() {
expect(reporter.initializeCalls, 1);
});
test('close failure rolls back revocation', () async {
test('close failure preserves persisted revocation', () async {
final controller = await createController(
storedValues: {diagnosticsConsentPreferenceKey: true},
);
@@ -183,8 +183,8 @@ void main() {
await expectLater(controller.setConsent(false), throwsA(isA<StateError>()));
expect(controller.consentGranted, isTrue);
expect(preferences.getBool(diagnosticsConsentPreferenceKey), isTrue);
expect(controller.consentGranted, isFalse);
expect(preferences.getBool(diagnosticsConsentPreferenceKey), isFalse);
expect(reporter.closeCalls, 1);
});