Files
ginxsom/tests/nip94_test_bud08.sh
2025-09-03 14:41:55 -04:00

238 lines
8.0 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# BUD-08 NIP-94 File Metadata Tags Test Suite
# This test is created FIRST (TDD) and will FAIL until implementation is added to src/main.c.
#
# Expected procedures to be implemented in src/main.c (BUD-08 section):
# - nip94_is_enabled() -> Read server_config.nip94_enabled (default true)
# - nip94_get_origin() -> Read server_config.cdn_origin (default http://localhost:9001)
# - mime_to_extension() -> Centralize MIME to extension mapping
# - nip94_build_blob_url() -> Build canonical blob URL from origin + sha256 + extension
# - get_file_dimensions() -> Detect WxH for PNG, JPEG, WebP (parse headers only)
# - nip94_build_tags() -> Build tags: ["url",...], ["m",...], ["x",...], ["size",...], optional ["dim","WxH"]
# - nip94_attach_to_descriptor() -> Attach nip94 array to JSON response in /upload and /mirror
#
# Integration points expected:
# - PUT /upload success JSON includes "nip94" array
# - PUT /mirror success JSON includes "nip94" array
#
# Requirements:
# - curl, jq, sqlite3 must be available
# - Server should be running at http://localhost:9001 (restart-all.sh)
set -e
SERVER_URL="http://localhost:9001"
UPLOAD_ENDPOINT="${SERVER_URL}/upload"
MIRROR_ENDPOINT="${SERVER_URL}/mirror"
DB_PATH="db/ginxsom.db"
echo "=== BUD-08 NIP-94 File Metadata Tags Test Suite ==="
# Prereq checks
if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: curl not found"
exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
echo "ERROR: jq not found (required for JSON parsing)"
exit 1
fi
if ! command -v sqlite3 >/dev/null 2>&1; then
echo "ERROR: sqlite3 not found"
exit 1
fi
# Helpers
die() {
echo "FATAL: $*" 1>&2
exit 1
}
json_has_nip94() {
local json="$1"
echo "$json" | jq -e '.nip94 and ( .nip94 | type == "array" )' >/dev/null 2>&1
}
nip94_get_tag() {
local json="$1"
local key="$2"
echo "$json" | jq -r --arg k "$key" '.nip94 | map(select(.[0]==$k)) | if length>0 then .[0][1] else empty end'
}
reset_config_defaults() {
# Restore defaults used by implementation
sqlite3 "$DB_PATH" "INSERT OR REPLACE INTO server_config (key, value) VALUES ('nip94_enabled','true');" || true
sqlite3 "$DB_PATH" "INSERT OR REPLACE INTO server_config (key, value) VALUES ('cdn_origin','http://localhost:9001');" || true
}
set_config_key() {
local key="$1"
local value="$2"
sqlite3 "$DB_PATH" "INSERT OR REPLACE INTO server_config (key, value) VALUES ('$key','$value');"
}
# Create temporary working directory
WORKDIR="tests/tmp_bud08"
mkdir -p "$WORKDIR"
# Create a tiny 1x1 PNG (base64)
TINY_PNG_B64="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO0RzjoAAAAASUVORK5CYII="
PNG_FILE="$WORKDIR/one_by_one.png"
echo "$TINY_PNG_B64" | base64 -d > "$PNG_FILE"
# Compute expected values
CONTENT_TYPE="image/png"
FILE_SIZE=$(wc -c < "$PNG_FILE" | tr -d ' ')
SHA256_HEX=$(sha256sum "$PNG_FILE" | awk '{print $1}')
echo ""
echo "Test artifact:"
echo " File: $PNG_FILE"
echo " Size: $FILE_SIZE"
echo " SHA256: $SHA256_HEX"
echo ""
# Ensure defaults
reset_config_defaults
# --- Test 1: PUT /upload returns nip94 with minimal required tags
echo "=== Test 1: PUT /upload returns nip94 minimal tags ==="
UPLOAD_JSON=$(curl -s -X PUT "$UPLOAD_ENDPOINT" \
-H "Content-Type: $CONTENT_TYPE" \
--data-binary @"$PNG_FILE")
echo "Response:"
echo "$UPLOAD_JSON"
echo ""
if json_has_nip94 "$UPLOAD_JSON"; then
URL_FIELD=$(echo "$UPLOAD_JSON" | jq -r '.url')
TYPE_FIELD=$(echo "$UPLOAD_JSON" | jq -r '.type')
SIZE_FIELD=$(echo "$UPLOAD_JSON" | jq -r '.size')
SHA256_FIELD=$(echo "$UPLOAD_JSON" | jq -r '.sha256')
TAG_URL=$(nip94_get_tag "$UPLOAD_JSON" "url")
TAG_M=$(nip94_get_tag "$UPLOAD_JSON" "m")
TAG_X=$(nip94_get_tag "$UPLOAD_JSON" "x")
TAG_SIZE=$(nip94_get_tag "$UPLOAD_JSON" "size")
PASS=1
[ -n "$TAG_URL" ] || { echo "FAIL: nip94 missing url tag"; PASS=0; }
[ -n "$TAG_M" ] || { echo "FAIL: nip94 missing m tag"; PASS=0; }
[ -n "$TAG_X" ] || { echo "FAIL: nip94 missing x tag"; PASS=0; }
[ -n "$TAG_SIZE" ] || { echo "FAIL: nip94 missing size tag"; PASS=0; }
# Validate tag values match descriptor
[ "$TAG_URL" = "$URL_FIELD" ] || { echo "FAIL: nip94 url tag != descriptor url"; PASS=0; }
[ "$TAG_M" = "$TYPE_FIELD" ] || { echo "FAIL: nip94 m tag != descriptor type"; PASS=0; }
[ "$TAG_X" = "$SHA256_FIELD" ] || { echo "FAIL: nip94 x tag != descriptor sha256"; PASS=0; }
[ "$TAG_SIZE" = "$SIZE_FIELD" ] || { echo "FAIL: nip94 size tag != descriptor size"; PASS=0; }
if [ "$PASS" = "1" ]; then
echo "✅ Test 1 PASSED: nip94 minimal tags present and correct"
else
echo "❌ Test 1 FAILED"
fi
else
echo "❌ Test 1 FAILED: Response missing nip94 array"
fi
# --- Test 2: dim present and equals 1x1 for PNG
echo ""
echo "=== Test 2: dim tag for 1x1 PNG ==="
TAG_DIM=$(nip94_get_tag "$UPLOAD_JSON" "dim" || true)
if [ -n "$TAG_DIM" ]; then
if [ "$TAG_DIM" = "1x1" ]; then
echo "✅ Test 2 PASSED: dim tag present and equals 1x1"
else
echo "❌ Test 2 FAILED: dim tag expected 1x1, got '$TAG_DIM'"
fi
else
echo "❌ Test 2 FAILED: dim tag not present"
fi
# --- Test 3: nip94 disabled via config should omit nip94 field
echo ""
echo "=== Test 3: nip94 disabled via server_config ==="
set_config_key "nip94_enabled" "false"
UPLOAD_JSON_DISABLED=$(curl -s -X PUT "$UPLOAD_ENDPOINT" \
-H "Content-Type: $CONTENT_TYPE" \
--data-binary @"$PNG_FILE")
echo "Response:"
echo "$UPLOAD_JSON_DISABLED"
echo ""
if json_has_nip94 "$UPLOAD_JSON_DISABLED"; then
echo "❌ Test 3 FAILED: nip94 present despite nip94_enabled=false"
else
echo "✅ Test 3 PASSED: nip94 omitted when nip94_enabled=false"
fi
# Restore true for next tests
set_config_key "nip94_enabled" "true"
# --- Test 4: cdn_origin config changes nip94 url (and descriptor url)
echo ""
echo "=== Test 4: cdn_origin origin override ==="
CUSTOM_ORIGIN="http://example-cdn.local"
set_config_key "cdn_origin" "$CUSTOM_ORIGIN"
UPLOAD_JSON_ORIGIN=$(curl -s -X PUT "$UPLOAD_ENDPOINT" \
-H "Content-Type: $CONTENT_TYPE" \
--data-binary @"$PNG_FILE")
echo "Response:"
echo "$UPLOAD_JSON_ORIGIN"
echo ""
if json_has_nip94 "$UPLOAD_JSON_ORIGIN"; then
URL_FIELD2=$(echo "$UPLOAD_JSON_ORIGIN" | jq -r '.url')
TAG_URL2=$(nip94_get_tag "$UPLOAD_JSON_ORIGIN" "url")
if [[ "$URL_FIELD2" == $CUSTOM_ORIGIN/* ]] && [[ "$TAG_URL2" == $CUSTOM_ORIGIN/* ]]; then
echo "✅ Test 4 PASSED: nip94 url and descriptor url use configured origin"
else
echo "❌ Test 4 FAILED: origin not applied to urls"
fi
else
echo "❌ Test 4 FAILED: Response missing nip94 array"
fi
# Restore default origin
set_config_key "cdn_origin" "http://localhost:9001"
# --- Test 5: PUT /mirror returns nip94 minimal tags (best effort, network dependent)
echo ""
echo "=== Test 5: PUT /mirror returns nip94 minimal tags (network dependent) ==="
# Use a public small PNG; if network/policy blocks, mark INFO instead of failure.
REMOTE_URL="https://upload.wikimedia.org/wikipedia/commons/3/3c/Shaki_waterfall.jpg"
MIRROR_JSON=$(curl -s -X PUT "$MIRROR_ENDPOINT" \
-H "Content-Type: application/json" \
--data "{\"url\":\"$REMOTE_URL\"}")
HTTP_OK=$(echo "$MIRROR_JSON" | jq -e '.sha256 and .type and .size' >/dev/null 2>&1; echo $?)
if [ "$HTTP_OK" = "0" ]; then
if json_has_nip94 "$MIRROR_JSON"; then
TAG_URL_M=$(nip94_get_tag "$MIRROR_JSON" "url")
TAG_M_M=$(nip94_get_tag "$MIRROR_JSON" "m")
TAG_X_M=$(nip94_get_tag "$MIRROR_JSON" "x")
TAG_SIZE_M=$(nip94_get_tag "$MIRROR_JSON" "size")
if [ -n "$TAG_URL_M" ] && [ -n "$TAG_M_M" ] && [ -n "$TAG_X_M" ] && [ -n "$TAG_SIZE_M" ]; then
echo "✅ Test 5 PASSED: nip94 minimal tags present for mirror"
else
echo "❌ Test 5 FAILED: nip94 minimal tags missing for mirror response"
fi
else
echo "❌ Test 5 FAILED: mirror response missing nip94 array"
fi
else
echo " Test 5 INFO: mirror request did not return a blob descriptor (network or policy); skipping strict check"
fi
# Cleanup and restore defaults
reset_config_defaults
rm -rf "$WORKDIR"
echo ""
echo "=== End of BUD-08 NIP-94 Test Suite ==="