Persist Home accessory preferences
This commit is contained in:
+124
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
harness="$repo_dir/config/dot/quickshell/home-preferences-harness.qml"
|
||||
state_home="$(mktemp -d /tmp/panama-home-preferences-state.XXXXXX)"
|
||||
|
||||
fail() {
|
||||
printf 'home preferences contract: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
qs_for_harness() {
|
||||
XDG_STATE_HOME="$state_home" qs -p "$harness" "$@"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
qs_for_harness kill >/dev/null 2>&1 || true
|
||||
rm -rf "$state_home"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
start_harness() {
|
||||
qs_for_harness --daemonize >/dev/null
|
||||
for _ in $(seq 1 40); do
|
||||
if qs_for_harness ipc show 2>/dev/null | rg -q '^target home-pref-test$'; then
|
||||
# Construct the lazy singleton and let its explicit reload finish
|
||||
# before issuing mutations through the IPC boundary.
|
||||
qs_for_harness ipc call home-pref-test status >/dev/null
|
||||
sleep 0.2
|
||||
return
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
fail 'test IPC target did not start'
|
||||
}
|
||||
|
||||
stop_harness() {
|
||||
qs_for_harness kill >/dev/null 2>&1 || true
|
||||
for _ in $(seq 1 40); do
|
||||
if ! qs_for_harness ipc show >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
fail 'test shell did not stop cleanly'
|
||||
}
|
||||
|
||||
status_without_state_dir() {
|
||||
qs_for_harness ipc call home-pref-test status | jq -c 'del(.stateDir)'
|
||||
}
|
||||
|
||||
wait_for_status() {
|
||||
local expected="$1"
|
||||
local actual=""
|
||||
|
||||
for _ in $(seq 1 40); do
|
||||
actual="$(status_without_state_dir)"
|
||||
if jq -e --argjson expected "$expected" \
|
||||
'.initialized == $expected.initialized and .favorites == $expected.favorites and .saveError == $expected.saveError' \
|
||||
<<<"$actual" >/dev/null; then
|
||||
return
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
fail "unexpected status: $actual"
|
||||
}
|
||||
|
||||
wait_for_file_content() {
|
||||
local expected="$1"
|
||||
|
||||
for _ in $(seq 1 40); do
|
||||
state_file="$(find "$state_home" -name panama-home.json -print -quit)"
|
||||
if [[ -n "$state_file" ]] \
|
||||
&& jq -e --argjson expected "$expected" \
|
||||
'.initialized == $expected.initialized and .favorites == $expected.favorites' \
|
||||
"$state_file" >/dev/null; then
|
||||
return
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
fail 'preferences file did not contain the complete atomic update'
|
||||
}
|
||||
|
||||
# A leading JSON whitespace prevents qs from expanding the array into IPC
|
||||
# positional arguments; JSON.parse() intentionally accepts that whitespace.
|
||||
initial_ids=' ["light.kitchen","light.hall","light.desk"]'
|
||||
expected='{"initialized":true,"favorites":[{"id":"light.desk","alias":""},{"id":"light.kitchen","alias":"Island"}],"saveError":""}'
|
||||
expected_file='{"initialized":true,"favorites":[{"id":"light.desk","alias":""},{"id":"light.kitchen","alias":"Island"}]}'
|
||||
empty_expected='{"initialized":true,"favorites":[],"saveError":""}'
|
||||
empty_file='{"initialized":true,"favorites":[]}'
|
||||
|
||||
start_harness
|
||||
qs_for_harness ipc call home-pref-test initialize "$initial_ids" >/dev/null
|
||||
qs_for_harness ipc call home-pref-test alias light.kitchen ' Island ' >/dev/null
|
||||
qs_for_harness ipc call home-pref-test move light.desk 0 >/dev/null
|
||||
qs_for_harness ipc call home-pref-test remove light.hall >/dev/null
|
||||
wait_for_status "$expected"
|
||||
wait_for_file_content "$expected_file"
|
||||
|
||||
stop_harness
|
||||
start_harness
|
||||
wait_for_status "$expected"
|
||||
|
||||
qs_for_harness ipc call home-pref-test remove light.desk >/dev/null
|
||||
qs_for_harness ipc call home-pref-test remove light.kitchen >/dev/null
|
||||
wait_for_status "$empty_expected"
|
||||
wait_for_file_content "$empty_file"
|
||||
stop_harness
|
||||
start_harness
|
||||
wait_for_status "$empty_expected"
|
||||
qs_for_harness ipc call home-pref-test initialize ' ["light.new","light.other"]' >/dev/null
|
||||
wait_for_status "$empty_expected"
|
||||
|
||||
jq -e '(keys | sort) == ["favorites", "initialized"]' "$state_file" >/dev/null \
|
||||
|| fail 'preferences file contains keys other than initialized and favorites'
|
||||
if jq -r '.. | strings' "$state_file" | rg -qi 'token|url|api'; then
|
||||
fail 'preferences file contains credential-like data'
|
||||
fi
|
||||
|
||||
trap - EXIT
|
||||
cleanup
|
||||
printf 'home preferences contract: PASS\n'
|
||||
Reference in New Issue
Block a user