From 2767f2523f7d26019998a1cc1bebd9204bc4abc6 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Sat, 18 Feb 2017 10:23:08 -0500 Subject: [PATCH] Only show crate once, even if search is like several category #524 --- src/krate.rs | 18 +++++++++--------- src/tests/category.rs | 8 ++++++++ src/tests/krate.rs | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/krate.rs b/src/krate.rs index 417a5181fd5..2756618db4d 100644 --- a/src/krate.rs +++ b/src/krate.rs @@ -538,16 +538,16 @@ pub fn index(req: &mut Request) -> CargoResult { }).or_else(|| { query.get("category").map(|cat| { args.insert(0, cat); - let base = "FROM crates \ - INNER JOIN crates_categories \ - ON crates.id = crates_categories.crate_id \ - INNER JOIN categories \ - ON crates_categories.category_id = \ - categories.id \ - WHERE categories.slug = $1 OR \ + let base = "FROM crates + INNER JOIN crates_categories + ON crates.id = crates_categories.crate_id + INNER JOIN categories + ON crates_categories.category_id = + categories.id + WHERE categories.slug = $1 OR categories.slug LIKE $1 || '::%'"; - (format!("SELECT crates.* {} ORDER BY {} LIMIT $2 OFFSET $3", base, sort_sql), - format!("SELECT COUNT(crates.*) {}", base)) + (format!("SELECT DISTINCT crates.* {} ORDER BY {} LIMIT $2 OFFSET $3", base, sort_sql), + format!("SELECT COUNT(DISTINCT crates.*) {}", base)) }) }).or_else(|| { query.get("user_id").and_then(|s| s.parse::().ok()).map(|user_id| { diff --git a/src/tests/category.rs b/src/tests/category.rs index be0448b2914..3771397b9de 100644 --- a/src/tests/category.rs +++ b/src/tests/category.rs @@ -136,4 +136,12 @@ fn update_crate() { assert_eq!(cnt(&mut req, "cat1"), 0); assert_eq!(cnt(&mut req, "category-2"), 0); + // Add a category and its subcategory + ::mock_category(&mut req, "cat1::bar", "cat1::bar"); + Category::update_crate( + tx(&req), &krate, &["cat1".to_string(), + "cat1::bar".to_string()]).unwrap(); + assert_eq!(cnt(&mut req, "cat1"), 1); + assert_eq!(cnt(&mut req, "cat1::bar"), 1); + assert_eq!(cnt(&mut req, "category-2"), 0); } diff --git a/src/tests/krate.rs b/src/tests/krate.rs index 752d4e7cb7f..8b60d8b77ef 100644 --- a/src/tests/krate.rs +++ b/src/tests/krate.rs @@ -17,6 +17,7 @@ use cargo_registry::krate::{Crate, EncodableCrate}; use cargo_registry::upload as u; use cargo_registry::user::EncodableUser; use cargo_registry::version::EncodableVersion; +use cargo_registry::category::Category; #[derive(RustcDecodable)] struct CrateList { crates: Vec, meta: CrateMeta } @@ -130,6 +131,23 @@ fn index_queries() { assert_eq!(::json::(&mut response).crates.len(), 2); let mut response = ok_resp!(middle.call(req.with_query("keyword=kw2"))); assert_eq!(::json::(&mut response).crates.len(), 0); + + ::mock_category(&mut req, "cat1", "cat1"); + ::mock_category(&mut req, "cat1::bar", "cat1::bar"); + Category::update_crate(tx(&req), &krate, &["cat1".to_string(), + "cat1::bar".to_string()]).unwrap(); + let mut response = ok_resp!(middle.call(req.with_query("category=cat1"))); + let cl = ::json::(&mut response); + assert_eq!(cl.crates.len(), 1); + assert_eq!(cl.meta.total, 1); + let mut response = ok_resp!(middle.call(req.with_query("category=cat1::bar"))); + let cl = ::json::(&mut response); + assert_eq!(cl.crates.len(), 1); + assert_eq!(cl.meta.total, 1); + let mut response = ok_resp!(middle.call(req.with_query("keyword=cat2"))); + let cl = ::json::(&mut response); + assert_eq!(cl.crates.len(), 0); + assert_eq!(cl.meta.total, 0); } #[test]