#!/usr/bin/env bats # Tests for safe_* functions in lib/core/common.sh 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-safe-functions.XXXXXX")" export HOME mkdir -p "$HOME" } teardown_file() { rm -rf "$HOME" if [[ -n "${ORIGINAL_HOME:-}" ]]; then export HOME="$ORIGINAL_HOME" fi } setup() { source "$PROJECT_ROOT/lib/core/common.sh" TEST_DIR="$HOME/test_safe_functions" mkdir -p "$TEST_DIR" } teardown() { rm -rf "$TEST_DIR" } # Test validate_path_for_deletion @test "validate_path_for_deletion rejects empty path" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion ''" [ "$status" -eq 1 ] } @test "validate_path_for_deletion rejects relative path" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion 'relative/path'" [ "$status" -eq 1 ] } @test "validate_path_for_deletion rejects path traversal" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion '/tmp/../etc'" [ "$status" -eq 1 ] } @test "validate_path_for_deletion rejects system directories" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion '/System'" [ "$status" -eq 1 ] run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion '/usr/bin'" [ "$status" -eq 1 ] run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion '/etc'" [ "$status" -eq 1 ] } @test "validate_path_for_deletion accepts valid path" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; validate_path_for_deletion '$TEST_DIR/valid'" [ "$status" -eq 0 ] } # Test safe_remove @test "safe_remove validates path before deletion" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_remove '/System/test' 2>&1" [ "$status" -eq 1 ] } @test "safe_remove successfully removes file" { local test_file="$TEST_DIR/test_file.txt" echo "test" > "$test_file" run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_remove '$test_file' true" [ "$status" -eq 0 ] [ ! -f "$test_file" ] } @test "safe_remove successfully removes directory" { local test_subdir="$TEST_DIR/test_subdir" mkdir -p "$test_subdir" touch "$test_subdir/file.txt" run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_remove '$test_subdir' true" [ "$status" -eq 0 ] [ ! -d "$test_subdir" ] } @test "safe_remove handles non-existent path gracefully" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_remove '$TEST_DIR/nonexistent' true" [ "$status" -eq 0 ] } @test "safe_remove in silent mode suppresses error output" { # Try to remove system directory in silent mode run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_remove '/System/test' true 2>&1" [ "$status" -eq 1 ] # Should not output error in silent mode } # Test safe_find_delete @test "safe_find_delete validates base directory" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_find_delete '/nonexistent' '*.tmp' 7 'f' 2>&1" [ "$status" -eq 1 ] } @test "safe_find_delete rejects symlinked directory" { local real_dir="$TEST_DIR/real" local link_dir="$TEST_DIR/link" mkdir -p "$real_dir" ln -s "$real_dir" "$link_dir" run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_find_delete '$link_dir' '*.tmp' 7 'f' 2>&1" [ "$status" -eq 1 ] [[ "$output" == *"symlink"* ]] rm -rf "$link_dir" "$real_dir" } @test "safe_find_delete validates type filter" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_find_delete '$TEST_DIR' '*.tmp' 7 'x' 2>&1" [ "$status" -eq 1 ] [[ "$output" == *"Invalid type filter"* ]] } @test "safe_find_delete deletes old files" { # Create test files with different ages local old_file="$TEST_DIR/old.tmp" local new_file="$TEST_DIR/new.tmp" touch "$old_file" touch "$new_file" # Make old_file 8 days old (requires touch -t) touch -t "$(date -v-8d '+%Y%m%d%H%M.%S' 2>/dev/null || date -d '8 days ago' '+%Y%m%d%H%M.%S')" "$old_file" 2>/dev/null || true run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; safe_find_delete '$TEST_DIR' '*.tmp' 7 'f'" [ "$status" -eq 0 ] } # Test MOLE constants are defined @test "MOLE_* constants are defined" { run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; echo \$MOLE_TEMP_FILE_AGE_DAYS" [ "$status" -eq 0 ] [ "$output" = "7" ] run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; echo \$MOLE_MAX_PARALLEL_JOBS" [ "$status" -eq 0 ] [ "$output" = "15" ] run bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; echo \$MOLE_TM_BACKUP_SAFE_HOURS" [ "$status" -eq 0 ] [ "$output" = "48" ] }