@@ -17,17 +17,19 @@ Get torrent info:
1717mod for_guests {
1818
1919 use torrust_index_backend:: web:: api;
20+ use uuid:: Uuid ;
2021
2122 use crate :: common:: client:: Client ;
2223 use crate :: common:: contexts:: category:: fixtures:: software_predefined_category_id;
2324 use crate :: common:: contexts:: torrent:: asserts:: assert_expected_torrent_details;
25+ use crate :: common:: contexts:: torrent:: fixtures:: TestTorrent ;
2426 use crate :: common:: contexts:: torrent:: requests:: InfoHash ;
2527 use crate :: common:: contexts:: torrent:: responses:: {
2628 Category , File , TorrentDetails , TorrentDetailsResponse , TorrentListResponse ,
2729 } ;
2830 use crate :: common:: http:: { Query , QueryParam } ;
2931 use crate :: e2e:: environment:: TestEnv ;
30- use crate :: e2e:: web:: api:: v1:: contexts:: torrent:: steps:: upload_random_torrent_to_index;
32+ use crate :: e2e:: web:: api:: v1:: contexts:: torrent:: steps:: { upload_random_torrent_to_index, upload_test_torrent } ;
3133 use crate :: e2e:: web:: api:: v1:: contexts:: user:: steps:: new_logged_in_user;
3234
3335 #[ tokio:: test]
@@ -164,7 +166,7 @@ mod for_guests {
164166 let uploader = new_logged_in_user ( & env) . await ;
165167 let ( test_torrent, uploaded_torrent) = upload_random_torrent_to_index ( & uploader, & env) . await ;
166168
167- let response = client. get_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
169+ let response = client. get_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
168170
169171 let torrent_details_response: TorrentDetailsResponse = serde_json:: from_str ( & response. body ) . unwrap ( ) ;
170172
@@ -213,7 +215,50 @@ mod for_guests {
213215 assert ! ( response. is_json_and_ok( ) ) ;
214216 }
215217
216- mod it_should_allow_guests_download_a_torrent_file_searching_by_info_hash {
218+ #[ tokio:: test]
219+ async fn it_should_allow_guests_to_find_torrent_details_using_a_non_canonical_info_hash ( ) {
220+ let mut env = TestEnv :: new ( ) ;
221+ env. start ( api:: Version :: V1 ) . await ;
222+
223+ if !env. provides_a_tracker ( ) {
224+ println ! ( "test skipped. It requires a tracker to be running." ) ;
225+ return ;
226+ }
227+
228+ let uploader = new_logged_in_user ( & env) . await ;
229+ let client = Client :: authenticated ( & env. server_socket_addr ( ) . unwrap ( ) , & uploader. token ) ;
230+
231+ // Sample data needed to build two torrents with the same canonical info-hash.
232+ // Those torrents belong to the same Canonical Infohash Group.
233+ let id = Uuid :: new_v4 ( ) ;
234+ let title = format ! ( "title-{id}" ) ;
235+ let file_contents = "data" . to_string ( ) ;
236+
237+ let mut first_torrent = TestTorrent :: with_custom_info_dict_field ( id, & file_contents, "custom 01" ) ;
238+ first_torrent. index_info . title = title. clone ( ) ;
239+
240+ let first_torrent_canonical_info_hash = upload_test_torrent ( & client, & first_torrent)
241+ . await
242+ . expect ( "first torrent should be uploaded" ) ;
243+
244+ let mut second_torrent = TestTorrent :: with_custom_info_dict_field ( id, & file_contents, "custom 02" ) ;
245+ second_torrent. index_info . title = format ! ( "{title}-clone" ) ;
246+
247+ let _result = upload_test_torrent ( & client, & second_torrent) . await ;
248+
249+ // Get torrent details using the non-canonical info-hash (second torrent info-hash)
250+ let response = client. get_torrent ( & second_torrent. file_info_hash ( ) ) . await ;
251+ let torrent_details_response: TorrentDetailsResponse = serde_json:: from_str ( & response. body ) . unwrap ( ) ;
252+
253+ // The returned torrent info should be the same as the first torrent
254+ assert_eq ! ( response. status, 200 ) ;
255+ assert_eq ! (
256+ torrent_details_response. data. info_hash,
257+ first_torrent_canonical_info_hash. to_hex_string( )
258+ ) ;
259+ }
260+
261+ mod it_should_allow_guests_to_download_a_torrent_file_searching_by_info_hash {
217262
218263 use torrust_index_backend:: utils:: parse_torrent:: { calculate_info_hash, decode_torrent} ;
219264 use torrust_index_backend:: web:: api;
@@ -241,7 +286,7 @@ mod for_guests {
241286 let ( test_torrent, _torrent_listed_in_index) = upload_random_torrent_to_index ( & uploader, & env) . await ;
242287
243288 // Download
244- let response = client. download_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
289+ let response = client. download_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
245290
246291 assert ! ( response. is_a_bit_torrent_file( ) ) ;
247292 }
@@ -264,13 +309,13 @@ mod for_guests {
264309 let ( test_torrent, _torrent_listed_in_index) = upload_random_torrent_to_index ( & uploader, & env) . await ;
265310
266311 // Download
267- let response = client. download_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
312+ let response = client. download_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
268313
269314 let downloaded_torrent_info_hash = calculate_info_hash ( & response. bytes ) ;
270315
271316 assert_eq ! (
272317 downloaded_torrent_info_hash. to_hex_string( ) ,
273- test_torrent. info_hash_as_hex_string ( ) ,
318+ test_torrent. file_info_hash ( ) ,
274319 "downloaded torrent info-hash does not match uploaded torrent info-hash"
275320 ) ;
276321 }
@@ -295,7 +340,7 @@ mod for_guests {
295340 decode_torrent ( & test_torrent. index_info . torrent_file . contents ) . expect ( "could not decode uploaded torrent" ) ;
296341
297342 // Download
298- let response = client. download_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
343+ let response = client. download_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
299344
300345 let downloaded_torrent = decode_torrent ( & response. bytes ) . expect ( "could not decode downloaded torrent" ) ;
301346
@@ -348,7 +393,7 @@ mod for_guests {
348393 let uploader = new_logged_in_user ( & env) . await ;
349394 let ( test_torrent, _uploaded_torrent) = upload_random_torrent_to_index ( & uploader, & env) . await ;
350395
351- let response = client. delete_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
396+ let response = client. delete_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
352397
353398 assert_eq ! ( response. status, 401 ) ;
354399 }
@@ -384,7 +429,7 @@ mod for_authenticated_users {
384429 let client = Client :: authenticated ( & env. server_socket_addr ( ) . unwrap ( ) , & uploader. token ) ;
385430
386431 let test_torrent = random_torrent ( ) ;
387- let info_hash = test_torrent. info_hash_as_hex_string ( ) . clone ( ) ;
432+ let info_hash = test_torrent. file_info_hash ( ) . clone ( ) ;
388433
389434 let form: UploadTorrentMultipartForm = test_torrent. index_info . into ( ) ;
390435
@@ -527,7 +572,7 @@ mod for_authenticated_users {
527572 let client = Client :: authenticated ( & env. server_socket_addr ( ) . unwrap ( ) , & downloader. token ) ;
528573
529574 // When the user downloads the torrent
530- let response = client. download_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
575+ let response = client. download_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
531576
532577 let torrent = decode_torrent ( & response. bytes ) . expect ( "could not decode downloaded torrent" ) ;
533578
@@ -569,7 +614,7 @@ mod for_authenticated_users {
569614
570615 let client = Client :: authenticated ( & env. server_socket_addr ( ) . unwrap ( ) , & uploader. token ) ;
571616
572- let response = client. delete_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
617+ let response = client. delete_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
573618
574619 assert_eq ! ( response. status, 403 ) ;
575620 }
@@ -597,7 +642,7 @@ mod for_authenticated_users {
597642
598643 let response = client
599644 . update_torrent (
600- & test_torrent. info_hash_as_hex_string ( ) ,
645+ & test_torrent. file_info_hash ( ) ,
601646 UpdateTorrentFrom {
602647 title : Some ( new_title. clone ( ) ) ,
603648 description : Some ( new_description. clone ( ) ) ,
@@ -642,7 +687,7 @@ mod for_authenticated_users {
642687
643688 let response = client
644689 . update_torrent (
645- & test_torrent. info_hash_as_hex_string ( ) ,
690+ & test_torrent. file_info_hash ( ) ,
646691 UpdateTorrentFrom {
647692 title : Some ( new_title. clone ( ) ) ,
648693 description : Some ( new_description. clone ( ) ) ,
@@ -689,7 +734,7 @@ mod for_authenticated_users {
689734 let admin = new_logged_in_admin ( & env) . await ;
690735 let client = Client :: authenticated ( & env. server_socket_addr ( ) . unwrap ( ) , & admin. token ) ;
691736
692- let response = client. delete_torrent ( & test_torrent. info_hash_as_hex_string ( ) ) . await ;
737+ let response = client. delete_torrent ( & test_torrent. file_info_hash ( ) ) . await ;
693738
694739 let deleted_torrent_response: DeletedTorrentResponse = serde_json:: from_str ( & response. body ) . unwrap ( ) ;
695740
@@ -718,7 +763,7 @@ mod for_authenticated_users {
718763
719764 let response = client
720765 . update_torrent (
721- & test_torrent. info_hash_as_hex_string ( ) ,
766+ & test_torrent. file_info_hash ( ) ,
722767 UpdateTorrentFrom {
723768 title : Some ( new_title. clone ( ) ) ,
724769 description : Some ( new_description. clone ( ) ) ,
0 commit comments