Skip to content

Commit e88e167

Browse files
author
Maurício Linhares
committed
Hides crates on index calls unless they have at least one available version
This makes the index call only show crates that have at least one available version. Crates that have all versions yanked will not show up anymore. Fixes #958
1 parent 405b2ad commit e88e167

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/krate.rs

+5
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,10 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
564564

565565
let recent_downloads = sql::<Nullable<BigInt>>("SUM(crate_downloads.downloads)");
566566

567+
let not_yanked_versions = sql::<Bool>(
568+
"crates.id = ANY (SELECT vs.crate_id FROM versions vs WHERE vs.crate_id = crates.id AND vs.yanked IS FALSE)",
569+
);
570+
567571
let mut query = crates::table
568572
.join(
569573
crate_downloads::table,
@@ -572,6 +576,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
572576
crate_downloads::date.gt(date(now - 90.days())),
573577
),
574578
)
579+
.filter(not_yanked_versions.clone())
575580
.group_by(crates::id)
576581
.select((
577582
ALL_COLUMNS,

src/tests/krate.rs

+41
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,7 @@ fn yanked_versions_not_included_in_reverse_dependencies() {
18151815
assert_eq!(deps.dependencies[0].crate_id, "c1");
18161816

18171817
// TODO: have this test call `version.yank()` once the yank method is converted to diesel
1818+
18181819
diesel::update(versions::table.filter(versions::num.eq("2.0.0")))
18191820
.set(versions::yanked.eq(true))
18201821
.execute(&*app.diesel_database.get().unwrap())
@@ -2108,6 +2109,46 @@ fn test_default_sort_recent() {
21082109
assert_eq!(json.crates[1].downloads, 20);
21092110
}
21102111

2112+
/* Given two crates, one with all versions yanked and another
2113+
with a good version only the one that doesn't have all versions
2114+
yanked is returned.
2115+
*/
2116+
#[test]
2117+
fn test_hides_yanked_crate() {
2118+
let (_b, app, middle) = ::app();
2119+
2120+
{
2121+
let conn = app.diesel_database.get().unwrap();
2122+
let user = ::new_user("Oskar").create_or_update(&conn).unwrap();
2123+
2124+
::CrateBuilder::new("green_ball", user.id)
2125+
.description("For fetching")
2126+
.downloads(0)
2127+
.recent_downloads(0)
2128+
.expect_build(&conn);
2129+
2130+
let yanked_crate = ::CrateBuilder::new("fully_yanked", user.id)
2131+
.description("Not here anymore")
2132+
.expect_build(&conn);
2133+
2134+
diesel::update(versions::table.filter(
2135+
versions::crate_id.eq(yanked_crate.id),
2136+
)).set(versions::yanked.eq(true))
2137+
.execute(&*conn)
2138+
.unwrap();
2139+
}
2140+
2141+
let mut req = ::req(app, Method::Get, "/api/v1/crates");
2142+
let mut response = ok_resp!(middle.call(req.with_query("sort=recent-downloads")));
2143+
let json: CrateList = ::json(&mut response);
2144+
2145+
assert_eq!(json.meta.total, 1);
2146+
2147+
assert_eq!(json.crates[0].name, "green_ball");
2148+
assert_eq!(json.crates[0].recent_downloads, Some(0));
2149+
assert_eq!(json.crates[0].downloads, 0);
2150+
}
2151+
21112152
#[test]
21122153
fn block_blacklisted_documentation_url() {
21132154
let (_b, app, middle) = ::app();

0 commit comments

Comments
 (0)