#!/usr/bin/env bash set -euo pipefail MOCK_PORT=18080 MOCK_PID="" MOCK_REQUEST_FILE="" MOCK_RESPONSE_CODE=201 MOCK_STATE_FILE="/tmp/mock_api_state" _kill_port() { local pids pids=$(lsof -ti ":$MOCK_PORT" 2>/dev/null) || true [ -n "$pids" ] && kill $pids 2>/dev/null || true sleep 0.2 } _wait_port_free() { local i=0 while lsof -ti ":$MOCK_PORT" >/dev/null 2>&1 && [ $i -lt 30 ]; do sleep 0.1 i=$((i + 1)) done } mock_start() { MOCK_RESPONSE_CODE="${MOCK_RESPONSE_CODE:-201}" MOCK_REQUEST_FILE=$(mktemp) echo "$MOCK_REQUEST_FILE" > "$MOCK_STATE_FILE" _kill_port _wait_port_free ( while true; do printf 'HTTP/1.1 %d OK\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n{"id":1}\n' "$MOCK_RESPONSE_CODE" \ | nc -l "$MOCK_PORT" >> "$MOCK_REQUEST_FILE" 2>/dev/null || break sleep 0.05 done ) & MOCK_PID=$! sleep 0.3 } mock_stop() { [ -n "${MOCK_PID:-}" ] && kill "$MOCK_PID" 2>/dev/null || true _kill_port _wait_port_free [ -n "${MOCK_REQUEST_FILE:-}" ] && rm -f "${MOCK_REQUEST_FILE}" 2>/dev/null || true rm -f "$MOCK_STATE_FILE" MOCK_PID="" } mock_set_response() { MOCK_RESPONSE_CODE="${1:-201}" } _get_request_file() { if [ -f "$MOCK_STATE_FILE" ]; then cat "$MOCK_STATE_FILE" elif [ -n "${MOCK_REQUEST_FILE:-}" ]; then echo "$MOCK_REQUEST_FILE" else echo "/dev/null" fi } mock_get_request_body() { tail -1 "$(_get_request_file)" 2>/dev/null || true } mock_get_request_path() { head -1 "$(_get_request_file)" 2>/dev/null | awk '{print $2}' || true } mock_get_request_method() { head -1 "$(_get_request_file)" 2>/dev/null | awk '{print $1}' || true }