Skip to content

Commit 7558f73

Browse files
authored
Merge pull request #398 from lazypenguin/master
Fix sort order in crates api
2 parents 0e8957e + 4b343a8 commit 7558f73

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

src/krate.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,12 +469,17 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
469469
let mut args = vec![&limit as &ToSql, &offset];
470470
let (q, cnt) = query.get("q").map(|query| {
471471
args.insert(0, query);
472+
let rank_sort_sql = match sort {
473+
"downloads" => format!("{}, rank DESC", sort_sql),
474+
_ => format!("rank DESC, {}", sort_sql),
475+
};
476+
format!("{},", sort_sql); // Append Comma
472477
(format!("SELECT crates.* FROM crates,
473478
plainto_tsquery($1) q,
474479
ts_rank_cd(textsearchable_index_col, q) rank
475480
WHERE q @@ textsearchable_index_col
476-
ORDER BY name = $1 DESC, rank DESC, {}
477-
LIMIT $2 OFFSET $3", sort_sql),
481+
ORDER BY name = $1 DESC, {}
482+
LIMIT $2 OFFSET $3", rank_sort_sql),
478483
"SELECT COUNT(crates.*) FROM crates,
479484
plainto_tsquery($1) q
480485
WHERE q @@ textsearchable_index_col".to_string())

src/tests/krate.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,72 @@ fn exact_match_first_on_queries() {
168168
assert_eq!(json.crates[2].name, "foo");
169169
}
170170

171+
#[test]
172+
fn exact_match_on_queries_with_sort() {
173+
let (_b, app, middle) = ::app();
174+
175+
let mut req = ::req(app, Method::Get, "/api/v1/crates");
176+
let _ = ::mock_user(&mut req, ::user("foo"));
177+
let mut krate = ::krate("foo");
178+
krate.description = Some("bar baz const".to_string());
179+
krate.downloads = 50;
180+
let (k, _) = ::mock_crate(&mut req, krate.clone());
181+
let mut krate2 = ::krate("bar");
182+
krate2.description = Some("foo baz foo baz const".to_string());
183+
krate2.downloads = 3333;
184+
let (k2, _) = ::mock_crate(&mut req, krate2.clone());
185+
let mut krate3 = ::krate("baz");
186+
krate3.description = Some("foo bar foo bar foo bar const".to_string());
187+
krate3.downloads = 100000;
188+
let (k3, _) = ::mock_crate(&mut req, krate3.clone());
189+
let mut krate4 = ::krate("other");
190+
krate4.description = Some("other const".to_string());
191+
krate4.downloads = 999999;
192+
let (k4, _) = ::mock_crate(&mut req, krate4.clone());
193+
194+
{
195+
let req2: &mut Request = &mut req;
196+
let tx = req2.tx().unwrap();
197+
tx.execute("UPDATE crates set downloads = $1
198+
WHERE id = $2", &[&krate.downloads, &k.id]).unwrap();
199+
tx.execute("UPDATE crates set downloads = $1
200+
WHERE id = $2", &[&krate2.downloads, &k2.id]).unwrap();
201+
tx.execute("UPDATE crates set downloads = $1
202+
WHERE id = $2", &[&krate3.downloads, &k3.id]).unwrap();
203+
tx.execute("UPDATE crates set downloads = $1
204+
WHERE id = $2", &[&krate4.downloads, &k4.id]).unwrap();
205+
}
206+
207+
let mut response = ok_resp!(middle.call(req.with_query("q=foo&sort=downloads")));
208+
let json: CrateList = ::json(&mut response);
209+
assert_eq!(json.meta.total, 3);
210+
assert_eq!(json.crates[0].name, "foo");
211+
assert_eq!(json.crates[1].name, "baz");
212+
assert_eq!(json.crates[2].name, "bar");
213+
214+
let mut response = ok_resp!(middle.call(req.with_query("q=bar&sort=downloads")));
215+
let json: CrateList = ::json(&mut response);
216+
assert_eq!(json.meta.total, 3);
217+
assert_eq!(json.crates[0].name, "bar");
218+
assert_eq!(json.crates[1].name, "baz");
219+
assert_eq!(json.crates[2].name, "foo");
220+
221+
let mut response = ok_resp!(middle.call(req.with_query("q=baz&sort=downloads")));
222+
let json: CrateList = ::json(&mut response);
223+
assert_eq!(json.meta.total, 3);
224+
assert_eq!(json.crates[0].name, "baz");
225+
assert_eq!(json.crates[1].name, "bar");
226+
assert_eq!(json.crates[2].name, "foo");
227+
228+
let mut response = ok_resp!(middle.call(req.with_query("q=const&sort=downloads")));
229+
let json: CrateList = ::json(&mut response);
230+
assert_eq!(json.meta.total, 4);
231+
assert_eq!(json.crates[0].name, "other");
232+
assert_eq!(json.crates[1].name, "baz");
233+
assert_eq!(json.crates[2].name, "bar");
234+
assert_eq!(json.crates[3].name, "foo");
235+
}
236+
171237
#[test]
172238
fn show() {
173239
let (_b, app, middle) = ::app();

0 commit comments

Comments
 (0)