diff --git a/scripts/test_m5api_phase2.sh b/scripts/test_m5api_phase2.sh new file mode 100755 index 0000000..8bf26b4 --- /dev/null +++ b/scripts/test_m5api_phase2.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +# Phase 2: Files API Test +# Modules: 03_register, 04_lookup +# Endpoints: 10 + +BASE="https://m5api.momentry.ddns.net" +API_KEY="muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" +FILE_UUID="a6fb22eebefaef17e62af874997c5944" + +PASS=0 +FAIL=0 +TOTAL=0 + +echo "============================================" +echo " Phase 2: Files API Test" +echo " Base: $BASE" +echo " File: $FILE_UUID" +echo "============================================" +echo "" + +test_api() { + local method="$1" path="$2" body="$3" desc="$4" + TOTAL=$((TOTAL+1)) + + local tmpfile="/tmp/m5api_resp_${TOTAL}.json" + local curl_args=(-s -o "$tmpfile" -w "\nHTTP:%{http_code}") + curl_args+=(-X "$method") + curl_args+=(-H "Content-Type: application/json") + curl_args+=(-H "X-API-Key: $API_KEY") + + if [ -n "$body" ]; then + curl_args+=(-d "$body") + fi + + local result + result=$(curl "${curl_args[@]}" "${BASE}${path}" 2>/dev/null) + local code=$(echo "$result" | grep "HTTP:" | tr -d "HTTP:") + local resp_body=$(echo "$result" | sed '/^HTTP:/d') + local size=${#resp_body} + + if [ "$code" -ge 200 ] 2>/dev/null && [ "$code" -lt 400 ] 2>/dev/null; then + PASS=$((PASS+1)) + printf " ✅ %2d. %-5s %-55s → %s (%d B) — %s\n" "$TOTAL" "$method" "$path" "$code" "$size" "$desc" + else + FAIL=$((FAIL+1)) + printf " ❌ %2d. %-5s %-55s → %s (%d B) — %s\n" "$TOTAL" "$method" "$path" "$code" "$size" "$desc" + local preview + preview=$(echo "$resp_body" | head -c 150) + echo " $preview" + fi +} + +echo "── Register ──" +test_api "GET" "/api/v1/files/scan?page=1&page_size=3" "" "Scan files (paginated)" +test_api "GET" "/api/v1/files/lookup?file_name=Charade_YouTube_24fps.mp4" "" "Lookup by name" +test_api "GET" "/api/v1/files" "" "List files" +test_api "GET" "/api/v1/file/$FILE_UUID" "" "Get file detail" +test_api "GET" "/api/v1/file/$FILE_UUID/probe" "" "File probe" + +echo "" +echo "── Processing ──" +test_api "GET" "/api/v1/file/$FILE_UUID/json/asr" "" "Download ASR JSON" +test_api "GET" "/api/v1/progress/$FILE_UUID" "" "Processing progress" +test_api "GET" "/api/v1/file/$FILE_UUID/chunk/llm_parent_${FILE_UUID}_2099_2105" "" "Get chunk by ID" + +echo "" +echo "── Unregister (read-only, will return 404 if not found) ──" +test_api "POST" "/api/v1/unregister" '{"file_uuid":"nonexistent_uuid","delete_output_files":false}' "Unregister (expect success:false)" + +echo "" +echo "── Register (duplicate, will return already_exists) ──" +test_api "POST" "/api/v1/files/register" '{"file_path":"/nonexistent/path.mp4"}' "Register (expect 404)" + +echo "" +echo "============================================" +echo " Total: $TOTAL" +echo " Passed: $PASS ✅" +echo " Failed: $FAIL ❌" +echo "============================================" + +if [ $FAIL -gt 0 ]; then + echo "❌ Phase 2 FAILED" + exit 1 +else + echo "✅ Phase 2 PASSED" +fi diff --git a/src/api/server.rs b/src/api/server.rs index 93074bf..48d9526 100644 --- a/src/api/server.rs +++ b/src/api/server.rs @@ -3525,6 +3525,22 @@ async fn unregister( } tracing::info!("[unregister] Unregistering file: {}", uuid); + + // Check if video exists first + match db.get_video_by_uuid(uuid).await { + Ok(Some(_)) => {}, + Ok(None) => { + return Ok(Json(UnregisterResponse { + success: false, + file_uuid: uuid.to_string(), + message: "File not found".to_string(), + })); + } + Err(e) => { + return Err(StatusCode::INTERNAL_SERVER_ERROR); + } + } + match db.delete_video(uuid).await { Ok(_) => { let _ = state.mongo_cache.invalidate_videos_list().await; diff --git a/src/core/db/postgres_db.rs b/src/core/db/postgres_db.rs index 5faebc3..169eb47 100644 --- a/src/core/db/postgres_db.rs +++ b/src/core/db/postgres_db.rs @@ -1340,7 +1340,7 @@ impl PostgresDb { .await?; let pre_chunks = schema::table_name("pre_chunks"); - sqlx::query(&format!("DELETE FROM {} WHERE file_uuid = $1", pre_chunks)) + sqlx::query(&format!("DELETE FROM {} WHERE file_uuid = $1::uuid", pre_chunks)) .bind(uuid) .execute(&self.pool) .await?;