Files
Keysat 9c3ddc01e7 Fix doc drift; document no-enforce-mode and universal publish
Corrections surfaced by doc-auditor + start9-spec-checker:
- testing.md: api suite 47 -> 54
- payments.md: FK enforcement confirmed at db/mod.rs:29
- startos-packaging.md: publish.sh now ships a universal s9pk
- licensing-tiers.md: record enforce-mode retirement and Creator caps
Refresh Current state for the StartOS submission-blocker work.
2026-06-13 06:40:06 -05:00

65 lines
2.8 KiB
Markdown

---
paths:
- "licensing-service-startos/licensing-service/tests/**"
---
# Testing, lint & CI status
## Running
From `licensing-service-startos/licensing-service/`:
```
cargo test # all suites
cargo test --test api # one suite — suites: api crosscheck migrations subscriptions upgrades worker
cargo test <name> # single test by name pattern
cargo clippy --all-targets # ~6 style lints (e.g. unnecessary_map_or)
cargo fmt --check # reports formatting diffs (does not write)
```
## There is no CI
No `.github/workflows`, no Gitea/Woodpecker/Drone config. **Nothing is enforced**
not `cargo test`, not `clippy`, not `fmt`. The release gate is `publish.sh`.
## Formatting is not clean and not enforced
The tree has never been run through `cargo fmt` (56 daemon files differ) or
`prettier` (37 wrapper files differ). `cargo check` and `tsc --noEmit` pass clean.
If you ever format, do it as a **standalone commit** so the mechanical churn
doesn't bury logic changes.
## Runtime-prepared SQL → tests are the only safety net
`db/repo.rs` queries are `sqlx::query(&format!(...))`, prepared at runtime, so bad
or ambiguous columns 500 only when executed. A real prod regression (every paid
purchase returning 500 on `:52`) shipped this way because the new merchant-profile
resolution path had no passing test. When adding/altering a repo query, add a test
that actually executes it. See [payments](payments.md).
## Driving the purchase / settle path — the provider seam
Integration tests are a separate crate, so `#[cfg(test)]` doesn't reach the lib
and `payment::build_provider` only ever makes real BTCPay/Zaprite clients. To
drive the real resolver (`resolve_provider_for_profile_rail` /
`payment_provider_by_id`) with a `MockPaymentProvider`, set the always-compiled
`AppState::provider_override` field (`None` in production; honored by
`provider_from_row`). `install_mock_provider` / `make_test_state_with_mock_provider`
wire a mock into BOTH that field AND the legacy `state.payment` singleton (the
back-compat `/v1/{kind}/webhook` route reads the singleton), and seed a real
`payment_providers` row on the default profile so profile/rail/row resolution
still runs for real. `MockPaymentProvider::new_unconfirmed()` /
`new_status_unavailable()` vary the `get_invoice_status` answer to exercise the
webhook settle-confirmation guard (see [payments](payments.md)).
The 3 `:52`-era known-failing tests are **resolved**: the two `paid_purchase_*`
greened via the seam, the dead `payment_provider_preference_round_trip` deleted.
api suite is now **54 pass / 0 fail** (47 after the `:52` fixes, plus the
post-`:54` scoped-key role-boundary and settle-tripwire tests); all other
suites green.
## Cross-language wire-format tests
The LIC1 format is verified across SDKs separately — see
[crypto-wire-format](crypto-wire-format.md).