Exercise existing purchase regressions through streamed Files copies

This commit is contained in:
archipelago
2026-10-06 06:03:20 -04:00
parent 9ce04627dd
commit 6fba95fe5a
2 changed files with 53 additions and 15 deletions
+8 -2
View File
@@ -180,7 +180,7 @@ async fn cache_peer_response(
async fn file_cached_purchase_in_files( async fn file_cached_purchase_in_files(
data_dir: &std::path::Path, data_dir: &std::path::Path,
item: &crate::content_owned::OwnedItem, item: &crate::content_owned::OwnedItem,
) -> Result<()> { ) -> Result<String> {
let folder = if item.mime_type.starts_with("image/") || item.mime_type.starts_with("video/") { let folder = if item.mime_type.starts_with("image/") || item.mime_type.starts_with("video/") {
"Photos" "Photos"
} else if item.mime_type.starts_with("audio/") { } else if item.mime_type.starts_with("audio/") {
@@ -201,8 +201,14 @@ async fn file_cached_purchase_in_files(
let (_, file) = crate::content_owned::open_owned(data_dir, &item.onion, &item.content_id) let (_, file) = crate::content_owned::open_owned(data_dir, &item.onion, &item.content_id)
.await? .await?
.context("Purchase unavailable")?; .context("Purchase unavailable")?;
let path =
crate::container::filebrowser::save_new_file_from(&root.join(folder), name, file).await?; crate::container::filebrowser::save_new_file_from(&root.join(folder), name, file).await?;
Ok(()) Ok(format!(
"{folder}/{}",
path.file_name()
.and_then(|name| name.to_str())
.context("Invalid Files name")?
))
} }
impl RpcHandler { impl RpcHandler {
+43 -11
View File
@@ -31,7 +31,24 @@ async fn files_copy_routes_media_and_sanitizes_the_filename() {
("audio/mpeg", "Music"), ("audio/mpeg", "Music"),
("text/plain", "Documents"), ("text/plain", "Documents"),
] { ] {
let relative = file_purchase_in_files(dir.path(), "../name #?.bin", mime, b"paid") crate::content_owned::record_purchase(
dir.path(),
"seller.onion",
"id",
"../name #?.bin",
mime,
b"paid",
1,
"cashu",
"now",
)
.await
.unwrap();
let item = crate::content_owned::list_owned_checked(dir.path())
.await
.unwrap()
.remove(0);
let relative = file_cached_purchase_in_files(dir.path(), &item)
.await .await
.unwrap(); .unwrap();
assert!(relative.starts_with(&format!("{folder}/name #?"))); assert!(relative.starts_with(&format!("{folder}/name #?")));
@@ -47,11 +64,26 @@ async fn files_copy_routes_media_and_sanitizes_the_filename() {
#[tokio::test] #[tokio::test]
async fn unavailable_files_storage_is_reported_without_creating_a_fake_installation() { async fn unavailable_files_storage_is_reported_without_creating_a_fake_installation() {
let dir = tempfile::tempdir().unwrap(); let dir = tempfile::tempdir().unwrap();
assert!( crate::content_owned::record_purchase(
file_purchase_in_files(dir.path(), "name", "text/plain", b"bytes") dir.path(),
"seller.onion",
"id",
"name",
"text/plain",
b"bytes",
1,
"cashu",
"now",
)
.await .await
.is_err() .unwrap();
); let item = crate::content_owned::list_owned_checked(dir.path())
.await
.unwrap()
.remove(0);
assert!(file_cached_purchase_in_files(dir.path(), &item)
.await
.is_err());
assert!(!dir.path().join("filebrowser").exists()); assert!(!dir.path().join("filebrowser").exists());
} }
@@ -76,7 +108,7 @@ fn seller_errors_are_bounded_printable_and_identified_as_peer_text() {
async fn known_purchase_never_becomes_a_new_spend_when_cache_or_index_is_unavailable() { async fn known_purchase_never_becomes_a_new_spend_when_cache_or_index_is_unavailable() {
let dir = tempfile::tempdir().unwrap(); let dir = tempfile::tempdir().unwrap();
assert!( assert!(
existing_paid_content(dir.path(), "seller.onion", "id", None) existing_paid_content(dir.path(), "seller.onion", "id", None, false)
.await .await
.unwrap() .unwrap()
.is_none() .is_none()
@@ -94,8 +126,8 @@ async fn known_purchase_never_becomes_a_new_spend_when_cache_or_index_is_unavail
) )
.await .await
.unwrap(); .unwrap();
for (id, filename) in [("id", None), ("duplicate-id", Some("/file.txt"))] { for (id, filename) in [("id", None, false), ("duplicate-id", Some("/file.txt"))] {
let cached = existing_paid_content(dir.path(), "seller.onion", id, filename) let cached = existing_paid_content(dir.path(), "seller.onion", id, filename, false)
.await .await
.unwrap() .unwrap()
.unwrap(); .unwrap();
@@ -104,7 +136,7 @@ async fn known_purchase_never_becomes_a_new_spend_when_cache_or_index_is_unavail
assert_eq!(cached["data"], "cGFpZA=="); assert_eq!(cached["data"], "cGFpZA==");
} }
assert!( assert!(
existing_paid_content(dir.path(), "different.onion", "id", None) existing_paid_content(dir.path(), "different.onion", "id", None, false)
.await .await
.unwrap() .unwrap()
.is_none() .is_none()
@@ -113,7 +145,7 @@ async fn known_purchase_never_becomes_a_new_spend_when_cache_or_index_is_unavail
.await .await
.unwrap(); .unwrap();
assert!( assert!(
existing_paid_content(dir.path(), "seller.onion", "id", None) existing_paid_content(dir.path(), "seller.onion", "id", None, false)
.await .await
.unwrap_err() .unwrap_err()
.to_string() .to_string()
@@ -123,7 +155,7 @@ async fn known_purchase_never_becomes_a_new_spend_when_cache_or_index_is_unavail
.await .await
.unwrap(); .unwrap();
assert!( assert!(
existing_paid_content(dir.path(), "seller.onion", "other-id", None) existing_paid_content(dir.path(), "seller.onion", "other-id", None, false)
.await .await
.unwrap_err() .unwrap_err()
.to_string() .to_string()