-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(api): [#187] add tests for new 'tag' context
- Loading branch information
1 parent
e766b4c
commit b97698a
Showing
12 changed files
with
297 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ pub mod about; | |
pub mod category; | ||
pub mod root; | ||
pub mod settings; | ||
pub mod tag; | ||
pub mod torrent; | ||
pub mod user; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use rand::Rng; | ||
|
||
pub fn random_tag_name() -> String { | ||
format!("category name {}", random_id()) | ||
} | ||
|
||
fn random_id() -> u64 { | ||
let mut rng = rand::thread_rng(); | ||
rng.gen_range(0..1_000_000) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use serde::Serialize; | ||
|
||
#[derive(Serialize)] | ||
pub struct AddTagForm { | ||
pub name: String, | ||
} | ||
|
||
#[derive(Serialize)] | ||
pub struct DeleteTagForm { | ||
pub tag_id: i64, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod fixtures; | ||
pub mod forms; | ||
pub mod responses; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use serde::Deserialize; | ||
|
||
#[derive(Deserialize)] | ||
pub struct AddedTagResponse { | ||
pub data: String, | ||
} | ||
|
||
#[derive(Deserialize)] | ||
pub struct DeletedTagResponse { | ||
pub data: i64, // tag_id | ||
} | ||
|
||
#[derive(Deserialize, Debug)] | ||
pub struct ListResponse { | ||
pub data: Vec<ListItem>, | ||
} | ||
|
||
impl ListResponse { | ||
pub fn find_tag_id(&self, tag_name: &str) -> i64 { | ||
self.data.iter().find(|tag| tag.name == tag_name).unwrap().tag_id | ||
} | ||
} | ||
|
||
#[derive(Deserialize, Debug, PartialEq)] | ||
pub struct ListItem { | ||
pub tag_id: i64, | ||
pub name: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ pub mod about; | |
pub mod category; | ||
pub mod root; | ||
pub mod settings; | ||
pub mod tag; | ||
pub mod torrent; | ||
pub mod user; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
//! API contract for `tag` context. | ||
use torrust_index_backend::web::api; | ||
|
||
use crate::common::asserts::assert_json_ok; | ||
use crate::common::client::Client; | ||
use crate::common::contexts::tag::fixtures::random_tag_name; | ||
use crate::common::contexts::tag::forms::{AddTagForm, DeleteTagForm}; | ||
use crate::common::contexts::tag::responses::{AddedTagResponse, DeletedTagResponse, ListResponse}; | ||
use crate::e2e::contexts::tag::steps::{add_random_tag, add_tag}; | ||
use crate::e2e::contexts::user::steps::{new_logged_in_admin, new_logged_in_user}; | ||
use crate::e2e::environment::TestEnv; | ||
|
||
#[tokio::test] | ||
async fn it_should_return_an_empty_tag_list_when_there_are_no_tags() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); | ||
|
||
let response = client.get_tags().await; | ||
|
||
assert_json_ok(&response); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_return_a_tag_list() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); | ||
|
||
// Add a tag | ||
let tag_name = random_tag_name(); | ||
let response = add_tag(&tag_name, &env).await; | ||
assert_eq!(response.status, 200); | ||
|
||
let response = client.get_tags().await; | ||
|
||
let res: ListResponse = serde_json::from_str(&response.body).unwrap(); | ||
|
||
// There should be at least the tag we added. | ||
// Since this is an E2E test that could be executed in a shred env, | ||
// there might be more tags. | ||
assert!(!res.data.is_empty()); | ||
if let Some(content_type) = &response.content_type { | ||
assert_eq!(content_type, "application/json"); | ||
} | ||
assert_eq!(response.status, 200); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_not_allow_adding_a_new_tag_to_unauthenticated_users() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); | ||
|
||
let response = client | ||
.add_tag(AddTagForm { | ||
name: "TAG NAME".to_string(), | ||
}) | ||
.await; | ||
|
||
assert_eq!(response.status, 401); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_not_allow_adding_a_new_tag_to_non_admins() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
|
||
let logged_non_admin = new_logged_in_user(&env).await; | ||
|
||
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &logged_non_admin.token); | ||
|
||
let response = client | ||
.add_tag(AddTagForm { | ||
name: "TAG NAME".to_string(), | ||
}) | ||
.await; | ||
|
||
assert_eq!(response.status, 403); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_allow_admins_to_add_new_tags() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
|
||
let logged_in_admin = new_logged_in_admin(&env).await; | ||
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &logged_in_admin.token); | ||
|
||
let tag_name = random_tag_name(); | ||
|
||
let response = client | ||
.add_tag(AddTagForm { | ||
name: tag_name.to_string(), | ||
}) | ||
.await; | ||
|
||
let res: AddedTagResponse = serde_json::from_str(&response.body).unwrap(); | ||
|
||
assert_eq!(res.data, tag_name); | ||
if let Some(content_type) = &response.content_type { | ||
assert_eq!(content_type, "application/json"); | ||
} | ||
assert_eq!(response.status, 200); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_allow_adding_duplicated_tags() { | ||
// code-review: is this an intended behavior? | ||
|
||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
|
||
// Add a tag | ||
let random_tag_name = random_tag_name(); | ||
let response = add_tag(&random_tag_name, &env).await; | ||
assert_eq!(response.status, 200); | ||
|
||
// Try to add the same tag again | ||
let response = add_tag(&random_tag_name, &env).await; | ||
assert_eq!(response.status, 200); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_allow_adding_a_tag_with_an_empty_name() { | ||
// code-review: is this an intended behavior? | ||
|
||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
|
||
let empty_tag_name = String::new(); | ||
let response = add_tag(&empty_tag_name, &env).await; | ||
assert_eq!(response.status, 200); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_allow_admins_to_delete_tags() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
|
||
let logged_in_admin = new_logged_in_admin(&env).await; | ||
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &logged_in_admin.token); | ||
|
||
let (tag_id, _tag_name) = add_random_tag(&env).await; | ||
|
||
let response = client.delete_tag(DeleteTagForm { tag_id }).await; | ||
|
||
let res: DeletedTagResponse = serde_json::from_str(&response.body).unwrap(); | ||
|
||
assert_eq!(res.data, tag_id); | ||
if let Some(content_type) = &response.content_type { | ||
assert_eq!(content_type, "application/json"); | ||
} | ||
assert_eq!(response.status, 200); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_not_allow_non_admins_to_delete_tags() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
|
||
let logged_in_non_admin = new_logged_in_user(&env).await; | ||
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &logged_in_non_admin.token); | ||
|
||
let (tag_id, _tag_name) = add_random_tag(&env).await; | ||
|
||
let response = client.delete_tag(DeleteTagForm { tag_id }).await; | ||
|
||
assert_eq!(response.status, 403); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_not_allow_guests_to_delete_tags() { | ||
let mut env = TestEnv::new(); | ||
env.start(api::Implementation::ActixWeb).await; | ||
let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); | ||
|
||
let (tag_id, _tag_name) = add_random_tag(&env).await; | ||
|
||
let response = client.delete_tag(DeleteTagForm { tag_id }).await; | ||
|
||
assert_eq!(response.status, 401); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod contract; | ||
pub mod steps; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use crate::common::client::Client; | ||
use crate::common::contexts::tag::fixtures::random_tag_name; | ||
use crate::common::contexts::tag::forms::AddTagForm; | ||
use crate::common::contexts::tag::responses::ListResponse; | ||
use crate::common::responses::TextResponse; | ||
use crate::e2e::contexts::user::steps::new_logged_in_admin; | ||
use crate::e2e::environment::TestEnv; | ||
|
||
pub async fn add_random_tag(env: &TestEnv) -> (i64, String) { | ||
let tag_name = random_tag_name(); | ||
|
||
add_tag(&tag_name, env).await; | ||
|
||
let tag_id = get_tag_id(&tag_name, env).await; | ||
|
||
(tag_id, tag_name) | ||
} | ||
|
||
pub async fn add_tag(tag_name: &str, env: &TestEnv) -> TextResponse { | ||
let logged_in_admin = new_logged_in_admin(env).await; | ||
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &logged_in_admin.token); | ||
|
||
client | ||
.add_tag(AddTagForm { | ||
name: tag_name.to_string(), | ||
}) | ||
.await | ||
} | ||
|
||
pub async fn get_tag_id(tag_name: &str, env: &TestEnv) -> i64 { | ||
let logged_in_admin = new_logged_in_admin(env).await; | ||
let client = Client::authenticated(&env.server_socket_addr().unwrap(), &logged_in_admin.token); | ||
|
||
let response = client.get_tags().await; | ||
|
||
let res: ListResponse = serde_json::from_str(&response.body).unwrap(); | ||
|
||
res.find_tag_id(tag_name) | ||
} |