diff --git a/.changes/fix-upload-handle-non-success-download.md b/.changes/fix-upload-handle-non-success-download.md new file mode 100644 index 00000000..0bfc4913 --- /dev/null +++ b/.changes/fix-upload-handle-non-success-download.md @@ -0,0 +1,5 @@ +--- +"upload": 'patch:bug' +--- + +fix download content to file when unsuccessful response diff --git a/Cargo.lock b/Cargo.lock index b05395e9..903454e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,16 @@ dependencies = [ "zbus", ] +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "async-broadcast" version = "0.7.1" @@ -1088,6 +1098,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "combine" version = "4.6.7" @@ -1961,7 +1981,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" dependencies = [ - "colored", + "colored 1.9.4", "log", ] @@ -2808,6 +2828,7 @@ dependencies = [ "http", "http-body", "httparse", + "httpdate", "itoa 1.0.11", "pin-project-lite", "smallvec", @@ -3623,6 +3644,30 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mockito" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b34bd91b9e5c5b06338d392463e1318d683cf82ec3d3af4014609be6e2108d" +dependencies = [ + "assert-json-diff", + "bytes", + "colored 2.1.0", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rand 0.8.5", + "regex", + "serde_json", + "serde_urlencoded", + "similar", + "tokio", +] + [[package]] name = "muda" version = "0.14.1" @@ -5614,6 +5659,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + [[package]] name = "single-instance-example" version = "0.1.0" @@ -6811,6 +6862,7 @@ version = "2.0.0-rc.1" dependencies = [ "futures-util", "log", + "mockito", "read-progress-stream", "reqwest", "serde", @@ -7113,6 +7165,7 @@ dependencies = [ "bytes", "libc", "mio 1.0.2", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", diff --git a/plugins/upload/Cargo.toml b/plugins/upload/Cargo.toml index a8021755..c43487a9 100644 --- a/plugins/upload/Cargo.toml +++ b/plugins/upload/Cargo.toml @@ -35,3 +35,7 @@ read-progress-stream = "1.0.0" native-tls = ["reqwest/native-tls"] native-tls-vendored = ["reqwest/native-tls-vendored"] rustls-tls = ["reqwest/rustls-tls"] + +[dev-dependencies] +mockito = "1.5.0" +tokio = { version = "*", features = ["macros"] } diff --git a/plugins/upload/src/lib.rs b/plugins/upload/src/lib.rs index 453f5665..9351b246 100644 --- a/plugins/upload/src/lib.rs +++ b/plugins/upload/src/lib.rs @@ -70,13 +70,19 @@ async fn download( let client = reqwest::Client::new(); let mut request = client.get(url); - // Loop trought the headers keys and values + // Loop through the headers keys and values // and add them to the request object. for (key, value) in headers { request = request.header(&key, value); } let response = request.send().await?; + if !response.status().is_success() { + return Err(Error::HttpErrorCode( + response.status().as_u16(), + response.text().await.unwrap_or_default(), + )); + } let total = response.content_length().unwrap_or(0); let mut file = BufWriter::new(File::create(file_path).await?); @@ -112,7 +118,7 @@ async fn upload( .header(reqwest::header::CONTENT_LENGTH, file_len) .body(file_to_body(on_progress, file)); - // Loop trought the headers keys and values + // Loop through the headers keys and values // and add them to the request object. for (key, value) in headers { request = request.header(&key, value); @@ -145,3 +151,64 @@ pub fn init() -> TauriPlugin { .invoke_handler(tauri::generate_handler![download, upload]) .build() } + +#[cfg(test)] +mod tests { + use super::*; + use mockito::{self, Mock, Server, ServerGuard}; + use tauri::ipc::InvokeResponseBody; + struct MockedServer { + _server: ServerGuard, + url: String, + mocked_endpoint: Mock, + } + + #[tokio::test] + async fn should_error_if_status_not_success() { + let mocked_server = spawn_server_mocked(400).await; + let result = download_file(&mocked_server.url).await; + mocked_server.mocked_endpoint.assert(); + assert!(result.is_err()); + } + + #[tokio::test] + async fn should_download_file_successfully() { + let mocked_server = spawn_server_mocked(200).await; + let result = download_file(&mocked_server.url).await; + mocked_server.mocked_endpoint.assert(); + assert!( + result.is_ok(), + "failed to download file: {}", + result.unwrap_err() + ); + } + + async fn download_file(url: &str) -> Result<()> { + let file_path = concat!(env!("CARGO_MANIFEST_DIR"), "/test/test.txt"); + let headers = HashMap::new(); + let sender: Channel = + Channel::new(|msg: InvokeResponseBody| -> tauri::Result<()> { + let _ = msg; + Ok(()) + }); + download(url, file_path, headers, sender).await + } + + async fn spawn_server_mocked(return_status: usize) -> MockedServer { + let mut _server = Server::new_async().await; + let path = "/mock_test"; + let mock = _server + .mock("GET", path) + .with_status(return_status) + .with_body("mocked response body") + .create_async() + .await; + + let url = _server.url() + path; + MockedServer { + _server, + url, + mocked_endpoint: mock, + } + } +} diff --git a/plugins/upload/test/test.txt b/plugins/upload/test/test.txt new file mode 100644 index 00000000..629b997b --- /dev/null +++ b/plugins/upload/test/test.txt @@ -0,0 +1 @@ +mocked response body \ No newline at end of file