Files
buzz/mobile/test/features/onboarding/community_link_input_test.dart
Matt Toohey 46cdc52d23 test(mobile): lock in invite-page and bare-host community link entry (#9047)
Both mobile community-link fields (Add community and the
welcome/onboarding "Enter a community link" page) already accept a typed
or pasted `https://<host>/invite/<code>` link and keep the code. They
also read a bare host as `wss://`. This PR adds regression coverage for
both. **It doesn't change any production code.**

Companion: block/buzz-app#2412 fixes the same two inputs in buzz-app's
Join a community.

## What's covered

- **`community_link_input_test.dart`**
- The address loop is now an input → relay table, with two new rows:
`secondary.example` and `relay.example.com:8443` (the port is kept).
- The invite case now uses `https://primary.example/invite/fixture`, and
expects relay `wss://primary.example` with code `fixture`.
- Two new rejected inputs: `ws://secondary.example`, and the invite path
with a trailing slash, which the relay doesn't serve.
- **`onboarding_entry_routes_test.dart`**: before the bare-host step,
the journey pastes the invite link into the Add route's field. It
expects the app-level `InviteJoinSheet` to show host `primary.example`
and code `fixture`.

## Shown to catch a regression

I removed the invite/add-community short-circuit in
`parseCommunityLinkInput`. Both the invite unit case and the new journey
step then failed.

## Not in this PR

Two parser differences are left for a separate decision, along with the
tests that depend on them:
- `buzz://connect?relay=…`: mobile rejects it in the fields and silently
drops it as an OS link, but buzz-app, desktop and the web repo browser's
Connect button all use it.
- An invite-page link with a query string: mobile accepts it and throws
the query away, but buzz-app rejects it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 09:49:51 +11:00

50 lines
1.8 KiB
Dart

import 'package:buzz/shared/deeplink/community_link_input.dart';
import 'package:buzz/shared/deeplink/deep_link.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('normalizes addresses through the existing community parser', () {
for (final (value, relay) in [
(' team.communities.buzz.xyz ', 'wss://team.communities.buzz.xyz'),
('https://team.communities.buzz.xyz/', 'wss://team.communities.buzz.xyz'),
('wss://team.communities.buzz.xyz', 'wss://team.communities.buzz.xyz'),
('secondary.example', 'wss://secondary.example'),
('relay.example.com:8443', 'wss://relay.example.com:8443'),
]) {
final uri = parseCommunityLinkInput(value)!;
final link = parseBuzzDeepLink(uri) as AddCommunityDeepLink;
expect(link.relayUrl, relay, reason: value);
}
});
test('preserves the invite and its destination', () {
final uri = parseCommunityLinkInput(
'https://primary.example/invite/fixture',
)!;
final link = parseBuzzDeepLink(uri) as InviteDeepLink;
expect(link.code, 'fixture');
expect(link.relayUrl, 'wss://primary.example');
});
test('rejects unrelated actions and unsafe or incomplete addresses', () {
for (final value in [
'',
'not a link',
'http://community.example.com',
'ws://secondary.example',
'https://user:secret@community.example.com',
'https://community.example.com/other',
'https://community.example.com/invite/',
'https://primary.example/invite/fixture/',
'https://community.example.com#secret',
'https://community.example.com?token=secret',
'https://127.0.0.1',
'https://community.example.com.',
'buzz://channel/580ca78b-9dae-46f3-8854-bd671853ba32',
'nostrpair://example',
]) {
expect(parseCommunityLinkInput(value), isNull, reason: value);
}
});
}