@@ -12,18 +12,38 @@ import (
1212 "gorm.io/gorm"
1313)
1414
15+ // model without -:migration, used to simulate a legacy database where
16+ // AutoMigrate created the private_key column
17+ type legacyActor struct {
18+ ID string `gorm:"primaryKey;size:15"`
19+ Address string `gorm:"index"`
20+ PrivateKey string
21+ }
22+
23+ func (legacyActor ) TableName () string { return "actors" }
24+
25+ // simulates a legacy database by running AutoMigrate with the old model
26+ // that includes private_key as a normal column
27+ func addLegacyColumn (t * testing.T , db * gorm.DB ) {
28+ t .Helper ()
29+ require .NoError (t , db .AutoMigrate (& legacyActor {}))
30+ }
31+
32+ // inserts an actor with a legacy private_key via the legacy model
33+ func createLegacyActor (t * testing.T , db * gorm.DB , id , address , privateKey string ) {
34+ t .Helper ()
35+ require .NoError (t , db .Create (& legacyActor {
36+ ID : id , Address : address , PrivateKey : privateKey ,
37+ }).Error )
38+ }
39+
1540func TestExportKeysHandler_ExportsActorKey (t * testing.T ) {
1641 testutil .All (t , func (ctx context.Context , t * testing.T , db * gorm.DB ) {
1742 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
1843 require .NoError (t , err )
1944
20- // create an actor with a legacy private key
21- actor := model.Actor {
22- ID : "f01234" ,
23- Address : testutil .TestWalletAddr ,
24- PrivateKey : testutil .TestPrivateKeyHex ,
25- }
26- require .NoError (t , db .Create (& actor ).Error )
45+ addLegacyColumn (t , db )
46+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
2747
2848 result , err := ExportKeysHandler (ctx , db , ks )
2949 require .NoError (t , err )
@@ -50,13 +70,8 @@ func TestExportKeysHandler_SkipsExistingWallet(t *testing.T) {
5070 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
5171 require .NoError (t , err )
5272
53- // create actor with legacy key
54- actor := model.Actor {
55- ID : "f01234" ,
56- Address : testutil .TestWalletAddr ,
57- PrivateKey : testutil .TestPrivateKeyHex ,
58- }
59- require .NoError (t , db .Create (& actor ).Error )
73+ addLegacyColumn (t , db )
74+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
6075
6176 // pre-import the wallet via normal import path
6277 h := DefaultHandler {}
@@ -83,13 +98,8 @@ func TestExportKeysHandler_SkipsExistingWalletLinksActor(t *testing.T) {
8398 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
8499 require .NoError (t , err )
85100
86- // create actor with legacy key
87- actor := model.Actor {
88- ID : "f01234" ,
89- Address : testutil .TestWalletAddr ,
90- PrivateKey : testutil .TestPrivateKeyHex ,
91- }
92- require .NoError (t , db .Create (& actor ).Error )
101+ addLegacyColumn (t , db )
102+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
93103
94104 // pre-import the wallet WITHOUT actor linkage
95105 h := DefaultHandler {}
@@ -116,12 +126,8 @@ func TestExportKeysHandler_Idempotent(t *testing.T) {
116126 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
117127 require .NoError (t , err )
118128
119- actor := model.Actor {
120- ID : "f01234" ,
121- Address : testutil .TestWalletAddr ,
122- PrivateKey : testutil .TestPrivateKeyHex ,
123- }
124- require .NoError (t , db .Create (& actor ).Error )
129+ addLegacyColumn (t , db )
130+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
125131
126132 // first run exports
127133 r1 , err := ExportKeysHandler (ctx , db , ks )
@@ -146,12 +152,12 @@ func TestExportKeysHandler_NoActorsWithKeys(t *testing.T) {
146152 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
147153 require .NoError (t , err )
148154
155+ addLegacyColumn (t , db )
149156 // actor with no private key
150- actor := model.Actor {
157+ require . NoError ( t , db . Create ( & model.Actor {
151158 ID : "f09999" ,
152159 Address : "f1abc" ,
153- }
154- require .NoError (t , db .Create (& actor ).Error )
160+ }).Error )
155161
156162 result , err := ExportKeysHandler (ctx , db , ks )
157163 require .NoError (t , err )
@@ -166,13 +172,8 @@ func TestExportKeysHandler_InvalidKeyRecordsError(t *testing.T) {
166172 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
167173 require .NoError (t , err )
168174
169- // actor with garbage key
170- actor := model.Actor {
171- ID : "f05555" ,
172- Address : "f1bad" ,
173- PrivateKey : "not-a-valid-key" ,
174- }
175- require .NoError (t , db .Create (& actor ).Error )
175+ addLegacyColumn (t , db )
176+ createLegacyActor (t , db , "f05555" , "f1bad" , "not-a-valid-key" )
176177
177178 result , err := ExportKeysHandler (ctx , db , ks )
178179 require .NoError (t , err ) // overall operation succeeds
@@ -189,13 +190,8 @@ func TestExportKeysHandler_MissingKeyFile(t *testing.T) {
189190 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
190191 require .NoError (t , err )
191192
192- // create actor with legacy key
193- actor := model.Actor {
194- ID : "f01234" ,
195- Address : testutil .TestWalletAddr ,
196- PrivateKey : testutil .TestPrivateKeyHex ,
197- }
198- require .NoError (t , db .Create (& actor ).Error )
193+ addLegacyColumn (t , db )
194+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
199195
200196 // create wallet record pointing to a nonexistent key file
201197 require .NoError (t , db .Create (& model.Wallet {
@@ -219,12 +215,8 @@ func TestExportKeysHandler_CorruptKeyFile(t *testing.T) {
219215 ks , err := keystore .NewLocalKeyStore (dir )
220216 require .NoError (t , err )
221217
222- actor := model.Actor {
223- ID : "f01234" ,
224- Address : testutil .TestWalletAddr ,
225- PrivateKey : testutil .TestPrivateKeyHex ,
226- }
227- require .NoError (t , db .Create (& actor ).Error )
218+ addLegacyColumn (t , db )
219+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
228220
229221 // write garbage to the key file path
230222 corruptPath := dir + "/corrupt"
@@ -245,17 +237,22 @@ func TestExportKeysHandler_CorruptKeyFile(t *testing.T) {
245237 })
246238}
247239
248- func TestDropPrivateKeyColumn (t * testing.T ) {
240+ func TestExportKeysHandler_AutoMigrateDoesNotRecreateColumn (t * testing.T ) {
249241 testutil .All (t , func (ctx context.Context , t * testing.T , db * gorm.DB ) {
250- // column exists after AutoMigrate
251- require .True (t , db .Migrator ().HasColumn (& model.Actor {}, "private_key" ))
242+ // AutoMigrate already ran (via testutil.All) -- column should NOT exist
243+ require .False (t , db .Migrator ().HasColumn (& model.Actor {}, "private_key" ),
244+ "AutoMigrate must not create private_key column (gorm:-:migration)" )
252245
253- // drop it
246+ // simulate legacy db, export, drop
247+ addLegacyColumn (t , db )
248+ require .True (t , HasPrivateKeyColumn (db ))
254249 require .NoError (t , DropPrivateKeyColumn (db ))
255- require .False (t , db . Migrator (). HasColumn ( & model. Actor {}, "private_key" ))
250+ require .False (t , HasPrivateKeyColumn ( db ))
256251
257- // idempotent -- second call is a no-op
258- require .NoError (t , DropPrivateKeyColumn (db ))
252+ // re-run AutoMigrate -- must NOT re-add the column
253+ require .NoError (t , model .AutoMigrate (db ))
254+ require .False (t , HasPrivateKeyColumn (db ),
255+ "AutoMigrate must not re-add private_key column after drop" )
259256 })
260257}
261258
@@ -264,13 +261,8 @@ func TestDropPrivateKeyColumn_ExportThenDrop(t *testing.T) {
264261 ks , err := keystore .NewLocalKeyStore (t .TempDir ())
265262 require .NoError (t , err )
266263
267- // create actor with legacy key
268- actor := model.Actor {
269- ID : "f01234" ,
270- Address : testutil .TestWalletAddr ,
271- PrivateKey : testutil .TestPrivateKeyHex ,
272- }
273- require .NoError (t , db .Create (& actor ).Error )
264+ addLegacyColumn (t , db )
265+ createLegacyActor (t , db , "f01234" , testutil .TestWalletAddr , testutil .TestPrivateKeyHex )
274266
275267 // export
276268 result , err := ExportKeysHandler (ctx , db , ks )
0 commit comments