diff --git a/src/test/fakes.rs b/src/test/fakes.rs index aec6590b8..f01bb182e 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -4,7 +4,7 @@ use crate::index::api::{CrateData, CrateOwner, ReleaseData}; use crate::storage::Storage; use crate::utils::{Dependency, MetadataPackage, Target}; use chrono::{DateTime, Utc}; -use failure::Error; +use failure::{Error, ResultExt}; use postgres::Client; use std::collections::HashMap; use std::sync::Arc; @@ -251,8 +251,16 @@ impl<'a> FakeRelease<'a> { // In real life, these would be highlighted HTML, but for testing we just use the files themselves. for (source_path, data) in &self.source_files { if let Some(src) = source_path.strip_prefix("src/") { - let updated = ["src", &package.name, src].join("/"); - rustdoc_files.push((Box::leak(Box::new(updated)), data)); + let mut updated = ["src", &package.name, src].join("/"); + updated += ".html"; + let source_html = format!( + "{}", + std::str::from_utf8(data).expect("invalid utf8") + ); + rustdoc_files.push(( + Box::leak(Box::new(updated)), + Box::leak(source_html.into_bytes().into_boxed_slice()), + )); } } @@ -264,9 +272,14 @@ impl<'a> FakeRelease<'a> { fs::create_dir(&path_prefix)?; for (path, data) in files { + if path.starts_with('/') { + failure::bail!("absolute paths not supported"); + } // allow `src/main.rs` if let Some(parent) = Path::new(path).parent() { - fs::create_dir_all(path_prefix.join(parent))?; + let path = path_prefix.join(parent); + fs::create_dir_all(&path) + .with_context(|_| format!("failed to create {}", path.display()))?; } let file = path_prefix.join(&path); log::debug!("writing file {}", file.display()); diff --git a/src/web/mod.rs b/src/web/mod.rs index 92c75bae8..9e2c2637d 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -799,7 +799,7 @@ mod test { assert_success("/crate/regex/0.3.0/source/src/main.rs", web)?; assert_success("/crate/regex/0.3.0/source", web)?; assert_success("/crate/regex/0.3.0/source/src", web)?; - assert_success("/regex/0.3.0/src/regex/main.rs", web)?; + assert_success("/regex/0.3.0/src/regex/main.rs.html", web)?; Ok(()) }) } diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 0d21fd9dd..7d9e25b9b 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -493,6 +493,13 @@ fn path_for_version( } else { "" }; + let is_source_view = if platform.is_empty() { + // /{name}/{version}/src/{crate}/index.html + req_path.get(3).copied() == Some("src") + } else { + // /{name}/{version}/{platform}/src/{crate}/index.html + req_path.get(4).copied() == Some("src") + }; // this page doesn't exist in the latest version let last_component = *req_path.last().unwrap(); let search_item = if last_component == "index.html" { @@ -502,9 +509,12 @@ fn path_for_version( } else if last_component == platform { // nothing to search for None - } else { + } else if !is_source_view { // this is an item last_component.split('.').nth(1) + } else { + // this is a source file; try searching for the module + Some(last_component.strip_suffix(".rs.html").unwrap()) }; if let Some(search) = search_item { format!("{}?search={}", platform, search) @@ -687,7 +697,7 @@ mod test { ) -> Result, failure::Error> { assert_success(path, web)?; let data = web.get(path).send()?.text()?; - log::info!("fetched path {} and got content {}", path, data); + log::info!("fetched path {} and got content {}\nhelp: if this is missing the header, remember to add ", path, data); let dom = kuchiki::parse_html().one(data); if let Some(elem) = dom @@ -1643,6 +1653,32 @@ mod test { }); } + #[test] + fn latest_version_works_when_source_deleted() { + wrapper(|env| { + env.fake_release() + .name("pyo3") + .version("0.2.7") + .source_file("src/objects/exc.rs", b"//! some docs") + .create()?; + env.fake_release().name("pyo3").version("0.13.2").create()?; + let target_redirect = "/crate/pyo3/0.13.2/target-redirect/x86_64-unknown-linux-gnu/src/pyo3/objects/exc.rs.html"; + assert_eq!( + latest_version_redirect( + "/pyo3/0.2.7/src/pyo3/objects/exc.rs.html", + env.frontend() + )?, + target_redirect + ); + assert_redirect( + target_redirect, + "/pyo3/0.13.2/pyo3/?search=exc", + env.frontend(), + )?; + Ok(()) + }) + } + #[test] fn test_version_link_goes_to_docs() { wrapper(|env| {