@@ -142,13 +142,21 @@ pub(crate) fn ensure_no_wallet_exists(
142
142
force : bool ,
143
143
mut reader : impl BufRead ,
144
144
) -> Result < ( ) > {
145
- if wallet_path. exists ( ) {
145
+ let remove_wallet = || {
146
+ if wallet_path. is_dir ( ) {
147
+ fs:: remove_dir_all ( wallet_path) . unwrap ( ) ;
148
+ } else {
149
+ fs:: remove_file ( wallet_path) . unwrap ( ) ;
150
+ }
151
+ } ;
152
+
153
+ if wallet_path. exists ( ) && fs:: metadata ( wallet_path) ?. len ( ) > 0 {
146
154
if force {
147
155
println_warning ( & format ! (
148
156
"Because the `--force` argument was supplied, the wallet at {} will be removed." ,
149
157
wallet_path. display( ) ,
150
158
) ) ;
151
- fs :: remove_file ( wallet_path ) . unwrap ( ) ;
159
+ remove_wallet ( ) ;
152
160
} else {
153
161
println_warning ( & format ! (
154
162
"There is an existing wallet at {}. \
@@ -158,7 +166,7 @@ pub(crate) fn ensure_no_wallet_exists(
158
166
let mut need_replace = String :: new ( ) ;
159
167
reader. read_line ( & mut need_replace) . unwrap ( ) ;
160
168
if need_replace. trim ( ) == "y" {
161
- fs :: remove_file ( wallet_path ) . unwrap ( ) ;
169
+ remove_wallet ( ) ;
162
170
} else {
163
171
bail ! (
164
172
"Failed to create a new wallet at {} \
@@ -174,32 +182,47 @@ pub(crate) fn ensure_no_wallet_exists(
174
182
#[ cfg( test) ]
175
183
mod tests {
176
184
use super :: * ;
177
- use crate :: utils:: test_utils:: { with_tmp_dir , TEST_MNEMONIC , TEST_PASSWORD } ;
185
+ use crate :: utils:: test_utils:: { TEST_MNEMONIC , TEST_PASSWORD } ;
178
186
// simulate input
179
187
const INPUT_NOP : & [ u8 ; 1 ] = b"\n " ;
180
188
const INPUT_YES : & [ u8 ; 2 ] = b"y\n " ;
181
189
const INPUT_NO : & [ u8 ; 2 ] = b"n\n " ;
182
190
183
- fn remove_wallet ( wallet_path : & Path ) {
184
- if wallet_path. exists ( ) {
185
- fs:: remove_file ( wallet_path) . unwrap ( ) ;
186
- }
191
+ /// Represents the possible serialized states of a wallet.
192
+ /// Used primarily for simulating wallet creation and serialization processes.
193
+ enum WalletSerializedState {
194
+ Empty ,
195
+ WithData ( String ) ,
187
196
}
188
- fn create_wallet ( wallet_path : & Path ) {
197
+
198
+ /// Simulates the serialization of a wallet to a file, optionally including dummy data.
199
+ /// Primarily used to test if checks for wallet file existence are functioning correctly.
200
+ fn serialize_wallet_to_file ( wallet_path : & Path , state : WalletSerializedState ) {
201
+ // Create the wallet file if it does not exist.
189
202
if !wallet_path. exists ( ) {
190
203
fs:: File :: create ( wallet_path) . unwrap ( ) ;
191
204
}
205
+
206
+ // Write content to the wallet file based on the specified state.
207
+ if let WalletSerializedState :: WithData ( data) = state {
208
+ fs:: write ( wallet_path, data) . unwrap ( ) ;
209
+ }
210
+ }
211
+
212
+ fn remove_wallet ( wallet_path : & Path ) {
213
+ if wallet_path. exists ( ) {
214
+ fs:: remove_file ( wallet_path) . unwrap ( ) ;
215
+ }
192
216
}
193
217
194
218
#[ test]
195
219
fn handle_absolute_path_argument ( ) {
196
- with_tmp_dir ( |tmp_dir| {
197
- let tmp_dir_abs = tmp_dir. canonicalize ( ) . unwrap ( ) ;
198
- let wallet_path = tmp_dir_abs. join ( "wallet.json" ) ;
199
- write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
200
- . unwrap ( ) ;
201
- load_wallet ( & wallet_path) . unwrap ( ) ;
202
- } )
220
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
221
+ let tmp_dir_abs = tmp_dir. path ( ) . canonicalize ( ) . unwrap ( ) ;
222
+ let wallet_path = tmp_dir_abs. join ( "wallet.json" ) ;
223
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
224
+ . unwrap ( ) ;
225
+ load_wallet ( & wallet_path) . unwrap ( ) ;
203
226
}
204
227
205
228
#[ test]
@@ -223,88 +246,113 @@ mod tests {
223
246
}
224
247
#[ test]
225
248
fn encrypt_and_save_phrase ( ) {
226
- with_tmp_dir ( |tmp_dir| {
227
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
228
- write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
229
- . unwrap ( ) ;
230
- let phrase_recovered = eth_keystore:: decrypt_key ( wallet_path, TEST_PASSWORD ) . unwrap ( ) ;
231
- let phrase = String :: from_utf8 ( phrase_recovered) . unwrap ( ) ;
232
- assert_eq ! ( phrase, TEST_MNEMONIC )
233
- } ) ;
249
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
250
+ let wallet_path = tmp_dir. path ( ) . join ( "wallet.json" ) ;
251
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
252
+ . unwrap ( ) ;
253
+ let phrase_recovered = eth_keystore:: decrypt_key ( wallet_path, TEST_PASSWORD ) . unwrap ( ) ;
254
+ let phrase = String :: from_utf8 ( phrase_recovered) . unwrap ( ) ;
255
+ assert_eq ! ( phrase, TEST_MNEMONIC )
234
256
}
235
257
236
258
#[ test]
237
259
fn write_wallet ( ) {
238
- with_tmp_dir ( |tmp_dir| {
239
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
240
- write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
241
- . unwrap ( ) ;
242
- load_wallet ( & wallet_path) . unwrap ( ) ;
243
- } )
260
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
261
+ let wallet_path = tmp_dir. path ( ) . join ( "wallet.json" ) ;
262
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
263
+ . unwrap ( ) ;
264
+ load_wallet ( & wallet_path) . unwrap ( ) ;
244
265
}
245
266
246
267
#[ test]
247
268
#[ should_panic]
248
269
fn write_wallet_to_existing_file_should_fail ( ) {
249
- with_tmp_dir ( |tmp_dir| {
250
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
251
- write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
252
- . unwrap ( ) ;
253
- write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
254
- . unwrap ( ) ;
255
- } )
270
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
271
+ let wallet_path = tmp_dir. path ( ) . join ( "wallet.json" ) ;
272
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
273
+ . unwrap ( ) ;
274
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
275
+ . unwrap ( ) ;
256
276
}
257
277
258
278
#[ test]
259
279
fn write_wallet_subdir ( ) {
260
- with_tmp_dir ( |tmp_dir| {
261
- let wallet_path = tmp_dir. join ( "path" ) . join ( "to" ) . join ( "wallet" ) ;
262
- write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
263
- . unwrap ( ) ;
264
- load_wallet ( & wallet_path) . unwrap ( ) ;
265
- } )
280
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
281
+ let wallet_path = tmp_dir. path ( ) . join ( "path" ) . join ( "to" ) . join ( "wallet.json" ) ;
282
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
283
+ . unwrap ( ) ;
284
+ load_wallet ( & wallet_path) . unwrap ( ) ;
266
285
}
267
286
268
287
#[ test]
269
288
fn test_ensure_no_wallet_exists_no_wallet ( ) {
270
- with_tmp_dir ( |tmp_dir| {
271
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
272
- remove_wallet ( & wallet_path) ;
273
- ensure_no_wallet_exists ( & wallet_path, false , & INPUT_NOP [ ..] ) . unwrap ( ) ;
274
- } ) ;
275
- }
276
-
277
- #[ test]
278
- #[ should_panic]
279
- fn test_ensure_no_wallet_exists_throws_err ( ) {
280
- with_tmp_dir ( |tmp_dir| {
281
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
282
- create_wallet ( & wallet_path) ;
283
- ensure_no_wallet_exists ( & wallet_path, false , & INPUT_NO [ ..] ) . unwrap ( ) ;
284
- } ) ;
289
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
290
+ let wallet_path = tmp_dir. path ( ) . join ( "wallet.json" ) ;
291
+ remove_wallet ( & wallet_path) ;
292
+ ensure_no_wallet_exists ( & wallet_path, false , & INPUT_NOP [ ..] ) . unwrap ( ) ;
285
293
}
286
294
287
295
#[ test]
288
296
fn test_ensure_no_wallet_exists_exists_wallet ( ) {
289
297
// case: wallet path exist without --force and input[yes]
290
- with_tmp_dir ( | tmp_dir| {
291
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
292
- create_wallet ( & wallet_path) ;
293
- ensure_no_wallet_exists ( & wallet_path, false , & INPUT_YES [ ..] ) . unwrap ( ) ;
294
- } ) ;
298
+ let tmp_dir = tempfile :: TempDir :: new ( ) . unwrap ( ) ;
299
+ let wallet_path = tmp_dir. path ( ) . join ( "wallet.json" ) ;
300
+ serialize_wallet_to_file ( & wallet_path, WalletSerializedState :: Empty ) ;
301
+ ensure_no_wallet_exists ( & wallet_path, false , & INPUT_YES [ ..] ) . unwrap ( ) ;
302
+
295
303
// case: wallet path exist with --force
296
- with_tmp_dir ( |tmp_dir| {
297
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
298
- create_wallet ( & wallet_path) ;
299
- ensure_no_wallet_exists ( & wallet_path, true , & INPUT_NOP [ ..] ) . unwrap ( ) ;
300
- } ) ;
301
- // case: wallet path exist without --force and supply a different wallet path
302
- with_tmp_dir ( |tmp_dir| {
303
- let wallet_path = tmp_dir. join ( "wallet.json" ) ;
304
- create_wallet ( & wallet_path) ;
305
- let diff_wallet_path = tmp_dir. join ( "custom-wallet.json" ) ;
306
- ensure_no_wallet_exists ( & diff_wallet_path, false , & INPUT_NOP [ ..] ) . unwrap ( ) ;
307
- } ) ;
304
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
305
+ let wallet_path = tmp_dir. path ( ) . join ( "empty_wallet.json" ) ;
306
+ serialize_wallet_to_file ( & wallet_path, WalletSerializedState :: Empty ) ;
307
+
308
+ // Empty file should not trigger the replacement prompt
309
+ ensure_no_wallet_exists ( & wallet_path, false , & INPUT_YES [ ..] ) . unwrap ( ) ;
310
+ assert ! ( wallet_path. exists( ) , "Empty file should remain untouched" ) ;
311
+ }
312
+
313
+ #[ test]
314
+ fn test_ensure_no_wallet_exists_nonempty_file ( ) {
315
+ let tmp_dir = tempfile:: TempDir :: new ( ) . unwrap ( ) ;
316
+ let wallet_path = tmp_dir. path ( ) . join ( "nonempty_wallet.json" ) ;
317
+
318
+ // Create non-empty file
319
+ serialize_wallet_to_file (
320
+ & wallet_path,
321
+ WalletSerializedState :: WithData ( "some wallet content" . to_string ( ) ) ,
322
+ ) ;
323
+
324
+ // Test with --force flag
325
+ ensure_no_wallet_exists ( & wallet_path, true , & INPUT_NO [ ..] ) . unwrap ( ) ;
326
+ assert ! (
327
+ !wallet_path. exists( ) ,
328
+ "File should be removed with --force flag"
329
+ ) ;
330
+
331
+ // Test with user confirmation (yes)
332
+ serialize_wallet_to_file (
333
+ & wallet_path,
334
+ WalletSerializedState :: WithData ( "some wallet content" . to_string ( ) ) ,
335
+ ) ;
336
+ ensure_no_wallet_exists ( & wallet_path, false , & INPUT_YES [ ..] ) . unwrap ( ) ;
337
+ assert ! (
338
+ !wallet_path. exists( ) ,
339
+ "File should be removed after user confirmation"
340
+ ) ;
341
+
342
+ // Test with user rejection (no)
343
+ serialize_wallet_to_file (
344
+ & wallet_path,
345
+ WalletSerializedState :: WithData ( "some wallet content" . to_string ( ) ) ,
346
+ ) ;
347
+ let result = ensure_no_wallet_exists ( & wallet_path, false , & INPUT_NO [ ..] ) ;
348
+ assert ! (
349
+ result. is_err( ) ,
350
+ "Should error when user rejects file removal"
351
+ ) ;
352
+ assert ! (
353
+ wallet_path. exists( ) ,
354
+ "File should remain when user rejects removal"
355
+ ) ;
308
356
}
309
357
}
310
358
@@ -316,35 +364,15 @@ pub(crate) mod test_utils {
316
364
pub ( crate ) const TEST_MNEMONIC : & str = "rapid mechanic escape victory bacon switch soda math embrace frozen novel document wait motor thrive ski addict ripple bid magnet horse merge brisk exile" ;
317
365
pub ( crate ) const TEST_PASSWORD : & str = "1234" ;
318
366
319
- /// Create a tmp folder and execute the given test function `f`
320
- pub ( crate ) fn with_tmp_dir < F > ( f : F )
321
- where
322
- F : FnOnce ( & Path ) + panic:: UnwindSafe ,
323
- {
324
- let tmp_dir_name = format ! ( "forc-wallet-test-{:x}" , rand:: random:: <u64 >( ) ) ;
325
- let tmp_dir = user_fuel_dir ( ) . join ( ".tmp" ) . join ( tmp_dir_name) ;
326
- std:: fs:: create_dir_all ( & tmp_dir) . unwrap ( ) ;
327
- let panic = panic:: catch_unwind ( || f ( & tmp_dir) ) ;
328
- std:: fs:: remove_dir_all ( & tmp_dir) . unwrap ( ) ;
329
- if let Err ( e) = panic {
330
- panic:: resume_unwind ( e) ;
331
- }
332
- }
333
-
334
- /// Saves a default test mnemonic to the disk
335
- pub ( crate ) fn save_dummy_wallet_file ( wallet_path : & Path ) {
336
- write_wallet_from_mnemonic_and_password ( wallet_path, TEST_MNEMONIC , TEST_PASSWORD ) . unwrap ( ) ;
337
- }
338
-
339
- /// The same as `with_tmp_dir`, but also provides a test wallet.
367
+ /// Creates temp dir with a temp/test wallet.
340
368
pub ( crate ) fn with_tmp_dir_and_wallet < F > ( f : F )
341
369
where
342
370
F : FnOnce ( & Path , & Path ) + panic:: UnwindSafe ,
343
371
{
344
- with_tmp_dir ( |dir| {
345
- let wallet_path = dir . join ( "wallet.json" ) ;
346
- save_dummy_wallet_file ( & wallet_path) ;
347
- f ( dir , & wallet_path ) ;
348
- } )
372
+ let tmp_dir = tempfile :: TempDir :: new ( ) . unwrap ( ) ;
373
+ let wallet_path = tmp_dir . path ( ) . join ( "wallet.json" ) ;
374
+ write_wallet_from_mnemonic_and_password ( & wallet_path, TEST_MNEMONIC , TEST_PASSWORD )
375
+ . unwrap ( ) ;
376
+ f ( tmp_dir . path ( ) , & wallet_path ) ;
349
377
}
350
378
}
0 commit comments