Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ cargo run # migrate, then serve on WAVEFLOW_BIND
cargo fmt --all --check # CI gate
cargo clippy --all-targets --all-features -- -D warnings # CI gate; warnings are errors
cargo test --all-features # hermetic; temporary SQLite databases
cargo test --all-features --test v2_foundations <name> # one test
cargo test --all-features --test subsonic_contract <name> # one test, in one target

bun --cwd=webapp install
bun run build # webapp first, then cargo — the order matters
```

Tests need no service container: `test_app()` builds a `Config` over a `TempDir` and the suite drives the same router `main` serves. FFmpeg and ffprobe must be on `PATH`.

The integration suite is twelve targets under `tests/`, one per subject — `auth`, `scanner`, `identity`, `catalog`, `subsonic_contract`, `subsonic_browse`, `subsonic_fields`, `subsonic_methods`, `native_api`, `sync`, `media`, `service` — sharing `tests/support/mod.rs`. That is a module and not a target: anything directly under `tests/` is compiled as its own test binary. File a new test by the surface it exercises, and check that by what it calls rather than by what its name says.

`cargo build` works without a client build — `build.rs` embeds a placeholder page when `webapp/dist` is absent. A real `vite build` overwrites it.

## Architecture & conventions
Expand Down
48 changes: 46 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,52 @@ tempfile = "3"
tokio-tungstenite = "0.30"

[[test]]
name = "v2_foundations"
path = "tests/v2_foundations.rs"
name = "auth"
path = "tests/auth.rs"

[[test]]
name = "scanner"
path = "tests/scanner.rs"

[[test]]
name = "identity"
path = "tests/identity.rs"

[[test]]
name = "catalog"
path = "tests/catalog.rs"

[[test]]
name = "subsonic_contract"
path = "tests/subsonic_contract.rs"

[[test]]
name = "subsonic_fields"
path = "tests/subsonic_fields.rs"

[[test]]
name = "subsonic_browse"
path = "tests/subsonic_browse.rs"

[[test]]
name = "subsonic_methods"
path = "tests/subsonic_methods.rs"

[[test]]
name = "native_api"
path = "tests/native_api.rs"

[[test]]
name = "sync"
path = "tests/sync.rs"

[[test]]
name = "media"
path = "tests/media.rs"

[[test]]
name = "service"
path = "tests/service.rs"

[profile.release]
codegen-units = 1
Expand Down
2 changes: 1 addition & 1 deletion docs/subsonic-compatibility.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Subsonic compatibility matrix — WaveFlow Server v2

Automated protocol coverage is enforced by `tests/v2_foundations.rs` for XML, JSON, `.view`, GET, form POST, `u/p`, `u/t/s`, `apiKey`, catalogue isolation, all documented mutations, media and artwork.
Automated protocol coverage is enforced by the `subsonic_contract`, `subsonic_browse`, `subsonic_fields` and `subsonic_methods` targets under `tests/` for XML, JSON, `.view`, GET, form POST, `u/p`, `u/t/s`, `apiKey`, catalogue isolation, all documented mutations, media and artwork.

> **The rows below are dated 2026-08-23 and the wire has moved since.** On
> 2026-08-24 an album gained five output fields — `originalReleaseDate`,
Expand Down
Loading
Loading