Files
buzz/mobile/test/shared/community/community_test.dart
Tom Brow 8f2c7710e9 fix(mobile): default community push notifications to on (#8425)
New mobile communities currently require a manual Settings opt-in before
push can start. Default that local preference to on for new communities
and stored records without a preference. Preserve every saved `true` or
`false`, including values written by older clients. Older default-off
values are indistinguishable from explicit opt-outs, so this does not
migrate them to on.

Push still requires a configured gateway, authenticated connectivity,
and a valid relay capability. iOS continues to control display
authorization through its existing permission prompt. Notification
eligibility and subscriptions are unchanged. Settings retains its
existing opt-out control for enabled communities even when capability is
unavailable.

Drafted from the 0.24 baseline; release-branch inclusion is a separate
decision.

### Related issue

Closest related issue: #3238 (synced defaults). This change is limited
to the mobile device-local community preference; no duplicate found.

### Validation

- Added or updated coverage for new and missing preferences, saved
true/false persistence, opt-out after restart, capability-gated
registration, and Settings without a configured gateway.
- Full configured mobile suite: 3,499 passed, 4 skipped. Separate
no-gateway suite: 4 passed. Flutter analysis passed.
- Existing permission-denied and unsupported-relay tests passed as part
of the mobile suite. No physical-device or end-to-end APNs validation
performed.
- Full local repository gate passed (formatting, lint, unit tests,
desktop/web builds, Tauri checks/tests, and mobile tests).



- Follow-up review edits: restored the original VISION.md wording and
shared the default in one private Community constant. All 43 focused
community/bootstrap tests passed.

<!-- buzz-review-completed -->

---------

Signed-off-by: Tom Brow <tomb@block.xyz>
2026-10-18 16:10:01 -07:00

94 lines
2.9 KiB
Dart

import 'package:buzz/shared/community/community.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('existing records default to device authentication', () {
final community = Community.fromJson({
'id': 'one',
'name': 'Buzz',
'relayUrl': 'https://relay.test',
'addedAt': '2026-08-05T00:00:00.000Z',
});
expect(
community.sensitiveActionPolicy,
SensitiveActionPolicy.disabledByUser,
);
expect(community.starterSetupIncomplete, isFalse);
expect(community.pushLeaseInstallationId, isNull);
expect(community.pushNotificationsEnabled, isTrue);
expect(community.pushSubscriptionState.pendingTombstoneGeneration, isNull);
});
test('new community gets a unique canonical push lease address id', () {
final first = Community.create(name: 'One', relayUrl: 'https://relay.test');
final second = Community.create(
name: 'Two',
relayUrl: 'https://relay.test',
);
expect(first.pushNotificationsEnabled, isTrue);
expect(Community.fromJson(first.toJson()).pushNotificationsEnabled, isTrue);
expect(first.pushLeaseInstallationId, matches(RegExp(r'^[0-9a-f]{32}$')));
expect(
second.pushLeaseInstallationId,
isNot(first.pushLeaseInstallationId),
);
});
test('community settings round trip', () {
final community = Community(
id: 'one',
name: 'Buzz',
relayUrl: 'https://relay.test',
sensitiveActionPolicy: SensitiveActionPolicy.enabled,
pushLeaseInstallationId: 'a' * 32,
starterSetupIncomplete: true,
addedAt: DateTime.utc(2026, 8, 5),
);
final roundTrip = Community.fromJson(community.toJson());
expect(roundTrip.sensitiveActionPolicy, SensitiveActionPolicy.enabled);
expect(roundTrip.starterSetupIncomplete, isTrue);
expect(roundTrip.pushLeaseInstallationId, 'a' * 32);
});
for (final enabled in [true, false]) {
test('saved push preference $enabled survives loading and copying', () {
final community = Community.fromJson({
'id': 'one',
'name': 'Buzz',
'relayUrl': 'https://relay.test',
'pushNotificationsEnabled': enabled,
'addedAt': '2026-08-05T00:00:00.000Z',
});
expect(community.pushNotificationsEnabled, enabled);
expect(
community.copyWith(name: 'Renamed').pushNotificationsEnabled,
enabled,
);
expect(
Community.fromJson(community.toJson()).pushNotificationsEnabled,
enabled,
);
expect(
community.pushSubscriptionState.pendingTombstoneGeneration,
isNull,
);
});
}
test('malformed stored push lease address id is rejected', () {
expect(
() => Community.fromJson({
'id': 'one',
'name': 'Buzz',
'relayUrl': 'https://relay.test',
'pushLeaseInstallationId': 'not-canonical',
'addedAt': '2026-08-05T00:00:00.000Z',
}),
throwsFormatException,
);
});
}