Skip to content

Commit 86a9270

Browse files
committed
Add a test demonstrating requests sent as two users
1 parent 1785f8e commit 86a9270

File tree

7 files changed

+155
-19
lines changed

7 files changed

+155
-19
lines changed

src/tests/helpers/app.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::request::RequestBuilder;
2-
use cargo_registry::models::{ApiToken, NewUser, User};
2+
use cargo_registry::models::{ApiToken, Email, NewUser, User};
33
use cargo_registry::util::CargoResult;
44
use conduit::Method;
55
use conduit_middleware::MiddlewareBuilder;
@@ -9,12 +9,17 @@ use std::sync::Arc;
99
pub struct App {
1010
app: Arc<cargo_registry::App>,
1111
middleware: MiddlewareBuilder,
12+
_bomb: crate::record::Bomb,
1213
}
1314

1415
impl App {
1516
pub fn new() -> Self {
16-
let (app, middleware) = crate::simple_app(None);
17-
Self { app, middleware }
17+
let (bomb, app, middleware) = crate::app();
18+
Self {
19+
app,
20+
middleware,
21+
_bomb: bomb,
22+
}
1823
}
1924

2025
/// Obtain the database connection and pass it to the closure
@@ -33,12 +38,18 @@ impl App {
3338

3439
/// Create a new user in the database with the given id
3540
pub fn create_user(&self, username: &str) -> CargoResult<User> {
41+
use cargo_registry::schema::emails;
42+
3643
self.db(|conn| {
3744
let new_user = NewUser {
3845
email: Some("[email protected]"),
3946
..crate::new_user(username)
4047
};
41-
Ok(new_user.create_or_update(conn)?)
48+
let user = new_user.create_or_update(conn)?;
49+
diesel::update(Email::belonging_to(&user))
50+
.set(emails::verified.eq(true))
51+
.execute(conn)?;
52+
Ok(user)
4253
})
4354
}
4455

@@ -58,6 +69,11 @@ impl App {
5869
RequestBuilder::new(&self.middleware, Method::Get, path)
5970
}
6071

72+
/// Create an HTTP `PUT` request
73+
pub fn put(&self, path: &str) -> RequestBuilder<'_> {
74+
RequestBuilder::new(&self.middleware, Method::Put, path)
75+
}
76+
6177
/// Create an HTTP `DELETE` request
6278
pub fn delete(&self, path: &str) -> RequestBuilder<'_> {
6379
RequestBuilder::new(&self.middleware, Method::Delete, path)

src/tests/helpers/request.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::response::{Response, ResponseError};
2-
use cargo_registry::models::ApiToken;
3-
use conduit::{Handler, Method};
2+
use cargo_registry::models::{ApiToken, User};
3+
use conduit::{Handler, Method, Request};
44
use conduit_middleware::MiddlewareBuilder;
55
use conduit_test::MockRequest;
66

@@ -18,6 +18,16 @@ impl<'a> RequestBuilder<'a> {
1818
.with_header("User-Agent", "conduit-test")
1919
}
2020

21+
/// Sends the request signed in as the given user
22+
pub fn as_user(mut self, user: &User) -> Self {
23+
use cargo_registry::middleware::current_user::AuthenticationSource;
24+
self.request.mut_extensions().insert(user.clone());
25+
self.request
26+
.mut_extensions()
27+
.insert(AuthenticationSource::SessionCookie);
28+
self
29+
}
30+
2131
/// Uses the given token for authentication
2232
pub fn with_token(self, token: &ApiToken) -> Self {
2333
self.with_header("Authorization", &token.token)
@@ -28,6 +38,11 @@ impl<'a> RequestBuilder<'a> {
2838
self
2939
}
3040

41+
pub fn with_body<T: Into<Vec<u8>>>(mut self, body: T) -> Self {
42+
self.request.with_body(&body.into());
43+
self
44+
}
45+
3146
/// Send the request
3247
///
3348
/// Returns an error if any of the middlewares returned an error, or if

src/tests/helpers/response.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ impl Response {
3333
pub fn text(&self) -> &str {
3434
&self.body
3535
}
36+
37+
pub fn json<'a, T>(&'a self) -> CargoResult<T>
38+
where
39+
T: serde::Deserialize<'a>,
40+
{
41+
serde_json::from_str(self.text()).map_err(Into::into)
42+
}
3643
}
3744

3845
pub enum ResponseError {
@@ -52,8 +59,8 @@ impl fmt::Debug for ResponseError {
5259
use ResponseError::*;
5360
match self {
5461
MiddlewareError(e) => write!(f, "MiddlewareError({:?})", e),
55-
BadRequest(_) => write!(f, "BadRequest(_)"),
56-
ServerError(_) => write!(f, "ServerError(_)"),
62+
BadRequest(e) => write!(f, "BadRequest({:?})", e.text()),
63+
ServerError(e) => write!(f, "ServerError({:?})", e.text()),
5764
}
5865
}
5966
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
[
2+
{
3+
"request": {
4+
"uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo_not/foo_not-1.0.0.crate",
5+
"method": "PUT",
6+
"headers": [
7+
[
8+
"host",
9+
"alexcrichton-test.s3.amazonaws.com"
10+
],
11+
[
12+
"date",
13+
"Fri, 15 Sep 2017 07:53:06 -0700"
14+
],
15+
[
16+
"accept",
17+
"*/*"
18+
],
19+
[
20+
"user-agent",
21+
"reqwest/0.9.1"
22+
],
23+
[
24+
"authorization",
25+
"AWS AKIAICL5IWUZYWWKA7JA:xCp3sUdUdmScjI6ct58zFv6BoGQ="
26+
],
27+
[
28+
"content-length",
29+
"35"
30+
],
31+
[
32+
"accept-encoding",
33+
"gzip"
34+
],
35+
[
36+
"content-type",
37+
"application/x-tar"
38+
]
39+
],
40+
"body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA="
41+
},
42+
"response": {
43+
"status": 200,
44+
"headers": [
45+
[
46+
"ETag",
47+
"\"f9016ad360cebb4fe2e6e96e5949f022\""
48+
],
49+
[
50+
"x-amz-id-2",
51+
"FCKNKZUo5EeUNwVyhZ9P7ehfXoctqePzXx2RSE1VxoSX9rdfskkyAJUNHAF2AQojRon00LfTLPY="
52+
],
53+
[
54+
"x-amz-request-id",
55+
"3233F8227A852593"
56+
],
57+
[
58+
"Server",
59+
"AmazonS3"
60+
],
61+
[
62+
"content-length",
63+
"0"
64+
],
65+
[
66+
"date",
67+
"Fri, 15 Sep 2017 14:53:07 GMT"
68+
]
69+
],
70+
"body": ""
71+
}
72+
}
73+
]

src/tests/krate.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::prelude::*;
12
use crate::{
23
builders::{CrateBuilder, DependencyBuilder, PublishBuilder, VersionBuilder},
34
new_category, new_dependency, new_user, CrateMeta, CrateResponse, GoodCrate, OkBool,
@@ -75,6 +76,16 @@ impl crate::util::MockTokenUser {
7576
}
7677
}
7778

79+
fn yank_request<'a>(app: &'a App, krate_name: &str, version: &str) -> RequestBuilder<'a> {
80+
let url = format!("/api/v1/crates/{}/{}/yank", krate_name, version);
81+
app.delete(&url)
82+
}
83+
84+
fn publish_request<'a>(app: &'a App, publish_builder: PublishBuilder) -> RequestBuilder<'a> {
85+
app.put("/api/v1/crates/new")
86+
.with_body(publish_builder.body())
87+
}
88+
7889
#[test]
7990
fn index() {
8091
let (app, anon) = TestApp::init().empty();
@@ -1403,19 +1414,31 @@ fn yank() {
14031414
}
14041415

14051416
#[test]
1406-
fn yank_not_owner() {
1407-
let (app, _, _, token) = TestApp::init().with_token();
1408-
let another_user = app.db_new_user("bar");
1409-
let another_user = another_user.as_model();
1410-
app.db(|conn| {
1411-
CrateBuilder::new("foo_not", another_user.id).expect_build(conn);
1412-
});
1417+
fn only_owners_can_yank() -> CargoResult<()> {
1418+
let app = App::new();
1419+
let owner = app.create_user("owner")?;
1420+
1421+
let crate_to_publish = PublishBuilder::new("foo_not");
1422+
publish_request(&app, crate_to_publish)
1423+
.as_user(&owner)
1424+
.send()?;
14131425

1414-
let json = token.yank("foo_not", "1.0.0").bad_with_status(200);
1426+
let user_yank_result = yank_request(&app, "foo_not", "1.0.0")
1427+
.as_user(&app.create_user("new_user")?)
1428+
.send()? // FIXME: We should return 403 here not 200
1429+
.json::<ErrorDetails>()?;
14151430
assert_eq!(
1416-
json.errors[0].detail,
1417-
"crate `foo_not` does not have a version `1.0.0`"
1431+
user_yank_result.errors[0].detail,
1432+
"must already be an owner to yank or unyank",
14181433
);
1434+
1435+
let owner_yank_result = yank_request(&app, "foo_not", "1.0.0")
1436+
.as_user(&owner)
1437+
.send()?
1438+
.json::<OkBool>()?;
1439+
assert!(owner_yank_result.ok);
1440+
1441+
Ok(())
14191442
}
14201443

14211444
#[test]

src/tests/prelude.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
pub use crate::helpers::app::*;
2+
pub use crate::helpers::request::RequestBuilder;
23
pub use crate::helpers::response::ResultExt as _;
4+
pub use crate::util::Bad as ErrorDetails;
35
pub use cargo_registry::util::CargoResult;

src/tests/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ pub struct Error {
332332
pub detail: String,
333333
}
334334

335-
#[derive(Deserialize)]
335+
#[derive(Deserialize, Debug)]
336336
pub struct Bad {
337337
pub errors: Vec<Error>,
338338
}

0 commit comments

Comments
 (0)