@@ -376,8 +376,9 @@ def answer(prompt: str) -> str:
376376 assert sys .stdout is not sys .stderr
377377 assert prompts == ["Enter a codex32 string:\n > " ] * 2
378378 assert rejected not in captured .out
379- assert "Rejected: Use either all uppercase or all lowercase letters." in captured .err
380- assert "Rejected: Use either all uppercase or all lowercase letters.\n \n " in captured .err
379+ assert (
380+ "Rejected: A codex32 string is all uppercase or all lowercase; either case recovers the same wallet.\n \n "
381+ ) in captured .err
381382 assert captured .err .endswith ("\n \n " )
382383
383384
@@ -1760,6 +1761,33 @@ def test_cli_rejects_sixteen_consecutive_erasures_as_outside_regular_bound() ->
17601761 assert "No valid correction found" in result .stderr
17611762
17621763
1764+ _UPPER_SECRET = VECTOR_1 ["secret_s" ].upper ()
1765+
1766+
1767+ @pytest .mark .parametrize (
1768+ ("damaged" , "reason" ),
1769+ (
1770+ (_UPPER_SECRET [:- 1 ] + "w" , "A codex32 string is all uppercase or all lowercase;" ),
1771+ (
1772+ _UPPER_SECRET [:3 ] + "A" + _UPPER_SECRET [4 :],
1773+ "The threshold must be 0 or a number from 2 through 9;" ,
1774+ ),
1775+ (
1776+ _UPPER_SECRET [:8 ] + "A" + _UPPER_SECRET [9 :],
1777+ "An unshared secret (threshold 0) must use S as its index." ,
1778+ ),
1779+ (_UPPER_SECRET [:12 ] + "B" + _UPPER_SECRET [13 :], "The character 'b' is not allowed" ),
1780+ (_UPPER_SECRET [:20 ] + "Q" + _UPPER_SECRET [20 :], "This input has 49 characters." ),
1781+ ),
1782+ )
1783+ def test_correct_says_why_the_input_was_invalid (damaged : str , reason : str ) -> None :
1784+ result = _invoke (["correct" ], damaged )
1785+
1786+ assert result .exit_code == 1
1787+ assert result .stderr .startswith (f"Invalid: { reason } " )
1788+ assert result .stderr .endswith (f"{ _UPPER_SECRET } \n " )
1789+
1790+
17631791def test_correct_rejects_malformed_immutable_hrp_as_usage () -> None :
17641792 damaged = "é" + VECTOR_1 ["secret_s" ][1 :]
17651793
@@ -2537,8 +2565,11 @@ def test_operational_candidate_whole_card_confirmation(monkeypatch, capsys, resp
25372565 monkeypatch .setattr (module , "_editable_input" , lambda prompt : prompts .append (prompt ) or response )
25382566 monkeypatch .setattr (module .sys .stderr , "isatty" , lambda : True )
25392567 candidate = CorrectionCandidate (artifact , (), 1 , 0 , 0 , None , capture_space_bits = 65 )
2540- assert module ._confirm_correction (candidate , [], False , _FakeBitcoinCore ().fingerprint ) is accepted
2568+ reason = "The checksum does not match."
2569+ fingerprint = _FakeBitcoinCore ().fingerprint
2570+ assert module ._confirm_correction (candidate , [], False , reason , fingerprint ) is accepted
25412571 output = capsys .readouterr ().err
2572+ assert output .startswith (f"Invalid: { reason } \n Possible correction:\n \n " )
25422573 assert "Master fingerprint: 3F3521A6\n \n " in output
25432574 assert module ._card_text (artifact .text ) in output
25442575 assert "> " not in output
@@ -2556,12 +2587,12 @@ def test_final_share_preview_is_isolated_and_basis_has_no_preview(monkeypatch, c
25562587 accepted = [first ]
25572588 monkeypatch .setattr (module .sys , "stdin" , _TTYInput ())
25582589 monkeypatch .setattr (module , "_editable_input" , lambda prompt : "n" )
2559- assert not module ._confirm_correction (candidate , accepted , False , _FakeBitcoinCore ().fingerprint )
2590+ assert not module ._confirm_correction (candidate , accepted , False , "" , _FakeBitcoinCore ().fingerprint )
25602591 assert accepted == [first ]
25612592 assert "Master fingerprint: FAB6868A\n \n " in capsys .readouterr ().err
2562- assert not module ._confirm_correction (candidate , accepted , True , _FakeBitcoinCore ().fingerprint )
2593+ assert not module ._confirm_correction (candidate , accepted , True , "" , _FakeBitcoinCore ().fingerprint )
25632594 assert "Master fingerprint" not in capsys .readouterr ().err
2564- assert not module ._confirm_correction (candidate , [], False , _FakeBitcoinCore ().fingerprint )
2595+ assert not module ._confirm_correction (candidate , [], False , "" , _FakeBitcoinCore ().fingerprint )
25652596 assert "Master fingerprint" not in capsys .readouterr ().err
25662597
25672598
@@ -2576,7 +2607,7 @@ def fail(seed):
25762607 candidate = CorrectionCandidate (
25772608 parse_codex32 (VECTOR_1 ["secret_s" ]), (), 1 , 0 , 0 , None , capture_space_bits = 65
25782609 )
2579- assert not module ._confirm_correction (candidate , [], False , fail )
2610+ assert not module ._confirm_correction (candidate , [], False , "" , fail )
25802611 assert "Could not recover a valid Bitcoin master seed using this correction." in capsys .readouterr ().err
25812612
25822613
0 commit comments