diff --git a/src/tests/krate.rs b/src/tests/krate.rs index f2f73239bbd..e37960180c1 100644 --- a/src/tests/krate.rs +++ b/src/tests/krate.rs @@ -677,6 +677,7 @@ fn summary_doesnt_die() { #[test] fn download() { + use ::time::{Duration, now_utc, strftime}; let (_b, app, middle) = ::app(); let mut req = ::req(app, Method::Get, "/api/v1/crates/foo_download/1.0.0/download"); ::mock_user(&mut req, ::user("foo")); @@ -697,6 +698,21 @@ fn download() { let mut resp = ok_resp!(middle.call(&mut req)); let downloads = ::json::(&mut resp); assert_eq!(downloads.version_downloads.len(), 1); + + let yesterday = now_utc() + Duration::days(-1); + req.with_path("/api/v1/crates/FOO_DOWNLOAD/1.0.0/downloads"); + req.with_query(&("before_date=".to_string() + &strftime("%Y-%m-%d", &yesterday).unwrap())); + let mut resp = ok_resp!(middle.call(&mut req)); + let downloads = ::json::(&mut resp); + assert_eq!(downloads.version_downloads.len(), 0); + + let tomorrow = now_utc() + Duration::days(1); + req.with_path("/api/v1/crates/FOO_DOWNLOAD/1.0.0/downloads"); + req.with_query(&("before_date=".to_string() + &strftime("%Y-%m-%d", &tomorrow).unwrap())); + let mut resp = ok_resp!(middle.call(&mut req)); + let downloads = ::json::(&mut resp); + assert_eq!(downloads.version_downloads.len(), 1); + } #[test] diff --git a/src/version.rs b/src/version.rs index 6815074db85..a6f0cb356c0 100644 --- a/src/version.rs +++ b/src/version.rs @@ -6,8 +6,7 @@ use pg::GenericConnection; use pg::rows::Row; use rustc_serialize::json; use semver; -use time::Duration; -use time::Timespec; +use time::{Duration, Timespec, now_utc, strptime}; use url; use {Model, Crate}; @@ -301,15 +300,17 @@ pub fn dependencies(req: &mut Request) -> CargoResult { /// Handles the `GET /crates/:crate_id/:version/downloads` route. pub fn downloads(req: &mut Request) -> CargoResult { let (version, _) = version_and_crate(req)?; + let cutoff_end_date = req.query().get("before_date") + .and_then(|d| strptime(d, "%Y-%m-%d").ok()) + .unwrap_or(now_utc()).to_timespec(); + let cutoff_start_date = cutoff_end_date + Duration::days(-89); let tx = req.tx()?; - let cutoff_date = ::now() + Duration::days(-90); let stmt = tx.prepare("SELECT * FROM version_downloads - WHERE date > $1 AND version_id = $2 + WHERE date BETWEEN $1 AND $2 AND version_id = $3 ORDER BY date ASC")?; - let downloads = stmt.query(&[&cutoff_date, &version.id])?.iter().map(|row| { - VersionDownload::from_row(&row).encodable() - }).collect(); + let downloads = stmt.query(&[&cutoff_start_date, &cutoff_end_date, &version.id])? + .iter().map(|row| VersionDownload::from_row(&row).encodable()).collect(); #[derive(RustcEncodable)] struct R { version_downloads: Vec }