diff --git a/tests/common/contexts/category/fixtures.rs b/tests/common/contexts/category/fixtures.rs index 18e62288..05ec2c26 100644 --- a/tests/common/contexts/category/fixtures.rs +++ b/tests/common/contexts/category/fixtures.rs @@ -1,6 +1,6 @@ use rand::Rng; -pub fn software_predefined_category_name() -> String { +pub fn software_category_name() -> String { "software".to_string() } diff --git a/tests/common/contexts/torrent/asserts.rs b/tests/common/contexts/torrent/asserts.rs index 6e76a4be..d0f1a8cf 100644 --- a/tests/common/contexts/torrent/asserts.rs +++ b/tests/common/contexts/torrent/asserts.rs @@ -1,37 +1,42 @@ use super::responses::TorrentDetails; +type Check = (&'static str, bool); + /// Assert that the torrent details match the expected ones. +/// /// It ignores some fields that are not relevant for the E2E tests /// or hard to assert due to the concurrent nature of the tests. pub fn assert_expected_torrent_details(torrent: &TorrentDetails, expected_torrent: &TorrentDetails) { - assert_eq!( - torrent.torrent_id, expected_torrent.torrent_id, - "torrent `file_size` mismatch" - ); - assert_eq!(torrent.uploader, expected_torrent.uploader, "torrent `uploader` mismatch"); - assert_eq!(torrent.info_hash, expected_torrent.info_hash, "torrent `info_hash` mismatch"); - assert_eq!(torrent.title, expected_torrent.title, "torrent `title` mismatch"); - assert_eq!( - torrent.description, expected_torrent.description, - "torrent `description` mismatch" - ); - assert_eq!( - torrent.category.category_id, expected_torrent.category.category_id, - "torrent `category.category_id` mismatch" - ); - assert_eq!( - torrent.category.name, expected_torrent.category.name, - "torrent `category.name` mismatch" - ); - // assert_eq!(torrent.category.num_torrents, expected_torrent.category.num_torrents, "torrent `category.num_torrents` mismatch"); // Ignored - // assert_eq!(torrent.upload_date, expected_torrent.upload_date, "torrent `upload_date` mismatch"); // Ignored, can't mock time easily for now. - assert_eq!(torrent.file_size, expected_torrent.file_size, "torrent `file_size` mismatch"); - assert_eq!(torrent.seeders, expected_torrent.seeders, "torrent `seeders` mismatch"); - assert_eq!(torrent.leechers, expected_torrent.leechers, "torrent `leechers` mismatch"); - assert_eq!(torrent.files, expected_torrent.files, "torrent `files` mismatch"); - assert_eq!(torrent.trackers, expected_torrent.trackers, "torrent `trackers` mismatch"); - assert_eq!( - torrent.magnet_link, expected_torrent.magnet_link, - "torrent `magnet_link` mismatch" - ); + let mut discrepancies = Vec::new(); + + let checks: Vec = vec![ + ("torrent_id", torrent.torrent_id == expected_torrent.torrent_id), + ("uploader", torrent.uploader == expected_torrent.uploader), + ("info_hash", torrent.info_hash == expected_torrent.info_hash), + ("title", torrent.title == expected_torrent.title), + ("description", torrent.description == expected_torrent.description), + ( + "category.category_id", + torrent.category.category_id == expected_torrent.category.category_id, + ), + ("category.name", torrent.category.name == expected_torrent.category.name), + ("file_size", torrent.file_size == expected_torrent.file_size), + ("seeders", torrent.seeders == expected_torrent.seeders), + ("leechers", torrent.leechers == expected_torrent.leechers), + ("files", torrent.files == expected_torrent.files), + ("trackers", torrent.trackers == expected_torrent.trackers), + ("magnet_link", torrent.magnet_link == expected_torrent.magnet_link), + ("tags", torrent.tags == expected_torrent.tags), + ("name", torrent.name == expected_torrent.name), + ]; + + for (field_name, equals) in &checks { + if !equals { + discrepancies.push((*field_name).to_string()); + } + } + + let error_message = format!("left:\n{torrent:#?}\nright:\n{expected_torrent:#?}\ndiscrepancies: {discrepancies:#?}"); + + assert!(discrepancies.is_empty(), "{}", error_message); } diff --git a/tests/common/contexts/torrent/fixtures.rs b/tests/common/contexts/torrent/fixtures.rs index 309be5bd..3ee8c84a 100644 --- a/tests/common/contexts/torrent/fixtures.rs +++ b/tests/common/contexts/torrent/fixtures.rs @@ -13,14 +13,15 @@ use super::file::{create_torrent, parse_torrent, TorrentFileInfo}; use super::forms::{BinaryFile, UploadTorrentMultipartForm}; use super::requests::InfoHash; use super::responses::Id; -use crate::common::contexts::category::fixtures::software_predefined_category_name; +use crate::common::contexts::category::fixtures::software_category_name; -/// Information about a torrent that is going to added to the index. +/// Information about a torrent that is going to be added to the index. #[derive(Clone)] pub struct TorrentIndexInfo { pub title: String, pub description: String, pub category: String, + pub tags: Option>, pub torrent_file: BinaryFile, pub name: String, } @@ -78,24 +79,7 @@ impl TestTorrent { // Create a random torrent file let torrent_path = random_torrent_file(&torrents_dir_path, &id); - // Load torrent binary file - let torrent_file = BinaryFile::from_file_at_path(&torrent_path); - - // Load torrent file metadata - let torrent_info = parse_torrent(&torrent_path); - - let torrent_to_index = TorrentIndexInfo { - title: format!("title-{id}"), - description: format!("description-{id}"), - category: software_predefined_category_name(), - torrent_file, - name: format!("name-{id}"), - }; - - TestTorrent { - file_info: torrent_info, - index_info: torrent_to_index, - } + Self::build_from_torrent_file(&id, &torrent_path) } pub fn with_custom_info_dict_field(id: Uuid, file_contents: &str, custom: &str) -> Self { @@ -110,25 +94,39 @@ impl TestTorrent { let torrent_data = TestTorrentWithCustomInfoField::encode(&torrent).unwrap(); // Torrent temporary file path - let filename = format!("file-{id}.txt.torrent"); - let torrent_path = torrents_dir_path.join(filename.clone()); + let contents_filename = contents_file_name(&id); + let torrent_filename = format!("{contents_filename}.torrent"); + let torrent_path = torrents_dir_path.join(torrent_filename.clone()); // Write the torrent file to the temporary file let mut file = File::create(torrent_path.clone()).unwrap(); file.write_all(&torrent_data).unwrap(); + Self::build_from_torrent_file(&id, &torrent_path) + } + + pub fn file_info_hash(&self) -> InfoHash { + self.file_info.info_hash.clone() + } + + /// It builds a `TestTorrent` from a torrent file. + fn build_from_torrent_file(id: &Uuid, torrent_path: &Path) -> TestTorrent { // Load torrent binary file - let torrent_file = BinaryFile::from_file_at_path(&torrent_path); + let torrent_file = BinaryFile::from_file_at_path(torrent_path); // Load torrent file metadata - let torrent_info = parse_torrent(&torrent_path); + let torrent_info = parse_torrent(torrent_path); let torrent_to_index = TorrentIndexInfo { title: format!("title-{id}"), description: format!("description-{id}"), - category: software_predefined_category_name(), + category: software_category_name(), + // todo: include one tag in test torrents. Implementation is not + // trivial because the tag must exist in the database and there are + // no predefined tags in the database like there are for categories. + tags: None, torrent_file, - name: filename, + name: contents_file_name(id), }; TestTorrent { @@ -136,10 +134,6 @@ impl TestTorrent { index_info: torrent_to_index, } } - - pub fn file_info_hash(&self) -> InfoHash { - self.file_info.info_hash.clone() - } } pub fn random_torrent() -> TestTorrent { @@ -156,7 +150,7 @@ pub fn random_torrent_file(dir: &Path, id: &Uuid) -> PathBuf { pub fn random_txt_file(dir: &Path, id: &Uuid) -> String { // Sample file name - let file_name = format!("file-{id}.txt"); + let file_name = contents_file_name(id); // Sample file path let file_path = dir.join(file_name.clone()); @@ -168,6 +162,10 @@ pub fn random_txt_file(dir: &Path, id: &Uuid) -> String { file_name } +fn contents_file_name(id: &Uuid) -> String { + format!("file-{id}.txt") +} + pub fn temp_dir() -> TempDir { tempdir().unwrap() } diff --git a/tests/common/contexts/torrent/responses.rs b/tests/common/contexts/torrent/responses.rs index 001784d2..ee08c2dc 100644 --- a/tests/common/contexts/torrent/responses.rs +++ b/tests/common/contexts/torrent/responses.rs @@ -2,6 +2,7 @@ use serde::Deserialize; pub type Id = i64; pub type CategoryId = i64; +pub type TagId = i64; pub type UtcDateTime = String; // %Y-%m-%d %H:%M:%S #[derive(Deserialize, PartialEq, Debug)] @@ -61,6 +62,7 @@ pub struct TorrentDetails { pub files: Vec, pub trackers: Vec, pub magnet_link: String, + pub tags: Vec, pub name: String, } @@ -71,6 +73,12 @@ pub struct Category { pub num_torrents: u64, } +#[derive(Deserialize, PartialEq, Debug)] +pub struct Tag { + pub tag_id: TagId, + pub name: String, +} + #[derive(Deserialize, PartialEq, Debug)] pub struct File { pub path: Vec, diff --git a/tests/e2e/web/api/v1/contexts/torrent/contract.rs b/tests/e2e/web/api/v1/contexts/torrent/contract.rs index bc93cfcc..5ed440b1 100644 --- a/tests/e2e/web/api/v1/contexts/torrent/contract.rs +++ b/tests/e2e/web/api/v1/contexts/torrent/contract.rs @@ -209,6 +209,7 @@ mod for_guests { encoded_tracker_url, encoded_tracker_url ), + tags: vec![], name: test_torrent.index_info.name.clone(), };