Skip to content

Commit

Permalink
refactor: extract logic from e2e tests to reuse it for integrations t…
Browse files Browse the repository at this point in the history
…ests

E2E tests run an independent application process with docker, and then they are executed against that public service. It's only one instance.

Integrations tests will use an independent process for each test, running the API on a different port. The instance SUT is launched by the tests. We need to refactor the application bootstrapping to be able lo launch an app instance from tests.

This refactor allows us to reuse the code from E2E tests in future integration tests.
  • Loading branch information
josecelano committed Apr 28, 2023
1 parent de2f59a commit 489061e
Show file tree
Hide file tree
Showing 48 changed files with 436 additions and 390 deletions.
4 changes: 2 additions & 2 deletions tests/e2e/asserts.rs → tests/common/asserts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::e2e::responses::TextResponse;

// Text responses

use super::responses::TextResponse;

pub fn assert_response_title(response: &TextResponse, title: &str) {
let title_element = format!("<title>{title}</title>");

Expand Down
16 changes: 8 additions & 8 deletions tests/e2e/client.rs → tests/common/client.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use reqwest::multipart;
use serde::Serialize;

use super::contexts::category::{AddCategoryForm, DeleteCategoryForm};
use super::contexts::settings::UpdateSettingsForm;
use super::contexts::torrent::requests::{TorrentId, UpdateTorrentFrom};
use super::contexts::user::{LoginForm, RegistrationForm, TokenRenewalForm, TokenVerificationForm, Username};
use super::responses::{self, BinaryResponse};
use crate::e2e::connection_info::ConnectionInfo;
use crate::e2e::http::{Query, ReqwestQuery};
use crate::e2e::responses::TextResponse;
use super::connection_info::ConnectionInfo;
use super::contexts::category::forms::{AddCategoryForm, DeleteCategoryForm};
use super::contexts::settings::form::UpdateSettingsForm;
use super::contexts::torrent::forms::UpdateTorrentFrom;
use super::contexts::torrent::requests::TorrentId;
use super::contexts::user::forms::{LoginForm, RegistrationForm, TokenRenewalForm, TokenVerificationForm, Username};
use super::http::{Query, ReqwestQuery};
use super::responses::{self, BinaryResponse, TextResponse};

/// API Client
pub struct Client {
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions tests/common/contexts/about/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

18 changes: 18 additions & 0 deletions tests/common/contexts/category/fixtures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use rand::Rng;

pub fn software_predefined_category_name() -> String {
"software".to_string()
}

pub fn software_predefined_category_id() -> i64 {
5
}

pub fn random_category_name() -> String {
format!("category name {}", random_id())
}

fn random_id() -> u64 {
let mut rng = rand::thread_rng();
rng.gen_range(0..1_000_000)
}
9 changes: 9 additions & 0 deletions tests/common/contexts/category/forms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use serde::Serialize;

#[derive(Serialize)]
pub struct AddCategoryForm {
pub name: String,
pub icon: Option<String>,
}

pub type DeleteCategoryForm = AddCategoryForm;
3 changes: 3 additions & 0 deletions tests/common/contexts/category/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod fixtures;
pub mod forms;
pub mod responses;
18 changes: 18 additions & 0 deletions tests/common/contexts/category/responses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serde::Deserialize;

#[derive(Deserialize)]
pub struct AddedCategoryResponse {
pub data: String,
}

#[derive(Deserialize, Debug)]
pub struct ListResponse {
pub data: Vec<ListItem>,
}

#[derive(Deserialize, Debug, PartialEq)]
pub struct ListItem {
pub category_id: i64,
pub name: String,
pub num_torrents: i64,
}
6 changes: 6 additions & 0 deletions tests/common/contexts/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod about;
pub mod category;
pub mod root;
pub mod settings;
pub mod torrent;
pub mod user;
1 change: 1 addition & 0 deletions tests/common/contexts/root/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

3 changes: 3 additions & 0 deletions tests/common/contexts/settings/form.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use super::Settings;

pub type UpdateSettingsForm = Settings;
59 changes: 59 additions & 0 deletions tests/common/contexts/settings/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
pub mod form;
pub mod responses;

use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Settings {
pub website: Website,
pub tracker: Tracker,
pub net: Net,
pub auth: Auth,
pub database: Database,
pub mail: Mail,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Website {
pub name: String,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Tracker {
pub url: String,
pub mode: String,
pub api_url: String,
pub token: String,
pub token_valid_seconds: u64,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Net {
pub port: u64,
pub base_url: Option<String>,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Auth {
pub email_on_signup: String,
pub min_password_length: u64,
pub max_password_length: u64,
pub secret_key: String,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Database {
pub connect_url: String,
pub torrent_info_update_interval: u64,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Mail {
pub email_verification_enabled: bool,
pub from: String,
pub reply_to: String,
pub username: String,
pub password: String,
pub server: String,
pub port: u64,
}
26 changes: 26 additions & 0 deletions tests/common/contexts/settings/responses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde::Deserialize;

use super::Settings;

#[derive(Deserialize)]
pub struct AllSettingsResponse {
pub data: Settings,
}

#[derive(Deserialize)]
pub struct PublicSettingsResponse {
pub data: Public,
}

#[derive(Deserialize, PartialEq, Debug)]
pub struct Public {
pub website_name: String,
pub tracker_url: String,
pub tracker_mode: String,
pub email_on_signup: String,
}

#[derive(Deserialize)]
pub struct SiteNameResponse {
pub data: String,
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ use tempfile::{tempdir, TempDir};
use uuid::Uuid;

use super::file::{create_torrent, parse_torrent, TorrentFileInfo};
use super::requests::{BinaryFile, UploadTorrentMultipartForm};
use super::responses::{Id, UploadedTorrentResponse};
use crate::e2e::contexts::category::fixtures::software_predefined_category_name;
use crate::e2e::contexts::user::LoggedInUserData;
use crate::e2e::environment::TestEnv;
use super::forms::{BinaryFile, UploadTorrentMultipartForm};
use super::responses::Id;
use crate::common::contexts::category::fixtures::software_predefined_category_name;

/// Information about a torrent that is going to added to the index.
#[derive(Clone)]
Expand Down Expand Up @@ -53,26 +51,6 @@ impl TorrentListedInIndex {
}
}

/// Add a new random torrent to the index
pub async fn upload_random_torrent_to_index(uploader: &LoggedInUserData) -> (TestTorrent, TorrentListedInIndex) {
let random_torrent = random_torrent();
let indexed_torrent = upload_torrent(uploader, &random_torrent.index_info).await;
(random_torrent, indexed_torrent)
}

/// Upload a torrent to the index
pub async fn upload_torrent(uploader: &LoggedInUserData, torrent: &TorrentIndexInfo) -> TorrentListedInIndex {
let client = TestEnv::default().authenticated_client(&uploader.token);

let form: UploadTorrentMultipartForm = torrent.clone().into();

let response = client.upload_torrent(form.into()).await;

let res: UploadedTorrentResponse = serde_json::from_str(&response.body).unwrap();

TorrentListedInIndex::from(torrent.clone(), res.data.torrent_id)
}

#[derive(Clone)]
pub struct TestTorrent {
/// Parsed info from torrent file.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use std::fs;
use std::path::Path;

use reqwest::multipart::Form;
use serde::{Deserialize, Serialize};

pub type TorrentId = i64;
#[derive(Deserialize, Serialize)]
pub struct UpdateTorrentFrom {
pub title: Option<String>,
pub description: Option<String>,
}

use reqwest::multipart::Form;

pub struct UploadTorrentMultipartForm {
pub title: String,
Expand Down Expand Up @@ -43,9 +48,3 @@ impl From<UploadTorrentMultipartForm> for Form {
)
}
}

#[derive(Deserialize, Serialize)]
pub struct UpdateTorrentFrom {
pub title: Option<String>,
pub description: Option<String>,
}
6 changes: 6 additions & 0 deletions tests/common/contexts/torrent/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod asserts;
pub mod file;
pub mod fixtures;
pub mod forms;
pub mod requests;
pub mod responses;
1 change: 1 addition & 0 deletions tests/common/contexts/torrent/requests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub type TorrentId = i64;
File renamed without changes.
18 changes: 18 additions & 0 deletions tests/common/contexts/user/fixtures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use rand::Rng;

use crate::common::contexts::user::forms::RegistrationForm;

pub fn random_user_registration() -> RegistrationForm {
let user_id = random_user_id();
RegistrationForm {
username: format!("username_{user_id}"),
email: Some(format!("email_{user_id}@email.com")),
password: "password".to_string(),
confirm_password: "password".to_string(),
}
}

fn random_user_id() -> u64 {
let mut rng = rand::thread_rng();
rng.gen_range(0..1_000_000)
}
37 changes: 37 additions & 0 deletions tests/common/contexts/user/forms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use serde::Serialize;

#[derive(Clone, Serialize)]
pub struct RegistrationForm {
pub username: String,
pub email: Option<String>,
pub password: String,
pub confirm_password: String,
}

pub type RegisteredUser = RegistrationForm;

#[derive(Serialize)]
pub struct LoginForm {
pub login: String,
pub password: String,
}

#[derive(Serialize)]
pub struct TokenVerificationForm {
pub token: String,
}

#[derive(Serialize)]
pub struct TokenRenewalForm {
pub token: String,
}

pub struct Username {
pub value: String,
}

impl Username {
pub fn new(value: String) -> Self {
Self { value }
}
}
3 changes: 3 additions & 0 deletions tests/common/contexts/user/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod fixtures;
pub mod forms;
pub mod responses;
35 changes: 35 additions & 0 deletions tests/common/contexts/user/responses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use serde::Deserialize;

#[derive(Deserialize)]
pub struct SuccessfulLoginResponse {
pub data: LoggedInUserData,
}

#[derive(Deserialize, Debug)]
pub struct LoggedInUserData {
pub token: String,
pub username: String,
pub admin: bool,
}

#[derive(Deserialize)]
pub struct TokenVerifiedResponse {
pub data: String,
}

#[derive(Deserialize)]
pub struct BannedUserResponse {
pub data: String,
}

#[derive(Deserialize)]
pub struct TokenRenewalResponse {
pub data: TokenRenewalData,
}

#[derive(Deserialize, PartialEq, Debug)]
pub struct TokenRenewalData {
pub token: String,
pub username: String,
pub admin: bool,
}
File renamed without changes.
6 changes: 6 additions & 0 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod asserts;
pub mod client;
pub mod connection_info;
pub mod contexts;
pub mod http;
pub mod responses;
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::e2e::asserts::{assert_response_title, assert_text_ok};
//! API contract for `about` context.
use crate::common::asserts::{assert_response_title, assert_text_ok};
use crate::e2e::environment::TestEnv;

#[tokio::test]
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/contexts/about/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod contract;
Loading

0 comments on commit 489061e

Please sign in to comment.