Skip to content

Commit

Permalink
test: [#115] add E2E tests for torrent download with personal announc…
Browse files Browse the repository at this point in the history
…e url
  • Loading branch information
josecelano committed May 5, 2023
1 parent e8bf537 commit 32af56d
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 8 deletions.
61 changes: 58 additions & 3 deletions tests/e2e/contexts/torrent/asserts.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,75 @@
use std::sync::Arc;

use torrust_index_backend::databases::database::connect_database;
use torrust_index_backend::models::torrent_file::Torrent;
use torrust_index_backend::models::tracker_key::TrackerKey;

use crate::common::contexts::user::responses::LoggedInUserData;
use crate::e2e::environment::TestEnv;

/// The backend does not generate exactly the same torrent that was uploaded.
/// So we need to update the expected torrent to match the one generated by
/// the backend.
pub fn expected_torrent(mut uploaded_torrent: Torrent) -> Torrent {
pub async fn expected_torrent(mut uploaded_torrent: Torrent, env: &TestEnv, downloader: &Option<LoggedInUserData>) -> Torrent {
// code-review: The backend does not generate exactly the same torrent
// that was uploaded and created by the `imdl` command-line tool.
// So we need to update the expected torrent to match the one generated
// by the backend. For some of them it makes sense (`announce` and `announce_list`),
// for others it does not.

let tracker_url = format!("{}", env.server_settings().unwrap().tracker.url);

let tracker_key = match downloader {
Some(logged_in_user) => get_user_tracker_key(logged_in_user, env).await,
None => None,
};

uploaded_torrent.info.private = Some(0);
uploaded_torrent.announce = Some("udp://tracker:6969".to_string());
uploaded_torrent.announce = Some(build_announce_url(&tracker_url, &tracker_key));
uploaded_torrent.encoding = None;
uploaded_torrent.announce_list = Some(vec![vec!["udp://tracker:6969".to_string()]]);
uploaded_torrent.announce_list = Some(build_announce_list(&tracker_url, &tracker_key));
uploaded_torrent.creation_date = None;
uploaded_torrent.created_by = None;

uploaded_torrent
}

async fn get_user_tracker_key(logged_in_user: &LoggedInUserData, env: &TestEnv) -> Option<TrackerKey> {
// code-review: could we add a new endpoint to get the user's tracker key?
// `/user/keys/recent` or `/user/keys/latest
// We could use that endpoint to get the user's tracker key instead of
// querying the database.

let database = Arc::new(
connect_database(&env.database_connect_url().unwrap())
.await
.expect("Database error."),
);

// Get the logged-in user id
let user_profile = database
.get_user_profile_from_username(&logged_in_user.username)
.await
.unwrap();

// Get the user's tracker key
let tracker_key = database.get_user_tracker_key(user_profile.user_id).await.unwrap();

Some(tracker_key)
}

fn build_announce_url(tracker_url: &str, tracker_key: &Option<TrackerKey>) -> String {
if let Some(key) = &tracker_key {
format!("{tracker_url}/{}", key.key)
} else {
format!("{tracker_url}")
}
}

fn build_announce_list(tracker_url: &str, tracker_key: &Option<TrackerKey>) -> Vec<Vec<String>> {
if let Some(key) = &tracker_key {
vec![vec![format!("{tracker_url}/{}", key.key)], vec![format!("{tracker_url}")]]
} else {
vec![vec![format!("{tracker_url}")]]
}
}
41 changes: 36 additions & 5 deletions tests/e2e/contexts/torrent/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
/*
todo:
Download torrent file:
- It should allow authenticated users to download a torrent with a personal tracker url
Delete torrent:
- After deleting a torrent, it should be removed from the tracker whitelist
Expand Down Expand Up @@ -132,7 +128,7 @@ mod for_guests {

let torrent = decode_torrent(&response.bytes).unwrap();
let uploaded_torrent = decode_torrent(&test_torrent.index_info.torrent_file.contents).unwrap();
let expected_torrent = expected_torrent(uploaded_torrent);
let expected_torrent = expected_torrent(uploaded_torrent, &env, &None).await;
assert_eq!(torrent, expected_torrent);
assert!(response.is_bittorrent_and_ok());
}
Expand Down Expand Up @@ -160,10 +156,14 @@ mod for_guests {

mod for_authenticated_users {

use torrust_index_backend::utils::parse_torrent::decode_torrent;

use crate::common::client::Client;
use crate::common::contexts::torrent::fixtures::random_torrent;
use crate::common::contexts::torrent::forms::UploadTorrentMultipartForm;
use crate::common::contexts::torrent::responses::UploadedTorrentResponse;
use crate::e2e::contexts::torrent::asserts::expected_torrent;
use crate::e2e::contexts::torrent::steps::upload_random_torrent_to_index;
use crate::e2e::contexts::user::steps::new_logged_in_user;
use crate::e2e::environment::TestEnv;

Expand Down Expand Up @@ -275,6 +275,37 @@ mod for_authenticated_users {
assert_eq!(response.status, 400);
}

#[tokio::test]
async fn it_should_allow_authenticated_users_to_download_a_torrent_with_a_personal_announce_url() {
let mut env = TestEnv::new();
env.start().await;

if !env.provides_a_tracker() {
println!("test skipped. It requires a tracker to be running.");
return;
}

// Given a previously uploaded torrent
let uploader = new_logged_in_user(&env).await;
let (test_torrent, torrent_listed_in_index) = upload_random_torrent_to_index(&uploader, &env).await;
let torrent_id = torrent_listed_in_index.torrent_id;
let uploaded_torrent = decode_torrent(&test_torrent.index_info.torrent_file.contents).unwrap();

// And a logged in user who is going to download the torrent
let downloader = new_logged_in_user(&env).await;
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &downloader.token);

// When the user downloads the torrent
let response = client.download_torrent(torrent_id).await;
let torrent = decode_torrent(&response.bytes).unwrap();

// Then the torrent should have the personal announce URL
let expected_torrent = expected_torrent(uploaded_torrent, &env, &Some(downloader)).await;

assert_eq!(torrent, expected_torrent);
assert!(response.is_bittorrent_and_ok());
}

mod and_non_admins {
use crate::common::client::Client;
use crate::e2e::contexts::torrent::steps::upload_random_torrent_to_index;
Expand Down

0 comments on commit 32af56d

Please sign in to comment.