mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 15:04:42 +00:00
refactor: Consolidate and refactor test suite by removing redundant files and simplifying test execution.
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
}
|
||||
|
||||
@test "is_critical_system_component matches known system services" {
|
||||
run bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/app_protection.sh"
|
||||
is_critical_system_component "backgroundtaskmanagement" && echo "yes"
|
||||
is_critical_system_component "SystemSettings" && echo "yes"
|
||||
EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "${lines[0]}" == "yes" ]]
|
||||
[[ "${lines[1]}" == "yes" ]]
|
||||
}
|
||||
|
||||
@test "is_critical_system_component ignores non-system names" {
|
||||
run bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/app_protection.sh"
|
||||
if is_critical_system_component "myapp"; then
|
||||
echo "bad"
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == "ok" ]]
|
||||
}
|
||||
@@ -88,3 +88,29 @@ EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Skipped: No permission"* ]]
|
||||
}
|
||||
|
||||
@test "is_critical_system_component matches known system services" {
|
||||
run bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/app_protection.sh"
|
||||
is_critical_system_component "backgroundtaskmanagement" && echo "yes"
|
||||
is_critical_system_component "SystemSettings" && echo "yes"
|
||||
EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "${lines[0]}" == "yes" ]]
|
||||
[[ "${lines[1]}" == "yes" ]]
|
||||
}
|
||||
|
||||
@test "is_critical_system_component ignores non-system names" {
|
||||
run bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/app_protection.sh"
|
||||
if is_critical_system_component "myapp"; then
|
||||
echo "bad"
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == "ok" ]]
|
||||
}
|
||||
|
||||
111
tests/cli.bats
111
tests/cli.bats
@@ -20,6 +20,30 @@ teardown_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
create_fake_utils() {
|
||||
local dir="$1"
|
||||
mkdir -p "$dir"
|
||||
|
||||
cat > "$dir/sudo" <<'SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
if [[ "$1" == "-n" || "$1" == "-v" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
exec "$@"
|
||||
SCRIPT
|
||||
chmod +x "$dir/sudo"
|
||||
|
||||
cat > "$dir/bioutil" <<'SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
if [[ "$1" == "-r" ]]; then
|
||||
echo "Touch ID: 1"
|
||||
exit 0
|
||||
fi
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$dir/bioutil"
|
||||
}
|
||||
|
||||
setup() {
|
||||
rm -rf "$HOME/.config"
|
||||
mkdir -p "$HOME"
|
||||
@@ -65,3 +89,90 @@ setup() {
|
||||
skip "analyze-go binary not built"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "mo clean --debug creates debug log file" {
|
||||
mkdir -p "$HOME/.config/mole"
|
||||
run env HOME="$HOME" TERM="xterm-256color" MOLE_TEST_MODE=1 MO_DEBUG=1 "$PROJECT_ROOT/mole" clean --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
MOLE_OUTPUT="$output"
|
||||
|
||||
DEBUG_LOG="$HOME/.config/mole/mole_debug_session.log"
|
||||
[ -f "$DEBUG_LOG" ]
|
||||
|
||||
run grep "Mole Debug Session" "$DEBUG_LOG"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
[[ "$MOLE_OUTPUT" =~ "Debug session log saved to" ]]
|
||||
}
|
||||
|
||||
@test "mo clean without debug does not show debug log path" {
|
||||
mkdir -p "$HOME/.config/mole"
|
||||
run env HOME="$HOME" TERM="xterm-256color" MOLE_TEST_MODE=1 MO_DEBUG=0 "$PROJECT_ROOT/mole" clean --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
[[ "$output" != *"Debug session log saved to"* ]]
|
||||
}
|
||||
|
||||
@test "mo clean --debug logs system info" {
|
||||
mkdir -p "$HOME/.config/mole"
|
||||
run env HOME="$HOME" TERM="xterm-256color" MOLE_TEST_MODE=1 MO_DEBUG=1 "$PROJECT_ROOT/mole" clean --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
DEBUG_LOG="$HOME/.config/mole/mole_debug_session.log"
|
||||
|
||||
run grep "User:" "$DEBUG_LOG"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run grep "Architecture:" "$DEBUG_LOG"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "touchid status reflects pam file contents" {
|
||||
pam_file="$HOME/pam_test"
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_opendirectory.so
|
||||
EOF
|
||||
|
||||
run env MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"not configured"* ]]
|
||||
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_tid.so
|
||||
EOF
|
||||
|
||||
run env MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"enabled"* ]]
|
||||
}
|
||||
|
||||
@test "enable_touchid inserts pam_tid line in pam file" {
|
||||
pam_file="$HOME/pam_enable"
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_opendirectory.so
|
||||
EOF
|
||||
|
||||
fake_bin="$HOME/fake-bin"
|
||||
create_fake_utils "$fake_bin"
|
||||
|
||||
run env PATH="$fake_bin:$PATH" MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" enable
|
||||
[ "$status" -eq 0 ]
|
||||
grep -q "pam_tid.so" "$pam_file"
|
||||
[[ -f "${pam_file}.mole-backup" ]]
|
||||
}
|
||||
|
||||
@test "disable_touchid removes pam_tid line" {
|
||||
pam_file="$HOME/pam_disable"
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_tid.so
|
||||
auth sufficient pam_opendirectory.so
|
||||
EOF
|
||||
|
||||
fake_bin="$HOME/fake-bin-disable"
|
||||
create_fake_utils "$fake_bin"
|
||||
|
||||
run env PATH="$fake_bin:$PATH" MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" disable
|
||||
[ "$status" -eq 0 ]
|
||||
run grep "pam_tid.so" "$pam_file"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@@ -174,3 +174,30 @@ EOF
|
||||
)
|
||||
[[ "$result" == *"done"* ]]
|
||||
}
|
||||
|
||||
@test "read_key maps j/k/h/l to navigation" {
|
||||
run bash -c "export MOLE_BASE_LOADED=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'j' | read_key"
|
||||
[ "$output" = "DOWN" ]
|
||||
|
||||
run bash -c "export MOLE_BASE_LOADED=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'k' | read_key"
|
||||
[ "$output" = "UP" ]
|
||||
|
||||
run bash -c "export MOLE_BASE_LOADED=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'h' | read_key"
|
||||
[ "$output" = "LEFT" ]
|
||||
|
||||
run bash -c "export MOLE_BASE_LOADED=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'l' | read_key"
|
||||
[ "$output" = "RIGHT" ]
|
||||
}
|
||||
|
||||
@test "read_key maps uppercase J/K/H/L to navigation" {
|
||||
run bash -c "export MOLE_BASE_LOADED=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'J' | read_key"
|
||||
[ "$output" = "DOWN" ]
|
||||
|
||||
run bash -c "export MOLE_BASE_LOADED=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'K' | read_key"
|
||||
[ "$output" = "UP" ]
|
||||
}
|
||||
|
||||
@test "read_key respects MOLE_READ_KEY_FORCE_CHAR" {
|
||||
run bash -c "export MOLE_BASE_LOADED=1; export MOLE_READ_KEY_FORCE_CHAR=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'j' | read_key"
|
||||
[ "$output" = "CHAR:j" ]
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-debug-logging.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
setup() {
|
||||
export TERM="xterm-256color"
|
||||
rm -rf "${HOME:?}"/*
|
||||
mkdir -p "$HOME/.config/mole"
|
||||
}
|
||||
|
||||
@test "mo clean --debug creates debug log file" {
|
||||
run env HOME="$HOME" MOLE_TEST_MODE=1 MO_DEBUG=1 "$PROJECT_ROOT/mole" clean --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
MOLE_OUTPUT="$output"
|
||||
|
||||
DEBUG_LOG="$HOME/.config/mole/mole_debug_session.log"
|
||||
[ -f "$DEBUG_LOG" ]
|
||||
|
||||
run grep "Mole Debug Session" "$DEBUG_LOG"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
[[ "$MOLE_OUTPUT" =~ "Debug session log saved to" ]]
|
||||
}
|
||||
|
||||
@test "mo clean without debug does not show debug log path" {
|
||||
run env HOME="$HOME" MOLE_TEST_MODE=1 MO_DEBUG=0 "$PROJECT_ROOT/mole" clean --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
[[ "$output" != *"Debug session log saved to"* ]]
|
||||
}
|
||||
|
||||
@test "mo clean --debug logs system info" {
|
||||
run env HOME="$HOME" MOLE_TEST_MODE=1 MO_DEBUG=1 "$PROJECT_ROOT/mole" clean --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
DEBUG_LOG="$HOME/.config/mole/mole_debug_session.log"
|
||||
|
||||
run grep "User:" "$DEBUG_LOG"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run grep "Architecture:" "$DEBUG_LOG"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
@@ -98,3 +98,28 @@ EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"LaunchServices repaired"* ]]
|
||||
}
|
||||
|
||||
@test "opt_msg uses dry-run output" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
opt_msg "dry"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"dry"* ]]
|
||||
}
|
||||
|
||||
@test "run_launchctl_unload skips in dry-run" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
launchctl() { echo "called"; }
|
||||
export -f launchctl
|
||||
run_launchctl_unload "/tmp/test.plist" false
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"called"* ]]
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-optimize-helpers.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "opt_msg uses dry-run output" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
opt_msg "dry"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"dry"* ]]
|
||||
}
|
||||
|
||||
@test "run_launchctl_unload skips in dry-run" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/optimize/tasks.sh"
|
||||
launchctl() { echo "called"; }
|
||||
export -f launchctl
|
||||
run_launchctl_unload "/tmp/test.plist" false
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"called"* ]]
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-purge-extra.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "is_project_container detects project indicators" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
mkdir -p "$HOME/Workspace2/project"
|
||||
touch "$HOME/Workspace2/project/package.json"
|
||||
if is_project_container "$HOME/Workspace2" 2; then
|
||||
echo "yes"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"yes"* ]]
|
||||
}
|
||||
|
||||
@test "discover_project_dirs includes detected containers" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
mkdir -p "$HOME/CustomProjects/app"
|
||||
touch "$HOME/CustomProjects/app/go.mod"
|
||||
discover_project_dirs | grep -q "$HOME/CustomProjects"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "save_discovered_paths writes config with tilde" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
save_discovered_paths "$HOME/Projects"
|
||||
grep -q "^~/" "$HOME/.config/mole/purge_paths"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "scan_purge_targets finds artifacts via find path" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_PURGE_MIN_DEPTH=1 MOLE_PURGE_MAX_DEPTH=2 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
PATH="/usr/bin:/bin"
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
mkdir -p "$HOME/dev/app/node_modules"
|
||||
scan_purge_targets "$HOME/dev" "$HOME/results.txt"
|
||||
grep -q "node_modules" "$HOME/results.txt"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "select_purge_categories returns failure on empty input" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
if select_purge_categories; then
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
@@ -204,6 +204,69 @@ setup() {
|
||||
[[ "$result" == "NOT_PROTECTED" ]]
|
||||
}
|
||||
|
||||
@test "is_project_container detects project indicators" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
mkdir -p "$HOME/Workspace2/project"
|
||||
touch "$HOME/Workspace2/project/package.json"
|
||||
if is_project_container "$HOME/Workspace2" 2; then
|
||||
echo "yes"
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"yes"* ]]
|
||||
}
|
||||
|
||||
@test "discover_project_dirs includes detected containers" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
mkdir -p "$HOME/CustomProjects/app"
|
||||
touch "$HOME/CustomProjects/app/go.mod"
|
||||
discover_project_dirs | grep -q "$HOME/CustomProjects"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "save_discovered_paths writes config with tilde" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
save_discovered_paths "$HOME/Projects"
|
||||
grep -q "^~/" "$HOME/.config/mole/purge_paths"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "scan_purge_targets finds artifacts via find path" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_PURGE_MIN_DEPTH=1 MOLE_PURGE_MAX_DEPTH=2 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
PATH="/usr/bin:/bin"
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
mkdir -p "$HOME/dev/app/node_modules"
|
||||
scan_purge_targets "$HOME/dev" "$HOME/results.txt"
|
||||
grep -q "node_modules" "$HOME/results.txt"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "select_purge_categories returns failure on empty input" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/clean/project.sh"
|
||||
if select_purge_categories; then
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "is_protected_vendor_dir: protects Go vendor" {
|
||||
mkdir -p "$HOME/www/go-app/vendor"
|
||||
touch "$HOME/www/go-app/go.mod"
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-touchid.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
create_fake_utils() {
|
||||
local dir="$1"
|
||||
mkdir -p "$dir"
|
||||
|
||||
cat > "$dir/sudo" <<'SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
if [[ "$1" == "-n" || "$1" == "-v" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
exec "$@"
|
||||
SCRIPT
|
||||
chmod +x "$dir/sudo"
|
||||
|
||||
cat > "$dir/bioutil" <<'SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
if [[ "$1" == "-r" ]]; then
|
||||
echo "Touch ID: 1"
|
||||
exit 0
|
||||
fi
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$dir/bioutil"
|
||||
}
|
||||
|
||||
@test "touchid status reflects pam file contents" {
|
||||
pam_file="$HOME/pam_test"
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_opendirectory.so
|
||||
EOF
|
||||
|
||||
run env MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"not configured"* ]]
|
||||
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_tid.so
|
||||
EOF
|
||||
|
||||
run env MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"enabled"* ]]
|
||||
}
|
||||
|
||||
@test "enable_touchid inserts pam_tid line in pam file" {
|
||||
pam_file="$HOME/pam_enable"
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_opendirectory.so
|
||||
EOF
|
||||
|
||||
fake_bin="$HOME/fake-bin"
|
||||
create_fake_utils "$fake_bin"
|
||||
|
||||
run env PATH="$fake_bin:$PATH" MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" enable
|
||||
[ "$status" -eq 0 ]
|
||||
grep -q "pam_tid.so" "$pam_file"
|
||||
[[ -f "${pam_file}.mole-backup" ]]
|
||||
}
|
||||
|
||||
@test "disable_touchid removes pam_tid line" {
|
||||
pam_file="$HOME/pam_disable"
|
||||
cat > "$pam_file" <<'EOF'
|
||||
auth sufficient pam_tid.so
|
||||
auth sufficient pam_opendirectory.so
|
||||
EOF
|
||||
|
||||
fake_bin="$HOME/fake-bin-disable"
|
||||
create_fake_utils "$fake_bin"
|
||||
|
||||
run env PATH="$fake_bin:$PATH" MOLE_PAM_SUDO_FILE="$pam_file" "$PROJECT_ROOT/bin/touchid.sh" disable
|
||||
[ "$status" -eq 0 ]
|
||||
run grep "pam_tid.so" "$pam_file"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
}
|
||||
|
||||
setup() {
|
||||
export MOLE_BASE_LOADED=1 # mock base loaded
|
||||
}
|
||||
|
||||
@test "read_key maps j/k/h/l to navigation" {
|
||||
source "$PROJECT_ROOT/lib/core/ui.sh"
|
||||
|
||||
run bash -c "source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'j' | read_key"
|
||||
[ "$output" = "DOWN" ]
|
||||
|
||||
run bash -c "source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'k' | read_key"
|
||||
[ "$output" = "UP" ]
|
||||
|
||||
run bash -c "source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'h' | read_key"
|
||||
[ "$output" = "LEFT" ]
|
||||
|
||||
run bash -c "source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'l' | read_key"
|
||||
[ "$output" = "RIGHT" ]
|
||||
}
|
||||
|
||||
@test "read_key maps uppercase J/K/H/L to navigation" {
|
||||
run bash -c "source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'J' | read_key"
|
||||
[ "$output" = "DOWN" ]
|
||||
|
||||
run bash -c "source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'K' | read_key"
|
||||
[ "$output" = "UP" ]
|
||||
}
|
||||
|
||||
@test "read_key respects MOLE_READ_KEY_FORCE_CHAR" {
|
||||
run bash -c "export MOLE_READ_KEY_FORCE_CHAR=1; source '$PROJECT_ROOT/lib/core/ui.sh'; echo -n 'j' | read_key"
|
||||
[ "$output" = "CHAR:j" ]
|
||||
}
|
||||
@@ -216,4 +216,25 @@ result=$(decode_file_list "$encoded_data" "TestApp")
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
}
|
||||
|
||||
@test "remove_mole deletes manual binaries and caches" {
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
touch "$HOME/.local/bin/mole"
|
||||
touch "$HOME/.local/bin/mo"
|
||||
mkdir -p "$HOME/.config/mole" "$HOME/.cache/mole"
|
||||
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="/usr/bin:/bin" bash --noprofile --norc << 'EOF'
|
||||
set -euo pipefail
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
export -f start_inline_spinner stop_inline_spinner
|
||||
printf '\n' | "$PROJECT_ROOT/mole" remove
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[ ! -f "$HOME/.local/bin/mole" ]
|
||||
[ ! -f "$HOME/.local/bin/mo" ]
|
||||
[ ! -d "$HOME/.config/mole" ]
|
||||
[ ! -d "$HOME/.cache/mole" ]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
CURRENT_VERSION="$(grep '^VERSION=' "$PROJECT_ROOT/mole" | head -1 | sed 's/VERSION=\"\\(.*\\)\"/\\1/')"
|
||||
export CURRENT_VERSION
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
@@ -161,3 +164,72 @@ EOF
|
||||
[[ "$output" == *"MOLE_CACHE_RESET"* ]]
|
||||
[[ "$output" == *"All updates completed"* ]]
|
||||
}
|
||||
|
||||
@test "update_via_homebrew reports already on latest version" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc << 'EOF'
|
||||
set -euo pipefail
|
||||
MOLE_TEST_BREW_UPDATE_OUTPUT="Updated 0 formulae"
|
||||
MOLE_TEST_BREW_UPGRADE_OUTPUT="Warning: mole 1.7.9 already installed"
|
||||
MOLE_TEST_BREW_LIST_OUTPUT="mole 1.7.9"
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
brew() {
|
||||
case "$1" in
|
||||
update) echo "$MOLE_TEST_BREW_UPDATE_OUTPUT";;
|
||||
upgrade) echo "$MOLE_TEST_BREW_UPGRADE_OUTPUT";;
|
||||
list) if [[ "$2" == "--versions" ]]; then echo "$MOLE_TEST_BREW_LIST_OUTPUT"; fi ;;
|
||||
esac
|
||||
}
|
||||
export -f brew start_inline_spinner stop_inline_spinner
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
update_via_homebrew "1.7.9"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Already on latest version"* ]]
|
||||
}
|
||||
|
||||
@test "update_mole skips download when already latest" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" CURRENT_VERSION="$CURRENT_VERSION" PATH="$HOME/fake-bin:/usr/bin:/bin" TERM="dumb" bash --noprofile --norc << 'EOF'
|
||||
set -euo pipefail
|
||||
curl() {
|
||||
local out=""
|
||||
local url=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-o)
|
||||
out="$2"
|
||||
shift 2
|
||||
;;
|
||||
http*://*)
|
||||
url="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -n "$out" ]]; then
|
||||
echo "Installer executed" > "$out"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$url" == *"api.github.com"* ]]; then
|
||||
echo "{\"tag_name\":\"$CURRENT_VERSION\"}"
|
||||
else
|
||||
echo "VERSION=\"$CURRENT_VERSION\""
|
||||
fi
|
||||
}
|
||||
export -f curl
|
||||
|
||||
brew() { exit 1; }
|
||||
export -f brew
|
||||
|
||||
"$PROJECT_ROOT/mole" update
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Already on latest version"* ]]
|
||||
}
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
CURRENT_VERSION="$(grep '^VERSION=' "$PROJECT_ROOT/mole" | head -1 | sed 's/VERSION="\(.*\)"/\1/')"
|
||||
export CURRENT_VERSION
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-update-home.XXXXXX")"
|
||||
export HOME
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
setup() {
|
||||
export TERM="dumb"
|
||||
rm -rf "${HOME:?}"/*
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
@test "update_via_homebrew reports already on latest version" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc << 'EOF'
|
||||
set -euo pipefail
|
||||
MOLE_TEST_BREW_UPDATE_OUTPUT="Updated 0 formulae"
|
||||
MOLE_TEST_BREW_UPGRADE_OUTPUT="Warning: mole 1.7.9 already installed"
|
||||
MOLE_TEST_BREW_LIST_OUTPUT="mole 1.7.9"
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
brew() {
|
||||
case "$1" in
|
||||
update) echo "$MOLE_TEST_BREW_UPDATE_OUTPUT";;
|
||||
upgrade) echo "$MOLE_TEST_BREW_UPGRADE_OUTPUT";;
|
||||
list) if [[ "$2" == "--versions" ]]; then echo "$MOLE_TEST_BREW_LIST_OUTPUT"; fi ;;
|
||||
esac
|
||||
}
|
||||
export -f brew start_inline_spinner stop_inline_spinner
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
update_via_homebrew "1.7.9"
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Already on latest version"* ]]
|
||||
}
|
||||
|
||||
@test "update_mole skips download when already latest" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="$HOME/fake-bin:/usr/bin:/bin" TERM="dumb" bash --noprofile --norc << 'EOF'
|
||||
set -euo pipefail
|
||||
mkdir -p "$HOME/fake-bin"
|
||||
cat > "$HOME/fake-bin/curl" <<'SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
out=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-o)
|
||||
out="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [[ -n "$out" ]]; then
|
||||
cat <<'INSTALLER' > "$out"
|
||||
#!/usr/bin/env bash
|
||||
echo "Installer executed"
|
||||
INSTALLER
|
||||
else
|
||||
echo "VERSION=\"$CURRENT_VERSION\""
|
||||
fi
|
||||
SCRIPT
|
||||
chmod +x "$HOME/fake-bin/curl"
|
||||
cat > "$HOME/fake-bin/brew" <<'SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
exit 1
|
||||
SCRIPT
|
||||
chmod +x "$HOME/fake-bin/brew"
|
||||
|
||||
"$PROJECT_ROOT/mole" update
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Already on latest version"* ]]
|
||||
}
|
||||
|
||||
@test "remove_mole deletes manual binaries and caches" {
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
touch "$HOME/.local/bin/mole"
|
||||
touch "$HOME/.local/bin/mo"
|
||||
mkdir -p "$HOME/.config/mole" "$HOME/.cache/mole"
|
||||
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="/usr/bin:/bin" bash --noprofile --norc << 'EOF'
|
||||
set -euo pipefail
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
export -f start_inline_spinner stop_inline_spinner
|
||||
printf '\n' | "$PROJECT_ROOT/mole" remove
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[ ! -f "$HOME/.local/bin/mole" ]
|
||||
[ ! -f "$HOME/.local/bin/mo" ]
|
||||
[ ! -d "$HOME/.config/mole" ]
|
||||
[ ! -d "$HOME/.cache/mole" ]
|
||||
}
|
||||
@@ -118,3 +118,43 @@ EOF
|
||||
[[ "$output" == *"Empty Library folders"* ]]
|
||||
[[ "$output" != *"Empty Library files"* ]]
|
||||
}
|
||||
|
||||
@test "clean_browsers calls expected cache paths" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_browsers
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Safari cache"* ]]
|
||||
[[ "$output" == *"Firefox cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_application_support_logs skips when no access" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
note_activity() { :; }
|
||||
clean_application_support_logs
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Skipped: No permission"* ]]
|
||||
}
|
||||
|
||||
@test "clean_apple_silicon_caches exits when not M-series" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" IS_M_SERIES=false bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_apple_silicon_caches
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ -z "$output" ]]
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
ORIGINAL_HOME="${HOME:-}"
|
||||
export ORIGINAL_HOME
|
||||
|
||||
HOME="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-user-clean.XXXXXX")"
|
||||
export HOME
|
||||
|
||||
mkdir -p "$HOME"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
rm -rf "$HOME"
|
||||
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
|
||||
export HOME="$ORIGINAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "clean_browsers calls expected cache paths" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_browsers
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Safari cache"* ]]
|
||||
[[ "$output" == *"Firefox cache"* ]]
|
||||
}
|
||||
|
||||
@test "clean_application_support_logs skips when no access" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
note_activity() { :; }
|
||||
clean_application_support_logs
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Skipped: No permission"* ]]
|
||||
}
|
||||
|
||||
@test "clean_apple_silicon_caches exits when not M-series" {
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" IS_M_SERIES=false bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||
source "$PROJECT_ROOT/lib/clean/user.sh"
|
||||
safe_clean() { echo "$2"; }
|
||||
clean_apple_silicon_caches
|
||||
EOF
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ -z "$output" ]]
|
||||
}
|
||||
Reference in New Issue
Block a user