import 'package:flutter_test/flutter_test.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/shared/tools/sc_cp_relation_level_utils.dart'; import 'package:yumi/shared/tools/sc_cp_relation_pair_utils.dart'; void main() { group('scCpRelationTypeBetweenProfiles', () { test('detects cp relation from either adjacent profile', () { final left = SocialChatUserProfile( id: '100', account: 'left', cpList: [ CPRes( meUserId: '100', meAccount: 'left', cpUserId: '200', cpAccount: 'right', relationType: 'CP', levelText: 'Lv.3 Sweet', ), ], ); final right = SocialChatUserProfile(id: '200', account: 'right'); expect(scCpRelationTypeBetweenProfiles(left, right), 'CP'); expect(scCpRelationTypeBetweenProfiles(right, left), 'CP'); expect(scCpRelationInfoBetweenProfiles(left, right)?.cpLevel, 3); }); test('detects brother and sister close-friend relations', () { final brotherLeft = SocialChatUserProfile( id: '100', closeFriendList: [ CPRes(meUserId: '100', cpUserId: '200', relationType: 'bro'), ], ); final brotherRight = SocialChatUserProfile(id: '200'); final sisterLeft = SocialChatUserProfile(id: '300'); final sisterRight = SocialChatUserProfile( id: '400', closeFriendList: [ CPRes(meUserId: '300', cpUserId: '400', relationType: 'sis'), ], ); expect( scCpRelationTypeBetweenProfiles(brotherLeft, brotherRight), 'BROTHER', ); expect( scCpRelationTypeBetweenProfiles(sisterLeft, sisterRight), 'SISTERS', ); }); test('detects close-friend relation aliases parsed from payload', () { final left = SocialChatUserProfile(id: '300'); final right = SocialChatUserProfile( id: '400', closeFriendList: [ CPRes.fromJson({ 'meUserId': '300', 'cpUserId': '400', 'cpRelationType': 'sis', }), ], ); expect(scCpRelationTypeBetweenProfiles(left, right), 'SISTERS'); }); test('does not match unrelated profiles', () { final left = SocialChatUserProfile( id: '100', cpList: [CPRes(meUserId: '100', cpUserId: '200', relationType: 'CP')], ); final right = SocialChatUserProfile(id: '300'); expect(scCpRelationTypeBetweenProfiles(left, right), isNull); }); test('ignores inactive relation payloads', () { final left = SocialChatUserProfile( id: '100', cpList: [ CPRes( meUserId: '100', cpUserId: '200', relationType: 'CP', status: 'DISMISSED', ), ], ); final right = SocialChatUserProfile(id: '200'); expect(scCpRelationTypeBetweenProfiles(left, right), isNull); }); test('relation version changes when cp level or value changes', () { final base = SocialChatUserProfile( id: '100', cpList: [ CPRes( meUserId: '100', cpUserId: '200', relationType: 'CP', levelText: 'Lv.1', cpValue: 90, ), ], ); final upgraded = base.copyWith( cpList: [ CPRes( meUserId: '100', cpUserId: '200', relationType: 'CP', levelText: 'Lv.2', cpValue: 120, ), ], ); expect( scCpProfileRelationVersion(base), isNot(scCpProfileRelationVersion(upgraded)), ); }); }); group('scCpRelationLevelTextFromCabin', () { test('uses cp value and config thresholds for current level text', () { final cabin = SCCpCabinRes( cpVal: 1200, cpCabinConfigCO: const [ {'level': 1, 'levelName': 'Simple Love', 'requiredCpValue': 0}, {'level': 2, 'levelName': 'Sweet Love', 'requiredCpValue': 1000}, {'level': 3, 'levelName': 'Deep Love', 'requiredCpValue': 3000}, ], currentCpCabinConfigCO: const {'level': 1, 'levelName': 'Simple Love'}, ); expect(scCpRelationLevelTextFromCabin(cabin), 'Lv.2 Sweet Love'); }); test('keeps zero value relation at level zero', () { final cabin = SCCpCabinRes( cpVal: 0, currentCpCabinConfigCO: const {'level': 5, 'levelName': 'Soulmate'}, ); expect(scCpRelationLevelTextFromCabin(cabin), 'Lv.0'); }); test( 'supports zero based CP levels and hides hardcoded simple love copy', () { expect(scCpRelationLevelIndex('Lv.0'), 0); expect(scCpRelationLevelDisplayText(null), 'Lv.0'); expect(scCpRelationLevelDisplayText('Lv.1 Simple Love'), 'Lv.1'); final cabin = SCCpCabinRes( cpVal: 0, cpCabinConfigCO: const [ {'level': 0, 'levelName': 'Start', 'requiredCpValue': 0}, {'level': 1, 'levelName': 'Simple Love', 'requiredCpValue': 100}, ], ); expect(scCpRelationLevelTextFromCabin(cabin), 'Lv.0 Start'); final levelOneCabin = SCCpCabinRes( cpVal: 100, cpCabinConfigCO: const [ {'level': 0, 'levelName': 'Start', 'requiredCpValue': 0}, {'level': 1, 'levelName': 'Simple Love', 'requiredCpValue': 100}, ], ); expect(scCpRelationLevelTextFromCabin(levelOneCabin), 'Lv.1'); }, ); test('does not infer cp level from unrelated digits', () { expect(scCpRelationLevelIndexOrNull('520 Couple'), isNull); expect(scCpRelationLevelIndexOrNull('Lv.5 Soulmate'), 5); expect(scCpRelationLevelIndexOrNull('5'), 5); }); test('does not parse generic relation name as level text', () { final relation = CPRes.fromJson({ 'meUserId': '100', 'cpUserId': '200', 'relationType': 'CP', 'name': '520 Couple', }); expect(relation.levelText, isNull); }); }); }