diff --git a/backend/tests/api/tasks.hurl b/backend/tests/api/tasks.hurl new file mode 100644 index 0000000..100a058 --- /dev/null +++ b/backend/tests/api/tasks.hurl @@ -0,0 +1,117 @@ +# Task API Tests + +# Test: Create a new task (POST /api/tasks) +POST {{host}}/api/tasks +Content-Type: application/json +{ + "title": "Test task", + "description": "A test task for the API", + "priority": "medium", + "due_date": "2024-12-31", + "status": "todo" +} + +HTTP 201 +[Captures] +task_id: jsonpath "$.id" +[Asserts] +jsonpath "$.title" == "Test task" +jsonpath "$.description" == "A test task for the API" +jsonpath "$.priority" == "medium" +jsonpath "$.due_date" == "2024-12-31" +jsonpath "$.status" == "todo" +jsonpath "$.id" exists +jsonpath "$.created_at" exists +jsonpath "$.updated_at" exists + +# Test: Create a minimal task (only required fields) +POST {{host}}/api/tasks +Content-Type: application/json +{ + "title": "Minimal task" +} + +HTTP 201 +[Captures] +minimal_task_id: jsonpath "$.id" +[Asserts] +jsonpath "$.title" == "Minimal task" +jsonpath "$.priority" == "medium" +jsonpath "$.status" == "todo" +jsonpath "$.description" == null +jsonpath "$.due_date" == null + +# Test: Create task with invalid data (missing title) +POST {{host}}/api/tasks +Content-Type: application/json +{ + "description": "Task without title" +} + +HTTP 400 +[Asserts] +jsonpath "$.error" exists + +# Test: Create task with invalid priority +POST {{host}}/api/tasks +Content-Type: application/json +{ + "title": "Invalid priority task", + "priority": "invalid" +} + +HTTP 400 +[Asserts] +jsonpath "$.error" exists + +# Test: Create task with invalid status +POST {{host}}/api/tasks +Content-Type: application/json +{ + "title": "Invalid status task", + "status": "invalid" +} + +HTTP 400 +[Asserts] +jsonpath "$.error" exists + +# Test: Get a specific task by ID (GET /api/tasks/{id}) +GET {{host}}/api/tasks/{{task_id}} + +HTTP 200 +[Asserts] +jsonpath "$.id" == "{{task_id}}" +jsonpath "$.title" == "Test task" +jsonpath "$.description" == "A test task for the API" +jsonpath "$.priority" == "medium" +jsonpath "$.due_date" == "2024-12-31" +jsonpath "$.status" == "todo" +jsonpath "$.created_at" exists +jsonpath "$.updated_at" exists + +# Test: Get a minimal task by ID +GET {{host}}/api/tasks/{{minimal_task_id}} + +HTTP 200 +[Asserts] +jsonpath "$.id" == "{{minimal_task_id}}" +jsonpath "$.title" == "Minimal task" +jsonpath "$.priority" == "medium" +jsonpath "$.status" == "todo" +jsonpath "$.description" == null +jsonpath "$.due_date" == null + +# Test: Get non-existent task +GET {{host}}/api/tasks/00000000-0000-0000-0000-000000000000 + +HTTP 404 +[Asserts] +jsonpath "$.error" exists + +# Test: Get task with invalid UUID format +GET {{host}}/api/tasks/invalid-uuid + +HTTP 400 +[Asserts] +jsonpath "$.error" exists diff --git a/justfile b/justfile index 93b00fa..a2c57d7 100644 --- a/justfile +++ b/justfile @@ -33,3 +33,18 @@ migrate: migrate-revert: sqlx migrate revert +test-integration: + #!/usr/bin/env bash + set -e + + cargo run & + SERVER_PID=$! + + trap 'echo "Stopping server..."; kill -TERM $SERVER_PID 2>/dev/null || true; wait $SERVER_PID 2>/dev/null || true' EXIT + + echo "Waiting for server to start..." + printf 'GET http://localhost:3000/health\nHTTP 200' | hurl --retry 30 > /dev/null + + echo "Running integration tests..." + hurl --test --variable host=http://localhost:3000 tests/api/*.hurl +