diff --git a/lib/core/router/app_router.dart b/lib/core/router/app_router.dart index d1edbc8..2825274 100644 --- a/lib/core/router/app_router.dart +++ b/lib/core/router/app_router.dart @@ -477,13 +477,27 @@ class AppRouter { pageBuilder: (context, state) => _page(context, state, const ProfileScreen()), routes: [ GoRoute( - path: 'view', + path: ':actor', pageBuilder: (context, state) => _page( context, state, - ProfileScreen(actor: state.uri.queryParameters['actor'], showBackButton: true), + ProfileScreen( + actor: Uri.decodeComponent(state.pathParameters['actor'] ?? ''), + showBackButton: true, + ), ), ), + GoRoute( + path: 'view', + redirect: (_, state) { + final rawActor = state.uri.queryParameters['actor']?.trim() ?? ''; + if (rawActor.isEmpty) { + return '/profile'; + } + final normalizedActor = rawActor.startsWith('@') ? rawActor.substring(1) : rawActor; + return '/profile/${Uri.encodeComponent(normalizedActor)}'; + }, + ), ], ), ], diff --git a/lib/core/router/in_app_link_resolver.dart b/lib/core/router/in_app_link_resolver.dart index 847f321..73b580a 100644 --- a/lib/core/router/in_app_link_resolver.dart +++ b/lib/core/router/in_app_link_resolver.dart @@ -47,7 +47,7 @@ class InAppLinkResolver { } if (collection == 'app.bsky.actor.profile') { - return '/profile/view?actor=${Uri.encodeQueryComponent(actor)}'; + return '/profile/${Uri.encodeComponent(actor)}'; } return null; @@ -73,6 +73,6 @@ class InAppLinkResolver { return '/post?uri=${Uri.encodeQueryComponent(atUri)}'; } - return '/profile/view?actor=${Uri.encodeQueryComponent(actor)}'; + return '/profile/${Uri.encodeComponent(actor)}'; } } diff --git a/lib/features/feed/bloc/feed_bloc.dart b/lib/features/feed/bloc/feed_bloc.dart index 35d7e53..0c89f55 100644 --- a/lib/features/feed/bloc/feed_bloc.dart +++ b/lib/features/feed/bloc/feed_bloc.dart @@ -35,7 +35,7 @@ class FeedBloc extends Bloc { ), ); } catch (error) { - emit(FeedState.error('Failed to load feed: $error')); + emit(FeedState.error('Failed to load feed: $error', actor: event.actor, filter: event.filter)); } } diff --git a/lib/features/feed/bloc/feed_state.dart b/lib/features/feed/bloc/feed_state.dart index 502cb2e..e634e71 100644 --- a/lib/features/feed/bloc/feed_state.dart +++ b/lib/features/feed/bloc/feed_state.dart @@ -28,7 +28,8 @@ class FeedState extends Equatable { bool hasMore = true, }) : this._(status: FeedStatus.loaded, actor: actor, posts: posts, cursor: cursor, filter: filter, hasMore: hasMore); - const FeedState.error(String message) : this._(status: FeedStatus.error, errorMessage: message); + const FeedState.error(String message, {String? actor, FeedFilter filter = FeedFilter.postsAndAuthorThreads}) + : this._(status: FeedStatus.error, actor: actor, errorMessage: message, filter: filter, hasMore: false); static const Object _unset = Object(); diff --git a/lib/features/feed/presentation/home_feed_screen.dart b/lib/features/feed/presentation/home_feed_screen.dart index 078a130..093381d 100644 --- a/lib/features/feed/presentation/home_feed_screen.dart +++ b/lib/features/feed/presentation/home_feed_screen.dart @@ -250,7 +250,7 @@ class _FeedListViewState extends State<_FeedListView> with AutomaticKeepAliveCli final List _posts = []; String? _cursor; bool _isLoading = false; - bool _showInitialLoading = false; + bool _showInitialLoading = true; bool _isLoadingMore = false; bool _hasError = false; String? _errorMessage; @@ -294,6 +294,7 @@ class _FeedListViewState extends State<_FeedListView> with AutomaticKeepAliveCli _cursor = cachedResult.cursor; _hasError = false; _errorMessage = null; + _showInitialLoading = false; }); } diff --git a/lib/features/profile/presentation/profile_screen.dart b/lib/features/profile/presentation/profile_screen.dart index 430dbdd..525f929 100644 --- a/lib/features/profile/presentation/profile_screen.dart +++ b/lib/features/profile/presentation/profile_screen.dart @@ -80,6 +80,8 @@ class _ProfileScreenState extends State with TickerProviderStateM int? _headerTrackingPointer; double _headerPullDistance = 0; bool _headerRefreshInFlight = false; + String? _lastScheduledProfileActorLoad; + String? _lastScheduledFeedLoadKey; @override void initState() { @@ -116,7 +118,103 @@ class _ProfileScreenState extends State with TickerProviderStateM String? get _resolvedActor { final authState = context.read().state; if (!authState.isAuthenticated) return null; - return widget.actor ?? authState.tokens?.did; + final rawActor = widget.actor ?? authState.tokens?.did; + if (rawActor == null) { + return null; + } + + final normalizedActor = _normalizeActor(rawActor); + return normalizedActor.isEmpty ? null : normalizedActor; + } + + String _normalizeActor(String actor) { + final trimmed = actor.trim(); + if (trimmed.startsWith('@')) { + return trimmed.substring(1); + } + return trimmed; + } + + String _canonicalActorForCompare(String actor) => _normalizeActor(actor).toLowerCase(); + + bool _profileMatchesExpectedActor(ProfileViewDetailed? profile, String expectedActor) { + if (profile == null) { + return false; + } + + final expected = _canonicalActorForCompare(expectedActor); + return _canonicalActorForCompare(profile.did) == expected || _canonicalActorForCompare(profile.handle) == expected; + } + + bool _feedMatchesExpectedActor(FeedState feedState, String expectedActor, ProfileViewDetailed? profile) { + final stateActor = feedState.actor; + if (stateActor == null) { + return false; + } + + final normalizedStateActor = _canonicalActorForCompare(stateActor); + final normalizedExpectedActor = _canonicalActorForCompare(expectedActor); + if (normalizedStateActor == normalizedExpectedActor) { + return true; + } + + if (profile != null) { + return normalizedStateActor == _canonicalActorForCompare(profile.did) || + normalizedStateActor == _canonicalActorForCompare(profile.handle); + } + + return false; + } + + void _scheduleProfileLoadIfNeeded(String actor, ProfileState profileState) { + if (_profileMatchesExpectedActor(profileState.profile, actor)) { + _lastScheduledProfileActorLoad = null; + return; + } + + if (profileState.status == ProfileStatus.loading) { + return; + } + + if (_lastScheduledProfileActorLoad == actor) { + return; + } + + _lastScheduledProfileActorLoad = actor; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) { + return; + } + context.read().add(ProfileLoadRequested(actor: actor)); + }); + } + + void _scheduleFeedLoadIfNeeded(String actor, FeedFilter filter, FeedState feedState, ProfileViewDetailed? profile) { + if (feedState.status == FeedStatus.loading && + feedState.filter == filter && + _feedMatchesExpectedActor(feedState, actor, profile)) { + return; + } + + if (feedState.status == FeedStatus.loaded && + feedState.filter == filter && + _feedMatchesExpectedActor(feedState, actor, profile)) { + _lastScheduledFeedLoadKey = null; + return; + } + + final requestKey = '$actor|${filter.name}'; + if (_lastScheduledFeedLoadKey == requestKey) { + return; + } + + _lastScheduledFeedLoadKey = requestKey; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) { + return; + } + context.read().add(FeedLoadRequested(actor: actor, filter: filter)); + }); } List get _tabLabels => @@ -234,10 +332,19 @@ class _ProfileScreenState extends State with TickerProviderStateM return BlocBuilder( builder: (context, feedState) { final profile = profileState.profile; + final expectedActor = _resolvedActor; + final profileMatchesExpectedActor = expectedActor == null + ? true + : _profileMatchesExpectedActor(profile, expectedActor); + if (expectedActor != null) { + _scheduleProfileLoadIfNeeded(expectedActor, profileState); + _scheduleFeedLoadIfNeeded(expectedActor, _currentFilter, feedState, profile); + } + final currentUserDid = context.read().state.tokens?.did; final isOwnProfile = profile?.did == currentUserDid; final tabChildren = [ - ..._feedTabs.map((t) => _buildFeedList(feedState, t.filter, profile)), + ..._feedTabs.map((t) => _buildFeedList(feedState, t.filter, profile, expectedActor)), _buildListsTab(context, profile), _buildStarterPacksTab(context, profile), if (_showSuggestedTab) _buildSuggestedFollowsTab(profile), @@ -298,6 +405,10 @@ class _ProfileScreenState extends State with TickerProviderStateM child: Center(child: CircularProgressIndicator()), ), ProfileStatus.error => _buildProfileError(context, profileState.errorMessage), + _ when !profileMatchesExpectedActor => const Padding( + padding: AppInsets.allLg, + child: Center(child: CircularProgressIndicator()), + ), _ => _buildProfileSummary(context, profile, isOwnProfile), }, ), @@ -815,13 +926,43 @@ class _ProfileScreenState extends State with TickerProviderStateM ); } - Widget _buildFeedList(FeedState feedState, FeedFilter tabFilter, ProfileViewDetailed? profile) { + Widget _buildFeedList( + FeedState feedState, + FeedFilter tabFilter, + ProfileViewDetailed? profile, + String? expectedActor, + ) { + final isActiveTab = tabFilter == _currentFilter; + final feedMatchesExpectedActor = expectedActor == null + ? true + : _feedMatchesExpectedActor(feedState, expectedActor, profile); + + if (expectedActor != null && isActiveTab && !feedMatchesExpectedActor) { + return const Center(child: CircularProgressIndicator()); + } + + if (isActiveTab && feedState.status == FeedStatus.initial) { + return const Center(child: CircularProgressIndicator()); + } + if (feedState.isLoading && feedState.filter == tabFilter) { return const Center(child: CircularProgressIndicator()); } - if (feedState.hasError && feedState.filter == tabFilter) { - return Center(child: Text(feedState.errorMessage ?? 'Failed to load posts')); + if (feedState.hasError && feedState.filter == tabFilter && feedMatchesExpectedActor) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(feedState.errorMessage ?? 'Failed to load posts'), + const SizedBox(height: 12), + FilledButton( + onPressed: () => _loadProfileAndFeed(filter: tabFilter), + child: const Text('Retry'), + ), + ], + ), + ); } if (feedState.filter != tabFilter) { diff --git a/lib/shared/presentation/helpers/navigation_helpers.dart b/lib/shared/presentation/helpers/navigation_helpers.dart index 27fd4c9..5b93fc4 100644 --- a/lib/shared/presentation/helpers/navigation_helpers.dart +++ b/lib/shared/presentation/helpers/navigation_helpers.dart @@ -11,7 +11,13 @@ Future? navigateToProfile(BuildContext context, String actorDid) { return null; } - final location = '/profile/view?actor=${Uri.encodeQueryComponent(actorDid)}'; + final actor = actorDid.trim(); + if (actor.isEmpty) { + return null; + } + + final normalizedActor = actor.startsWith('@') ? actor.substring(1) : actor; + final location = '/profile/${Uri.encodeComponent(normalizedActor)}'; final currentPath = _currentPath(context); if (!_isStatefulShellPath(currentPath)) { diff --git a/test/core/router/in_app_link_resolver_test.dart b/test/core/router/in_app_link_resolver_test.dart index 6f55a1e..3caca67 100644 --- a/test/core/router/in_app_link_resolver_test.dart +++ b/test/core/router/in_app_link_resolver_test.dart @@ -6,7 +6,7 @@ void main() { test('resolves bsky profile URL to in-app profile route', () { final route = InAppLinkResolver.resolveRoute('https://bsky.app/profile/alice.bsky.social'); - expect(route, '/profile/view?actor=alice.bsky.social'); + expect(route, '/profile/alice.bsky.social'); }); test('resolves bsky post URL to in-app post route', () { @@ -24,7 +24,7 @@ void main() { test('resolves at:// profile URI to in-app profile route', () { final route = InAppLinkResolver.resolveRoute('at://did:plc:alice/app.bsky.actor.profile/self'); - expect(route, '/profile/view?actor=did%3Aplc%3Aalice'); + expect(route, '/profile/did%3Aplc%3Aalice'); }); test('returns null for unsupported hosts and malformed values', () { diff --git a/test/features/feed/presentation/grid_post_card_test.dart b/test/features/feed/presentation/grid_post_card_test.dart index dfebbf1..d2e0bde 100644 --- a/test/features/feed/presentation/grid_post_card_test.dart +++ b/test/features/feed/presentation/grid_post_card_test.dart @@ -232,7 +232,7 @@ void main() { ), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { pushedRoute = state.uri.toString(); return const Scaffold(body: Text('profile')); diff --git a/test/features/feed/presentation/post_card_test.dart b/test/features/feed/presentation/post_card_test.dart index 5766202..fddca5b 100644 --- a/test/features/feed/presentation/post_card_test.dart +++ b/test/features/feed/presentation/post_card_test.dart @@ -184,7 +184,7 @@ void main() { builder: (context, state) => Scaffold(body: PostCard(feedViewPost: post)), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { pushedRoute = state.uri.toString(); return const Scaffold(body: Text('profile')); @@ -200,7 +200,7 @@ void main() { await tester.pumpAndSettle(); expect(pushedRoute, isNotNull); - expect(Uri.parse(pushedRoute!).path, '/profile/view'); + expect(Uri.parse(pushedRoute!).path, '/profile/alice.bsky.social'); expect(fakeUrlLauncher.launchedUrls, isEmpty); }); @@ -420,7 +420,7 @@ void main() { builder: (context, state) => Scaffold(body: PostCard(feedViewPost: post)), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { pushedRoute = state.uri.toString(); return const Scaffold(body: Text('profile')); diff --git a/test/features/feed/presentation/widgets/facet_text_test.dart b/test/features/feed/presentation/widgets/facet_text_test.dart index 5cc5327..a32b8b4 100644 --- a/test/features/feed/presentation/widgets/facet_text_test.dart +++ b/test/features/feed/presentation/widgets/facet_text_test.dart @@ -76,7 +76,7 @@ void main() { builder: (context, state) => const Scaffold(body: FacetText(text: text)), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { pushed = state.uri.toString(); return const Scaffold(body: Text('profile')); @@ -92,8 +92,7 @@ void main() { await tester.pumpAndSettle(); expect(pushed, isNotNull); - expect(Uri.parse(pushed!).path, '/profile/view'); - expect(Uri.parse(pushed!).queryParameters['actor'], 'alice.bsky.social'); + expect(Uri.parse(pushed!).path, '/profile/alice.bsky.social'); }); testWidgets('at:// post URI routes in-app to post thread', (tester) async { diff --git a/test/features/notifications/presentation/widgets/notification_list_item_test.dart b/test/features/notifications/presentation/widgets/notification_list_item_test.dart index 1c3f8f0..5c9bbd0 100644 --- a/test/features/notifications/presentation/widgets/notification_list_item_test.dart +++ b/test/features/notifications/presentation/widgets/notification_list_item_test.dart @@ -32,7 +32,7 @@ void main() { builder: (context, state) => Scaffold(body: NotificationListItem(notification: notification)), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { pushedRoute = state.uri.toString(); return const Scaffold(body: Text('profile')); @@ -48,7 +48,7 @@ void main() { await tester.pumpAndSettle(); expect(pushedRoute, isNotNull); - expect(Uri.parse(pushedRoute!).path, '/profile/view'); + expect(Uri.parse(pushedRoute!).path, '/profile/${Uri.encodeComponent('did:plc:author')}'); }); testWidgets('like notification uses reasonSubject to navigate to post', (tester) async { diff --git a/test/features/profile/presentation/follow_audit_screen_test.dart b/test/features/profile/presentation/follow_audit_screen_test.dart index 2312730..4291731 100644 --- a/test/features/profile/presentation/follow_audit_screen_test.dart +++ b/test/features/profile/presentation/follow_audit_screen_test.dart @@ -45,8 +45,8 @@ Widget _buildRoutedSubject(MockFollowAuditCubit cubit) { BlocProvider.value(value: cubit, child: const FollowAuditScreen()), ), GoRoute( - path: '/profile/view', - builder: (context, state) => Scaffold(body: Text('profile:${state.uri.queryParameters['actor'] ?? ''}')), + path: '/profile/:actor', + builder: (context, state) => Scaffold(body: Text('profile:${state.pathParameters['actor'] ?? ''}')), ), ], ); diff --git a/test/features/profile/presentation/profile_context_screen_test.dart b/test/features/profile/presentation/profile_context_screen_test.dart index 3ce18e7..f2e74dd 100644 --- a/test/features/profile/presentation/profile_context_screen_test.dart +++ b/test/features/profile/presentation/profile_context_screen_test.dart @@ -73,8 +73,8 @@ void main() { ), routes: [ GoRoute( - path: 'profile/view', - builder: (context, state) => Scaffold(body: Text('Profile View ${state.uri.queryParameters['actor']}')), + path: 'profile/:actor', + builder: (context, state) => Scaffold(body: Text('Profile View ${state.pathParameters['actor']}')), ), GoRoute( path: 'list', @@ -148,7 +148,7 @@ void main() { expect(find.text('User did:plc:user2'), findsOneWidget); }); - testWidgets('profile tile navigates to /profile/view on tap', (tester) async { + testWidgets('profile tile navigates to /profile/:actor on tap', (tester) async { final profiles = [_profile('did:plc:user1')]; final state = initialState().copyWith( blockedByStatus: ProfileContextTabStatus.loaded, @@ -352,7 +352,7 @@ void main() { verify(() => cubit.loadBlocking()).called(greaterThanOrEqualTo(1)); }); - testWidgets('profile tile navigates to /profile/view on tap', (tester) async { + testWidgets('profile tile navigates to /profile/:actor on tap', (tester) async { final profiles = [_profile('did:plc:blocked1')]; final state = const ProfileContextState.initial( did: _did, diff --git a/test/features/profile/presentation/profile_screen_test.dart b/test/features/profile/presentation/profile_screen_test.dart index 8047f66..aee421d 100644 --- a/test/features/profile/presentation/profile_screen_test.dart +++ b/test/features/profile/presentation/profile_screen_test.dart @@ -254,6 +254,19 @@ void main() { const Stream.empty(), initialState: const ProfileState.loaded(profile: otherProfile), ); + when(() => feedBloc.state).thenReturn( + const FeedState.loaded(actor: 'did:plc:other', posts: [], filter: FeedFilter.postsNoReplies, hasMore: false), + ); + whenListen( + feedBloc, + const Stream.empty(), + initialState: const FeedState.loaded( + actor: 'did:plc:other', + posts: [], + filter: FeedFilter.postsNoReplies, + hasMore: false, + ), + ); when(() => profileRepository.getSuggestedFollows('did:plc:other')).thenAnswer((_) async => suggestions); await tester.pumpWidget( @@ -298,6 +311,19 @@ void main() { const Stream.empty(), initialState: const ProfileState.loaded(profile: otherProfile), ); + when(() => feedBloc.state).thenReturn( + const FeedState.loaded(actor: 'did:plc:other', posts: [], filter: FeedFilter.postsNoReplies, hasMore: false), + ); + whenListen( + feedBloc, + const Stream.empty(), + initialState: const FeedState.loaded( + actor: 'did:plc:other', + posts: [], + filter: FeedFilter.postsNoReplies, + hasMore: false, + ), + ); final mockProfileActionRepository = MockProfileActionRepository(); final router = GoRouter( @@ -683,6 +709,19 @@ void main() { const Stream.empty(), initialState: const ProfileState.loaded(profile: otherProfile), ); + when(() => feedBloc.state).thenReturn( + const FeedState.loaded(actor: 'did:plc:other', posts: [], filter: FeedFilter.postsNoReplies, hasMore: false), + ); + whenListen( + feedBloc, + const Stream.empty(), + initialState: const FeedState.loaded( + actor: 'did:plc:other', + posts: [], + filter: FeedFilter.postsNoReplies, + hasMore: false, + ), + ); final mockProfileActionRepository = MockProfileActionRepository(); @@ -725,6 +764,19 @@ void main() { const Stream.empty(), initialState: const ProfileState.loaded(profile: otherProfile), ); + when(() => feedBloc.state).thenReturn( + const FeedState.loaded(actor: 'did:plc:other', posts: [], filter: FeedFilter.postsNoReplies, hasMore: false), + ); + whenListen( + feedBloc, + const Stream.empty(), + initialState: const FeedState.loaded( + actor: 'did:plc:other', + posts: [], + filter: FeedFilter.postsNoReplies, + hasMore: false, + ), + ); final mockProfileActionRepository = MockProfileActionRepository(); diff --git a/test/features/profile/presentation/widgets/suggested_follows_sheet_test.dart b/test/features/profile/presentation/widgets/suggested_follows_sheet_test.dart index 3ffcd40..30d6d38 100644 --- a/test/features/profile/presentation/widgets/suggested_follows_sheet_test.dart +++ b/test/features/profile/presentation/widgets/suggested_follows_sheet_test.dart @@ -41,8 +41,8 @@ void main() { ), routes: [ GoRoute( - path: 'profile/view', - builder: (context, state) => Scaffold(body: Text('Profile View ${state.uri.queryParameters['actor']}')), + path: 'profile/:actor', + builder: (context, state) => Scaffold(body: Text('Profile View ${state.pathParameters['actor']}')), ), ], ), @@ -147,7 +147,7 @@ void main() { expect(find.text('Following'), findsOneWidget); }); - testWidgets('tapping a suggestion navigates to /profile/view', (tester) async { + testWidgets('tapping a suggestion navigates to /profile/:actor', (tester) async { final profiles = [_profile('did:plc:bob', displayName: 'Bob Builder')]; when(() => cubit.state).thenReturn(SuggestedFollowsState.loaded(profiles)); whenListen( diff --git a/test/features/search/presentation/hashtag_screen_test.dart b/test/features/search/presentation/hashtag_screen_test.dart index 2840ceb..60b16c1 100644 --- a/test/features/search/presentation/hashtag_screen_test.dart +++ b/test/features/search/presentation/hashtag_screen_test.dart @@ -46,8 +46,8 @@ void main() { }, ), GoRoute( - path: '/profile/view', - builder: (context, state) => Scaffold(body: Text('profile:${state.uri.queryParameters['actor']}')), + path: '/profile/:actor', + builder: (context, state) => Scaffold(body: Text('profile:${state.pathParameters['actor']}')), ), GoRoute( path: '/post', diff --git a/test/features/search/presentation/search_screen_test.dart b/test/features/search/presentation/search_screen_test.dart index cf91312..4e4cd9a 100644 --- a/test/features/search/presentation/search_screen_test.dart +++ b/test/features/search/presentation/search_screen_test.dart @@ -148,8 +148,8 @@ void main() { ), ), GoRoute( - path: '/profile/view', - builder: (context, state) => Scaffold(body: Text('profile:${state.uri.queryParameters['actor']}')), + path: '/profile/:actor', + builder: (context, state) => Scaffold(body: Text('profile:${state.pathParameters['actor']}')), ), GoRoute( path: '/feeds', diff --git a/test/features/settings/presentation/settings_screen_test.dart b/test/features/settings/presentation/settings_screen_test.dart index de984a8..46a4e04 100644 --- a/test/features/settings/presentation/settings_screen_test.dart +++ b/test/features/settings/presentation/settings_screen_test.dart @@ -112,9 +112,13 @@ void main() { await tester.pumpWidget(buildSubject()); await tester.pumpAndSettle(); - expect(find.text('APPEARANCE'), findsOneWidget); + expect(find.text('APPEARANCE', skipOffstage: false), findsOneWidget); expect(find.text('System'), findsOneWidget); - expect(find.text('LAYOUT'), findsOneWidget); + + await tester.scrollUntilVisible(find.text('Feed Layout'), 300); + await tester.pumpAndSettle(); + + expect(find.text('LAYOUT', skipOffstage: false), findsOneWidget); expect(find.text('Feed Layout'), findsOneWidget); expect(find.text('Thread Auto-Collapse'), findsOneWidget); expect(find.text('Animations'), findsOneWidget); diff --git a/test/shared/presentation/helpers/navigation_helpers_test.dart b/test/shared/presentation/helpers/navigation_helpers_test.dart index 50d752b..250c247 100644 --- a/test/shared/presentation/helpers/navigation_helpers_test.dart +++ b/test/shared/presentation/helpers/navigation_helpers_test.dart @@ -20,7 +20,7 @@ void main() { ), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { pushedRoute = state.uri.toString(); return const Scaffold(body: Text('profile')); @@ -36,8 +36,7 @@ void main() { await tester.pumpAndSettle(); expect(pushedRoute, isNotNull); - expect(Uri.parse(pushedRoute!).path, '/profile/view'); - expect(Uri.parse(pushedRoute!).queryParameters['actor'], actorDid); + expect(Uri.parse(pushedRoute!).path, '/profile/${Uri.encodeComponent(actorDid)}'); }); testWidgets('navigateToProfile uses go from non-shell routes like /post', (tester) async { @@ -56,7 +55,7 @@ void main() { ), ), GoRoute( - path: '/profile/view', + path: '/profile/:actor', builder: (context, state) { activePath = state.uri.path; return const Scaffold(body: Text('profile')); @@ -71,7 +70,7 @@ void main() { await tester.tap(find.text('go')); await tester.pumpAndSettle(); - expect(activePath, '/profile/view'); + expect(activePath, '/profile/${Uri.encodeComponent(actorDid)}'); expect(router.canPop(), isFalse); expect(tester.takeException(), isNull); });