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:
@@ -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/*
|
||||||
@@ -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
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user