Skip to content

Commit 000ce86

Browse files
committed
Auto merge of #1940 - integer32llc:owned-crates-shouldnt-include-deleted, r=smarnach
Use `CrateOwner::by_owner_kind` everywhere to exclude deleted ownerships I found some places I missed checking for where we should be using the new `CrateOwner::by_owner_kind` helper method added in 6d94155 that adds the filter for `deleted` being false. I've also added one test that currently passes and two tests that failed before this fix to hopefully cover everywhere that selects crate owners; the other places already have tests.
2 parents d05c351 + 9c32906 commit 000ce86

File tree

4 files changed

+48
-10
lines changed

4 files changed

+48
-10
lines changed

src/controllers/user/me.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ pub fn me(req: &mut dyn Request) -> AppResult<Response> {
3838
))
3939
.first::<(User, Option<bool>, Option<String>, bool)>(&*conn)?;
4040

41-
let owned_crates = crate_owners::table
41+
let owned_crates = CrateOwner::by_owner_kind(OwnerKind::User)
4242
.inner_join(crates::table)
4343
.filter(crate_owners::owner_id.eq(user_id))
44-
.filter(crate_owners::owner_kind.eq(OwnerKind::User as i32))
4544
.select((crates::id, crates::name, crate_owners::email_notifications))
4645
.order(crates::name.asc())
4746
.load(&*conn)?

src/controllers/user/other.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::controllers::prelude::*;
22

3-
use crate::models::{OwnerKind, User};
3+
use crate::models::{CrateOwner, OwnerKind, User};
44
use crate::schema::{crate_owners, crates, users};
55
use crate::views::EncodablePublicUser;
66

@@ -31,13 +31,9 @@ pub fn stats(req: &mut dyn Request) -> AppResult<Response> {
3131
let user_id = &req.params()["user_id"].parse::<i32>().ok().unwrap();
3232
let conn = req.db_conn()?;
3333

34-
let data = crate_owners::table
34+
let data = CrateOwner::by_owner_kind(OwnerKind::User)
3535
.inner_join(crates::table)
36-
.filter(
37-
crate_owners::owner_id
38-
.eq(user_id)
39-
.and(crate_owners::owner_kind.eq(OwnerKind::User as i32)),
40-
)
36+
.filter(crate_owners::owner_id.eq(user_id))
4137
.select(sum(crates::downloads))
4238
.first::<Option<i64>>(&*conn)?
4339
.unwrap_or(0);

src/tests/owners.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,22 @@ fn check_ownership_one_crate() {
268268
assert_eq!(json.users[0].name, user.name);
269269
}
270270

271+
#[test]
272+
fn deleted_ownership_isnt_in_owner_user() {
273+
let (app, anon, user) = TestApp::init().with_user();
274+
let user = user.as_model();
275+
276+
app.db(|conn| {
277+
let krate = CrateBuilder::new("foo_my_packages", user.id).expect_build(conn);
278+
krate
279+
.owner_remove(app.as_inner(), conn, user, &user.gh_login)
280+
.unwrap();
281+
});
282+
283+
let json: UserResponse = anon.get("/api/v1/crates/foo_my_packages/owner_user").good();
284+
assert_eq!(json.users.len(), 0);
285+
}
286+
271287
#[test]
272288
fn invitations_are_empty_by_default() {
273289
let (_, _, user) = TestApp::init().with_user();

src/tests/user.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,11 +323,22 @@ fn user_total_downloads() {
323323
.set(&another_krate)
324324
.execute(conn)
325325
.unwrap();
326+
327+
let mut no_longer_my_krate = CrateBuilder::new("nacho", user.id).expect_build(conn);
328+
no_longer_my_krate.downloads = 5;
329+
update(&no_longer_my_krate)
330+
.set(&no_longer_my_krate)
331+
.execute(conn)
332+
.unwrap();
333+
no_longer_my_krate
334+
.owner_remove(app.as_inner(), conn, user, &user.gh_login)
335+
.unwrap();
326336
});
327337

328338
let url = format!("/api/v1/users/{}/stats", user.id);
329339
let stats: UserStats = anon.get(&url).good();
330-
assert_eq!(stats.total_downloads, 30); // instead of 32
340+
// does not include crates user never owned (2) or no longer owns (5)
341+
assert_eq!(stats.total_downloads, 30);
331342
}
332343

333344
#[test]
@@ -601,6 +612,22 @@ fn test_existing_user_email() {
601612
assert!(!json.user.email_verification_sent);
602613
}
603614

615+
#[test]
616+
fn test_user_owned_crates_doesnt_include_deleted_ownership() {
617+
let (app, _, user) = TestApp::init().with_user();
618+
let user_model = user.as_model();
619+
620+
app.db(|conn| {
621+
let krate = CrateBuilder::new("foo_my_packages", user_model.id).expect_build(conn);
622+
krate
623+
.owner_remove(app.as_inner(), conn, user_model, &user_model.gh_login)
624+
.unwrap();
625+
});
626+
627+
let json = user.show_me();
628+
assert_eq!(json.owned_crates.len(), 0);
629+
}
630+
604631
/* A user should be able to update the email notifications for crates they own. Only the crates that
605632
were sent in the request should be updated to the corresponding `email_notifications` value.
606633
*/

0 commit comments

Comments
 (0)