Skip to content

Commit 58b48b0

Browse files
committed
Add unit tests for the patch API
Signed-off-by: Rustin170506 <[email protected]>
1 parent 23bbe2a commit 58b48b0

17 files changed

+130
-1
lines changed

src/tests/krate/publish/snapshots/all__krate__publish__links__crate_with_links_field-2.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ expression: response.json()
4545
"readme_path": "/api/v1/crates/foo/1.0.0/readme",
4646
"rust_version": null,
4747
"updated_at": "[datetime]",
48+
"yank_message": null,
4849
"yanked": false
4950
}
5051
}

src/tests/krate/publish/snapshots/all__krate__publish__manifest__boolean_readme-2.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ expression: response.json()
4545
"readme_path": "/api/v1/crates/foo/1.0.0/readme",
4646
"rust_version": "1.69",
4747
"updated_at": "[datetime]",
48+
"yank_message": null,
4849
"yanked": false
4950
}
5051
}

src/tests/krate/publish/snapshots/all__krate__publish__manifest__lib_and_bin_crate-2.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ expression: response.json()
4848
"readme_path": "/api/v1/crates/foo/1.0.0/readme",
4949
"rust_version": null,
5050
"updated_at": "[datetime]",
51+
"yank_message": null,
5152
"yanked": false
5253
}
5354
}

src/tests/krate/yanking.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,66 @@ async fn publish_after_yank_max_version() {
220220
let json = anon.show_crate("fyk_max").await;
221221
assert_eq!(json.krate.max_version, "2.0.0");
222222
}
223+
224+
#[tokio::test(flavor = "multi_thread")]
225+
async fn patch_version_yank_unyank() {
226+
let (_, anon, _, token) = TestApp::full().with_token();
227+
228+
// Upload a new crate
229+
let crate_to_publish = PublishBuilder::new("patchable", "1.0.0");
230+
token.publish_crate(crate_to_publish).await.good();
231+
232+
// Check initial state
233+
let json = anon.show_version("patchable", "1.0.0").await;
234+
assert!(!json.version.yanked);
235+
assert_eq!(json.version.yank_message, None);
236+
237+
// Yank with message
238+
token
239+
.update_yank_status("patchable", "1.0.0", Some(true), Some("Yanking reason"))
240+
.await
241+
.good();
242+
243+
let json = anon.show_version("patchable", "1.0.0").await;
244+
assert!(json.version.yanked);
245+
assert_eq!(
246+
json.version.yank_message,
247+
Some("Yanking reason".to_string())
248+
);
249+
250+
// Update yank message
251+
token
252+
.update_yank_status("patchable", "1.0.0", None, Some("Updated reason"))
253+
.await
254+
.good();
255+
256+
let json = anon.show_version("patchable", "1.0.0").await;
257+
assert!(json.version.yanked);
258+
assert_eq!(
259+
json.version.yank_message,
260+
Some("Updated reason".to_string())
261+
);
262+
263+
// Unyank
264+
token
265+
.update_yank_status("patchable", "1.0.0", Some(false), None)
266+
.await
267+
.good();
268+
269+
let json = anon.show_version("patchable", "1.0.0").await;
270+
assert!(!json.version.yanked);
271+
assert_eq!(json.version.yank_message, None);
272+
273+
// Attempt to set yank message on unyanked version (should fail)
274+
token
275+
.update_yank_status("patchable", "1.0.0", None, Some("Invalid message"))
276+
.await
277+
.status()
278+
.is_client_error();
279+
// Attempt to unyank with message (should fail)
280+
token
281+
.update_yank_status("patchable", "1.0.0", Some(false), Some("Invalid message"))
282+
.await
283+
.status()
284+
.is_client_error();
285+
}

src/tests/routes/crates/snapshots/all__routes__crates__read__show.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ expression: response.json()
7171
"readme_path": "/api/v1/crates/foo_show/1.0.0/readme",
7272
"rust_version": null,
7373
"updated_at": "[datetime]",
74+
"yank_message": null,
7475
"yanked": false
7576
},
7677
{
@@ -103,6 +104,7 @@ expression: response.json()
103104
"readme_path": "/api/v1/crates/foo_show/0.5.1/readme",
104105
"rust_version": null,
105106
"updated_at": "[datetime]",
107+
"yank_message": null,
106108
"yanked": false
107109
},
108110
{
@@ -135,6 +137,7 @@ expression: response.json()
135137
"readme_path": "/api/v1/crates/foo_show/0.5.0/readme",
136138
"rust_version": null,
137139
"updated_at": "[datetime]",
140+
"yank_message": null,
138141
"yanked": false
139142
}
140143
]

src/tests/routes/crates/snapshots/all__routes__crates__reverse_dependencies__prerelease_versions_not_included_in_reverse_dependencies.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ expression: response.json()
5151
"readme_path": "/api/v1/crates/c3/1.0.0/readme",
5252
"rust_version": null,
5353
"updated_at": "[datetime]",
54+
"yank_message": null,
5455
"yanked": false
5556
}
5657
]

src/tests/routes/crates/snapshots/all__routes__crates__reverse_dependencies__reverse_dependencies.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ expression: response.json()
5151
"readme_path": "/api/v1/crates/c2/1.1.0/readme",
5252
"rust_version": null,
5353
"updated_at": "[datetime]",
54+
"yank_message": null,
5455
"yanked": false
5556
}
5657
]

src/tests/routes/crates/snapshots/all__routes__crates__reverse_dependencies__reverse_dependencies_includes_published_by_user_when_present.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ expression: response.json()
6363
"readme_path": "/api/v1/crates/c3/3.0.0/readme",
6464
"rust_version": null,
6565
"updated_at": "[datetime]",
66+
"yank_message": null,
6667
"yanked": false
6768
},
6869
{
@@ -89,6 +90,7 @@ expression: response.json()
8990
"readme_path": "/api/v1/crates/c2/2.0.0/readme",
9091
"rust_version": null,
9192
"updated_at": "[datetime]",
93+
"yank_message": null,
9294
"yanked": false
9395
}
9496
]

src/tests/routes/crates/snapshots/all__routes__crates__reverse_dependencies__reverse_dependencies_query_supports_u64_version_number_parts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ expression: response.json()
5151
"readme_path": "/api/v1/crates/c2/1.0.18446744073709551615/readme",
5252
"rust_version": null,
5353
"updated_at": "[datetime]",
54+
"yank_message": null,
5455
"yanked": false
5556
}
5657
]

src/tests/routes/crates/snapshots/all__routes__crates__reverse_dependencies__reverse_dependencies_when_old_version_doesnt_depend_but_new_does.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ expression: response.json()
5151
"readme_path": "/api/v1/crates/c2/2.0.0/readme",
5252
"rust_version": null,
5353
"updated_at": "[datetime]",
54+
"yank_message": null,
5455
"yanked": false
5556
}
5657
]

src/tests/routes/crates/snapshots/all__routes__crates__reverse_dependencies__yanked_versions_not_included_in_reverse_dependencies.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ expression: response.json()
5151
"readme_path": "/api/v1/crates/c2/2.0.0/readme",
5252
"rust_version": null,
5353
"updated_at": "[datetime]",
54+
"yank_message": null,
5455
"yanked": false
5556
}
5657
]

src/tests/routes/crates/versions/snapshots/all__routes__crates__versions__list__versions.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ expression: response.json()
2828
"readme_path": "/api/v1/crates/foo_versions/1.0.0/readme",
2929
"rust_version": "1.64",
3030
"updated_at": "[datetime]",
31+
"yank_message": null,
3132
"yanked": false
3233
},
3334
{
@@ -60,6 +61,7 @@ expression: response.json()
6061
"readme_path": "/api/v1/crates/foo_versions/0.5.1/readme",
6162
"rust_version": null,
6263
"updated_at": "[datetime]",
64+
"yank_message": null,
6365
"yanked": false
6466
},
6567
{
@@ -92,6 +94,7 @@ expression: response.json()
9294
"readme_path": "/api/v1/crates/foo_versions/0.5.0/readme",
9395
"rust_version": null,
9496
"updated_at": "[datetime]",
97+
"yank_message": null,
9598
"yanked": false
9699
}
97100
]

src/tests/routes/crates/versions/snapshots/all__routes__crates__versions__read__show_by_crate_name_and_semver_no_published_by.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ expression: json
2727
"readme_path": "/api/v1/crates/foo_vers_show_no_pb/1.0.0/readme",
2828
"rust_version": null,
2929
"updated_at": "[datetime]",
30+
"yank_message": null,
3031
"yanked": false
3132
}
3233
}

src/tests/routes/crates/versions/snapshots/all__routes__crates__versions__read__show_by_crate_name_and_version.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ expression: json
3333
"readme_path": "/api/v1/crates/foo_vers_show/2.0.0/readme",
3434
"rust_version": "1.64",
3535
"updated_at": "[datetime]",
36+
"yank_message": null,
3637
"yanked": false
3738
}
3839
}

src/tests/routes/crates/versions/yank_unyank.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
use crate::builders::{CrateBuilder, PublishBuilder};
22
use crate::util::{RequestHelper, Response, TestApp};
3-
use crate::OkBool;
3+
use crate::{OkBool, VersionResponse};
44
use http::StatusCode;
5+
use serde_json::json;
56

67
pub trait YankRequestHelper {
78
/// Yank the specified version of the specified crate and run all pending background jobs
89
async fn yank(&self, krate_name: &str, version: &str) -> Response<OkBool>;
910

1011
/// Unyank the specified version of the specified crate and run all pending background jobs
1112
async fn unyank(&self, krate_name: &str, version: &str) -> Response<OkBool>;
13+
14+
/// Update the yank status of the specified version of the specified crate with a patch request and run all pending background jobs
15+
async fn update_yank_status(
16+
&self,
17+
krate_name: &str,
18+
version: &str,
19+
yanked: Option<bool>,
20+
yank_message: Option<&str>,
21+
) -> Response<VersionResponse>;
1222
}
1323

1424
impl<T: RequestHelper> YankRequestHelper for T {
@@ -25,6 +35,26 @@ impl<T: RequestHelper> YankRequestHelper for T {
2535
self.app().run_pending_background_jobs().await;
2636
response
2737
}
38+
39+
async fn update_yank_status(
40+
&self,
41+
krate_name: &str,
42+
version: &str,
43+
yanked: Option<bool>,
44+
yank_message: Option<&str>,
45+
) -> Response<VersionResponse> {
46+
let url = format!("/api/v1/crates/{krate_name}/{version}");
47+
48+
let json_body = json!({
49+
"yanked": yanked,
50+
"yank_message": yank_message
51+
});
52+
let body = serde_json::to_string(&json_body).expect("Failed to serialize JSON body");
53+
54+
let response = self.patch(&url, body).await;
55+
self.app().run_pending_background_jobs().await;
56+
response
57+
}
2858
}
2959

3060
#[tokio::test(flavor = "multi_thread")]

src/tests/util.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,20 @@ pub trait RequestHelper {
146146
self.run(request).await
147147
}
148148

149+
/// Issue a PATCH request
150+
async fn patch<T>(&self, path: &str, body: impl Into<Bytes>) -> Response<T> {
151+
let body = body.into();
152+
let is_json = body.starts_with(b"{") && body.ends_with(b"}");
153+
154+
let mut request = self.request_builder(Method::PATCH, path);
155+
*request.body_mut() = body;
156+
if is_json {
157+
request.header(header::CONTENT_TYPE, "application/json");
158+
}
159+
160+
self.run(request).await
161+
}
162+
149163
/// Issue a DELETE request
150164
async fn delete<T>(&self, path: &str) -> Response<T> {
151165
let request = self.request_builder(Method::DELETE, path);

src/views.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ pub struct EncodableVersion {
558558
pub downloads: i32,
559559
pub features: serde_json::Value,
560560
pub yanked: bool,
561+
pub yank_message: Option<String>,
561562
pub lib_links: Option<String>,
562563
// NOTE: Used by shields.io, altering `license` requires a PR with shields.io
563564
pub license: Option<String>,
@@ -586,6 +587,7 @@ impl EncodableVersion {
586587
downloads,
587588
features,
588589
yanked,
590+
yank_message,
589591
links: lib_links,
590592
license,
591593
crate_size,
@@ -613,6 +615,7 @@ impl EncodableVersion {
613615
downloads,
614616
features,
615617
yanked,
618+
yank_message,
616619
lib_links,
617620
license,
618621
links,
@@ -736,6 +739,7 @@ mod tests {
736739
downloads: 0,
737740
features: serde_json::from_str("{}").unwrap(),
738741
yanked: false,
742+
yank_message: None,
739743
license: None,
740744
lib_links: None,
741745
links: EncodableVersionLinks {

0 commit comments

Comments
 (0)