chore: remove generated openapi.json from tracking, add test and docs

- Remove resources/gen/openapi.json from git (served dynamically at /api/openapi.json)
- Add resources/gen/ to .gitignore
- Add OpenAPI spec validation test (paths, schemas, serialization)
- Restore removed doc-comment on get_version
- Fix cargo fmt violation in mod.rs import
- Update CLAUDE.md: test count (~208), generate-openapi command, justfile reference
This commit is contained in:
iltumio
2026-04-01 12:25:10 +02:00
parent bf7e030cd6
commit 9c009aecd1
5 changed files with 68 additions and 2022 deletions
+3
View File
@@ -78,5 +78,8 @@ storage/
*.swo *.swo
nohup.out nohup.out
# Generated files (OpenAPI spec, etc.)
resources/gen/
# Helm chart dependencies # Helm chart dependencies
charts/*/charts/* charts/*/charts/*
+5 -1
View File
@@ -8,15 +8,19 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
cargo build # Dev build cargo build # Dev build
cargo build --release # Optimized release build cargo build --release # Optimized release build
cargo run # Run server (port 8086) cargo run # Run server (port 8086)
cargo test --workspace # Run all tests (~112) cargo test --workspace # Run all tests (~208)
cargo test <test_name> # Run a single test by name cargo test <test_name> # Run a single test by name
cargo test --features test_utils # Run tests that use mockall mocks cargo test --features test_utils # Run tests that use mockall mocks
cargo clippy -- -D warnings # Lint (zero warnings policy) cargo clippy -- -D warnings # Lint (zero warnings policy)
cargo fmt --all --check # Format check cargo fmt --all --check # Format check
cargo fmt --all # Auto-format cargo fmt --all # Auto-format
RUST_LOG=debug cargo run # Run with debug logging RUST_LOG=debug cargo run # Run with debug logging
cargo run --bin generate-openapi # Regenerate resources/gen/openapi.json
``` ```
A `justfile` is available for common tasks (`just --list` to see all). Key recipes: `just check` (fmt + clippy), `just test`, `just openapi`.
Requires **Rust 1.93+** (edition 2024) and **PostgreSQL 13+** (with `pg_trgm` and `ltree` extensions). Requires **Rust 1.93+** (edition 2024) and **PostgreSQL 13+** (with `pg_trgm` and `ltree` extensions).
Database setup: `docker compose up -d postgres` — schema is applied automatically via sqlx migrations on app startup. Migration files live in `migrations/`. For local dev, set `DATABASE_URL` in `.env` (see `example.env`). Database setup: `docker compose up -d postgres` — schema is applied automatically via sqlx migrations on app startup. Migration files live in `migrations/`. For local dev, set `DATABASE_URL` in `.env` (see `example.env`).
File diff suppressed because it is too large Load Diff
+59 -1
View File
@@ -11,7 +11,9 @@ use crate::application::dtos::favorites_dto::{
BatchFavoritesResult, BatchFavoritesStats, FavoriteItemDto, BatchFavoritesResult, BatchFavoritesStats, FavoriteItemDto,
}; };
use crate::application::dtos::file_dto::FileDto; use crate::application::dtos::file_dto::FileDto;
use crate::application::dtos::folder_dto::{CreateFolderDto, FolderDto, MoveFolderDto, RenameFolderDto}; use crate::application::dtos::folder_dto::{
CreateFolderDto, FolderDto, MoveFolderDto, RenameFolderDto,
};
use crate::application::dtos::folder_listing_dto::FolderListingDto; use crate::application::dtos::folder_listing_dto::FolderListingDto;
use crate::application::dtos::pagination::{PaginationDto, PaginationRequestDto}; use crate::application::dtos::pagination::{PaginationDto, PaginationRequestDto};
use crate::application::dtos::recent_dto::RecentItemDto; use crate::application::dtos::recent_dto::RecentItemDto;
@@ -119,3 +121,59 @@ use crate::interfaces::api::handlers::file_handler::MoveFilePayload;
) )
)] )]
pub struct ApiDoc; pub struct ApiDoc;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn openapi_spec_is_valid_and_has_expected_structure() {
let spec = ApiDoc::openapi();
assert_eq!(spec.info.title, "OxiCloud API");
assert!(!spec.info.version.is_empty());
let paths = &spec.paths;
assert!(
paths.paths.len() >= 10,
"expected at least 10 paths, got {}",
paths.paths.len()
);
assert!(paths.paths.contains_key("/api/trash"), "missing /api/trash");
assert!(
paths.paths.contains_key("/api/shares"),
"missing /api/shares"
);
assert!(
paths.paths.contains_key("/api/favorites"),
"missing /api/favorites"
);
assert!(
paths.paths.contains_key("/api/recent"),
"missing /api/recent"
);
let schemas = &spec
.components
.as_ref()
.expect("components missing")
.schemas;
assert!(
schemas.len() >= 25,
"expected at least 25 schemas, got {}",
schemas.len()
);
for name in [
"FileDto",
"FolderDto",
"ShareDto",
"TrashedItemDto",
"UserDto",
] {
assert!(schemas.contains_key(name), "missing schema: {name}");
}
let json = serde_json::to_string(&spec).expect("spec should serialise to JSON");
assert!(json.len() > 1000, "spec JSON suspiciously small");
}
}
+1
View File
@@ -11,6 +11,7 @@ use std::sync::Arc;
use tower_http::{compression::CompressionLayer, trace::TraceLayer}; use tower_http::{compression::CompressionLayer, trace::TraceLayer};
use utoipa::OpenApi; use utoipa::OpenApi;
/// Returns the application version from Cargo.toml (compile-time constant)
async fn get_version() -> AxumJson<serde_json::Value> { async fn get_version() -> AxumJson<serde_json::Value> {
AxumJson(json!({ AxumJson(json!({
"name": "OxiCloud", "name": "OxiCloud",