import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:yumi/services/audio/rtc_manager.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/shared/business_logic/models/res/mic_res.dart'; import 'package:yumi/shared/business_logic/models/res/sc_mic_go_up_res.dart' as mic_go_up; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; void main() { test('self go-up keeps optimistic mic seat over stale mic list data', () { SharedPreferences.setMockInitialValues({}); AccountStorage().setCurrentUser( SocialChatLoginRes( userProfile: SocialChatUserProfile(id: 'user-1', userNickname: 'Me'), ), ); final rtcProvider = RealTimeCommunicationManager() ..roomWheatMap = { 3: MicRes( micIndex: 3, user: SocialChatUserProfile(id: 'user-1', userNickname: 'Me'), ), }; rtcProvider.debugStartSelfMicGoUpGuard(3); rtcProvider.debugApplyMicListSnapshot([ MicRes(micIndex: 3), ], notifyIfUnchanged: false); expect(rtcProvider.roomWheatMap[3]?.user?.id, 'user-1'); expect(rtcProvider.isOnMai(), isTrue); }); test('self mic detection matches account when mic user id is missing', () { SharedPreferences.setMockInitialValues({}); AccountStorage().setCurrentUser( SocialChatLoginRes( userProfile: SocialChatUserProfile( id: 'user-1', account: '8826517', userNickname: 'Me', ), ), ); final rtcProvider = RealTimeCommunicationManager() ..roomWheatMap = { 2: MicRes( micIndex: 2, user: SocialChatUserProfile(account: '8826517'), ), }; expect(rtcProvider.isOnMai(), isTrue); expect(rtcProvider.isOnMaiInIndex(2), isTrue); expect(rtcProvider.userOnMaiInIndex('user-1'), 2); }); test('self go-up uses response user when local profile is unavailable', () { SharedPreferences.setMockInitialValues({}); final rtcProvider = RealTimeCommunicationManager()..roomWheatMap = {4: MicRes(micIndex: 4)}; rtcProvider.debugApplySelfMicGoUpResponse( targetIndex: 4, micGoUpRes: mic_go_up.SCMicGoUpRes( micIndex: 4, micMute: false, micLock: false, roomToken: 'token', user: mic_go_up.User( id: 'user-android', account: 'android-account', userNickname: 'Android User', ), ), ); expect(rtcProvider.isOnMai(), isTrue); expect(rtcProvider.isOnMaiInIndex(4), isTrue); expect(rtcProvider.roomWheatMap[4]?.user?.id, 'user-android'); expect(rtcProvider.roomWheatMap[4]?.user?.account, 'android-account'); }); test('self go-up prefers response identity over stale local profile', () { SharedPreferences.setMockInitialValues({}); AccountStorage().setCurrentUser( SocialChatLoginRes( userProfile: SocialChatUserProfile( id: 'stale-local-id', account: 'stale-local-account', userNickname: 'Me', ), ), ); final rtcProvider = RealTimeCommunicationManager()..roomWheatMap = {5: MicRes(micIndex: 5)}; rtcProvider.debugApplySelfMicGoUpResponse( localUser: AccountStorage().getCurrentUser()?.userProfile, targetIndex: 5, micGoUpRes: mic_go_up.SCMicGoUpRes( micIndex: 5, micMute: false, user: mic_go_up.User( id: 'server-seat-id', account: 'server-seat-account', userNickname: 'Server User', ), ), ); expect(rtcProvider.isOnMai(), isTrue); expect(rtcProvider.isOnMaiInIndex(5), isTrue); expect(rtcProvider.roomWheatMap[5]?.user?.id, 'server-seat-id'); expect(rtcProvider.roomWheatMap[5]?.user?.account, 'server-seat-account'); }); test('self mic state follows microphone list snapshots', () { SharedPreferences.setMockInitialValues({}); AccountStorage().setCurrentUser( SocialChatLoginRes( userProfile: SocialChatUserProfile(id: 'user-1', userNickname: 'Me'), ), ); final rtcProvider = RealTimeCommunicationManager(); rtcProvider.debugApplyMicListSnapshot([ MicRes( micIndex: 2, user: SocialChatUserProfile(id: 'user-1', userNickname: 'Me'), ), ], notifyIfUnchanged: false); expect(rtcProvider.isOnMai(), isTrue); rtcProvider.debugApplyMicListSnapshot([ MicRes(micIndex: 2), ], notifyIfUnchanged: false); expect(rtcProvider.isOnMai(), isFalse); }); }