MotorSignal-App/test/social_screens_widget_test....

242 lines
7.4 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:motorcycle_dash/features/records/records_service.dart';
import 'package:motorcycle_dash/features/social/friends_screen.dart';
import 'package:motorcycle_dash/features/social/rider_profile_screen.dart';
import 'package:motorcycle_dash/services/auth/auth_providers.dart';
import 'package:motorcycle_dash/services/auth/auth_service.dart';
import 'package:motorcycle_dash/services/auth/auth_state.dart';
import 'package:motorcycle_dash/services/auth/auth_user.dart';
import 'package:motorcycle_dash/services/social/rider_profile_models.dart';
import 'package:motorcycle_dash/services/social/social_providers.dart';
import 'package:shared_preferences/shared_preferences.dart';
class _FakeAuth implements AuthService {
@override Future<void> ensureBackendIdentity() async {}
final _states = StreamController<AuthState>.broadcast();
AuthUser? user;
_FakeAuth({this.user});
@override
Stream<AuthState> get authStateChanges => _states.stream;
@override
AuthState get currentState => user == null
? const AuthState.unauthenticated(isFirebaseConfigured: true)
: (user!.isAnonymous
? AuthState.anonymous(user!, isFirebaseConfigured: true)
: AuthState.authenticated(user!, isFirebaseConfigured: true));
@override
AuthUser? get currentUser => user;
@override
bool get isConfigured => true;
@override
bool get isEmailVerified => true;
@override
Future<void> deleteCurrentUser() async {}
@override
void dispose() => _states.close();
@override
Future<String?> getIdToken([bool forceRefresh = false]) async => 'token';
@override
Future<void> reauthenticate({String? password}) async {}
@override
Future<void> reloadCurrentUser() async {}
@override
Future<void> sendEmailVerification() async {}
@override
Future<void> sendPasswordResetEmail(String email) async {}
@override
Future<void> signInAnonymously() async {}
@override
Future<void> signInWithEmailAndPassword(String email, String password) async {}
@override
Future<void> createUserWithEmailAndPassword(String email, String password,
{String? displayName}) async {}
@override
Future<void> signInWithGoogle() async {}
@override
Future<void> signOut() async {}
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
late SharedPreferences prefs;
setUp(() async {
SharedPreferences.setMockInitialValues({});
prefs = await SharedPreferences.getInstance();
});
Widget buildTestable(Widget child, List<Override> overrides) {
return ProviderScope(
overrides: [
sharedPreferencesProvider.overrideWithValue(prefs),
...overrides,
],
child: MaterialApp(home: child),
);
}
group('RiderProfileScreen Widget Tests', () {
testWidgets('shows account required notice when signed out', (tester) async {
final fakeAuth = _FakeAuth(user: null);
await tester.pumpWidget(
buildTestable(
const RiderProfileScreen(),
[authServiceProvider.overrideWithValue(fakeAuth)],
),
);
await tester.pumpAndSettle();
expect(find.text('MOTORCLOUD ACCOUNT REQUIRED'), findsOneWidget);
expect(find.text('SIGN IN OR REGISTER'), findsOneWidget);
});
testWidgets('renders profile form and privacy controls when authenticated', (tester) async {
final user = const AuthUser(
uid: 'pilot_1',
email: 'pilot@example.com',
displayName: 'Test Pilot',
);
final fakeAuth = _FakeAuth(user: user);
final existingProfile = RiderProfile(
uid: 'pilot_1',
handle: 'test_pilot',
displayName: 'Test Pilot',
bio: 'Speed and curves.',
region: 'Tail of the Dragon',
avatarPreset: 'helmet_cyan',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
await tester.pumpWidget(
buildTestable(
const RiderProfileScreen(),
[
authServiceProvider.overrideWithValue(fakeAuth),
myRiderProfileProvider.overrideWith((ref) => Stream.value(existingProfile)),
],
),
);
await tester.pumpAndSettle();
expect(find.text('Rider Profile'), findsOneWidget);
expect(find.text('@test_pilot'), findsWidgets);
expect(find.text('Test Pilot'), findsWidgets);
expect(find.text('Speed and curves.'), findsWidgets);
expect(find.text('Tail of the Dragon'), findsWidgets);
// Privacy switches
expect(find.text('PRIVACY CONTROLS'), findsOneWidget);
expect(find.text('Discoverable by Handle'), findsOneWidget);
expect(find.text('Public Profile'), findsOneWidget);
expect(find.text('Allow Friend Requests'), findsOneWidget);
// Save button
expect(find.text('SAVE PROFILE'), findsOneWidget);
});
});
group('FriendsScreen Widget Tests', () {
testWidgets('shows account required notice when signed out', (tester) async {
final fakeAuth = _FakeAuth(user: null);
await tester.pumpWidget(
buildTestable(
const FriendsScreen(),
[authServiceProvider.overrideWithValue(fakeAuth)],
),
);
await tester.pumpAndSettle();
expect(find.text('MOTORCLOUD ACCOUNT REQUIRED'), findsOneWidget);
});
testWidgets('renders tabs and empty states when authenticated', (tester) async {
final user = const AuthUser(
uid: 'rider_1',
email: 'rider@example.com',
displayName: 'Rider One',
);
final fakeAuth = _FakeAuth(user: user);
await tester.pumpWidget(
buildTestable(
const FriendsScreen(),
[
authServiceProvider.overrideWithValue(fakeAuth),
myFriendsProvider.overrideWith((ref) => Stream.value([])),
myIncomingRequestsProvider.overrideWith((ref) => Stream.value([])),
myOutgoingRequestsProvider.overrideWith((ref) => Stream.value([])),
],
),
);
await tester.pumpAndSettle();
expect(find.text('FRIENDS (0)'), findsOneWidget);
expect(find.text('REQUESTS'), findsOneWidget);
expect(find.text('FIND RIDERS'), findsNWidgets(2));
expect(find.text('NO FRIENDS ADDED YET'), findsOneWidget);
});
testWidgets('displays friend item with action menu', (tester) async {
final user = const AuthUser(
uid: 'rider_1',
email: 'rider@example.com',
displayName: 'Rider One',
);
final fakeAuth = _FakeAuth(user: user);
final friendsList = [
FriendSummary(
uid: 'friend_99',
handle: 'corner_carver',
displayName: 'Corner Carver',
avatarPreset: 'tach_neon',
friendedAt: DateTime.now(),
),
];
await tester.pumpWidget(
buildTestable(
const FriendsScreen(),
[
authServiceProvider.overrideWithValue(fakeAuth),
myFriendsProvider.overrideWith((ref) => Stream.value(friendsList)),
myIncomingRequestsProvider.overrideWith((ref) => Stream.value([])),
myOutgoingRequestsProvider.overrideWith((ref) => Stream.value([])),
],
),
);
await tester.pumpAndSettle();
expect(find.text('FRIENDS (1)'), findsOneWidget);
expect(find.text('Corner Carver'), findsOneWidget);
expect(find.text('@corner_carver'), findsOneWidget);
});
});
}