From 65dbfaca25ce2ea6ab7cb64d0ef3cead938b287e Mon Sep 17 00:00:00 2001 From: chodak166 Date: Wed, 11 Feb 2026 18:40:32 +0100 Subject: [PATCH] Added tavern test plans --- apps/app_api/src/api/v1.rs | 32 +++++++++----- apps/app_api/src/api/v1/auth.rs | 13 +++--- tavern-tests/export.sh | 5 ++- tavern-tests/tavern-run-all.sh | 15 +++++-- tavern-tests/tavern-run-single.sh | 7 ++- .../test_plans/decode_test.tavern.yaml | 29 ++++++++++++ .../test_plans/dictionary_test.tavern.yaml | 28 ++++++++++++ .../test_plans/encode_test.tavern.yaml | 44 +++++++++++++++++++ tavern-tests/test_plans/includes.yaml | 1 + ...t.tavern.yaml => version_test.tavern.yaml} | 7 +-- 10 files changed, 154 insertions(+), 27 deletions(-) create mode 100644 tavern-tests/test_plans/decode_test.tavern.yaml create mode 100644 tavern-tests/test_plans/dictionary_test.tavern.yaml create mode 100644 tavern-tests/test_plans/encode_test.tavern.yaml rename tavern-tests/test_plans/{info_test.tavern.yaml => version_test.tavern.yaml} (58%) diff --git a/apps/app_api/src/api/v1.rs b/apps/app_api/src/api/v1.rs index a0ef1af..0ffed1f 100644 --- a/apps/app_api/src/api/v1.rs +++ b/apps/app_api/src/api/v1.rs @@ -5,11 +5,21 @@ pub mod major; use crate::state::AppState; use axum::{ - Router, extract::Request, extract::State, http::StatusCode, middleware::Next, - response::Response, + Json, Router, + extract::Request, + extract::State, + http::StatusCode, + middleware::Next, + response::{IntoResponse, Response}, }; +use serde::Serialize; use std::sync::Arc; +#[derive(Debug, Serialize)] +struct ErrorResponseBody { + error: String, +} + pub fn routes(state: Arc) -> Router> { Router::new() .nest("/info", info::routes()) @@ -44,10 +54,10 @@ async fn auth_middleware_inner( } else if let Some(key) = api_key_header { key.to_string() } else { - return Response::builder() - .status(StatusCode::UNAUTHORIZED) - .body("Missing authorization header or API key".into()) - .unwrap(); + let error = ErrorResponseBody { + error: "Missing authorization header or API key".to_string(), + }; + return (StatusCode::UNAUTHORIZED, Json(error)).into_response(); }; match state.0.dependencies.auth_service.authenticate(&token).await { @@ -55,9 +65,11 @@ async fn auth_middleware_inner( request.extensions_mut().insert(claims); next.run(request).await } - Err(_) => Response::builder() - .status(StatusCode::UNAUTHORIZED) - .body("Unauthorized".into()) - .unwrap(), + Err(_) => { + let error = ErrorResponseBody { + error: "Unauthorized".to_string(), + }; + (StatusCode::UNAUTHORIZED, Json(error)).into_response() + } } } diff --git a/apps/app_api/src/api/v1/auth.rs b/apps/app_api/src/api/v1/auth.rs index 6f666c5..27b5c49 100644 --- a/apps/app_api/src/api/v1/auth.rs +++ b/apps/app_api/src/api/v1/auth.rs @@ -7,7 +7,7 @@ use crate::state::AppState; #[derive(Debug, Deserialize)] pub struct LoginRequest { - pub token: String, + pub token: Option, } #[derive(Debug, Serialize)] @@ -21,11 +21,12 @@ pub async fn login_handler( State(state): State>, Json(req): Json, ) -> Result, ErrorResponse> { - let claims = state - .dependencies - .auth_service - .authenticate(&req.token) - .await?; + let token = req.token.ok_or_else(|| ErrorResponse { + error: "Invalid input".to_string(), + message: Some("Token field is required".to_string()), + })?; + + let claims = state.dependencies.auth_service.authenticate(&token).await?; Ok(Json(LoginResponse { user_id: claims.user_id, diff --git a/tavern-tests/export.sh b/tavern-tests/export.sh index 6b29a65..ebb1ce2 100644 --- a/tavern-tests/export.sh +++ b/tavern-tests/export.sh @@ -8,7 +8,8 @@ else fi export TEST_SERVER_ADDRESS="127.0.0.1:3000" -export TEST_API_BASE="/api/v1" +export TEST_API_BASE="api/v1" export TEST_API_KEY="test-api-key" -export TEST_USER_ID="test-user-id" \ No newline at end of file +export TEST_USER_ID="test-user-id" +export TEST_VALID_TOKEN="test-api-key" \ No newline at end of file diff --git a/tavern-tests/tavern-run-all.sh b/tavern-tests/tavern-run-all.sh index 0293f0b..ab0ae63 100755 --- a/tavern-tests/tavern-run-all.sh +++ b/tavern-tests/tavern-run-all.sh @@ -1,13 +1,20 @@ #!/usr/bin/env bash +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd "$SCRIPT_DIR" + if [ -z "$TEST_SERVER_ADDRESS" ]; then source export.sh fi -tavern-ci --alluredir=reports test_plans/info_test.tavern.yaml +tavern-ci --alluredir=reports test_plans/version_test.tavern.yaml +# tavern-ci --alluredir=reports test_plans/auth_test.tavern.yaml +tavern-ci --alluredir=reports test_plans/decode_test.tavern.yaml +tavern-ci --alluredir=reports test_plans/dictionary_test.tavern.yaml +tavern-ci --alluredir=reports test_plans/encode_test.tavern.yaml -if command -v allure > /dev/null; then - allure generate --clean --single-file --output /tmp/vm-allure-report --name index.html reports -fi +# if command -v allure > /dev/null; then +# allure generate --clean --single-file --output /tmp/vm-allure-report --name index.html reports +# fi # allure package: https://github.com/allure-framework/allure2/releases/download/2.34.0/allure_2.34.0-1_all.deb diff --git a/tavern-tests/tavern-run-single.sh b/tavern-tests/tavern-run-single.sh index 51c1a00..1d3cd13 100755 --- a/tavern-tests/tavern-run-single.sh +++ b/tavern-tests/tavern-run-single.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd "$SCRIPT_DIR" + if [ -z "$1" ]; then echo "Usage: $0 " exit 1 @@ -9,8 +12,8 @@ if [ -z "$TEST_SERVER_ADDRESS" ]; then source export.sh fi -tavern-ci --alluredir=reports $1 +tavern-ci --log-cli-level=DEBUG --alluredir=reports $1 -allure generate --clean --single-file --output /tmp/vm-allure-report --name index.html reports +# allure generate --clean --single-file --output /tmp/vm-allure-report --name index.html reports # allure package: https://github.com/allure-framework/allure2/releases/download/2.34.0/allure_2.34.0-1_all.deb diff --git a/tavern-tests/test_plans/decode_test.tavern.yaml b/tavern-tests/test_plans/decode_test.tavern.yaml new file mode 100644 index 0000000..9cc4ce1 --- /dev/null +++ b/tavern-tests/test_plans/decode_test.tavern.yaml @@ -0,0 +1,29 @@ +test_name: "Test major decode endpoint" + +includes: + - !include includes.yaml + +stages: + + - name: "Successful decode with valid encoded input" + request: + url: "http://{server_address}/{api_base}/major/decode/pl/hello" + method: GET + headers: + X-API-Key: "{api_key}" + response: + strict: False + status_code: 200 + json: + input: "hello" + result: !anystr + + - name: "Missing authentication returns 401 error" + request: + url: "http://{server_address}/{api_base}/major/decode/pl/hello" + method: GET + response: + strict: False + status_code: 401 + json: + error: !anystr diff --git a/tavern-tests/test_plans/dictionary_test.tavern.yaml b/tavern-tests/test_plans/dictionary_test.tavern.yaml new file mode 100644 index 0000000..518a1c2 --- /dev/null +++ b/tavern-tests/test_plans/dictionary_test.tavern.yaml @@ -0,0 +1,28 @@ +test_name: "Test dictionary API endpoint" + +includes: + - !include includes.yaml + +stages: + + - name: "Successful list dictionaries with valid authentication" + request: + url: "http://{server_address}/{api_base}/dicts" + method: GET + headers: + X-API-Key: "{api_key}" + response: + strict: False + status_code: 200 + json: + dictionaries: !anylist + + - name: "Missing authentication returns 401 error" + request: + url: "http://{server_address}/{api_base}/dicts" + method: GET + response: + strict: False + status_code: 401 + json: + error: !anystr diff --git a/tavern-tests/test_plans/encode_test.tavern.yaml b/tavern-tests/test_plans/encode_test.tavern.yaml new file mode 100644 index 0000000..14aec64 --- /dev/null +++ b/tavern-tests/test_plans/encode_test.tavern.yaml @@ -0,0 +1,44 @@ +test_name: "Test major encode endpoint" + +includes: + - !include includes.yaml + +stages: + + - name: "Successful encode with default dictionary" + request: + url: "http://{server_address}/{api_base}/major/encode/pl/hello" + method: GET + headers: + X-API-Key: "{api_key}" + response: + strict: False + status_code: 200 + json: + input: "hello" + dict: "demo_pl" + result: !anylist + + - name: "Successful encode with custom dictionary" + request: + url: "http://{server_address}/{api_base}/major/encode/pl/test?dict=demo_pl" + method: GET + headers: + X-API-Key: "{api_key}" + response: + strict: False + status_code: 200 + json: + input: "test" + dict: "demo_pl" + result: !anylist + + - name: "Missing authentication returns 401 error" + request: + url: "http://{server_address}/{api_base}/major/encode/pl/hello" + method: GET + response: + strict: False + status_code: 401 + json: + error: !anystr diff --git a/tavern-tests/test_plans/includes.yaml b/tavern-tests/test_plans/includes.yaml index 54c2bfb..7ea61a6 100644 --- a/tavern-tests/test_plans/includes.yaml +++ b/tavern-tests/test_plans/includes.yaml @@ -3,3 +3,4 @@ variables: api_base: "{tavern.env_vars.TEST_API_BASE}" api_key: "{tavern.env_vars.TEST_API_KEY}" user_id: "{tavern.env_vars.TEST_USER_ID}" + diff --git a/tavern-tests/test_plans/info_test.tavern.yaml b/tavern-tests/test_plans/version_test.tavern.yaml similarity index 58% rename from tavern-tests/test_plans/info_test.tavern.yaml rename to tavern-tests/test_plans/version_test.tavern.yaml index 87c82b8..96f9f74 100644 --- a/tavern-tests/test_plans/info_test.tavern.yaml +++ b/tavern-tests/test_plans/version_test.tavern.yaml @@ -1,12 +1,12 @@ -test_name: "Test server API info endpoint" +test_name: "Test version endpoint" includes: - !include includes.yaml stages: - - name: "Check version" + - name: "Successful version test - valid authentication returns version info" request: - url: "http://{server_address}/{api_base}/info/version" + url: "http://{server_address}/api/v1/info/version" method: GET headers: X-API-Key: "{api_key}" @@ -17,3 +17,4 @@ stages: name: !anystr version: !anystr +