Files
quoter/tests/handler_tests.rs
Untone 4a174bd2cb
Some checks failed
Deploy / deploy (push) Has been skipped
CI / test (push) Failing after 1m23s
CI / lint (push) Failing after 55s
0.3.0-less-expect
2025-08-12 14:48:59 +03:00

405 lines
13 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
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.
use actix_web::{test, web, App, HttpRequest, HttpResponse, Error as ActixError};
use actix_web::http::StatusCode;
use serde_json::json;
use std::collections::HashMap;
use discoursio_quoter::{
app_state::AppState,
handlers::{
get_quota_handler, increase_quota_handler, set_quota_handler,
upload_handler, proxy_handler, serve_file
},
auth::get_id_by_token,
};
/// Мок для Redis соединения
#[derive(Clone)]
struct MockRedisConnection;
/// Мок для S3 клиента
#[derive(Clone)]
struct MockS3Client;
/// Мок для AppState
#[derive(Clone)]
struct MockAppState {
redis: MockRedisConnection,
storj_client: MockS3Client,
aws_client: MockS3Client,
bucket: String,
}
impl MockAppState {
fn new() -> Self {
Self {
redis: MockRedisConnection,
storj_client: MockS3Client,
aws_client: MockS3Client,
bucket: "test-bucket".to_string(),
}
}
async fn get_or_create_quota(&self, _user_id: &str) -> Result<u64, actix_web::Error> {
Ok(1024 * 1024) // 1MB
}
async fn increase_user_quota(&self, _user_id: &str, _additional_bytes: u64) -> Result<u64, actix_web::Error> {
Ok(2 * 1024 * 1024) // 2MB
}
async fn set_user_quota(&self, _user_id: &str, _bytes: u64) -> Result<u64, actix_web::Error> {
Ok(3 * 1024 * 1024) // 3MB
}
async fn get_path(&self, _filename: &str) -> Result<Option<String>, actix_web::Error> {
Ok(Some("test/path/file.jpg".to_string()))
}
async fn set_path(&self, _filename: &str, _filepath: &str) {
// Mock implementation
}
async fn cache_filelist(&self) {
// Mock implementation
}
}
/// Тест для get_quota_handler
#[actix_web::test]
async fn test_get_quota_handler() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/quota", web::get().to(get_quota_handler))
).await;
// Тест без авторизации
let req = test::TestRequest::get()
.uri("/quota?user_id=test-user")
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
// Тест с авторизацией (мокаем токен)
let req = test::TestRequest::get()
.uri("/quota?user_id=test-user")
.header("Authorization", "Bearer valid-token")
.to_request();
let resp = test::call_service(&app, req).await;
// Должен вернуть ошибку, так как токен невалидный в тестовой среде
assert!(resp.status().is_client_error() || resp.status().is_server_error());
}
/// Тест для increase_quota_handler
#[actix_web::test]
async fn test_increase_quota_handler() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/quota/increase", web::post().to(increase_quota_handler))
).await;
let quota_data = json!({
"user_id": "test-user",
"additional_bytes": 1024 * 1024
});
let req = test::TestRequest::post()
.uri("/quota/increase")
.header("Authorization", "Bearer valid-token")
.set_json(quota_data)
.to_request();
let resp = test::call_service(&app, req).await;
// Должен вернуть ошибку, так как токен невалидный в тестовой среде
assert!(resp.status().is_client_error() || resp.status().is_server_error());
}
/// Тест для set_quota_handler
#[actix_web::test]
async fn test_set_quota_handler() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/quota/set", web::post().to(set_quota_handler))
).await;
let quota_data = json!({
"user_id": "test-user",
"new_quota_bytes": 5 * 1024 * 1024
});
let req = test::TestRequest::post()
.uri("/quota/set")
.header("Authorization", "Bearer valid-token")
.set_json(quota_data)
.to_request();
let resp = test::call_service(&app, req).await;
// Должен вернуть ошибку, так как токен невалидный в тестовой среде
assert!(resp.status().is_client_error() || resp.status().is_server_error());
}
/// Тест для upload_handler
#[actix_web::test]
async fn test_upload_handler() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/", web::post().to(upload_handler))
).await;
// Тест с пустым multipart
let req = test::TestRequest::post()
.uri("/")
.header("Authorization", "Bearer valid-token")
.to_request();
let resp = test::call_service(&app, req).await;
// Должен вернуть ошибку, так как нет multipart данных
assert!(resp.status().is_client_error() || resp.status().is_server_error());
}
/// Тест для proxy_handler
#[actix_web::test]
async fn test_proxy_handler() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/{path:.*}", web::get().to(proxy_handler))
).await;
// Тест с несуществующим файлом
let req = test::TestRequest::get()
.uri("/nonexistent.jpg")
.to_request();
let resp = test::call_service(&app, req).await;
// Должен вернуть ошибку, так как файл не найден
assert!(resp.status().is_client_error() || resp.status().is_server_error());
}
/// Тест для serve_file
#[actix_web::test]
async fn test_serve_file() {
let app_state = MockAppState::new();
// Тест с пустым путем
let result = serve_file("", &app_state, "").await;
assert!(result.is_err());
// Тест с несуществующим файлом
let result = serve_file("nonexistent.jpg", &app_state, "").await;
// Должен вернуть ошибку, так как файл не найден в S3
assert!(result.is_err());
}
/// Тест для проверки обработки ошибок в handlers
#[actix_web::test]
async fn test_handler_error_handling() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/test", web::get().to(|_req: HttpRequest| async {
Err::<HttpResponse, ActixError>(
actix_web::error::ErrorInternalServerError("Test error")
)
}))
).await;
let req = test::TestRequest::get().uri("/test").to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
/// Тест для проверки CORS headers
#[actix_web::test]
async fn test_cors_headers() {
let app = test::init_service(
App::new()
.app_data(web::Data::new(MockAppState::new()))
.route("/test", web::get().to(|_req: HttpRequest| async {
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok().body("test")
)
}))
.wrap(actix_cors::Cors::default().allow_any_origin())
).await;
let req = test::TestRequest::get().uri("/test").to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
// Проверяем наличие CORS headers
let headers = resp.headers();
assert!(headers.contains_key("access-control-allow-origin"));
}
/// Тест для проверки различных HTTP методов
#[actix_web::test]
async fn test_http_methods() {
let app = test::init_service(
App::new()
.route("/test", web::get().to(|_req: HttpRequest| async {
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok().body("GET method")
)
}))
.route("/test", web::post().to(|_req: HttpRequest| async {
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok().body("POST method")
)
}))
).await;
// Тест GET метода
let req = test::TestRequest::get().uri("/test").to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = test::read_body(resp).await;
assert_eq!(body, "GET method");
// Тест POST метода
let req = test::TestRequest::post().uri("/test").to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = test::read_body(resp).await;
assert_eq!(body, "POST method");
}
/// Тест для проверки query параметров
#[actix_web::test]
async fn test_query_parameters() {
let app = test::init_service(
App::new()
.route("/test", web::get().to(|req: HttpRequest| async {
let query_string = req.query_string();
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok().body(query_string)
)
}))
).await;
let req = test::TestRequest::get()
.uri("/test?param1=value1&param2=value2")
.to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = test::read_body(resp).await;
assert_eq!(body, "param1=value1&param2=value2");
}
/// Тест для проверки headers
#[actix_web::test]
async fn test_headers() {
let app = test::init_service(
App::new()
.route("/test", web::get().to(|req: HttpRequest| async {
let user_agent = req.headers()
.get("user-agent")
.and_then(|h| h.to_str().ok())
.unwrap_or("unknown");
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok().body(user_agent)
)
}))
).await;
let req = test::TestRequest::get()
.uri("/test")
.header("user-agent", "test-agent")
.to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = test::read_body(resp).await;
assert_eq!(body, "test-agent");
}
/// Тест для проверки JSON responses
#[actix_web::test]
async fn test_json_responses() {
let app = test::init_service(
App::new()
.route("/test", web::get().to(|_req: HttpRequest| async {
let data = json!({
"status": "success",
"message": "test message",
"data": {
"id": 123,
"name": "test"
}
});
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok().json(data)
)
}))
).await;
let req = test::TestRequest::get().uri("/test").to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = test::read_body(resp).await;
let response_data: serde_json::Value = serde_json::from_slice(&body).unwrap();
assert_eq!(response_data["status"], "success");
assert_eq!(response_data["message"], "test message");
assert_eq!(response_data["data"]["id"], 123);
assert_eq!(response_data["data"]["name"], "test");
}
/// Тест для проверки различных content types
#[actix_web::test]
async fn test_content_types() {
let app = test::init_service(
App::new()
.route("/text", web::get().to(|_req: HttpRequest| async {
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok()
.content_type("text/plain")
.body("plain text")
)
}))
.route("/html", web::get().to(|_req: HttpRequest| async {
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok()
.content_type("text/html")
.body("<html><body>test</body></html>")
)
}))
.route("/json", web::get().to(|_req: HttpRequest| async {
Ok::<HttpResponse, ActixError>(
HttpResponse::Ok()
.content_type("application/json")
.json(json!({"test": "data"}))
)
}))
).await;
// Тест text/plain
let req = test::TestRequest::get().uri("/text").to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.headers().get("content-type").unwrap(), "text/plain");
// Тест text/html
let req = test::TestRequest::get().uri("/html").to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.headers().get("content-type").unwrap(), "text/html");
// Тест application/json
let req = test::TestRequest::get().uri("/json").to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.headers().get("content-type").unwrap(), "application/json");
}