aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/user/test-userctl.sh
blob: cc90550344d700e5481f3c43cba4df13d29d2df0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash
#
# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# The one runnable check for userctl. busctl, kwriteconfig6, git and gpg are
# stubs on PATH that log their arguments, so nothing here reaches the real
# AccountsService, emaildefaults or git config. jq is the real one.
#
# Usage: ./test-userctl.sh   (exit 0 = all passed)

set -u

here="$(cd "$(dirname "$0")" && pwd)"
ctl="$here/userctl"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

mkdir "$tmp/bin"
cat > "$tmp/bin/stub" <<'EOF'
#!/bin/bash
n="${0##*/}"
{ printf '%s' "$n"; printf ' [%s]' "$@"; echo; } >> "$LOG"
[[ "${FAIL:-}" == "$n" ]] && { echo boom >&2; exit 1; }
case "$n" in
    busctl) [[ " $* " == *" get-property "* ]] && printf '{"type":"s","data":"%s"}\n' "${@: -1}" ;;
    git) [[ " $* " == *" --get "* ]] && { [[ -n "${GIT_VALUE:-}" ]] && echo "$GIT_VALUE" || exit 1; } ;;
    gpg) cat "$GPG_FIXTURE" ;;
esac
exit 0
EOF
chmod +x "$tmp/bin/stub"
for n in busctl kwriteconfig6 git gpg; do ln -s stub "$tmp/bin/$n"; done
export PATH="$tmp/bin:$PATH" HOME="$tmp" LOG="$tmp/log"

obj="/org/freedesktop/Accounts/User$(id -u)"
acc="busctl [--system] [call] [org.freedesktop.Accounts] [$obj] [org.freedesktop.Accounts.User]"

pass=0
fail=0
check() {
    local label="$1" want="$2" got="$3"
    if [[ "$want" == "$got" ]]; then
        printf 'ok   %s\n' "$label"; pass=$((pass + 1))
    else
        printf 'FAIL %s:\n  want %q\n  got  %q\n' "$label" "$want" "$got"; fail=$((fail + 1))
    fi
}
reset() { : > "$LOG"; unset FAIL GIT_VALUE; }

# get: one line per field, AccountsService through --json, the key from git.
reset
export GIT_VALUE=ABCDEF
check "get" "name=RealName
email=Email
avatar=IconFile
language=Language
location=Location
signingkey=ABCDEF" "$("$ctl" get)"

# keys: the primary fingerprint and first uid of each secret key; subkey
# fingerprints and later uids are skipped.
reset
cat > "$tmp/gpg.txt" <<'EOF'
sec:u:255:22:AAAA1111:1700000000:::u:::scESC:::+:::23::0:
fpr:::::::::1111222233334444555566667777AAAA1111:
grp:::::::::0000:
uid:u::::1700000000::HASH::Jane Doèr <jane@example.org>::::::::::0:
uid:u::::1700000000::HASH::Jane D. <jd@example.org>::::::::::0:
ssb:u:255:18:SUB1:1700000000::::::e:::+:::23:
fpr:::::::::9999888877776666555544443333SUB1:
sec:u:255:22:BBBB2222:1700000000:::u:::scESC:::#:::23::0:
fpr:::::::::AAAABBBBCCCCDDDDEEEEFFFF0000BBBB2222:
uid:u::::1700000000::HASH::Work Key <work@example.org>::::::::::0:
EOF
export GPG_FIXTURE="$tmp/gpg.txt"
check "keys" "1111222233334444555566667777AAAA1111	Jane Doèr <jane@example.org>
AAAABBBBCCCCDDDDEEEEFFFF0000BBBB2222	Work Key <work@example.org>" "$("$ctl" keys)"

# set name: AccountsService, emaildefaults, git with the surname shortened.
reset
out="$("$ctl" set name "Jane Doèr")"
check "set name prints nothing" "" "$out"
check "set name writes" "$acc [SetRealName] [s] [Jane Doèr]
kwriteconfig6 [--file] [emaildefaults] [--group] [PROFILE_Default] [--key] [FullName] [Jane Doèr]
git [config] [--global] [user.name] [Jane D.]" "$(cat "$LOG")"

gitname() { reset; "$ctl" set name "$1" >/dev/null; grep '^git' "$LOG"; }
check "three words" "git [config] [--global] [user.name] [Anna Maria R.]" "$(gitname "Anna Maria Rossi")"
check "one word" "git [config] [--global] [user.name] [Cher]" "$(gitname "Cher")"
check "accented initial" "git [config] [--global] [user.name] [Ève À.]" "$(gitname "Ève Àlba")"
check "extra spaces" "git [config] [--global] [user.name] [Jane D.]" "$(gitname "  Jane   Doèr ")"

# set email: the same three stores.
reset
"$ctl" set email jane@example.org >/dev/null
check "set email writes" "$acc [SetEmail] [s] [jane@example.org]
kwriteconfig6 [--file] [emaildefaults] [--group] [PROFILE_Default] [--key] [EmailAddress] [jane@example.org]
git [config] [--global] [user.email] [jane@example.org]" "$(cat "$LOG")"

# AccountsService only.
for pair in avatar:SetIconFile language:SetLanguage location:SetLocation; do
    reset
    "$ctl" set "${pair%%:*}" v >/dev/null
    check "set ${pair%%:*} writes" "$acc [${pair#*:}] [s] [v]" "$(cat "$LOG")"
done

# signingkey: a fingerprint is written; empty unsets, but only if one is set.
reset
"$ctl" set signingkey ABCD >/dev/null
check "set signingkey" "git [config] [--global] [user.signingkey] [ABCD]" "$(cat "$LOG")"
reset
export GIT_VALUE=OLD
"$ctl" set signingkey "" >/dev/null
check "unset signingkey" "git [config] [--global] [--get] [user.signingkey]
git [config] [--global] [--unset] [user.signingkey]" "$(cat "$LOG")"
reset
"$ctl" set signingkey "" >/dev/null
check "unset when none is set" "git [config] [--global] [--get] [user.signingkey]" "$(cat "$LOG")"

# A failing write stops there, says why on stdout, and exits 1.
reset
export FAIL=busctl
out="$("$ctl" set name "Jane Doèr")"; rc=$?
check "failure exit" "1" "$rc"
check "failure message" "busctl: boom" "$out"
check "failure stops" "1" "$(wc -l < "$LOG" | tr -d ' ')"

# An unknown field is refused.
reset
"$ctl" set shoesize 42 >/dev/null 2>&1; rc=$?
check "unknown field" "2" "$rc"

printf '\n%d passed, %d failed\n' "$pass" "$fail"
[[ $fail -eq 0 ]]