Skip to content

Commit 584d849

Browse files
authored
crate/update: Fix request payload structure (#12380)
The request payload should have matched the payload structure of the response, where a `crate` wrapper property is used. This change adjusts the API accordingly.
1 parent 83acab1 commit 584d849

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

src/controllers/krate/update.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ use tracing::{info, warn};
1919

2020
#[derive(Debug, Deserialize, utoipa::ToSchema)]
2121
pub struct PatchRequest {
22+
/// The crate settings to update.
23+
#[serde(rename = "crate")]
24+
pub krate: PatchRequestCrate,
25+
}
26+
27+
#[derive(Debug, Deserialize, utoipa::ToSchema)]
28+
pub struct PatchRequestCrate {
2229
/// Whether this crate can only be published via Trusted Publishing.
2330
#[serde(default, skip_serializing_if = "Option::is_none")]
2431
pub trustpub_only: Option<bool>,
@@ -105,7 +112,7 @@ async fn update_inner(
105112
}
106113

107114
// Update trustpub_only if provided
108-
if let Some(trustpub_only) = body.trustpub_only
115+
if let Some(trustpub_only) = body.krate.trustpub_only
109116
&& trustpub_only != krate.trustpub_only
110117
{
111118
diesel::update(crates::table)

src/tests/routes/crates/update.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async fn test_enable_trustpub_only() {
1717
let url = "/api/v1/crates/foo";
1818

1919
// Try to set trustpub_only to false when it's already false (no change)
20-
let body = serde_json::json!({ "trustpub_only": false });
20+
let body = serde_json::json!({ "crate": { "trustpub_only": false } });
2121
let response = user.patch::<()>(url, body.to_string()).await;
2222
assert_snapshot!(response.status(), @"200 OK");
2323
let json = response.json();
@@ -28,7 +28,7 @@ async fn test_enable_trustpub_only() {
2828
});
2929

3030
// Now enable trustpub_only
31-
let body = serde_json::json!({ "trustpub_only": true });
31+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
3232
let response = user.patch::<()>(url, body.to_string()).await;
3333
assert_snapshot!(response.status(), @"200 OK");
3434
let json = response.json();
@@ -68,7 +68,7 @@ async fn test_disable_trustpub_only() {
6868
let url = "/api/v1/crates/foo";
6969

7070
// Try to set trustpub_only to true when it's already true (no change)
71-
let body = serde_json::json!({ "trustpub_only": true });
71+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
7272
let response = user.patch::<()>(url, body.to_string()).await;
7373
assert_snapshot!(response.status(), @"200 OK");
7474
let json = response.json();
@@ -79,7 +79,7 @@ async fn test_disable_trustpub_only() {
7979
});
8080

8181
// Now disable trustpub_only
82-
let body = serde_json::json!({ "trustpub_only": false });
82+
let body = serde_json::json!({ "crate": { "trustpub_only": false } });
8383
let response = user.patch::<()>(url, body.to_string()).await;
8484
assert_snapshot!(response.status(), @"200 OK");
8585
let json = response.json();
@@ -117,7 +117,7 @@ async fn test_update_trustpub_only_requires_authentication() {
117117

118118
// Try to update as an unauthenticated user
119119
let url = "/api/v1/crates/foo";
120-
let body = serde_json::json!({ "trustpub_only": true });
120+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
121121
let response = anon.patch::<()>(url, body.to_string()).await;
122122
assert_snapshot!(response.status(), @"403 Forbidden");
123123

@@ -140,7 +140,7 @@ async fn test_update_trustpub_only_requires_ownership() {
140140

141141
// Try to update with a different user
142142
let url = "/api/v1/crates/foo";
143-
let body = serde_json::json!({ "trustpub_only": true });
143+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
144144
let response = another_user.patch::<()>(url, body.to_string()).await;
145145
assert_snapshot!(response.status(), @"403 Forbidden");
146146

@@ -152,7 +152,7 @@ async fn test_update_nonexistent_crate() {
152152
let (app, _, user) = TestApp::full().with_user().await;
153153

154154
let url = "/api/v1/crates/nonexistent";
155-
let body = serde_json::json!({ "trustpub_only": true });
155+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
156156
let response = user.patch::<()>(url, body.to_string()).await;
157157
assert_snapshot!(response.status(), @"404 Not Found");
158158

@@ -183,7 +183,7 @@ mod auth {
183183
let token = user.db_new_token("test-token").await;
184184

185185
let url = format!("/api/v1/crates/{}", CRATE_NAME);
186-
let body = serde_json::json!({ "trustpub_only": true });
186+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
187187
let response = token.patch::<()>(&url, body.to_string()).await;
188188
assert_snapshot!(response.status(), @"403 Forbidden");
189189
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"This endpoint cannot be used with legacy API tokens. Use a scoped API token instead."}]}"#);
@@ -204,7 +204,7 @@ mod auth {
204204
.await;
205205

206206
let url = format!("/api/v1/crates/{}", CRATE_NAME);
207-
let body = serde_json::json!({ "trustpub_only": true });
207+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
208208
let response = token.patch::<()>(&url, body.to_string()).await;
209209
assert_snapshot!(response.status(), @"200 OK");
210210

@@ -224,7 +224,7 @@ mod auth {
224224
.await;
225225

226226
let url = format!("/api/v1/crates/{}", CRATE_NAME);
227-
let body = serde_json::json!({ "trustpub_only": true });
227+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
228228
let response = token.patch::<()>(&url, body.to_string()).await;
229229
assert_snapshot!(response.status(), @"403 Forbidden");
230230
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"this token does not have the required permissions to perform this action"}]}"#);
@@ -245,7 +245,7 @@ mod auth {
245245
.await;
246246

247247
let url = format!("/api/v1/crates/{}", CRATE_NAME);
248-
let body = serde_json::json!({ "trustpub_only": true });
248+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
249249
let response = token.patch::<()>(&url, body.to_string()).await;
250250
assert_snapshot!(response.status(), @"403 Forbidden");
251251
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"This endpoint cannot be used with legacy API tokens. Use a scoped API token instead."}]}"#);
@@ -266,7 +266,7 @@ mod auth {
266266
.await;
267267

268268
let url = format!("/api/v1/crates/{}", CRATE_NAME);
269-
let body = serde_json::json!({ "trustpub_only": true });
269+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
270270
let response = token.patch::<()>(&url, body.to_string()).await;
271271
assert_snapshot!(response.status(), @"403 Forbidden");
272272
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"this token does not have the required permissions to perform this action"}]}"#);
@@ -287,7 +287,7 @@ mod auth {
287287
.await;
288288

289289
let url = format!("/api/v1/crates/{}", CRATE_NAME);
290-
let body = serde_json::json!({ "trustpub_only": true });
290+
let body = serde_json::json!({ "crate": { "trustpub_only": true } });
291291
let response = token.patch::<()>(&url, body.to_string()).await;
292292
assert_snapshot!(response.status(), @"200 OK");
293293

src/tests/snapshots/integration__openapi__openapi_snapshot-2.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,18 @@ expression: response.json()
913913
"type": "object"
914914
},
915915
"PatchRequest": {
916+
"properties": {
917+
"crate": {
918+
"$ref": "#/components/schemas/PatchRequestCrate",
919+
"description": "The crate settings to update."
920+
}
921+
},
922+
"required": [
923+
"crate"
924+
],
925+
"type": "object"
926+
},
927+
"PatchRequestCrate": {
916928
"properties": {
917929
"trustpub_only": {
918930
"description": "Whether this crate can only be published via Trusted Publishing.",

0 commit comments

Comments
 (0)