@@ -587,7 +587,7 @@ describe('AccountTreeController', () => {
587
587
type : AccountGroupType . SingleAccount ,
588
588
accounts : [ MOCK_SNAP_ACCOUNT_2 . id ] ,
589
589
metadata : {
590
- name : 'Account 1' , // Updated: per-wallet numbering (different wallet)
590
+ name : 'Snap Account 1' , // Updated: per-wallet numbering (different wallet)
591
591
pinned : false ,
592
592
hidden : false ,
593
593
} ,
@@ -610,7 +610,7 @@ describe('AccountTreeController', () => {
610
610
type : AccountGroupType . SingleAccount ,
611
611
accounts : [ MOCK_HARDWARE_ACCOUNT_1 . id ] ,
612
612
metadata : {
613
- name : 'Account 1' , // Updated: per-wallet numbering (different wallet)
613
+ name : 'Ledger Account 1' , // Updated: per-wallet numbering (different wallet)
614
614
pinned : false ,
615
615
hidden : false ,
616
616
} ,
@@ -652,13 +652,13 @@ describe('AccountTreeController', () => {
652
652
} ,
653
653
[ expectedKeyringWalletIdGroup ] : {
654
654
name : {
655
- value : 'Account 1' , // Updated: per-wallet numbering (different wallet)
655
+ value : 'Ledger Account 1' , // Updated: per-wallet numbering (different wallet)
656
656
lastUpdatedAt : expect . any ( Number ) ,
657
657
} ,
658
658
} ,
659
659
[ expectedSnapWalletIdGroup ] : {
660
660
name : {
661
- value : 'Account 1' , // Updated: per-wallet numbering (different wallet)
661
+ value : 'Snap Account 1' , // Updated: per-wallet numbering (different wallet)
662
662
lastUpdatedAt : expect . any ( Number ) ,
663
663
} ,
664
664
} ,
@@ -2902,9 +2902,9 @@ describe('AccountTreeController', () => {
2902
2902
// Critical assertion: should have 2 unique names (no duplicates)
2903
2903
expect ( uniqueNames . size ) . toBe ( 2 ) ;
2904
2904
2905
- // Due to optimization, names start at wallet.length, so we get "Account 1 " and "Account 2 "
2906
- expect ( allNames ) . toContain ( 'Account 1' ) ;
2907
- expect ( allNames ) . toContain ( 'Account 2' ) ;
2905
+ // Due to optimization, names start at wallet.length, so we get "Account 3 " and "Account 4 "
2906
+ expect ( allNames ) . toContain ( 'Ledger Account 1' ) ;
2907
+ expect ( allNames ) . toContain ( 'Ledger Account 2' ) ;
2908
2908
2909
2909
// Verify they're actually different
2910
2910
expect ( group1 . metadata . name ) . not . toBe ( group2 . metadata . name ) ;
@@ -4033,4 +4033,219 @@ describe('AccountTreeController', () => {
4033
4033
) . toBe ( 'Conflict Name (2)' ) ;
4034
4034
} ) ;
4035
4035
} ) ;
4036
+
4037
+ describe ( 'naming' , ( ) => {
4038
+ const mockAccount1 = {
4039
+ ...MOCK_HARDWARE_ACCOUNT_1 ,
4040
+ id : 'mock-id-1' ,
4041
+ address : '0x123' ,
4042
+ } ;
4043
+ const mockAccount2 = {
4044
+ ...MOCK_HARDWARE_ACCOUNT_1 ,
4045
+ id : 'mock-id-2' ,
4046
+ address : '0x456' ,
4047
+ } ;
4048
+ const mockAccount3 = {
4049
+ ...MOCK_HARDWARE_ACCOUNT_1 ,
4050
+ id : 'mock-id-3' ,
4051
+ address : '0x789' ,
4052
+ } ;
4053
+ const mockAccount4 = {
4054
+ ...MOCK_HARDWARE_ACCOUNT_1 ,
4055
+ id : 'mock-id-4' ,
4056
+ address : '0xabc' ,
4057
+ } ;
4058
+
4059
+ const mockWalletId = toAccountWalletId (
4060
+ AccountWalletType . Keyring ,
4061
+ KeyringTypes . ledger ,
4062
+ ) ;
4063
+
4064
+ const getAccountGroupFromAccount = (
4065
+ controller : AccountTreeController ,
4066
+ mockAccount : InternalAccount ,
4067
+ ) => {
4068
+ const groupId = toAccountGroupId ( mockWalletId , mockAccount . address ) ;
4069
+ return controller . state . accountTree . wallets [ mockWalletId ] . groups [ groupId ] ;
4070
+ } ;
4071
+
4072
+ it ( 'names non-HD keyrings accounts properly' , ( ) => {
4073
+ const { controller, messenger } = setup ( ) ;
4074
+
4075
+ // Add all 3 accounts.
4076
+ [ mockAccount1 , mockAccount2 , mockAccount3 ] . forEach (
4077
+ ( mockAccount , index ) => {
4078
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount ) ;
4079
+
4080
+ const mockGroup = getAccountGroupFromAccount ( controller , mockAccount ) ;
4081
+ expect ( mockGroup ) . toBeDefined ( ) ;
4082
+ expect ( mockGroup . metadata . name ) . toBe ( `Ledger Account ${ index + 1 } ` ) ;
4083
+ } ,
4084
+ ) ;
4085
+
4086
+ // Remove account 2, should still create account 4 afterward.
4087
+ messenger . publish ( 'AccountsController:accountRemoved' , mockAccount2 . id ) ;
4088
+
4089
+ expect (
4090
+ getAccountGroupFromAccount ( controller , mockAccount4 ) ,
4091
+ ) . toBeUndefined ( ) ;
4092
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount4 ) ;
4093
+
4094
+ const mockGroup4 = getAccountGroupFromAccount ( controller , mockAccount4 ) ;
4095
+ expect ( mockGroup4 ) . toBeDefined ( ) ;
4096
+ expect ( mockGroup4 . metadata . name ) . toBe ( 'Ledger Account 4' ) ;
4097
+
4098
+ // Now, removing account 3 and 4, should defaults to an index of "2" (since only
4099
+ // account 1 remains), thus, re-inserting account 2, should be named "* Account 2".
4100
+ messenger . publish ( 'AccountsController:accountRemoved' , mockAccount4 . id ) ;
4101
+ messenger . publish ( 'AccountsController:accountRemoved' , mockAccount3 . id ) ;
4102
+
4103
+ expect (
4104
+ getAccountGroupFromAccount ( controller , mockAccount2 ) ,
4105
+ ) . toBeUndefined ( ) ;
4106
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount2 ) ;
4107
+
4108
+ const mockGroup2 = getAccountGroupFromAccount ( controller , mockAccount2 ) ;
4109
+ expect ( mockGroup2 ) . toBeDefined ( ) ;
4110
+ expect ( mockGroup2 . metadata . name ) . toBe ( 'Ledger Account 2' ) ;
4111
+ } ) ;
4112
+
4113
+ it ( 'ignores bad account group name pattern and fallback to natural indexing' , ( ) => {
4114
+ const { controller, messenger } = setup ( {
4115
+ accounts : [ mockAccount1 ] ,
4116
+ } ) ;
4117
+
4118
+ controller . init ( ) ;
4119
+
4120
+ const mockGroup1 = getAccountGroupFromAccount ( controller , mockAccount1 ) ;
4121
+ expect ( mockGroup1 ) . toBeDefined ( ) ;
4122
+
4123
+ const mockIndex = 90 ;
4124
+ controller . setAccountGroupName (
4125
+ mockGroup1 . id ,
4126
+ `Account${ mockIndex } ` , // No space, so this should fallback to natural indexing
4127
+ ) ;
4128
+
4129
+ // The first account has a non-matching pattern, thus we should fallback to the next
4130
+ // natural index.
4131
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount2 ) ;
4132
+ const mockGroup2 = getAccountGroupFromAccount ( controller , mockAccount2 ) ;
4133
+ expect ( mockGroup2 ) . toBeDefined ( ) ;
4134
+ expect ( mockGroup2 . metadata . name ) . toBe ( `Ledger Account 2` ) ; // Natural indexing.
4135
+ } ) ;
4136
+
4137
+ it . each ( [
4138
+ [ 'Account' , 'account' ] ,
4139
+ [ 'Account' , 'aCCount' ] ,
4140
+ [ 'Account' , 'accOunT' ] ,
4141
+ [ ' ' , ' ' ] ,
4142
+ [ ' ' , '\t' ] ,
4143
+ [ ' ' , ' \t' ] ,
4144
+ [ ' ' , '\t ' ] ,
4145
+ ] ) (
4146
+ 'ignores case (case-insensitive) and spaces when extracting highest index: "$0" -> "$1"' ,
4147
+ ( toReplace , replaced ) => {
4148
+ const { controller, messenger } = setup ( {
4149
+ accounts : [ mockAccount1 ] ,
4150
+ } ) ;
4151
+
4152
+ controller . init ( ) ;
4153
+
4154
+ const mockGroup1 = getAccountGroupFromAccount ( controller , mockAccount1 ) ;
4155
+ expect ( mockGroup1 ) . toBeDefined ( ) ;
4156
+
4157
+ const mockIndex = 90 ;
4158
+ controller . setAccountGroupName (
4159
+ mockGroup1 . id ,
4160
+ mockGroup1 . metadata . name
4161
+ . replace ( toReplace , replaced )
4162
+ . replace ( '1' , `${ mockIndex } ` ) , // Use index different than 1.
4163
+ ) ;
4164
+
4165
+ // Even if the account is not strictly named "Ledger Account 90", we should be able
4166
+ // to compute the next index from there.
4167
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount2 ) ;
4168
+ const mockGroup2 = getAccountGroupFromAccount ( controller , mockAccount2 ) ;
4169
+ expect ( mockGroup2 ) . toBeDefined ( ) ;
4170
+ expect ( mockGroup2 . metadata . name ) . toBe (
4171
+ `Ledger Account ${ mockIndex + 1 } ` ,
4172
+ ) ;
4173
+ } ,
4174
+ ) ;
4175
+
4176
+ it . each ( [ ' ' , ' ' , '\t' , ' \t' ] ) (
4177
+ 'extract name indexes and ignore multiple spaces: "%s"' ,
4178
+ ( space ) => {
4179
+ const { controller, messenger } = setup ( {
4180
+ accounts : [ mockAccount1 ] ,
4181
+ } ) ;
4182
+
4183
+ controller . init ( ) ;
4184
+
4185
+ const mockGroup1 = getAccountGroupFromAccount ( controller , mockAccount1 ) ;
4186
+ expect ( mockGroup1 ) . toBeDefined ( ) ;
4187
+
4188
+ const mockIndex = 90 ;
4189
+ controller . setAccountGroupName (
4190
+ mockGroup1 . id ,
4191
+ mockGroup1 . metadata . name
4192
+ . replace ( ' ' , space )
4193
+ . replace ( '1' , `${ mockIndex } ` ) , // Use index different than 1.
4194
+ ) ;
4195
+
4196
+ // Even if the account is not strictly named "Ledger Account 90", we should be able
4197
+ // to compute the next index from there.
4198
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount2 ) ;
4199
+ const mockGroup2 = getAccountGroupFromAccount ( controller , mockAccount2 ) ;
4200
+ expect ( mockGroup2 ) . toBeDefined ( ) ;
4201
+ expect ( mockGroup2 . metadata . name ) . toBe (
4202
+ `Ledger Account ${ mockIndex + 1 } ` ,
4203
+ ) ;
4204
+ } ,
4205
+ ) ;
4206
+
4207
+ it ( 'uses natural indexing for pre-existing accounts' , ( ) => {
4208
+ const { controller } = setup ( {
4209
+ accounts : [ mockAccount1 , mockAccount2 , mockAccount3 ] ,
4210
+ } ) ;
4211
+
4212
+ controller . init ( ) ;
4213
+
4214
+ // After initializing the controller, all accounts should be named appropriately.
4215
+ [ mockAccount1 , mockAccount2 , mockAccount3 ] . forEach (
4216
+ ( mockAccount , index ) => {
4217
+ const mockGroup = getAccountGroupFromAccount ( controller , mockAccount ) ;
4218
+ expect ( mockGroup ) . toBeDefined ( ) ;
4219
+ expect ( mockGroup . metadata . name ) . toBe ( `Ledger Account ${ index + 1 } ` ) ;
4220
+ } ,
4221
+ ) ;
4222
+ } ) ;
4223
+
4224
+ it ( 'fallbacks to natural indexing if group names are not using our default name pattern' , ( ) => {
4225
+ const { controller, messenger } = setup ( ) ;
4226
+
4227
+ [ mockAccount1 , mockAccount2 , mockAccount3 ] . forEach ( ( mockAccount ) =>
4228
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount ) ,
4229
+ ) ;
4230
+
4231
+ const mockGroup1 = getAccountGroupFromAccount ( controller , mockAccount1 ) ;
4232
+ const mockGroup2 = getAccountGroupFromAccount ( controller , mockAccount2 ) ;
4233
+ const mockGroup3 = getAccountGroupFromAccount ( controller , mockAccount3 ) ;
4234
+ expect ( mockGroup1 ) . toBeDefined ( ) ;
4235
+ expect ( mockGroup2 ) . toBeDefined ( ) ;
4236
+ expect ( mockGroup3 ) . toBeDefined ( ) ;
4237
+
4238
+ // Rename all accounts to something different than "* Account <index>".
4239
+ controller . setAccountGroupName ( mockGroup1 . id , 'Account A' ) ;
4240
+ controller . setAccountGroupName ( mockGroup2 . id , 'The next account' ) ;
4241
+ controller . setAccountGroupName ( mockGroup3 . id , 'Best account so far' ) ;
4242
+
4243
+ // Adding a new account should not reset back to "Account 1", but it should
4244
+ // use the next natural index, here, "Account 4".
4245
+ messenger . publish ( 'AccountsController:accountAdded' , mockAccount4 ) ;
4246
+ const mockGroup4 = getAccountGroupFromAccount ( controller , mockAccount4 ) ;
4247
+ expect ( mockGroup4 ) . toBeDefined ( ) ;
4248
+ expect ( mockGroup4 . metadata . name ) . toBe ( 'Ledger Account 4' ) ;
4249
+ } ) ;
4250
+ } ) ;
4036
4251
} ) ;
0 commit comments