Parent: #151 — scoping: #165
Summary
Today, crates/clickhousectl/src/cloud/commands.rs has a #[cfg(test)] mod tests block (line ~2030 onwards) that asserts the JSON shape of a handful of build_*_request helpers — build_create_service_request, build_update_service_request, build_api_key_create_request, build_api_key_update_request, build_org_update_request, build_backup_config_update_request, build_query_endpoint_create_request, build_service_password_patch_request.
The coverage is partial and ad-hoc:
- Some helpers have one happy-path test; some only have rejection tests.
- Assertions cherry-pick a few fields (
json["tags"][0]["key"], etc) rather than asserting the full serialized shape.
- Optional-vs-required distinctions (camelCase keys absent when
Option::None) are not consistently verified.
- New
build_*_request helpers can land without any test at all — there's no structural guard.
This issue makes the existing pattern systematic: a single test module that snapshots the full serialized JSON for every build_*_request helper, under both a minimal-required-only and a maximal-all-fields-set input. No new dependencies (no wiremock, no insta); plain assert_eq! against an inline serde_json::json!(...) expected value, so review diffs stay readable.
Scope
- For every
build_*_request helper in crates/clickhousectl/src/cloud/commands.rs, add:
<helper>_minimal_request_shape — only required CLI args set, assert the complete serialized JSON via serde_json::to_value(&request).
<helper>_maximal_request_shape — every optional CLI arg set, assert the complete serialized JSON.
- Keep tests in the same
#[cfg(test)] mod tests block (consistent with existing pattern); do not introduce a new tests/ directory yet.
- Each test must use
assert_eq!(json, serde_json::json!({ ... })) against the full expected object, so adding a field to the request silently is a compile-time-stable / test-failure regression.
- Replace the cherry-pick assertions in the existing
*_supports_* / *_trims_* tests where they duplicate the new full-shape tests.
- Leave the existing
*_rejects_* validation tests untouched — they cover input parsing, not request shape.
Out of scope
- Going through
clap parsing (covered by the second sub-issue).
- Transport-level testing via
wiremock (covered by the second sub-issue).
CloudClient wrapper methods that don't build a body (GET / DELETE / list) — those have no request shape to assert.
Definition of done
- Every
build_*_request helper has a minimal and a maximal full-shape snapshot test.
- A new
build_*_request helper that lands without a paired test is caught by reviewer convention — add a one-line comment on the test module documenting the rule.
cargo test -p clickhousectl passes.
- Single PR, no new dependencies.
Parent: #151 — scoping: #165
Summary
Today,
crates/clickhousectl/src/cloud/commands.rshas a#[cfg(test)] mod testsblock (line ~2030 onwards) that asserts the JSON shape of a handful ofbuild_*_requesthelpers —build_create_service_request,build_update_service_request,build_api_key_create_request,build_api_key_update_request,build_org_update_request,build_backup_config_update_request,build_query_endpoint_create_request,build_service_password_patch_request.The coverage is partial and ad-hoc:
json["tags"][0]["key"], etc) rather than asserting the full serialized shape.Option::None) are not consistently verified.build_*_requesthelpers can land without any test at all — there's no structural guard.This issue makes the existing pattern systematic: a single test module that snapshots the full serialized JSON for every
build_*_requesthelper, under both a minimal-required-only and a maximal-all-fields-set input. No new dependencies (nowiremock, noinsta); plainassert_eq!against an inlineserde_json::json!(...)expected value, so review diffs stay readable.Scope
build_*_requesthelper incrates/clickhousectl/src/cloud/commands.rs, add:<helper>_minimal_request_shape— only required CLI args set, assert the complete serialized JSON viaserde_json::to_value(&request).<helper>_maximal_request_shape— every optional CLI arg set, assert the complete serialized JSON.#[cfg(test)] mod testsblock (consistent with existing pattern); do not introduce a new tests/ directory yet.assert_eq!(json, serde_json::json!({ ... }))against the full expected object, so adding a field to the request silently is a compile-time-stable / test-failure regression.*_supports_*/*_trims_*tests where they duplicate the new full-shape tests.*_rejects_*validation tests untouched — they cover input parsing, not request shape.Out of scope
clapparsing (covered by the second sub-issue).wiremock(covered by the second sub-issue).CloudClientwrapper methods that don't build a body (GET / DELETE / list) — those have no request shape to assert.Definition of done
build_*_requesthelper has a minimal and a maximal full-shape snapshot test.build_*_requesthelper that lands without a paired test is caught by reviewer convention — add a one-line comment on the test module documenting the rule.cargo test -p clickhousectlpasses.