-
Notifications
You must be signed in to change notification settings - Fork 605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Team page #790
Team page #790
Changes from 1 commit
850f693
1a9d58a
2a33f2b
5b4ca02
d0e0282
f2dd45a
60ac320
4a72903
e2c1a3c
fe02763
7b0661e
e1794d3
500f9af
ca637bc
6da41f9
f8e595a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,12 +31,15 @@ use cargo_registry::keyword::Keyword; | |
use cargo_registry::krate::NewCrate; | ||
use cargo_registry::upload as u; | ||
use cargo_registry::user::NewUser; | ||
use cargo_registry::owner::{CrateOwner, NewTeam, Team}; | ||
use cargo_registry::version::NewVersion; | ||
use cargo_registry::{User, Crate, Version, Dependency, Category, Model, Replica}; | ||
use conduit::{Request, Method}; | ||
use conduit_test::MockRequest; | ||
use diesel::pg::PgConnection; | ||
use diesel::prelude::*; | ||
use diesel::pg::upsert::*; | ||
use cargo_registry::schema::*; | ||
|
||
macro_rules! t { | ||
($e:expr) => ( | ||
|
@@ -212,6 +215,37 @@ fn user(login: &str) -> User { | |
} | ||
} | ||
|
||
fn new_team(login: &str) -> NewTeam { | ||
NewTeam { | ||
github_id: NEXT_ID.fetch_add(1, Ordering::SeqCst) as i32, | ||
login: login, | ||
name: None, | ||
avatar: None, | ||
} | ||
} | ||
|
||
fn add_team_to_crate( | ||
t: &Team, | ||
krate: &Crate, | ||
u: &User, | ||
conn: &PgConnection) -> CargoResult<()> { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✂️ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're just talking about cutting the newline here, right? #ambiguousemoji |
||
let crate_owner = CrateOwner { | ||
crate_id: krate.id, | ||
owner_id: t.id, | ||
created_by: u.id, | ||
owner_kind: 1, // Team owner kind is 1 according to owner.rs | ||
}; | ||
|
||
diesel::insert(&crate_owner.on_conflict( | ||
crate_owners::table.primary_key(), | ||
do_update().set(crate_owners::deleted.eq(false)), | ||
)).into(crate_owners::table) | ||
.execute(conn)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
use cargo_registry::util::CargoResult; | ||
|
||
struct CrateBuilder<'a> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ use cargo_registry::upload as u; | |
use cargo_registry::user::EncodableUser; | ||
use cargo_registry::version::EncodableVersion; | ||
use cargo_registry::category::Category; | ||
use cargo_registry::owner::EncodableOwner; | ||
|
||
#[derive(RustcDecodable)] | ||
struct CrateList { | ||
|
@@ -61,6 +62,10 @@ struct RevDeps { | |
struct Downloads { | ||
version_downloads: Vec<EncodableVersionDownload>, | ||
} | ||
#[derive(RustcDecodable)] | ||
struct TeamResponse { teams: Vec<EncodableOwner> } | ||
#[derive(RustcDecodable)] | ||
struct UserResponse { users: Vec<EncodableOwner> } | ||
|
||
fn new_crate(name: &str) -> u::NewCrate { | ||
u::NewCrate { | ||
|
@@ -1740,3 +1745,95 @@ fn author_license_and_description_required() { | |
json.errors | ||
); | ||
} | ||
|
||
/* Testing the crate ownership between two crates and one team. | ||
Given two crates, one crate owned by both a team and a user, | ||
one only owned by a user, check that the CrateList returned | ||
for the user_id contains only the crates owned by that user, | ||
and that the CrateList returned for the team_id contains | ||
only crates owned by that team. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😻 love these comments!! |
||
*/ | ||
#[test] | ||
fn check_ownership_two_crates() { | ||
let (_b, app, middle) = ::app(); | ||
|
||
let (krate_owned_by_team, team) = { | ||
let conn = app.diesel_database.get().unwrap(); | ||
let u = ::new_user("user_foo") | ||
.create_or_update(&conn) | ||
.unwrap(); | ||
let t = ::new_team("team_foo") | ||
.create_or_update(&conn) | ||
.unwrap(); | ||
let krate = ::CrateBuilder::new("foo", u.id) | ||
.expect_build(&conn); | ||
::add_team_to_crate(&t, &krate, &u, &conn).unwrap(); | ||
(krate, t) | ||
}; | ||
|
||
let (krate_not_owned_by_team, user) = { | ||
let conn = app.diesel_database.get().unwrap(); | ||
let u = ::new_user("user_bar") | ||
.create_or_update(&conn) | ||
.unwrap(); | ||
(::CrateBuilder::new("bar", u.id) | ||
.expect_build(&conn), u) | ||
}; | ||
|
||
let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates"); | ||
|
||
let query = format!("user_id={}", user.id); | ||
let mut response = ok_resp!(middle.call(req.with_query(&query))); | ||
let json: CrateList = ::json(&mut response); | ||
|
||
assert_eq!(json.crates[0].name, krate_not_owned_by_team.name); | ||
assert_eq!(json.crates.len(), 1); | ||
|
||
let query = format!("team_id={}", team.id); | ||
let mut response = ok_resp!(middle.call(req.with_query(&query))); | ||
|
||
let json: CrateList = ::json(&mut response); | ||
assert_eq!(json.crates.len(), 1); | ||
assert_eq!(json.crates[0].name, krate_owned_by_team.name); | ||
} | ||
|
||
/* Given a crate owned by both a team and a user, check that the | ||
JSON returned by the /owner_team route and /owner_user route | ||
contains the correct kind of owner | ||
|
||
Note that in this case function new_team must take a team name | ||
of form github:org_name:team_name as that is the format | ||
EncodableOwner::encodable is expecting | ||
*/ | ||
#[test] | ||
fn check_ownership_one_crate() { | ||
let (_b, app, middle) = ::app(); | ||
|
||
let (team, user) = { | ||
let conn = app.diesel_database.get().unwrap(); | ||
let u = ::new_user("user_cat") | ||
.create_or_update(&conn) | ||
.unwrap(); | ||
let t = ::new_team("github:test_org:team_sloth") | ||
.create_or_update(&conn) | ||
.unwrap(); | ||
let krate = ::CrateBuilder::new("best_crate", u.id) | ||
.expect_build(&conn); | ||
::add_team_to_crate(&t, &krate, &u, &conn).unwrap(); | ||
(t, u) | ||
}; | ||
|
||
let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates/best_crate/owner_team"); | ||
let mut response = ok_resp!(middle.call(&mut req)); | ||
let json: TeamResponse = ::json(&mut response); | ||
|
||
assert_eq!(json.teams[0].kind, "team"); | ||
assert_eq!(json.teams[0].name, team.name); | ||
|
||
let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates/best_crate/owner_user"); | ||
let mut response = ok_resp!(middle.call(&mut req)); | ||
let json: UserResponse = ::json(&mut response); | ||
|
||
assert_eq!(json.users[0].kind, "user"); | ||
assert_eq!(json.users[0].name, user.name); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to put this on
index
instead of adding a new route?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with how getting a user's crates works, mostly. If we're going to pull this out into its own route, then I think users should be pulled out too, which imo should be a separate PR. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that users should be pulled out as well, but I don't think that should block this PR being a separate route, if it's not significantly more work for this PR.