#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) HELPER_PATH=$(cd "$SCRIPT_DIR/.." && pwd)/notify-telegram.sh fail() { echo "FAIL: $*" >&2 exit 1 } assert_equals() { local actual=$1 local expected=$2 if [[ "$actual" != "$expected" ]]; then fail "expected '$expected', got '$actual'" fi } assert_file_contains() { local file=$1 local pattern=$2 if ! grep -qF -- "$pattern" "$file"; then echo "--- $file ---" >&2 sed -n '1,200p' "$file" >&2 || true fail "expected '$pattern' in $file" fi } capture_curl() { local bin_dir=$1 local curl_args_file=$2 mkdir -p "$bin_dir" cat >"$bin_dir/curl" <"$curl_args_file" printf '{"ok":true}\n' EOF chmod +x "$bin_dir/curl" } read_curl_value() { local file=$1 local key=$2 awk -v prefix="${key}=" 'index($0, prefix) == 1 { print substr($0, length(prefix) + 1); exit }' "$file" } test_missing_credentials() { local tmp_dir=$1 local output_file=$tmp_dir/missing-credentials.out set +e env -u TELEGRAM_BOT_TOKEN -u TELEGRAM_CHAT_ID \ "$HELPER_PATH" --message "hello" >"$output_file" 2>&1 local exit_code=$? set -e [[ "$exit_code" -eq 2 ]] || fail "expected exit code 2 for missing credentials, got $exit_code" assert_file_contains "$output_file" "bot token is required" } test_rejects_message_and_message_file_together() { local tmp_dir=$1 local message_file=$tmp_dir/message.txt local output_file=$tmp_dir/message-and-file.out printf 'hello from file\n' >"$message_file" set +e TELEGRAM_BOT_TOKEN=test-token \ TELEGRAM_CHAT_ID=123456 \ "$HELPER_PATH" --message "hello" --message-file "$message_file" >"$output_file" 2>&1 local exit_code=$? set -e [[ "$exit_code" -eq 2 ]] || fail "expected exit code 2 for mutually exclusive arguments, got $exit_code" assert_file_contains "$output_file" "use either --message or --message-file, not both" } test_successful_request() { local tmp_dir=$1 local bin_dir=$tmp_dir/bin local curl_args_file=$tmp_dir/curl-args.txt capture_curl "$bin_dir" "$curl_args_file" PATH="$bin_dir:$PATH" \ TELEGRAM_BOT_TOKEN=test-token \ TELEGRAM_CHAT_ID=123456 \ "$HELPER_PATH" --message "Plan completed" assert_file_contains "$curl_args_file" "https://api.telegram.org/bottest-token/sendMessage" assert_file_contains "$curl_args_file" "chat_id=123456" assert_file_contains "$curl_args_file" "text=Plan completed" assert_file_contains "$curl_args_file" "disable_web_page_preview=true" assert_file_contains "$curl_args_file" "parse_mode=HTML" } test_message_file_and_custom_api_base() { local tmp_dir=$1 local bin_dir=$tmp_dir/bin-message-file local curl_args_file=$tmp_dir/curl-message-file.txt local message_file=$tmp_dir/telegram-message.txt capture_curl "$bin_dir" "$curl_args_file" printf 'Plan completed from file\n' >"$message_file" PATH="$bin_dir:$PATH" \ TELEGRAM_BOT_TOKEN=test-token \ TELEGRAM_CHAT_ID=654321 \ "$HELPER_PATH" \ --message-file "$message_file" \ --api-base-url "https://telegram.example.test/custom" assert_file_contains "$curl_args_file" "https://telegram.example.test/custom/bottest-token/sendMessage" assert_file_contains "$curl_args_file" "chat_id=654321" assert_file_contains "$curl_args_file" "text=Plan completed from file" } test_truncates_long_message() { local tmp_dir=$1 local bin_dir=$tmp_dir/bin-truncate local curl_args_file=$tmp_dir/curl-truncate.txt local long_message_file=$tmp_dir/long-message.txt local truncated_message capture_curl "$bin_dir" "$curl_args_file" python3 - <<'PY' >"$long_message_file" print("A" * 5000, end="") PY PATH="$bin_dir:$PATH" \ TELEGRAM_BOT_TOKEN=test-token \ TELEGRAM_CHAT_ID=123456 \ "$HELPER_PATH" --message-file "$long_message_file" truncated_message=$(read_curl_value "$curl_args_file" "text") assert_equals "${#truncated_message}" "4096" } main() { [[ -x "$HELPER_PATH" ]] || fail "helper is not executable: $HELPER_PATH" local tmp_dir tmp_dir=$(mktemp -d) trap "rm -rf '$tmp_dir'" EXIT test_missing_credentials "$tmp_dir" test_rejects_message_and_message_file_together "$tmp_dir" test_successful_request "$tmp_dir" test_message_file_and_custom_api_base "$tmp_dir" test_truncates_long_message "$tmp_dir" echo "PASS: telegram notifier tests" } main "$@"