278 lines
8.9 KiB
Bash
Executable file
278 lines
8.9 KiB
Bash
Executable file
#!/bin/bash
|
|
# Unit tests for un.sh - tests internal functions without API calls
|
|
|
|
set -o pipefail
|
|
|
|
PASSED=0
|
|
FAILED=0
|
|
|
|
# Colors
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m'
|
|
|
|
test_case() {
|
|
local name="$1"
|
|
shift
|
|
if "$@"; then
|
|
echo -e " ${GREEN}✓${NC} $name"
|
|
PASSED=$((PASSED + 1))
|
|
else
|
|
echo -e " ${RED}✗${NC} $name"
|
|
FAILED=$((FAILED + 1))
|
|
fi
|
|
}
|
|
|
|
assert_equal() {
|
|
local actual="$1"
|
|
local expected="$2"
|
|
[ "$actual" = "$expected" ]
|
|
}
|
|
|
|
assert_not_equal() {
|
|
local a="$1"
|
|
local b="$2"
|
|
[ "$a" != "$b" ]
|
|
}
|
|
|
|
assert_contains() {
|
|
local str="$1"
|
|
local substr="$2"
|
|
[[ "$str" == *"$substr"* ]]
|
|
}
|
|
|
|
# ============================================================================
|
|
# Extension Mapping Tests
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== Extension Mapping Tests ==="
|
|
|
|
# Extension to language mapping (from un.sh)
|
|
get_language() {
|
|
local ext="${1##*.}"
|
|
case ".$ext" in
|
|
.py) echo "python" ;;
|
|
.js) echo "javascript" ;;
|
|
.ts) echo "typescript" ;;
|
|
.rb) echo "ruby" ;;
|
|
.php) echo "php" ;;
|
|
.pl) echo "perl" ;;
|
|
.lua) echo "lua" ;;
|
|
.sh) echo "bash" ;;
|
|
.go) echo "go" ;;
|
|
.rs) echo "rust" ;;
|
|
.c) echo "c" ;;
|
|
.cpp|.cc|.cxx) echo "cpp" ;;
|
|
.java) echo "java" ;;
|
|
.kt) echo "kotlin" ;;
|
|
.cs) echo "csharp" ;;
|
|
.fs) echo "fsharp" ;;
|
|
.hs) echo "haskell" ;;
|
|
.ml) echo "ocaml" ;;
|
|
.clj) echo "clojure" ;;
|
|
.scm) echo "scheme" ;;
|
|
.lisp) echo "commonlisp" ;;
|
|
.erl) echo "erlang" ;;
|
|
.ex|.exs) echo "elixir" ;;
|
|
.jl) echo "julia" ;;
|
|
.r|.R) echo "r" ;;
|
|
.cr) echo "crystal" ;;
|
|
.d) echo "d" ;;
|
|
.nim) echo "nim" ;;
|
|
.zig) echo "zig" ;;
|
|
.v) echo "v" ;;
|
|
.dart) echo "dart" ;;
|
|
.groovy) echo "groovy" ;;
|
|
.scala) echo "scala" ;;
|
|
.f90|.f95) echo "fortran" ;;
|
|
.cob) echo "cobol" ;;
|
|
.pro) echo "prolog" ;;
|
|
.forth|.4th) echo "forth" ;;
|
|
.tcl) echo "tcl" ;;
|
|
.raku) echo "raku" ;;
|
|
.m) echo "objc" ;;
|
|
*) echo "" ;;
|
|
esac
|
|
}
|
|
|
|
test_case "Python extension maps correctly" assert_equal "$(get_language script.py)" "python"
|
|
test_case "JavaScript extension maps correctly" assert_equal "$(get_language app.js)" "javascript"
|
|
test_case "TypeScript extension maps correctly" assert_equal "$(get_language app.ts)" "typescript"
|
|
test_case "Ruby extension maps correctly" assert_equal "$(get_language app.rb)" "ruby"
|
|
test_case "Go extension maps correctly" assert_equal "$(get_language main.go)" "go"
|
|
test_case "Rust extension maps correctly" assert_equal "$(get_language main.rs)" "rust"
|
|
test_case "C extension maps correctly" assert_equal "$(get_language main.c)" "c"
|
|
test_case "C++ extension maps correctly" assert_equal "$(get_language main.cpp)" "cpp"
|
|
test_case "Java extension maps correctly" assert_equal "$(get_language Main.java)" "java"
|
|
test_case "Kotlin extension maps correctly" assert_equal "$(get_language main.kt)" "kotlin"
|
|
test_case "Haskell extension maps correctly" assert_equal "$(get_language main.hs)" "haskell"
|
|
test_case "Elixir extension maps correctly" assert_equal "$(get_language main.ex)" "elixir"
|
|
test_case "Julia extension maps correctly" assert_equal "$(get_language main.jl)" "julia"
|
|
|
|
# ============================================================================
|
|
# HMAC Signature Tests
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== HMAC Signature Tests ==="
|
|
|
|
# HMAC function (requires openssl)
|
|
hmac_sha256() {
|
|
local secret="$1"
|
|
local message="$2"
|
|
echo -n "$message" | openssl dgst -sha256 -hmac "$secret" | sed 's/^.* //'
|
|
}
|
|
|
|
test_case "HMAC-SHA256 generates 64 character hex string" \
|
|
bash -c 'sig=$(echo -n "test" | openssl dgst -sha256 -hmac "secret" | sed "s/^.* //"); [ ${#sig} -eq 64 ]'
|
|
|
|
test_case "Same input produces same signature" \
|
|
bash -c '[[ "$(echo -n "msg" | openssl dgst -sha256 -hmac "key" | sed "s/^.* //")" == "$(echo -n "msg" | openssl dgst -sha256 -hmac "key" | sed "s/^.* //")" ]]'
|
|
|
|
SIG1=$(echo -n "msg" | openssl dgst -sha256 -hmac "key1" | sed 's/^.* //')
|
|
SIG2=$(echo -n "msg" | openssl dgst -sha256 -hmac "key2" | sed 's/^.* //')
|
|
test_case "Different secrets produce different signatures" assert_not_equal "$SIG1" "$SIG2"
|
|
|
|
SIG3=$(echo -n "msg1" | openssl dgst -sha256 -hmac "key" | sed 's/^.* //')
|
|
SIG4=$(echo -n "msg2" | openssl dgst -sha256 -hmac "key" | sed 's/^.* //')
|
|
test_case "Different messages produce different signatures" assert_not_equal "$SIG3" "$SIG4"
|
|
|
|
test_case "Signature format is timestamp:METHOD:path:body" \
|
|
bash -c 'msg="1234567890:POST:/execute:{}"; [[ "$msg" == *":"* ]] && [[ $(echo "$msg" | tr -cd ":" | wc -c) -eq 3 ]]'
|
|
|
|
# ============================================================================
|
|
# Language Detection Tests
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== Language Detection Tests ==="
|
|
|
|
detect_from_shebang() {
|
|
local first_line="$1"
|
|
if [[ "$first_line" == "#!"* ]]; then
|
|
case "$first_line" in
|
|
*python*) echo "python" ;;
|
|
*node*) echo "javascript" ;;
|
|
*ruby*) echo "ruby" ;;
|
|
*perl*) echo "perl" ;;
|
|
*bash*|*/sh*) echo "bash" ;;
|
|
*lua*) echo "lua" ;;
|
|
*php*) echo "php" ;;
|
|
*) echo "" ;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
test_case "Python shebang detection" \
|
|
assert_equal "$(detect_from_shebang '#!/usr/bin/env python3')" "python"
|
|
|
|
test_case "Node shebang detection" \
|
|
assert_equal "$(detect_from_shebang '#!/usr/bin/env node')" "javascript"
|
|
|
|
test_case "Ruby shebang detection" \
|
|
assert_equal "$(detect_from_shebang '#!/usr/bin/env ruby')" "ruby"
|
|
|
|
test_case "Bash shebang detection" \
|
|
assert_equal "$(detect_from_shebang '#!/bin/bash')" "bash"
|
|
|
|
test_case "Sh shebang detection" \
|
|
assert_equal "$(detect_from_shebang '#!/bin/sh')" "bash"
|
|
|
|
# ============================================================================
|
|
# Argument Parsing Tests
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== Argument Parsing Tests ==="
|
|
|
|
parse_env_var() {
|
|
local arg="$1"
|
|
local key="${arg%%=*}"
|
|
local value="${arg#*=}"
|
|
echo "$key|$value"
|
|
}
|
|
|
|
test_case "Parse -e KEY=VALUE format" \
|
|
assert_equal "$(parse_env_var 'DEBUG=1')" "DEBUG|1"
|
|
|
|
test_case "Parse -e KEY=VALUE with equals in value" \
|
|
assert_equal "$(parse_env_var 'URL=https://example.com?foo=bar')" "URL|https://example.com?foo=bar"
|
|
|
|
test_case "Valid network mode zerotrust" \
|
|
bash -c '[[ "zerotrust" =~ ^(zerotrust|semitrusted)$ ]]'
|
|
|
|
test_case "Valid network mode semitrusted" \
|
|
bash -c '[[ "semitrusted" =~ ^(zerotrust|semitrusted)$ ]]'
|
|
|
|
test_case "Invalid network mode rejected" \
|
|
bash -c '! [[ "invalid" =~ ^(zerotrust|semitrusted)$ ]]'
|
|
|
|
is_subcommand() {
|
|
local cmd="$1"
|
|
case "$cmd" in
|
|
session|service|key|restore) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
test_case "Subcommand detection - session" is_subcommand "session"
|
|
test_case "Subcommand detection - service" is_subcommand "service"
|
|
test_case "Subcommand detection - key" is_subcommand "key"
|
|
test_case "Not a subcommand - script.py" bash -c '! is_subcommand "script.py"'
|
|
|
|
# ============================================================================
|
|
# File Operations Tests
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== File Operations Tests ==="
|
|
|
|
TMPFILE=$(mktemp --suffix=.py)
|
|
echo -n 'print("hello world")' > "$TMPFILE"
|
|
|
|
test_case "Read text file" \
|
|
assert_equal "$(cat "$TMPFILE")" 'print("hello world")'
|
|
|
|
test_case "Base64 encoding/decoding" \
|
|
bash -c '[[ "$(echo -n "hello" | base64 | base64 -d)" == "hello" ]]'
|
|
|
|
test_case "Extract file basename" \
|
|
assert_equal "$(basename /home/user/project/script.py)" "script.py"
|
|
|
|
EXT="${TMPFILE##*.}"
|
|
test_case "Extract file extension" \
|
|
assert_equal "$EXT" "py"
|
|
|
|
rm -f "$TMPFILE"
|
|
|
|
# ============================================================================
|
|
# API Constants Tests
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== API Constants Tests ==="
|
|
|
|
API_BASE="https://api.unsandbox.com"
|
|
PORTAL_BASE="https://unsandbox.com"
|
|
|
|
test_case "API base URL starts with https" \
|
|
bash -c '[[ "https://api.unsandbox.com" == https://* ]]'
|
|
|
|
test_case "API base URL contains unsandbox.com" \
|
|
assert_contains "$API_BASE" "unsandbox.com"
|
|
|
|
test_case "Portal base URL starts with https" \
|
|
bash -c '[[ "https://unsandbox.com" == https://* ]]'
|
|
|
|
# ============================================================================
|
|
# Summary
|
|
# ============================================================================
|
|
|
|
echo ""
|
|
echo "=== Summary ==="
|
|
echo "Passed: $PASSED"
|
|
echo "Failed: $FAILED"
|
|
echo "Total: $((PASSED + FAILED))"
|
|
|
|
exit $((FAILED > 0 ? 1 : 0))
|