Skip to content

Commit c19e7fb

Browse files
Rustin170506Turbo87
authored andcommitted
Add unit tests for the patch API
Signed-off-by: Rustin170506 <[email protected]>
1 parent 6090566 commit c19e7fb

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

src/tests/krate/yanking.rs

+63
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/versions/yank_unyank.rs

+31-1
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

+14
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);

0 commit comments

Comments
 (0)