diff --git a/openleadr-client/src/error.rs b/openleadr-client/src/error.rs index 5c08bfe..da1499f 100644 --- a/openleadr-client/src/error.rs +++ b/openleadr-client/src/error.rs @@ -43,6 +43,16 @@ impl Error { _ => false, } } + + #[allow(missing_docs)] + pub fn is_bad_request(&self) -> bool { + match self { + Error::Problem(openleadr_wire::problem::Problem { status, .. }) => { + *status == StatusCode::BAD_REQUEST + } + _ => false, + } + } } impl From for Error { diff --git a/openleadr-client/tests/event.rs b/openleadr-client/tests/event.rs index 39a25f1..bc0ef3d 100644 --- a/openleadr-client/tests/event.rs +++ b/openleadr-client/tests/event.rs @@ -1,11 +1,14 @@ +use crate::common::setup; use axum::http::StatusCode; use openleadr_client::{Error, Filter, PaginationOptions}; +use openleadr_vtn::jwt::AuthRole; use openleadr_wire::{ event::{EventContent, EventInterval, EventType, EventValuesMap, Priority}, program::{ProgramContent, ProgramId}, target::{TargetEntry, TargetMap, TargetType}, values_map::Value, }; +use serial_test::serial; use sqlx::PgPool; mod common; @@ -30,6 +33,190 @@ fn default_content(program_id: &ProgramId) -> EventContent { } } +#[tokio::test] +#[serial] +async fn crud() { + let ctx = setup(AuthRole::AnyBusiness).await; + let new_program = ProgramContent::new("test-program-name".to_string()); + let program = ctx.create_program(new_program).await.unwrap(); + + // Create + let event_content = EventContent { + event_name: Some("event1".to_string()), + ..default_content(program.id()) + }; + let event = program.create_event(event_content.clone()).await.unwrap(); + assert_eq!(event.content().event_name, event_content.event_name); + + // Creating a second event with the same name succeeds + { + let event_2 = program.create_event(event_content.clone()).await.unwrap(); + assert_eq!(event_2.content().event_name, event_content.event_name); + event_2.delete().await.unwrap(); + } + + // Retrieve + { + let event_content_2 = EventContent { + program_id: program.id().clone(), + event_name: Some("event2".to_string()), + targets: Some(TargetMap(vec![TargetEntry { + label: TargetType::Group, + values: ["Group 2".to_string()], + }])), + ..default_content(program.id()) + }; + let event_2 = program.create_event(event_content_2.clone()).await.unwrap(); + + let event_content_3 = EventContent { + program_id: program.id().clone(), + event_name: Some("event3".to_string()), + targets: Some(TargetMap(vec![TargetEntry { + label: TargetType::Group, + values: ["Group 1".to_string()], + }])), + ..default_content(program.id()) + }; + let event_3 = program.create_event(event_content_3.clone()).await.unwrap(); + + let events = program + .get_events_request(Filter::None, PaginationOptions { skip: 0, limit: 50 }) + .await + .unwrap(); + assert_eq!(events.len(), 3); + + // skip + let events = program + .get_events_request(Filter::None, PaginationOptions { skip: 1, limit: 50 }) + .await + .unwrap(); + assert_eq!(events.len(), 2); + + // limit + let events = program + .get_events_request(Filter::None, PaginationOptions { skip: 0, limit: 2 }) + .await + .unwrap(); + assert_eq!(events.len(), 2); + + // event name + let events = program + .get_events_request( + Filter::By(TargetType::Private("NONSENSE".to_string()), &["test"]), + PaginationOptions { skip: 0, limit: 2 }, + ) + .await + .unwrap(); + assert_eq!(events.len(), 0); + + let err = program + .get_events_request( + Filter::By(TargetType::Private("NONSENSE".to_string()), &[""]), + PaginationOptions { skip: 0, limit: 2 }, + ) + .await + .unwrap_err(); + + let Error::Problem(problem) = err else { + unreachable!() + }; + assert_eq!( + problem.status, + StatusCode::BAD_REQUEST, + "Do return BAD_REQUEST on empty targetValue" + ); + + let err = program + .get_events_request( + Filter::By(TargetType::Private("NONSENSE".to_string()), &[]), + PaginationOptions { skip: 0, limit: 2 }, + ) + .await + .unwrap_err(); + + let Error::Problem(problem) = err else { + unreachable!() + }; + assert_eq!( + problem.status, + StatusCode::BAD_REQUEST, + "Do return BAD_REQUEST on empty targetValue" + ); + + let events = program + .get_events_request( + Filter::By(TargetType::Group, &["Group 1", "Group 2"]), + PaginationOptions { skip: 0, limit: 50 }, + ) + .await + .unwrap(); + assert_eq!(events.len(), 2); + + let events = program + .get_events_request( + Filter::By(TargetType::Group, &["Group 1"]), + PaginationOptions { skip: 0, limit: 50 }, + ) + .await + .unwrap(); + assert_eq!(events.len(), 1); + + let events = program + .get_events_request( + Filter::By(TargetType::Group, &["Not existent"]), + PaginationOptions { skip: 0, limit: 50 }, + ) + .await + .unwrap(); + assert_eq!(events.len(), 0); + + event_2.delete().await.unwrap(); + event_3.delete().await.unwrap(); + } + + // update + { + let updated_name = "event1_updated"; + let updated_priority = Priority::MIN; + let events = program.get_event_list(Filter::None).await.unwrap(); + let mut event = events.into_iter().next().unwrap(); + let creation_date_time = event.modification_date_time(); + + event.content_mut().event_name = Some(updated_name.to_string()); + event.content_mut().priority = updated_priority; + event.content_mut().targets = Some(TargetMap(vec![TargetEntry { + label: TargetType::Group, + values: ["Updated Group".to_string()], + }])); + event.update().await.unwrap(); + + assert_eq!(event.content().event_name, Some(updated_name.to_string())); + assert_eq!(event.content().priority, updated_priority); + + let updated_events = program + .get_events_request( + Filter::By(TargetType::Group, &["Updated Group"]), + PaginationOptions { skip: 0, limit: 50 }, + ) + .await + .unwrap(); + assert_eq!(updated_events.len(), 1); + + let updated_event = updated_events.into_iter().next().unwrap(); + + assert_eq!( + updated_event.content().event_name, + event.content().event_name + ); + assert_eq!(updated_event.content().priority, updated_priority); + assert!(updated_event.modification_date_time() > creation_date_time); + } + + // Cleanup + event.delete().await.unwrap(); + program.delete().await.unwrap(); +} + #[sqlx::test(fixtures("users"))] async fn get(db: PgPool) { let client = common::setup_program_client("program", db).await; @@ -79,31 +266,6 @@ async fn delete(db: PgPool) { assert_eq!(events.len(), 2); } -#[sqlx::test(fixtures("users"))] -async fn update(db: PgPool) { - let client = common::setup_program_client("program", db).await; - - let event1 = EventContent { - event_name: Some("event1".to_string()), - ..default_content(client.id()) - }; - - let mut event = client.create_event(event1).await.unwrap(); - let creation_date_time = event.modification_date_time(); - - let event2 = EventContent { - event_name: Some("event1".to_string()), - priority: Priority::MIN, - ..default_content(client.id()) - }; - - *event.content_mut() = event2.clone(); - event.update().await.unwrap(); - - assert_eq!(event.content(), &event2); - assert!(event.modification_date_time() > creation_date_time); -} - #[sqlx::test(fixtures("users"))] async fn update_same_name(db: PgPool) { let client = common::setup_program_client("program", db).await; @@ -149,128 +311,6 @@ async fn create_same_name(db: PgPool) { let _ = client.create_event(event1).await.unwrap(); } -#[sqlx::test(fixtures("users"))] -async fn retrieve_all_with_filter(db: PgPool) { - let client = common::setup_program_client("program1", db).await; - - let event1 = EventContent { - program_id: client.id().clone(), - event_name: Some("event1".to_string()), - ..default_content(client.id()) - }; - let event2 = EventContent { - program_id: client.id().clone(), - event_name: Some("event2".to_string()), - targets: Some(TargetMap(vec![TargetEntry { - label: TargetType::Group, - values: ["Group 2".to_string()], - }])), - ..default_content(client.id()) - }; - let event3 = EventContent { - program_id: client.id().clone(), - event_name: Some("event3".to_string()), - targets: Some(TargetMap(vec![TargetEntry { - label: TargetType::Group, - values: ["Group 1".to_string()], - }])), - ..default_content(client.id()) - }; - - for content in [event1, event2, event3] { - let _ = client.create_event(content).await.unwrap(); - } - - let events = client - .get_events_request(Filter::None, PaginationOptions { skip: 0, limit: 50 }) - .await - .unwrap(); - assert_eq!(events.len(), 3); - - // skip - let events = client - .get_events_request(Filter::None, PaginationOptions { skip: 1, limit: 50 }) - .await - .unwrap(); - assert_eq!(events.len(), 2); - - // limit - let events = client - .get_events_request(Filter::None, PaginationOptions { skip: 0, limit: 2 }) - .await - .unwrap(); - assert_eq!(events.len(), 2); - - // event name - let events = client - .get_events_request( - Filter::By(TargetType::Private("NONSENSE".to_string()), &["test"]), - PaginationOptions { skip: 0, limit: 2 }, - ) - .await - .unwrap(); - assert_eq!(events.len(), 0); - - let err = client - .get_events_request( - Filter::By(TargetType::Private("NONSENSE".to_string()), &[""]), - PaginationOptions { skip: 0, limit: 2 }, - ) - .await - .unwrap_err(); - let Error::Problem(problem) = err else { - unreachable!() - }; - assert_eq!( - problem.status, - StatusCode::BAD_REQUEST, - "Do return BAD_REQUEST on empty targetValue" - ); - - let err = client - .get_events_request( - Filter::By(TargetType::Private("NONSENSE".to_string()), &[]), - PaginationOptions { skip: 0, limit: 2 }, - ) - .await - .unwrap_err(); - let Error::Problem(problem) = err else { - unreachable!() - }; - assert_eq!( - problem.status, - StatusCode::BAD_REQUEST, - "Do return BAD_REQUEST on empty targetValue" - ); - - let events = client - .get_events_request( - Filter::By(TargetType::Group, &["Group 1", "Group 2"]), - PaginationOptions { skip: 0, limit: 50 }, - ) - .await - .unwrap(); - assert_eq!(events.len(), 2); - - let events = client - .get_events_request( - Filter::By(TargetType::Group, &["Group 1"]), - PaginationOptions { skip: 0, limit: 50 }, - ) - .await - .unwrap(); - assert_eq!(events.len(), 1); - - let events = client - .get_events_request( - Filter::By(TargetType::Group, &["Not existent"]), - PaginationOptions { skip: 0, limit: 50 }, - ) - .await - .unwrap(); - assert_eq!(events.len(), 0); -} - #[sqlx::test(fixtures("users"))] async fn get_program_events(db: PgPool) { let client = common::setup_client(db).await;