use std::collections::HashMap; use std::io::Write; use tempfile::NamedTempFile; use tus_client; use tus_client::http::{HttpHandler, HttpMethod, HttpRequest, HttpResponse}; use tus_client::{Error, TusExtension}; struct TestHandler { pub upload_progress: usize, pub total_upload_size: usize, pub status_code: usize, pub tus_version: String, pub extensions: String, pub max_upload_size: usize, } impl Default for TestHandler { fn default() -> Self { TestHandler { upload_progress: 1234, total_upload_size: 2345, status_code: 200, tus_version: String::from("1.0.0"), extensions: String::from(""), max_upload_size: 12345, } } } impl HttpHandler for TestHandler { fn handle_request(&self, req: HttpRequest) -> Result { match &req.method { HttpMethod::Head => { let mut headers = HashMap::new(); headers.insert( "upload-length".to_owned(), self.total_upload_size.to_string(), ); headers.insert("upload-offset".to_owned(), self.upload_progress.to_string()); headers.insert( "upload-metadata".to_owned(), base64::encode("key_one:value_one;key_two:value_two;k"), ); Ok(HttpResponse { status_code: self.status_code, headers, }) } HttpMethod::Options => { let mut headers = HashMap::new(); headers.insert("tus-version".to_owned(), self.tus_version.clone()); headers.insert("tus-extension".to_owned(), self.extensions.clone()); headers.insert("tus-max-size".to_owned(), self.max_upload_size.to_string()); Ok(HttpResponse { status_code: self.status_code, headers, }) } HttpMethod::Patch => { let mut headers = HashMap::new(); headers.insert("tus-version".to_owned(), self.tus_version.clone()); headers.insert( "upload-offset".to_owned(), (req.body.unwrap().len() + req .headers .get("upload-offset") .unwrap() .parse::() .unwrap()) .to_string(), ); Ok(HttpResponse { status_code: self.status_code, headers, }) } HttpMethod::Post => { let mut headers = HashMap::new(); headers.insert("tus-version".to_owned(), self.tus_version.clone()); headers.insert("location".to_owned(), "/something_else".to_owned()); Ok(HttpResponse { status_code: self.status_code, headers, }) } HttpMethod::Delete => { let mut headers = HashMap::new(); headers.insert("tus-version".to_owned(), self.tus_version.clone()); Ok(HttpResponse { status_code: self.status_code, headers, }) } _ => unreachable!(), } } } fn create_temp_file() -> NamedTempFile { let mut temp_file = NamedTempFile::new().unwrap(); let buffer: Vec = (0..(1024 * 763)).map(|_| rand::random::()).collect(); for _ in 0..20 { temp_file.write_all(&buffer[..]).unwrap(); } temp_file } #[test] fn should_report_correct_upload_progress() { let client = tus_client::Client::new(TestHandler { status_code: 204, ..TestHandler::default() }); let info = client .get_info("/something") .expect("'get_progress' call failed"); let metadata = info.metadata.unwrap(); assert_eq!(1234, info.bytes_uploaded); assert_eq!(2345, info.total_size.unwrap()); assert_eq!( String::from("value_one"), metadata.get("key_one").unwrap().to_owned() ); assert_eq!( String::from("value_two"), metadata.get("key_two").unwrap().to_owned() ); } #[test] fn should_return_not_found_at_4xx_status() { let client = tus_client::Client::new(TestHandler { status_code: 400, ..TestHandler::default() }); let result = client.get_info("/something"); assert!(result.is_err()); match result { Err(tus_client::Error::NotFoundError) => {} _ => panic!("Expected 'Error::NotFoundError'"), } } #[test] fn should_return_server_info() { let client = tus_client::Client::new(TestHandler { status_code: 204, tus_version: String::from("1.0.0,0.2.2"), extensions: String::from("creation, termination"), ..TestHandler::default() }); let result = client .get_server_info("/something") .expect("'get_server_info' call failed"); assert_eq!(vec!["1.0.0", "0.2.2"], result.supported_versions); assert_eq!( vec![TusExtension::Creation, TusExtension::Termination], result.extensions ); assert_eq!(12345, result.max_upload_size.unwrap()); } #[test] fn should_upload_file() { let temp_file = create_temp_file(); let client = tus_client::Client::new(TestHandler { upload_progress: 0, total_upload_size: temp_file.as_file().metadata().unwrap().len() as usize, status_code: 204, ..TestHandler::default() }); client .upload("/something", temp_file.path()) .expect("'upload' call failed"); } #[test] fn should_upload_file_with_custom_chunk_size() { let temp_file = create_temp_file(); let client = tus_client::Client::new(TestHandler { upload_progress: 0, total_upload_size: temp_file.as_file().metadata().unwrap().len() as usize, status_code: 204, ..TestHandler::default() }); client .upload_with_chunk_size("/something", temp_file.path(), 9 * 87 * 65 * 43) .expect("'upload_with_chunk_size' call failed"); } #[test] fn should_receive_upload_path() { let temp_file = create_temp_file(); let client = tus_client::Client::new(TestHandler { status_code: 201, ..TestHandler::default() }); let mut metadata = HashMap::new(); metadata.insert("key_one".to_owned(), "value_one".to_owned()); metadata.insert("key_two".to_owned(), "value_two".to_owned()); let result = client .create("/something", temp_file.path()) .expect("'create_with_metadata' call failed"); assert!(!result.is_empty()); } #[test] fn should_receive_upload_path_with_metadata() { let temp_file = create_temp_file(); let client = tus_client::Client::new(TestHandler { status_code: 201, ..TestHandler::default() }); let mut metadata = HashMap::new(); metadata.insert("key_one".to_owned(), "value_one".to_owned()); metadata.insert("key_two".to_owned(), "value_two".to_owned()); let result = client .create_with_metadata("/something", temp_file.path(), metadata) .expect("'create_with_metadata' call failed"); assert!(!result.is_empty()); } #[test] fn should_receive_204_after_deleting_file() { let client = tus_client::Client::new(TestHandler { status_code: 204, ..TestHandler::default() }); client.delete("/something").expect("'delete' call failed"); }