Skip to content

Commit aea4d4a

Browse files
authored
Merge pull request #9950 from Turbo87/owners-helpers
tests/util: Move `add/remove_owner()` fns into `RequestHelper` trait
2 parents 9e7c0ce + d97bb62 commit aea4d4a

File tree

5 files changed

+53
-93
lines changed

5 files changed

+53
-93
lines changed

src/tests/issues/issue1205.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::tests::builders::CrateBuilder;
2-
use crate::tests::util::TestApp;
2+
use crate::tests::util::{RequestHelper, TestApp};
33
use crates_io_github::{GitHubOrganization, GitHubTeam, GitHubTeamMembership, MockGitHubClient};
44
use http::StatusCode;
55
use insta::assert_snapshot;

src/tests/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ pub struct OkBool {
8686
ok: bool,
8787
}
8888

89+
#[derive(Deserialize, Debug)]
90+
pub struct OwnerResp {
91+
// server must include `ok: true` to support old cargo clients
92+
ok: bool,
93+
msg: String,
94+
}
95+
8996
fn new_user(login: &str) -> NewUser<'_> {
9097
NewUser {
9198
gh_id: next_gh_id(),

src/tests/routes/crates/owners/add.rs

Lines changed: 14 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,8 @@ async fn test_cargo_invite_owners() {
1616
let new_user = app.db_new_user("cilantro");
1717
CrateBuilder::new("guacamole", owner.as_model().id).expect_build(&mut conn);
1818

19-
#[derive(Serialize)]
20-
struct OwnerReq {
21-
owners: Option<Vec<String>>,
22-
}
23-
#[derive(Deserialize, Debug)]
24-
struct OwnerResp {
25-
// server must include `ok: true` to support old cargo clients
26-
ok: bool,
27-
msg: String,
28-
}
29-
30-
let body = serde_json::to_string(&OwnerReq {
31-
owners: Some(vec![new_user.as_model().gh_login.clone()]),
32-
});
33-
let json: OwnerResp = owner
34-
.put("/api/v1/crates/guacamole/owners", body.unwrap())
19+
let json = owner
20+
.add_named_owner("guacamole", &new_user.as_model().gh_login)
3521
.await
3622
.good();
3723

@@ -57,10 +43,7 @@ async fn owner_change_via_cookie() {
5743

5844
let krate = CrateBuilder::new("foo_crate", cookie.as_model().id).expect_build(&mut conn);
5945

60-
let url = format!("/api/v1/crates/{}/owners", krate.name);
61-
let body = json!({ "owners": [user2.gh_login] });
62-
let body = serde_json::to_vec(&body).unwrap();
63-
let response = cookie.put::<()>(&url, body).await;
46+
let response = cookie.add_named_owner(&krate.name, &user2.gh_login).await;
6447
assert_eq!(response.status(), StatusCode::OK);
6548
assert_snapshot!(response.text(), @r#"{"msg":"user user-2 has been invited to be an owner of crate foo_crate","ok":true}"#);
6649
}
@@ -75,10 +58,7 @@ async fn owner_change_via_token() {
7558

7659
let krate = CrateBuilder::new("foo_crate", token.as_model().user_id).expect_build(&mut conn);
7760

78-
let url = format!("/api/v1/crates/{}/owners", krate.name);
79-
let body = json!({ "owners": [user2.gh_login] });
80-
let body = serde_json::to_vec(&body).unwrap();
81-
let response = token.put::<()>(&url, body).await;
61+
let response = token.add_named_owner(&krate.name, &user2.gh_login).await;
8262
assert_eq!(response.status(), StatusCode::OK);
8363
assert_snapshot!(response.text(), @r#"{"msg":"user user-2 has been invited to be an owner of crate foo_crate","ok":true}"#);
8464
}
@@ -95,10 +75,7 @@ async fn owner_change_via_change_owner_token() {
9575

9676
let krate = CrateBuilder::new("foo_crate", token.as_model().user_id).expect_build(&mut conn);
9777

98-
let url = format!("/api/v1/crates/{}/owners", krate.name);
99-
let body = json!({ "owners": [user2.gh_login] });
100-
let body = serde_json::to_vec(&body).unwrap();
101-
let response = token.put::<()>(&url, body).await;
78+
let response = token.add_named_owner(&krate.name, &user2.gh_login).await;
10279
assert_eq!(response.status(), StatusCode::OK);
10380
assert_snapshot!(response.text(), @r#"{"msg":"user user-2 has been invited to be an owner of crate foo_crate","ok":true}"#);
10481
}
@@ -115,10 +92,7 @@ async fn owner_change_via_change_owner_token_with_matching_crate_scope() {
11592

11693
let krate = CrateBuilder::new("foo_crate", token.as_model().user_id).expect_build(&mut conn);
11794

118-
let url = format!("/api/v1/crates/{}/owners", krate.name);
119-
let body = json!({ "owners": [user2.gh_login] });
120-
let body = serde_json::to_vec(&body).unwrap();
121-
let response = token.put::<()>(&url, body).await;
95+
let response = token.add_named_owner(&krate.name, &user2.gh_login).await;
12296
assert_eq!(response.status(), StatusCode::OK);
12397
assert_snapshot!(response.text(), @r#"{"msg":"user user-2 has been invited to be an owner of crate foo_crate","ok":true}"#);
12498
}
@@ -135,10 +109,7 @@ async fn owner_change_via_change_owner_token_with_wrong_crate_scope() {
135109

136110
let krate = CrateBuilder::new("foo_crate", token.as_model().user_id).expect_build(&mut conn);
137111

138-
let url = format!("/api/v1/crates/{}/owners", krate.name);
139-
let body = json!({ "owners": [user2.gh_login] });
140-
let body = serde_json::to_vec(&body).unwrap();
141-
let response = token.put::<()>(&url, body).await;
112+
let response = token.add_named_owner(&krate.name, &user2.gh_login).await;
142113
assert_eq!(response.status(), StatusCode::FORBIDDEN);
143114
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"this token does not have the required permissions to perform this action"}]}"#);
144115
}
@@ -155,10 +126,7 @@ async fn owner_change_via_publish_token() {
155126

156127
let krate = CrateBuilder::new("foo_crate", token.as_model().user_id).expect_build(&mut conn);
157128

158-
let url = format!("/api/v1/crates/{}/owners", krate.name);
159-
let body = json!({ "owners": [user2.gh_login] });
160-
let body = serde_json::to_vec(&body).unwrap();
161-
let response = token.put::<()>(&url, body).await;
129+
let response = token.add_named_owner(&krate.name, &user2.gh_login).await;
162130
assert_eq!(response.status(), StatusCode::FORBIDDEN);
163131
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"this token does not have the required permissions to perform this action"}]}"#);
164132
}
@@ -173,10 +141,7 @@ async fn owner_change_without_auth() {
173141

174142
let krate = CrateBuilder::new("foo_crate", cookie.as_model().id).expect_build(&mut conn);
175143

176-
let url = format!("/api/v1/crates/{}/owners", krate.name);
177-
let body = json!({ "owners": [user2.gh_login] });
178-
let body = serde_json::to_vec(&body).unwrap();
179-
let response = anon.put::<()>(&url, body).await;
144+
let response = anon.add_named_owner(&krate.name, &user2.gh_login).await;
180145
assert_eq!(response.status(), StatusCode::FORBIDDEN);
181146
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"this action requires authentication"}]}"#);
182147
}
@@ -294,10 +259,7 @@ async fn test_unknown_crate() {
294259
let (app, _, user) = TestApp::full().with_user();
295260
app.db_new_user("bar");
296261

297-
let body = json!({ "owners": ["bar"] });
298-
let body = serde_json::to_vec(&body).unwrap();
299-
300-
let response = user.put::<()>("/api/v1/crates/unknown/owners", body).await;
262+
let response = user.add_named_owner("unknown", "bar").await;
301263
assert_eq!(response.status(), StatusCode::NOT_FOUND);
302264
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"crate `unknown` does not exist"}]}"#);
303265
}
@@ -309,8 +271,7 @@ async fn test_unknown_user() {
309271

310272
CrateBuilder::new("foo", cookie.as_model().id).expect_build(&mut conn);
311273

312-
let body = serde_json::to_vec(&json!({ "owners": ["unknown"] })).unwrap();
313-
let response = cookie.put::<()>("/api/v1/crates/foo/owners", body).await;
274+
let response = cookie.add_named_owner("foo", "unknown").await;
314275
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
315276
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"could not find user with login `unknown`"}]}"#);
316277
}
@@ -322,8 +283,9 @@ async fn test_unknown_team() {
322283

323284
CrateBuilder::new("foo", cookie.as_model().id).expect_build(&mut conn);
324285

325-
let body = serde_json::to_vec(&json!({ "owners": ["github:unknown:unknown"] })).unwrap();
326-
let response = cookie.put::<()>("/api/v1/crates/foo/owners", body).await;
286+
let response = cookie
287+
.add_named_owner("foo", "github:unknown:unknown")
288+
.await;
327289
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
328290
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"could not find the github team unknown/unknown. Make sure that you have the right permissions in GitHub. See https://doc.rust-lang.org/cargo/reference/publishing.html#github-permissions"}]}"#);
329291
}

src/tests/routes/crates/owners/remove.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ async fn test_unknown_crate() {
4141
let (app, _, user) = TestApp::full().with_user();
4242
app.db_new_user("bar");
4343

44-
let body = json!({ "owners": ["bar"] });
45-
let body = serde_json::to_vec(&body).unwrap();
46-
47-
let response = user
48-
.delete_with_body::<()>("/api/v1/crates/unknown/owners", body)
49-
.await;
44+
let response = user.remove_named_owner("unknown", "bar").await;
5045
assert_eq!(response.status(), StatusCode::NOT_FOUND);
5146
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"crate `unknown` does not exist"}]}"#);
5247
}
@@ -58,10 +53,7 @@ async fn test_unknown_user() {
5853

5954
CrateBuilder::new("foo", cookie.as_model().id).expect_build(&mut conn);
6055

61-
let body = serde_json::to_vec(&json!({ "owners": ["unknown"] })).unwrap();
62-
let response = cookie
63-
.delete_with_body::<()>("/api/v1/crates/foo/owners", body)
64-
.await;
56+
let response = cookie.remove_named_owner("foo", "unknown").await;
6557
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
6658
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"could not find user with login `unknown`"}]}"#);
6759
}
@@ -73,9 +65,8 @@ async fn test_unknown_team() {
7365

7466
CrateBuilder::new("foo", cookie.as_model().id).expect_build(&mut conn);
7567

76-
let body = serde_json::to_vec(&json!({ "owners": ["github:unknown:unknown"] })).unwrap();
7768
let response = cookie
78-
.delete_with_body::<()>("/api/v1/crates/foo/owners", body)
69+
.remove_named_owner("foo", "github:unknown:unknown")
7970
.await;
8071
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
8172
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"could not find team with login `github:unknown:unknown`"}]}"#);

src/tests/util.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
use crate::middleware::session;
2323
use crate::models::{ApiToken, CreatedApiToken, User};
2424
use crate::tests::{
25-
CategoryListResponse, CategoryResponse, CrateList, CrateResponse, GoodCrate, OkBool,
25+
CategoryListResponse, CategoryResponse, CrateList, CrateResponse, GoodCrate, OwnerResp,
2626
OwnersResponse, VersionResponse,
2727
};
2828

@@ -221,6 +221,33 @@ pub trait RequestHelper {
221221
let url = "/api/v1/categories";
222222
self.get(url).await.good()
223223
}
224+
225+
/// Add to the specified crate the specified owners.
226+
async fn add_named_owners<T>(&self, krate_name: &str, owners: &[T]) -> Response<OwnerResp>
227+
where
228+
T: serde::Serialize,
229+
{
230+
let url = format!("/api/v1/crates/{krate_name}/owners");
231+
let body = json!({ "owners": owners }).to_string();
232+
self.put(&url, body).await
233+
}
234+
235+
/// Add a single owner to the specified crate.
236+
async fn add_named_owner(&self, krate_name: &str, owner: &str) -> Response<OwnerResp> {
237+
self.add_named_owners(krate_name, &[owner]).await
238+
}
239+
240+
/// Remove from the specified crate the specified owners.
241+
async fn remove_named_owners(&self, krate_name: &str, owners: &[&str]) -> Response<OwnerResp> {
242+
let url = format!("/api/v1/crates/{krate_name}/owners");
243+
let body = json!({ "owners": owners }).to_string();
244+
self.delete_with_body(&url, body).await
245+
}
246+
247+
/// Remove a single owner to the specified crate.
248+
async fn remove_named_owner(&self, krate_name: &str, owner: &str) -> Response<OwnerResp> {
249+
self.remove_named_owners(krate_name, &[owner]).await
250+
}
224251
}
225252

226253
fn req(method: Method, path: &str) -> MockRequest {
@@ -345,31 +372,4 @@ impl MockTokenUser {
345372
pub fn plaintext(&self) -> &PlainToken {
346373
&self.token.plaintext
347374
}
348-
349-
/// Add to the specified crate the specified owners.
350-
pub async fn add_named_owners<T>(&self, krate_name: &str, owners: &[T]) -> Response<OkBool>
351-
where
352-
T: serde::Serialize,
353-
{
354-
let url = format!("/api/v1/crates/{krate_name}/owners");
355-
let body = json!({ "owners": owners }).to_string();
356-
self.put(&url, body).await
357-
}
358-
359-
/// Add a single owner to the specified crate.
360-
pub async fn add_named_owner(&self, krate_name: &str, owner: &str) -> Response<OkBool> {
361-
self.add_named_owners(krate_name, &[owner]).await
362-
}
363-
364-
/// Remove from the specified crate the specified owners.
365-
pub async fn remove_named_owners(&self, krate_name: &str, owners: &[&str]) -> Response<OkBool> {
366-
let url = format!("/api/v1/crates/{krate_name}/owners");
367-
let body = json!({ "owners": owners }).to_string();
368-
self.delete_with_body(&url, body).await
369-
}
370-
371-
/// Remove a single owner to the specified crate.
372-
pub async fn remove_named_owner(&self, krate_name: &str, owner: &str) -> Response<OkBool> {
373-
self.remove_named_owners(krate_name, &[owner]).await
374-
}
375375
}

0 commit comments

Comments
 (0)