pashage

Yet Another Opinionated Re-engineering of the Unix Password Store
git clone https://git.instinctive.eu/pashage.git
Log | Files | Refs | README | LICENSE

commit 01e117c384689f8487df6d1f2af53840a0210b97
parent 8fb48354bcb063080abdb85c7323c5291e8de158
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Sat,  2 Nov 2024 15:49:03 +0000

List and show commands are fully covered by integrated suites
Diffstat:
Mspec/pashage_extra_spec.sh | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mspec/pass_spec.sh | 47+++++++++++++++++++++++++++++++++++++++++++++--
Mspec/usage_spec.sh | 13+++++++++++++
3 files changed, 159 insertions(+), 50 deletions(-)

diff --git a/spec/pashage_extra_spec.sh b/spec/pashage_extra_spec.sh @@ -62,10 +62,26 @@ Describe 'Integrated Command Functions' #| fluff/one.age | 3 +++ #| fluff/three.age | 5 +++++ #| fluff/two.age | 4 ++++ + #| old.gpg | 3 +++ #| shared/.age-recipients | 2 ++ #| stale.age | 3 +++ #| subdir/file.age | 2 ++ - #| 8 files changed, 23 insertions(+) + #| 9 files changed, 26 insertions(+) + } + + setup_log_bin() { %text + #|Initial setup + #| + #| extra/subdir/file.age | Bin 0 -> 33 bytes + #| fluff/.age-recipients | 2 ++ + #| fluff/one.age | Bin 0 -> 55 bytes + #| fluff/three.age | Bin 0 -> 110 bytes + #| fluff/two.age | Bin 0 -> 90 bytes + #| old.gpg | 3 +++ + #| shared/.age-recipients | 2 ++ + #| stale.age | Bin 0 -> 55 bytes + #| subdir/file.age | Bin 0 -> 33 bytes + #| 9 files changed, 7 insertions(+) } expected_log() { setup_log; } # Default log to override as needed @@ -120,6 +136,10 @@ Describe 'Integrated Command Functions' #|Recipient:master #|Recipient:myself #|:0-password + %text >"${PREFIX}/old.gpg" + #|gpgRecipient:myOldSelf + #|gpg:very-old-password + #|gpg:Username: previous-life @git -C "${PREFIX}" add . @git -C "${PREFIX}" commit -m 'Initial setup' >/dev/null @@ -306,8 +326,9 @@ Describe 'Integrated Command Functions' It 'interprets the pattern as a regular expression' expected_output() { %text #|Search pattern: ^o - #|`- (B)fluff(N) - #| `- one + #||- (B)fluff(N) + #|| `- one + #|`- (R)old(N) } When call cmd_find '^o' The status should be success @@ -410,17 +431,7 @@ Describe 'Integrated Command Functions' #| #| .gitattributes | 1 + #| 1 file changed, 1 insertion(+) - #|Initial setup - #| - #| extra/subdir/file.age | Bin 0 -> 33 bytes - #| fluff/.age-recipients | 2 ++ - #| fluff/one.age | Bin 0 -> 55 bytes - #| fluff/three.age | Bin 0 -> 110 bytes - #| fluff/two.age | Bin 0 -> 90 bytes - #| shared/.age-recipients | 2 ++ - #| stale.age | Bin 0 -> 55 bytes - #| subdir/file.age | Bin 0 -> 33 bytes - #| 8 files changed, 4 insertions(+) + setup_log_bin } The result of function check_git_log should be successful PREFIX="${SOURCE}" @@ -445,17 +456,7 @@ Describe 'Integrated Command Functions' #| #| .gitattributes | 1 + #| 1 file changed, 1 insertion(+) - #|Initial setup - #| - #| extra/subdir/file.age | Bin 0 -> 33 bytes - #| fluff/.age-recipients | 2 ++ - #| fluff/one.age | Bin 0 -> 55 bytes - #| fluff/three.age | Bin 0 -> 110 bytes - #| fluff/two.age | Bin 0 -> 90 bytes - #| shared/.age-recipients | 2 ++ - #| stale.age | Bin 0 -> 55 bytes - #| subdir/file.age | Bin 0 -> 33 bytes - #| 8 files changed, 4 insertions(+) + setup_log_bin } The result of function check_git_log should be successful End @@ -487,17 +488,7 @@ Describe 'Integrated Command Functions' #| #| .gitattributes | 1 + #| 1 file changed, 1 insertion(+) - #|Initial setup - #| - #| extra/subdir/file.age | Bin 0 -> 33 bytes - #| fluff/.age-recipients | 2 ++ - #| fluff/one.age | Bin 0 -> 55 bytes - #| fluff/three.age | Bin 0 -> 110 bytes - #| fluff/two.age | Bin 0 -> 90 bytes - #| shared/.age-recipients | 2 ++ - #| stale.age | Bin 0 -> 55 bytes - #| subdir/file.age | Bin 0 -> 33 bytes - #| 8 files changed, 4 insertions(+) + setup_log_bin } The result of function check_git_log should be successful End @@ -518,17 +509,7 @@ Describe 'Integrated Command Functions' #| #| .gitattributes | 1 + #| 1 file changed, 1 insertion(+) - #|Initial setup - #| - #| extra/subdir/file.age | Bin 0 -> 33 bytes - #| fluff/.age-recipients | 2 ++ - #| fluff/one.age | Bin 0 -> 55 bytes - #| fluff/three.age | Bin 0 -> 110 bytes - #| fluff/two.age | Bin 0 -> 90 bytes - #| shared/.age-recipients | 2 ++ - #| stale.age | Bin 0 -> 55 bytes - #| subdir/file.age | Bin 0 -> 33 bytes - #| 8 files changed, 4 insertions(+) + setup_log_bin } The result of function check_git_log should be successful End @@ -742,9 +723,81 @@ Describe 'Integrated Command Functions' End End -# Describe 'cmd_list_or_show' + Describe 'cmd_list_or_show' + SHOW=text + + It 'decrypts a GPG secret in the store' + GPG=mock-gpg + When call cmd_list_or_show old + The status should be success + The error should be blank + expected_out() { %text + #|very-old-password + #|Username: previous-life + } + The output should equal "$(expected_out)" + End + + It 'displays both list and show usage on parse error with ambiguity' + PROGRAM=prg + COMMAND=both + When run cmd_list_or_show -x + The status should equal 1 + The output should be blank + expected_err() { %text + #|Usage: prg [list] [subfolder] + #| prg [show] [--clip[=line-number],-c[line-number] | + #| --qrcode[=line-number],-q[line-number]] pass-name + } + The error should equal "$(expected_err)" + End + + It 'displays list usage on parse error with list command' + PROGRAM=prg + COMMAND=list + When run cmd_list_or_show -x + The status should equal 1 + The output should be blank + expected_err() { %text + #|Usage: prg [list] [subfolder] + } + The error should equal "$(expected_err)" + End + + It 'displays show usage on parse error with show command' + PROGRAM=prg + COMMAND=show + When run cmd_list_or_show -x + The status should equal 1 + The output should be blank + expected_err() { %text + #|Usage: prg [show] [--clip[=line-number],-c[line-number] | + #| --qrcode[=line-number],-q[line-number]] pass-name + } + The error should equal "$(expected_err)" + End + End + # Describe 'cmd_move' is not needed (covered by 'cmd_copy_move') # Describe 'cmd_random' # Describe 'cmd_usage' # Describe 'cmd_version' + + Describe 'unreachable defensive code' + # This sections breaks the end-to-end scheme of this file + # to reach full coverage, by precisely identifying unreachable lines + # written for defensive programming against internal inconsistencies. + + It 'includes invalid values of SHOW in do_show' + SHOW='invalid' + When run do_show + The status should equal 1 + The output should be blank + expected_err() { %text + #|Usage: prg [show] [--clip[=line-number],-c[line-number] | + #| --qrcode[=line-number],-q[line-number]] pass-name + } + The error should equal 'Unexpected SHOW value "invalid"' + End + End End diff --git a/spec/pass_spec.sh b/spec/pass_spec.sh @@ -742,7 +742,7 @@ Describe 'Pass-like command' fi End - It 'displays the given line as a QR-code' + It 'displays the given long-option line as a QR-code' DISPLAY=mock Skip if 'pass(age) needs bash' check_skip $2 When run script $1 --qrcode=2 fluff/three @@ -759,6 +759,23 @@ Describe 'Pass-like command' fi End + It 'displays the given short-option line as a QR-code' + DISPLAY=mock + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 -q2 fluff/three + The status should be success + expected_err() { %text:expand + #|$ feh -x --title ${1}: fluff/three -g +200+200 - + #|0000000 55 73 65 72 6e 61 6d 65 3a 20 33 4a 61 6e 65 + #|0000017 + } + if [ $2 = pashage ]; then + The error should equal "$(expected_err 'pashage')" + else + The error should equal "$(expected_err 'pass')" + fi + End + It 'pastes into the clipboard' DISPLAY=mock Skip if 'pass(age) needs bash' check_skip $2 @@ -774,7 +791,22 @@ Describe 'Pass-like command' The error should start with "$(expected_err)" End - It 'pastes a selected line into the clipboard' + It 'pastes a selected long-option line into the clipboard' + DISPLAY=mock + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 show --clip=2 fluff/three + The status should be success + The output should start with \ + 'Copied fluff/three to clipboard. Will clear in 45 seconds.' + expected_err() { %text + #|$ xclip -selection clipboard + #|0000000 55 73 65 72 6e 61 6d 65 3a 20 33 4a 61 6e 65 + #|0000017 + } + The error should start with "$(expected_err)" + End + + It 'pastes a selected short-option line into the clipboard' DISPLAY=mock Skip if 'pass(age) needs bash' check_skip $2 When run script $1 show -c2 fluff/three @@ -806,6 +838,17 @@ Describe 'Pass-like command' The error should equal 'Error: y.txt is not in the password store.' End + It 'displays usage when called with incompatible arguments' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 show -c -q subdir/file + The status should equal 1 + The output should be blank + The error should include 'Usage:' + The error should include 'show' + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(setup_log)" + End + It 'rejects a path containing ..' Skip if 'pass(age) needs bash' check_skip $2 When run script $1 subdir/../fluff/one diff --git a/spec/usage_spec.sh b/spec/usage_spec.sh @@ -1501,6 +1501,19 @@ Describe 'Command-Line Parsing' The error should equal "$(result)" End + It 'reports incompatible show options' + cat() { @cat; } + result() { %text + #|Usage: prg [list] [subfolder] + #| prg [show] [--clip[=line-number],-c[line-number] | + #| --qrcode[=line-number],-q[line-number]] pass-name + } + When run cmd_list_or_show -q -c arg + The output should be blank + The error should equal "$(result)" + The status should equal 1 + End + It 'reports a bad option for both commands' cat() { @cat; } result() { %text