From 7d6b2bfe96c1addce02867ac8181d80434954198 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 11 Jul 2021 17:12:36 +0200 Subject: [PATCH] Add functions to files to retrieve information, associate urls and get tags Signed-off-by: trivernis --- src/client.rs | 90 +++++++++------- src/endpoints/access_management.rs | 8 +- src/endpoints/adding_files.rs | 10 +- src/endpoints/adding_tags.rs | 4 +- src/endpoints/adding_urls.rs | 8 +- src/endpoints/common.rs | 18 ++-- src/endpoints/mod.rs | 4 +- src/endpoints/searching_and_fetching_files.rs | 10 +- src/error.rs | 8 +- src/models/builders/import_builder.rs | 4 +- src/models/hydrus.rs | 20 +++- src/models/hydrus_file.rs | 102 +++++++++++++++++- src/models/service.rs | 4 +- tests/client/test_access_management.rs | 8 +- tests/client/test_adding_files.rs | 12 +-- tests/client/test_adding_tags.rs | 4 +- tests/client/test_adding_urls.rs | 10 +- .../test_searching_and_fetching_files.rs | 12 +-- tests/wrapper/mod.rs | 1 + tests/wrapper/test_files.rs | 49 +++++++++ tests/wrapper/test_hydrus.rs | 6 +- tests/wrapper/test_import.rs | 6 +- tests/wrapper/test_url.rs | 2 +- 23 files changed, 292 insertions(+), 108 deletions(-) create mode 100644 tests/wrapper/test_files.rs diff --git a/src/client.rs b/src/client.rs index fc162ab..1e9f2c2 100644 --- a/src/client.rs +++ b/src/client.rs @@ -11,7 +11,7 @@ use crate::endpoints::adding_urls::{ AddUrl, AddUrlRequest, AddUrlResponse, AssociateUrl, AssociateUrlRequest, GetUrlFiles, GetUrlFilesResponse, GetUrlInfo, GetUrlInfoResponse, }; -use crate::endpoints::common::{FileIdentifier, FileRecord}; +use crate::endpoints::common::{FileIdentifier, FileMetadataInfo, FileRecord}; use crate::endpoints::searching_and_fetching_files::{ FileMetadata, FileMetadataResponse, FileSearchLocation, GetFile, SearchFiles, SearchFilesResponse, @@ -43,10 +43,10 @@ impl Client { } /// Starts a get request to the path - async fn get(&mut self, query: &Q) -> Result { + async fn get(&self, query: &Q) -> Result { let response = self .inner - .get(format!("{}/{}", self.base_url, E::get_path())) + .get(format!("{}/{}", self.base_url, E::path())) .header(ACCESS_KEY_HEADER, &self.access_key) .query(query) .send() @@ -57,7 +57,7 @@ impl Client { /// Starts a get request to the path associated with the Endpoint Type async fn get_and_parse( - &mut self, + &self, query: &Q, ) -> Result { let response = self.get::(query).await?; @@ -66,10 +66,10 @@ impl Client { } /// Stats a post request to the path associated with the Endpoint Type - async fn post(&mut self, body: E::Request) -> Result { + async fn post(&self, body: E::Request) -> Result { let response = self .inner - .post(format!("{}/{}", self.base_url, E::get_path())) + .post(format!("{}/{}", self.base_url, E::path())) .json(&body) .header(ACCESS_KEY_HEADER, &self.access_key) .send() @@ -79,17 +79,17 @@ impl Client { } /// Stats a post request and parses the body as json - async fn post_and_parse(&mut self, body: E::Request) -> Result { + async fn post_and_parse(&self, body: E::Request) -> Result { let response = self.post::(body).await?; Self::extract_content(response).await } /// Stats a post request to the path associated with the return type - async fn post_binary(&mut self, data: Vec) -> Result { + async fn post_binary(&self, data: Vec) -> Result { let response = self .inner - .post(format!("{}/{}", self.base_url, E::get_path())) + .post(format!("{}/{}", self.base_url, E::path())) .body(data) .header(ACCESS_KEY_HEADER, &self.access_key) .header("Content-Type", "application/octet-stream") @@ -116,27 +116,27 @@ impl Client { } /// Returns the current API version. It's being incremented every time the API changes. - pub async fn api_version(&mut self) -> Result { + pub async fn api_version(&self) -> Result { self.get_and_parse::(&()).await } /// Creates a new session key - pub async fn session_key(&mut self) -> Result { + pub async fn session_key(&self) -> Result { self.get_and_parse::(&()).await } /// Verifies if the access key is valid and returns some information about its permissions - pub async fn verify_access_key(&mut self) -> Result { + pub async fn verify_access_key(&self) -> Result { self.get_and_parse::(&()).await } /// Returns the list of tag and file services of the client - pub async fn get_services(&mut self) -> Result { + pub async fn get_services(&self) -> Result { self.get_and_parse::(&()).await } /// Adds a file to hydrus - pub async fn add_file>(&mut self, path: S) -> Result { + pub async fn add_file>(&self, path: S) -> Result { self.post_and_parse::(AddFileRequest { path: path.as_ref().to_string(), }) @@ -144,12 +144,12 @@ impl Client { } /// Adds a file from binary data to hydrus - pub async fn add_binary_file(&mut self, data: Vec) -> Result { + pub async fn add_binary_file(&self, data: Vec) -> Result { self.post_binary::(data).await } /// Moves files with matching hashes to the trash - pub async fn delete_files(&mut self, hashes: Vec) -> Result<()> { + pub async fn delete_files(&self, hashes: Vec) -> Result<()> { self.post::(DeleteFilesRequest { hashes }) .await?; @@ -157,7 +157,7 @@ impl Client { } /// Pulls files out of the trash by hash - pub async fn undelete_files(&mut self, hashes: Vec) -> Result<()> { + pub async fn undelete_files(&self, hashes: Vec) -> Result<()> { self.post::(UndeleteFilesRequest { hashes }) .await?; @@ -165,7 +165,7 @@ impl Client { } /// Moves files from the inbox into the archive - pub async fn archive_files(&mut self, hashes: Vec) -> Result<()> { + pub async fn archive_files(&self, hashes: Vec) -> Result<()> { self.post::(ArchiveFilesRequest { hashes }) .await?; @@ -173,7 +173,7 @@ impl Client { } /// Moves files from the archive into the inbox - pub async fn unarchive_files(&mut self, hashes: Vec) -> Result<()> { + pub async fn unarchive_files(&self, hashes: Vec) -> Result<()> { self.post::(UnarchiveFilesRequest { hashes }) .await?; @@ -181,7 +181,7 @@ impl Client { } /// Returns the list of tags as the client would see them in a human friendly order - pub async fn clean_tags(&mut self, tags: Vec) -> Result { + pub async fn clean_tags(&self, tags: Vec) -> Result { self.get_and_parse::(&[( "tags", string_list_to_json_array(tags), @@ -190,7 +190,7 @@ impl Client { } /// Adds tags to files with the given hashes - pub async fn add_tags(&mut self, request: AddTagsRequest) -> Result<()> { + pub async fn add_tags(&self, request: AddTagsRequest) -> Result<()> { self.post::(request).await?; Ok(()) @@ -198,7 +198,7 @@ impl Client { /// Searches for files in the inbox, the archive or both pub async fn search_files( - &mut self, + &self, tags: Vec, location: FileSearchLocation, ) -> Result { @@ -212,19 +212,37 @@ impl Client { /// Returns the metadata for a given list of file_ids or hashes pub async fn get_file_metadata( - &mut self, + &self, file_ids: Vec, hashes: Vec, ) -> Result { - self.get_and_parse::(&[ - ("file_ids", number_list_to_json_array(file_ids)), - ("hashes", string_list_to_json_array(hashes)), - ]) - .await + let query = if file_ids.len() > 0 { + ("file_ids", number_list_to_json_array(file_ids)) + } else { + ("hashes", string_list_to_json_array(hashes)) + }; + self.get_and_parse::(&[query]) + .await + } + + /// Returns the metadata for a single file identifier + pub async fn get_file_metadata_by_identifier( + &self, + identifier: FileIdentifier, + ) -> Result { + let mut response = match identifier.clone() { + FileIdentifier::ID(id) => self.get_file_metadata(vec![id], vec![]).await?, + FileIdentifier::Hash(hash) => self.get_file_metadata(vec![], vec![hash]).await?, + }; + + response + .metadata + .pop() + .ok_or_else(|| Error::FileNotFound(identifier)) } /// Returns the bytes of a file from hydrus - pub async fn get_file(&mut self, id: FileIdentifier) -> Result { + pub async fn get_file(&self, id: FileIdentifier) -> Result { let response = match id { FileIdentifier::ID(id) => { self.get::(&[("file_id", id)]) @@ -248,24 +266,24 @@ impl Client { } /// Returns all files associated with the given url - pub async fn get_url_files>(&mut self, url: S) -> Result { + pub async fn get_url_files>(&self, url: S) -> Result { self.get_and_parse::(&[("url", url.as_ref())]) .await } /// Returns information about the given url - pub async fn get_url_info>(&mut self, url: S) -> Result { + pub async fn get_url_info>(&self, url: S) -> Result { self.get_and_parse::(&[("url", url.as_ref())]) .await } /// Adds an url to hydrus, optionally with additional tags and a destination page - pub async fn add_url(&mut self, request: AddUrlRequest) -> Result { + pub async fn add_url(&self, request: AddUrlRequest) -> Result { self.post_and_parse::(request).await } /// Associates urls with the given file hashes - pub async fn associate_urls(&mut self, urls: Vec, hashes: Vec) -> Result<()> { + pub async fn associate_urls(&self, urls: Vec, hashes: Vec) -> Result<()> { self.post::(AssociateUrlRequest { hashes, urls_to_add: urls, @@ -277,11 +295,7 @@ impl Client { } /// Disassociates urls with the given file hashes - pub async fn disassociate_urls( - &mut self, - urls: Vec, - hashes: Vec, - ) -> Result<()> { + pub async fn disassociate_urls(&self, urls: Vec, hashes: Vec) -> Result<()> { self.post::(AssociateUrlRequest { hashes, urls_to_add: vec![], diff --git a/src/endpoints/access_management.rs b/src/endpoints/access_management.rs index 6f2597d..d7c55ad 100644 --- a/src/endpoints/access_management.rs +++ b/src/endpoints/access_management.rs @@ -23,7 +23,7 @@ impl Endpoint for ApiVersion { type Request = (); type Response = ApiVersionResponse; - fn get_path() -> String { + fn path() -> String { String::from("api_version") } } @@ -39,7 +39,7 @@ impl Endpoint for SessionKey { type Request = (); type Response = SessionKeyResponse; - fn get_path() -> String { + fn path() -> String { String::from("session_key") } } @@ -56,7 +56,7 @@ impl Endpoint for VerifyAccessKey { type Request = (); type Response = VerifyAccessKeyResponse; - fn get_path() -> String { + fn path() -> String { String::from("verify_access_key") } } @@ -70,7 +70,7 @@ impl Endpoint for GetServices { type Request = (); type Response = GetServicesResponse; - fn get_path() -> String { + fn path() -> String { String::from("get_services") } } diff --git a/src/endpoints/adding_files.rs b/src/endpoints/adding_files.rs index 09da721..412cf09 100644 --- a/src/endpoints/adding_files.rs +++ b/src/endpoints/adding_files.rs @@ -25,7 +25,7 @@ impl Endpoint for AddFile { type Request = AddFileRequest; type Response = AddFileResponse; - fn get_path() -> String { + fn path() -> String { String::from("add_files/add_file") } } @@ -38,7 +38,7 @@ impl Endpoint for DeleteFiles { type Request = DeleteFilesRequest; type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("add_files/delete_files") } } @@ -50,7 +50,7 @@ impl Endpoint for UndeleteFiles { type Request = UndeleteFilesRequest; type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("add_files/undelete_files") } } @@ -62,7 +62,7 @@ impl Endpoint for ArchiveFiles { type Request = ArchiveFilesRequest; type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("add_files/archive_files") } } @@ -74,7 +74,7 @@ impl Endpoint for UnarchiveFiles { type Request = UndeleteFilesRequest; type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("add_files/unarchive_files") } } diff --git a/src/endpoints/adding_tags.rs b/src/endpoints/adding_tags.rs index 04c09d8..c78f396 100644 --- a/src/endpoints/adding_tags.rs +++ b/src/endpoints/adding_tags.rs @@ -12,7 +12,7 @@ impl Endpoint for CleanTags { type Request = (); type Response = CleanTagsResponse; - fn get_path() -> String { + fn path() -> String { String::from("add_tags/clean_tags") } } @@ -30,7 +30,7 @@ impl Endpoint for AddTags { type Request = AddTagsRequest; type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("add_tags/add_tags") } } diff --git a/src/endpoints/adding_urls.rs b/src/endpoints/adding_urls.rs index 9c6432c..094262b 100644 --- a/src/endpoints/adding_urls.rs +++ b/src/endpoints/adding_urls.rs @@ -27,7 +27,7 @@ impl Endpoint for GetUrlFiles { type Request = (); type Response = GetUrlFilesResponse; - fn get_path() -> String { + fn path() -> String { String::from("add_urls/get_url_files") } } @@ -47,7 +47,7 @@ impl Endpoint for GetUrlInfo { type Request = (); type Response = GetUrlInfoResponse; - fn get_path() -> String { + fn path() -> String { String::from("add_urls/get_url_info") } } @@ -164,7 +164,7 @@ impl Endpoint for AddUrl { type Request = AddUrlRequest; type Response = AddUrlResponse; - fn get_path() -> String { + fn path() -> String { String::from("add_urls/add_url") } } @@ -181,7 +181,7 @@ impl Endpoint for AssociateUrl { type Request = AssociateUrlRequest; type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("add_urls/associate_url") } } diff --git a/src/endpoints/common.rs b/src/endpoints/common.rs index f3d368d..ac9fb65 100644 --- a/src/endpoints/common.rs +++ b/src/endpoints/common.rs @@ -11,17 +11,17 @@ pub struct BasicHashList { pub hashes: Vec, } -#[derive(Clone, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize)] pub struct FileMetadataInfo { pub file_id: u64, pub hash: String, - pub size: u64, + pub size: Option, pub mime: String, pub ext: String, - pub width: u32, - pub height: u32, + pub width: Option, + pub height: Option, pub duration: Option, - pub has_audio: bool, + pub has_audio: Option, pub num_frames: Option, pub num_words: Option, pub is_inbox: bool, @@ -32,12 +32,18 @@ pub struct FileMetadataInfo { pub service_names_to_statuses_to_display_tags: HashMap>>, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum FileIdentifier { ID(u64), Hash(String), } +impl FileIdentifier { + pub fn hash(hash: S) -> Self { + Self::Hash(hash.to_string()) + } +} + #[derive(Clone)] pub struct FileRecord { pub bytes: Vec, diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index 13cda47..468521c 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -8,9 +8,9 @@ pub mod adding_urls; pub mod common; pub mod searching_and_fetching_files; -pub trait Endpoint { +pub(crate) trait Endpoint { type Request: Serialize; type Response: DeserializeOwned; - fn get_path() -> String; + fn path() -> String; } diff --git a/src/endpoints/searching_and_fetching_files.rs b/src/endpoints/searching_and_fetching_files.rs index aa07178..5739587 100644 --- a/src/endpoints/searching_and_fetching_files.rs +++ b/src/endpoints/searching_and_fetching_files.rs @@ -44,14 +44,14 @@ impl Endpoint for SearchFiles { type Request = (); type Response = SearchFilesResponse; - fn get_path() -> String { + fn path() -> String { String::from("get_files/search_files") } } -#[derive(Clone, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize)] pub struct FileMetadataResponse { - metadata: Vec, + pub metadata: Vec, } pub struct FileMetadata; @@ -60,7 +60,7 @@ impl Endpoint for FileMetadata { type Request = (); type Response = FileMetadataResponse; - fn get_path() -> String { + fn path() -> String { String::from("get_files/file_metadata") } } @@ -71,7 +71,7 @@ impl Endpoint for GetFile { type Request = (); type Response = (); - fn get_path() -> String { + fn path() -> String { String::from("get_files/file") } } diff --git a/src/error.rs b/src/error.rs index 24010d0..c62f74e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,4 @@ +use crate::endpoints::common::FileIdentifier; use std::error::Error as StdError; use std::fmt; @@ -10,6 +11,7 @@ pub enum Error { InvalidServiceType(String), ImportVetoed(String), ImportFailed(String), + FileNotFound(FileIdentifier), } impl fmt::Display for Error { @@ -22,6 +24,7 @@ impl fmt::Display for Error { } Self::ImportFailed(msg) => write!(f, "File import failed: {}", msg), Self::ImportVetoed(msg) => write!(f, "File import vetoed: {}", msg), + Self::FileNotFound(id) => write!(f, "File {:?} not found", id), } } } @@ -30,10 +33,7 @@ impl StdError for Error { fn source(&self) -> Option<&(dyn StdError + 'static)> { match self { Self::Reqwest(e) => e.source(), - Self::Hydrus(_) => None, - Self::InvalidServiceType(_) => None, - Self::ImportVetoed(_) => None, - Self::ImportFailed(_) => None, + _ => None, } } } diff --git a/src/models/builders/import_builder.rs b/src/models/builders/import_builder.rs index 66442c7..48c5e4b 100644 --- a/src/models/builders/import_builder.rs +++ b/src/models/builders/import_builder.rs @@ -51,7 +51,7 @@ pub struct FileImportBuilder { } impl FileImportBuilder { - pub async fn run(mut self) -> Result { + pub async fn run(self) -> Result { let response = match self.file { FileImport::Path(path) => self.client.add_file(path).await?, FileImport::Binary(b) => self.client.add_binary_file(b).await?, @@ -137,7 +137,7 @@ impl UrlImportBuilder { } /// Imports the URL - pub async fn run(mut self) -> Result { + pub async fn run(self) -> Result { let mut request = AddUrlRequestBuilder::default().url(&self.url); for (service, tags) in self.service_tag_mappings { diff --git a/src/models/hydrus.rs b/src/models/hydrus.rs index 4522a37..bfc1fe0 100644 --- a/src/models/hydrus.rs +++ b/src/models/hydrus.rs @@ -1,5 +1,7 @@ use crate::builders::import_builder::ImportBuilder; +use crate::endpoints::common::FileIdentifier; use crate::error::Result; +use crate::hydrus_file::HydrusFile; use crate::models::url::Url; use crate::models::version::Version; use crate::service::Services; @@ -16,7 +18,7 @@ impl Hydrus { } /// Returns the Hydrus and API Version - pub async fn version(&mut self) -> Result { + pub async fn version(&self) -> Result { let response = self.client.api_version().await?; Ok(Version { api: response.version, @@ -25,14 +27,14 @@ impl Hydrus { } /// Returns a list of available services - pub async fn services(&mut self) -> Result { + pub async fn services(&self) -> Result { let response = self.client.get_services().await?; Ok(Services::from_response(self.client.clone(), response)) } /// Creates an import builder to build an import request to hydrus - pub fn import(&mut self) -> ImportBuilder { + pub fn import(&self) -> ImportBuilder { ImportBuilder { client: self.client.clone(), } @@ -40,7 +42,7 @@ impl Hydrus { /// Returns information about a given url in an object that allows /// further operations with that url - pub async fn url>(&mut self, url: S) -> Result { + pub async fn url>(&self, url: S) -> Result { let info = self.client.get_url_info(&url).await?; Ok(Url { @@ -52,4 +54,14 @@ impl Hydrus { can_parse: info.can_parse, }) } + + /// Returns a file by identifier to perform further operations on + pub async fn file(&self, identifier: FileIdentifier) -> Result { + let metadata = self + .client + .get_file_metadata_by_identifier(identifier) + .await?; + + Ok(HydrusFile::from_metadata(self.client.clone(), metadata)) + } } diff --git a/src/models/hydrus_file.rs b/src/models/hydrus_file.rs index 6c7af26..d60a37e 100644 --- a/src/models/hydrus_file.rs +++ b/src/models/hydrus_file.rs @@ -1,5 +1,9 @@ -use crate::endpoints::common::FileIdentifier; +use crate::endpoints::common::{FileIdentifier, FileMetadataInfo}; +use crate::error::Result; +use crate::service::ServiceName; +use crate::tag::Tag; use crate::Client; +use std::collections::HashMap; #[derive(Clone, Debug, PartialOrd, PartialEq)] pub enum FileStatus { @@ -16,6 +20,7 @@ pub struct HydrusFile { pub(crate) client: Client, pub id: FileIdentifier, pub status: FileStatus, + pub(crate) metadata: Option, } impl HydrusFile { @@ -35,6 +40,101 @@ impl HydrusFile { client, id: FileIdentifier::Hash(hash.to_string()), status, + metadata: None, } } + + pub(crate) fn from_metadata(client: Client, metadata: FileMetadataInfo) -> Self { + let status = if metadata.is_trashed { + FileStatus::Deleted + } else { + FileStatus::InDatabase + }; + + Self { + client, + id: FileIdentifier::Hash(metadata.hash.clone()), + status, + metadata: Some(metadata), + } + } + + /// Deletes the internally stored metadata about the file retrieves it again + pub async fn update(&mut self) -> Result<()> { + self.metadata = None; + self.metadata().await?; + Ok(()) + } + + /// Returns the metadata for the given file + /// if there's already known metadata about the file it uses that + async fn metadata(&mut self) -> Result<&FileMetadataInfo> { + if self.metadata.is_none() { + let metadata = self + .client + .get_file_metadata_by_identifier(self.id.clone()) + .await?; + self.status = if metadata.is_trashed { + FileStatus::Deleted + } else { + FileStatus::InDatabase + }; + self.metadata = Some(metadata); + } + + Ok(self.metadata.as_ref().unwrap()) + } + + /// Returns the hash of the file + /// if the file identifier is an id it calls hydrus to resolve the file + pub async fn hash(&mut self) -> Result { + match &self.id { + FileIdentifier::ID(_) => { + let metadata = self.metadata().await?; + Ok(metadata.hash.clone()) + } + FileIdentifier::Hash(hash) => Ok(hash.clone()), + } + } + + /// Associates the file with a list of urls + pub async fn associate_urls(&mut self, urls: Vec) -> Result<()> { + let hash = self.hash().await?; + self.client.associate_urls(urls, vec![hash]).await + } + + /// Disassociates the file with a list of urls + pub async fn disassociate_urls(&mut self, urls: Vec) -> Result<()> { + let hash = self.hash().await?; + self.client.disassociate_urls(urls, vec![hash]).await + } + + /// Returns map mapping lists of tags to services + pub async fn services_with_tags(&mut self) -> Result>> { + let metadata = self.metadata().await?; + let mut tag_mappings = HashMap::new(); + + for (service, status_tags) in &metadata.service_names_to_statuses_to_tags { + let mut tag_list = Vec::new(); + + for (_, tags) in status_tags { + tag_list.append(&mut tags.into_iter().map(|t| t.into()).collect()) + } + tag_mappings.insert(ServiceName(service.clone()), tag_list); + } + + Ok(tag_mappings) + } + + /// Returns a list of all tags assigned to the file + pub async fn tags(&mut self) -> Result> { + let mut tag_list = Vec::new(); + let tag_mappings = self.services_with_tags().await?; + + for (_, mut tags) in tag_mappings { + tag_list.append(&mut tags); + } + + Ok(tag_list) + } } diff --git a/src/models/service.rs b/src/models/service.rs index d39df71..447213c 100644 --- a/src/models/service.rs +++ b/src/models/service.rs @@ -56,9 +56,11 @@ impl ToString for ServiceType { } } -#[derive(Clone)] +#[derive(Clone, PartialOrd, PartialEq, Hash)] pub struct ServiceName(pub String); +impl Eq for ServiceName {} + impl ServiceName { pub fn my_tags() -> Self { Self(String::from("my tags")) diff --git a/tests/client/test_access_management.rs b/tests/client/test_access_management.rs index 1834fca..0ff5101 100644 --- a/tests/client/test_access_management.rs +++ b/tests/client/test_access_management.rs @@ -2,7 +2,7 @@ use super::super::common; #[tokio::test] async fn it_returns_the_api_version() { - let mut client = common::get_client(); + let client = common::get_client(); let api_version = client.api_version().await.unwrap(); assert!(api_version.hydrus_version > 0); assert!(api_version.version > 0); @@ -10,14 +10,14 @@ async fn it_returns_the_api_version() { #[tokio::test] async fn it_returns_the_session_key() { - let mut client = common::get_client(); + let client = common::get_client(); let session_key = client.session_key().await.unwrap(); assert!(session_key.session_key.len() > 0); } #[tokio::test] async fn it_verifies_the_access_key() { - let mut client = common::get_client(); + let client = common::get_client(); let verification_response = client.verify_access_key().await.unwrap(); assert!(verification_response.basic_permissions.len() > 0); // needs to be configured in the client but we want at least some permissions for the test assert!(verification_response.human_description.len() > 0); @@ -25,7 +25,7 @@ async fn it_verifies_the_access_key() { #[tokio::test] async fn it_returns_a_list_of_services() { - let mut client = common::get_client(); + let client = common::get_client(); let services_response = client.get_services().await.unwrap(); assert!(services_response.0.keys().len() > 0); } diff --git a/tests/client/test_adding_files.rs b/tests/client/test_adding_files.rs index aa12bcc..37b1a7e 100644 --- a/tests/client/test_adding_files.rs +++ b/tests/client/test_adding_files.rs @@ -2,14 +2,14 @@ use super::super::common; #[tokio::test] async fn it_adds_files() { - let mut client = common::get_client(); + let client = common::get_client(); let result = client.add_file("/does/not/exist").await; assert!(result.is_err()); // because the path does not exist } #[tokio::test] async fn it_adds_binary_files() { - let mut client = common::get_client(); + let client = common::get_client(); let result = client .add_binary_file(vec![0u8, 0u8, 0u8, 0u8]) .await @@ -19,24 +19,24 @@ async fn it_adds_binary_files() { #[tokio::test] async fn it_deletes_files() { - let mut client = common::get_client(); + let client = common::get_client(); client.delete_files(vec![]).await.unwrap(); } #[tokio::test] async fn it_undeletes_files() { - let mut client = common::get_client(); + let client = common::get_client(); client.undelete_files(vec![]).await.unwrap(); } #[tokio::test] async fn it_archives_files() { - let mut client = common::get_client(); + let client = common::get_client(); client.archive_files(vec![]).await.unwrap(); } #[tokio::test] async fn it_unarchives_files() { - let mut client = common::get_client(); + let client = common::get_client(); client.unarchive_files(vec![]).await.unwrap(); } diff --git a/tests/client/test_adding_tags.rs b/tests/client/test_adding_tags.rs index 819cdc1..2bc6fa3 100644 --- a/tests/client/test_adding_tags.rs +++ b/tests/client/test_adding_tags.rs @@ -3,7 +3,7 @@ use hydrus_api::endpoints::adding_tags::{AddTagsRequestBuilder, TagAction}; #[tokio::test] async fn it_cleans_tags() { - let mut client = common::get_client(); + let client = common::get_client(); let response = client .clean_tags(vec![ "summer".into(), @@ -18,7 +18,7 @@ async fn it_cleans_tags() { #[tokio::test] async fn it_adds_tags() { - let mut client = common::get_client(); + let client = common::get_client(); let request = AddTagsRequestBuilder::default() .add_hash("0000000000000000000000000000000000000000000000000000000000000000") // valid hash, I hope no files are affected .add_tags("my tags", vec!["beach".into(), "summer".into()]) diff --git a/tests/client/test_adding_urls.rs b/tests/client/test_adding_urls.rs index 01e5af0..ab6dd3b 100644 --- a/tests/client/test_adding_urls.rs +++ b/tests/client/test_adding_urls.rs @@ -3,7 +3,7 @@ use hydrus_api::endpoints::adding_urls::{AddUrlRequestBuilder, URL_TYPE_POST}; #[tokio::test] async fn it_returns_files_for_an_url() { - let mut client = common::get_client(); + let client = common::get_client(); let response = client .get_url_files("https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium") .await @@ -14,7 +14,7 @@ async fn it_returns_files_for_an_url() { #[tokio::test] async fn it_returns_url_information() { - let mut client = common::get_client(); + let client = common::get_client(); let info = client .get_url_info("https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium") .await @@ -25,7 +25,7 @@ async fn it_returns_url_information() { #[tokio::test] async fn it_adds_urls() { - let mut client = common::get_client(); + let client = common::get_client(); let request = AddUrlRequestBuilder::default() .url("https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium") .add_tags( @@ -41,7 +41,7 @@ async fn it_adds_urls() { #[tokio::test] async fn it_associates_urls() { - let mut client = common::get_client(); + let client = common::get_client(); client .associate_urls( vec![ @@ -56,7 +56,7 @@ async fn it_associates_urls() { #[tokio::test] async fn it_disassociates_urls() { - let mut client = common::get_client(); + let client = common::get_client(); client .disassociate_urls( vec![ diff --git a/tests/client/test_searching_and_fetching_files.rs b/tests/client/test_searching_and_fetching_files.rs index 42d4940..db0ffaf 100644 --- a/tests/client/test_searching_and_fetching_files.rs +++ b/tests/client/test_searching_and_fetching_files.rs @@ -4,7 +4,7 @@ use hydrus_api::endpoints::searching_and_fetching_files::FileSearchLocation; #[tokio::test] async fn is_searches_files() { - let mut client = common::get_client(); + let client = common::get_client(); client .search_files(vec!["beach".to_string()], FileSearchLocation::Archive) .await @@ -13,19 +13,19 @@ async fn is_searches_files() { #[tokio::test] async fn it_fetches_file_metadata() { - let mut client = common::get_client(); - client + let client = common::get_client(); + let response = client .get_file_metadata( vec![], vec!["0000000000000000000000000000000000000000000000000000000000000000".to_string()], ) - .await - .unwrap(); + .await; + assert!(response.is_ok()); // Even if the file doesn't exist it still returns some information about it } #[tokio::test] async fn it_fetches_single_files() { - let mut client = common::get_client(); + let client = common::get_client(); let response = client .get_file(FileIdentifier::Hash( "0000000000000000000000000000000000000000000000000000000000000000".to_string(), diff --git a/tests/wrapper/mod.rs b/tests/wrapper/mod.rs index fe956cc..44e1c9a 100644 --- a/tests/wrapper/mod.rs +++ b/tests/wrapper/mod.rs @@ -1,3 +1,4 @@ +mod test_files; mod test_hydrus; mod test_import; mod test_url; diff --git a/tests/wrapper/test_files.rs b/tests/wrapper/test_files.rs new file mode 100644 index 0000000..48f2c83 --- /dev/null +++ b/tests/wrapper/test_files.rs @@ -0,0 +1,49 @@ +use super::super::common; +use hydrus_api::endpoints::common::FileIdentifier; +use hydrus_api::hydrus_file::HydrusFile; + +async fn get_file() -> HydrusFile { + let hydrus = common::get_hydrus(); + hydrus + .file(FileIdentifier::hash( + "277a138cd1ee79fc1fdb2869c321b848d4861e45b82184487139ef66dd40b62d", // needs to exist + )) + .await + .unwrap() +} + +#[tokio::test] +async fn it_associates_with_urls() { + let mut file = get_file().await; + file.associate_urls(vec![ + "https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium".to_string(), + ]) + .await + .unwrap(); +} + +#[tokio::test] +async fn it_disassociates_with_urls() { + let mut file = get_file().await; + file.disassociate_urls(vec![ + "https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium".to_string(), + ]) + .await + .unwrap(); +} + +#[tokio::test] +async fn it_has_tags_with_services() { + let mut file = get_file().await; + let tags = file.services_with_tags().await.unwrap(); + + assert!(tags.keys().len() > 0) +} + +#[tokio::test] +async fn it_has_tags() { + let mut file = get_file().await; + let tags = file.tags().await.unwrap(); + + assert!(tags.len() > 0) // test data needs to be prepared this way +} diff --git a/tests/wrapper/test_hydrus.rs b/tests/wrapper/test_hydrus.rs index f9ec065..5e04b21 100644 --- a/tests/wrapper/test_hydrus.rs +++ b/tests/wrapper/test_hydrus.rs @@ -4,7 +4,7 @@ use hydrus_api::url::UrlType; #[tokio::test] async fn it_retrieves_version_info() { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); let version = hydrus.version().await.unwrap(); assert!(version.hydrus > 0); assert!(version.api > 0); @@ -12,7 +12,7 @@ async fn it_retrieves_version_info() { #[tokio::test] async fn it_retrieves_services() { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); let services = hydrus.services().await.unwrap(); // assuming hydrus is configured correctly @@ -22,7 +22,7 @@ async fn it_retrieves_services() { #[tokio::test] async fn it_retrieves_url_information() { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); let url = hydrus .url("https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium") .await diff --git a/tests/wrapper/test_import.rs b/tests/wrapper/test_import.rs index f1e2140..39281c0 100644 --- a/tests/wrapper/test_import.rs +++ b/tests/wrapper/test_import.rs @@ -7,7 +7,7 @@ use hydrus_api::url::UrlType; #[tokio::test] async fn it_imports_file_paths() { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); let result = hydrus .import() .file(FileImport::path("/does/not/exist/sadly")) @@ -19,7 +19,7 @@ async fn it_imports_file_paths() { #[tokio::test] async fn it_imports_binary_files() { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); let bytes = [0u8, 0u8, 0u8, 0u8]; let result = hydrus .import() @@ -32,7 +32,7 @@ async fn it_imports_binary_files() { #[tokio::test] async fn it_imports_urls() { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); let result = hydrus .import() diff --git a/tests/wrapper/test_url.rs b/tests/wrapper/test_url.rs index 7df9806..cc97bd6 100644 --- a/tests/wrapper/test_url.rs +++ b/tests/wrapper/test_url.rs @@ -5,7 +5,7 @@ use hydrus_api::tag::Tag; use hydrus_api::url::Url; async fn get_url() -> Url { - let mut hydrus = common::get_hydrus(); + let hydrus = common::get_hydrus(); hydrus .url("https://www.pixiv.net/member_illust.php?illust_id=83406361&mode=medium") .await