diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 15428cc..664be9e 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -226,17 +226,63 @@ impl EcdarApi for ConcreteEcdarApi { None => return Err(Status::invalid_argument("No components info provided")), }; - let model = model::Model { + let mut model = model::Model { id: Default::default(), name: message.clone().name, components_info, owner_id: uid, }; - match self.contexts.model_context.create(model).await { - Ok(model) => Ok(Response::new(CreateModelResponse { id: model.id })), - Err(error) => Err(Status::internal(error.to_string())), - } + model = match self.contexts.model_context.create(model).await { + Ok(model) => model, + Err(error) => { + return match error.sql_err() { + Some(SqlErr::UniqueConstraintViolation(e)) => { + let error_msg = match e.to_lowercase() { + _ if e.contains("name") => "A model with that name already exists", + _ => "Model already exists", + }; + println!("{}", e); + Err(Status::already_exists(error_msg)) + } + Some(SqlErr::ForeignKeyConstraintViolation(e)) => { + let error_msg = match e.to_lowercase() { + _ if e.contains("owner_id") => "No user with that id exists", + _ => "Could not create model", + }; + println!("{}", e); + Err(Status::invalid_argument(error_msg)) + } + _ => Err(Status::internal(error.to_string())), + }; + } + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), //todo!("Use role enum") + model_id: model.clone().id, + user_id: uid, + }; + + let session = self + .contexts + .session_context + .get_by_token(TokenType::AccessToken, request.token_string().unwrap()) + .await + .unwrap() + .unwrap(); + + let in_use = in_use::Model { + model_id: model.clone().id, + session_id: session.id, + latest_activity: Default::default(), + }; + + self.contexts.in_use_context.create(in_use).await.unwrap(); + self.contexts.access_context.create(access).await.unwrap(); + + Ok(Response::new(CreateModelResponse { id: model.id })) } async fn update_model( diff --git a/src/database/model_context.rs b/src/database/model_context.rs index c16ce1f..9f6c2ca 100644 --- a/src/database/model_context.rs +++ b/src/database/model_context.rs @@ -61,6 +61,7 @@ impl ModelContext { ModelContext { db_context } } } + #[async_trait] impl EntityContextTrait for ModelContext { /// Used for creating a model::Model entity diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index e002595..4761a69 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -2,7 +2,8 @@ use crate::{ api::{ auth::TokenType, server::server::{ - ecdar_api_server::EcdarApi, DeleteModelRequest, GetModelRequest, ModelInfo, + ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, + GetModelRequest, ModelInfo, }, }, entities::{access, in_use, model, query, session}, @@ -10,9 +11,132 @@ use crate::{ }; use chrono::Utc; use mockall::predicate; +use sea_orm::DbErr; use std::str::FromStr; use tonic::{metadata, Code, Request}; +#[tokio::test] +async fn create_model_returns_ok() { + let mut mock_services = get_mock_services(); + + let uid = 0; + + let components_info = ComponentsInfo { + components: vec![], + components_hash: 0, + }; + + let model = model::Model { + id: Default::default(), + name: Default::default(), + components_info: serde_json::to_value(components_info.clone()).unwrap(), + owner_id: uid, + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + user_id: uid, + model_id: model.id, + }; + + let session = session::Model { + id: Default::default(), + refresh_token: "refresh_token".to_string(), + access_token: "access_token".to_string(), + updated_at: Default::default(), + user_id: uid, + }; + + let in_use = in_use::Model { + model_id: model.id, + session_id: session.id, + latest_activity: Default::default(), + }; + + mock_services + .model_context_mock + .expect_create() + .with(predicate::eq(model.clone())) + .returning(move |_| Ok(model.clone())); + + mock_services + .access_context_mock + .expect_create() + .with(predicate::eq(access.clone())) + .returning(move |_| Ok(access.clone())); + + mock_services + .session_context_mock + .expect_get_by_token() + .with( + predicate::eq(TokenType::AccessToken), + predicate::eq("access_token".to_string()), + ) + .returning(move |_, _| Ok(Some(session.clone()))); + + mock_services + .in_use_context_mock + .expect_create() + .with(predicate::eq(in_use.clone())) + .returning(move |_| Ok(in_use.clone())); + + let mut request = Request::new(CreateModelRequest { + name: Default::default(), + components_info: Option::from(components_info), + }); + + request + .metadata_mut() + .insert("uid", uid.to_string().parse().unwrap()); + + request.metadata_mut().insert( + "authorization", + metadata::MetadataValue::from_str("Bearer access_token").unwrap(), + ); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.create_model(request).await; + + assert!(res.is_ok()); +} + +#[tokio::test] +async fn create_model_existing_name_returns_err() { + let mut mock_services = get_mock_services(); + + let uid = 0; + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: uid, + }; + + mock_services + .model_context_mock + .expect_create() + .with(predicate::eq(model.clone())) + .returning(move |_| Err(DbErr::RecordNotInserted)); //todo!("Needs to be a SqlError with UniqueConstraintViolation with 'name' in message) + + let mut request = Request::new(CreateModelRequest { + name: "model".to_string(), + components_info: Default::default(), + }); + + request + .metadata_mut() + .insert("uid", uid.to_string().parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.create_model(request).await; + + assert_eq!(res.unwrap_err().code(), Code::InvalidArgument); //todo!("Needs to be code AlreadyExists when mocked Error is corrected) +} + #[tokio::test] async fn get_model_user_has_access_returns_ok() { let mut mock_services = get_mock_services(); @@ -74,6 +198,7 @@ async fn get_model_user_has_access_returns_ok() { assert!(res.is_ok()); } +#[tokio::test] async fn delete_not_owner_returns_err() { let mut mock_services = get_mock_services(); diff --git a/src/tests/database/access_context.rs b/src/tests/database/access_context.rs index d8d4237..a4eae13 100644 --- a/src/tests/database/access_context.rs +++ b/src/tests/database/access_context.rs @@ -1,7 +1,6 @@ #[cfg(test)] mod database_tests { use crate::database::access_context::AccessContextTrait; - use crate::tests::database::helpers::{ create_accesses, create_models, create_users, get_reset_database_context, }; diff --git a/src/tests/database/in_use_context.rs b/src/tests/database/in_use_context.rs index ca3e204..dee9275 100644 --- a/src/tests/database/in_use_context.rs +++ b/src/tests/database/in_use_context.rs @@ -1,261 +1,264 @@ -use crate::tests::database::helpers::*; -use crate::{ - database::{ - entity_context::EntityContextTrait, - in_use_context::{DbErr, InUseContext}, - }, - entities::{in_use, model, session, user}, - to_active_models, -}; -use chrono::{Duration, Utc}; -use sea_orm::{entity::prelude::*, IntoActiveModel}; -use std::matches; -use std::ops::Add; - -async fn seed_db() -> ( - InUseContext, - in_use::Model, - session::Model, - model::Model, - user::Model, -) { - let db_context = get_reset_database_context().await; - - let in_use_context = InUseContext::new(db_context); - - let user = create_users(1)[0].clone(); - let model = create_models(1, user.id)[0].clone(); - let session = create_sessions(1, user.id)[0].clone(); - let in_use = create_in_uses(1, model.id, session.id)[0].clone(); - - user::Entity::insert(user.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); - model::Entity::insert(model.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); - session::Entity::insert(session.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); - - (in_use_context, in_use, session, model, user) -} - -#[tokio::test] -async fn create_test() { - let (in_use_context, mut in_use, _, _, _) = seed_db().await; - - let inserted_in_use = in_use_context.create(in_use.clone()).await.unwrap(); - - in_use.latest_activity = inserted_in_use.latest_activity; +#[cfg(test)] +mod database_tests { + use crate::tests::database::helpers::*; + use crate::{ + database::{ + entity_context::EntityContextTrait, + in_use_context::{DbErr, InUseContext}, + }, + entities::{in_use, model, session, user}, + to_active_models, + }; + use chrono::{Duration, Utc}; + use sea_orm::{entity::prelude::*, IntoActiveModel}; + use std::matches; + use std::ops::Add; + + async fn seed_db() -> ( + InUseContext, + in_use::Model, + session::Model, + model::Model, + user::Model, + ) { + let db_context = get_reset_database_context().await; - let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.clone().model_id) - .one(&in_use_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let in_use_context = InUseContext::new(db_context); + + let user = create_users(1)[0].clone(); + let model = create_models(1, user.id)[0].clone(); + let session = create_sessions(1, user.id)[0].clone(); + let in_use = create_in_uses(1, model.id, session.id)[0].clone(); - assert_eq!(in_use, inserted_in_use); - assert_eq!(in_use, fetched_in_use); -} + user::Entity::insert(user.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); + model::Entity::insert(model.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); + session::Entity::insert(session.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); -#[tokio::test] -async fn create_default_latest_activity_test() { - let t_min = Utc::now().timestamp(); + (in_use_context, in_use, session, model, user) + } - let (in_use_context, in_use, _, _, _) = seed_db().await; + #[tokio::test] + async fn create_test() { + let (in_use_context, mut in_use, _, _, _) = seed_db().await; - let inserted_in_use = in_use_context.create(in_use.clone()).await.unwrap(); + let inserted_in_use = in_use_context.create(in_use.clone()).await.unwrap(); - let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.model_id) - .one(&in_use_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + in_use.latest_activity = inserted_in_use.latest_activity; - let t_max = Utc::now().timestamp(); + let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.clone().model_id) + .one(&in_use_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - let t_actual = fetched_in_use.clone().latest_activity.timestamp(); + assert_eq!(in_use, inserted_in_use); + assert_eq!(in_use, fetched_in_use); + } - assert!(t_min <= t_actual && t_actual <= t_max) -} + #[tokio::test] + async fn create_default_latest_activity_test() { + let t_min = Utc::now().timestamp(); -#[tokio::test] -async fn get_by_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + let (in_use_context, in_use, _, _, _) = seed_db().await; - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + let inserted_in_use = in_use_context.create(in_use.clone()).await.unwrap(); - let fetched_in_use = in_use_context - .get_by_id(in_use.model_id) - .await - .unwrap() - .unwrap(); + let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.model_id) + .one(&in_use_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - assert_eq!(fetched_in_use, in_use) -} + let t_max = Utc::now().timestamp(); -#[tokio::test] -async fn get_by_non_existing_id_test() { - let (in_use_context, _in_use, _, _, _) = seed_db().await; + let t_actual = fetched_in_use.clone().latest_activity.timestamp(); - let in_use = in_use_context.get_by_id(1).await; + assert!(t_min <= t_actual && t_actual <= t_max) + } - assert!(in_use.unwrap().is_none()) -} + #[tokio::test] + async fn get_by_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; -#[tokio::test] -async fn get_all_test() { - let (in_use_context, _in_use, session, model, _user) = seed_db().await; + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - let in_uses = create_in_uses(1, model.id, session.id); + let fetched_in_use = in_use_context + .get_by_id(in_use.model_id) + .await + .unwrap() + .unwrap(); - in_use::Entity::insert_many(to_active_models!(in_uses.clone())) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + assert_eq!(fetched_in_use, in_use) + } - assert_eq!(in_use_context.get_all().await.unwrap().len(), 1); -} + #[tokio::test] + async fn get_by_non_existing_id_test() { + let (in_use_context, _in_use, _, _, _) = seed_db().await; -#[tokio::test] -async fn get_all_empty_test() { - let (in_use_context, _, _, _, _) = seed_db().await; + let in_use = in_use_context.get_by_id(1).await; - let in_uses = in_use_context.get_all().await.unwrap(); + assert!(in_use.unwrap().is_none()) + } - assert_eq!(0, in_uses.len()) -} + #[tokio::test] + async fn get_all_test() { + let (in_use_context, _in_use, session, model, _user) = seed_db().await; -#[tokio::test] -async fn update_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + let in_uses = create_in_uses(1, model.id, session.id); - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + in_use::Entity::insert_many(to_active_models!(in_uses.clone())) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - let new_in_use = in_use::Model { ..in_use }; + assert_eq!(in_use_context.get_all().await.unwrap().len(), 1); + } - let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); + #[tokio::test] + async fn get_all_empty_test() { + let (in_use_context, _, _, _, _) = seed_db().await; - let fetched_in_use = in_use::Entity::find_by_id(updated_in_use.model_id) - .one(&in_use_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let in_uses = in_use_context.get_all().await.unwrap(); - assert_eq!(new_in_use, updated_in_use); - assert_eq!(updated_in_use, fetched_in_use); -} + assert_eq!(0, in_uses.len()) + } -#[tokio::test] -async fn update_modifies_latest_activity_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + #[tokio::test] + async fn update_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - let new_in_use = in_use::Model { - latest_activity: in_use.clone().latest_activity.add(Duration::seconds(1)), - ..in_use - }; + let new_in_use = in_use::Model { ..in_use }; - let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); + let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); - assert_ne!(in_use, updated_in_use); - assert_ne!(in_use, new_in_use); -} + let fetched_in_use = in_use::Entity::find_by_id(updated_in_use.model_id) + .one(&in_use_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); -#[tokio::test] -async fn update_does_not_modify_model_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + assert_eq!(new_in_use, updated_in_use); + assert_eq!(updated_in_use, fetched_in_use); + } - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + #[tokio::test] + async fn update_modifies_latest_activity_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - let updated_in_use = in_use::Model { - model_id: in_use.model_id + 1, - ..in_use.clone() - }; + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - let updated_in_use = in_use_context.update(updated_in_use.clone()).await; + let new_in_use = in_use::Model { + latest_activity: in_use.clone().latest_activity.add(Duration::seconds(1)), + ..in_use + }; - assert!(matches!( - updated_in_use.unwrap_err(), - DbErr::RecordNotUpdated - )); -} + let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); -#[tokio::test] -async fn update_does_not_modify_session_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + assert_ne!(in_use, updated_in_use); + assert_ne!(in_use, new_in_use); + } - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + #[tokio::test] + async fn update_does_not_modify_model_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - let updated_in_use = in_use::Model { - session_id: in_use.session_id + 1, - ..in_use.clone() - }; + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - let updated_in_use = in_use_context.update(updated_in_use.clone()).await.unwrap(); - assert_eq!(in_use, updated_in_use); -} + let updated_in_use = in_use::Model { + model_id: in_use.model_id + 1, + ..in_use.clone() + }; -#[tokio::test] -async fn update_non_existing_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + let updated_in_use = in_use_context.update(updated_in_use.clone()).await; - let updated_in_use = in_use_context.update(in_use.clone()).await; + assert!(matches!( + updated_in_use.unwrap_err(), + DbErr::RecordNotUpdated + )); + } - assert!(matches!( - updated_in_use.unwrap_err(), - DbErr::RecordNotUpdated - )); -} + #[tokio::test] + async fn update_does_not_modify_session_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; -#[tokio::test] -async fn delete_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + let updated_in_use = in_use::Model { + session_id: in_use.session_id + 1, + ..in_use.clone() + }; - let deleted_in_use = in_use_context.delete(in_use.model_id).await.unwrap(); + let updated_in_use = in_use_context.update(updated_in_use.clone()).await.unwrap(); + assert_eq!(in_use, updated_in_use); + } - let all_in_uses = in_use::Entity::find() - .all(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + #[tokio::test] + async fn update_non_existing_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - assert_eq!(in_use, deleted_in_use); - assert!(all_in_uses.is_empty()); -} + let updated_in_use = in_use_context.update(in_use.clone()).await; -#[tokio::test] -async fn delete_non_existing_id_test() { - let (in_use_context, _, _, _, _) = seed_db().await; + assert!(matches!( + updated_in_use.unwrap_err(), + DbErr::RecordNotUpdated + )); + } - let deleted_in_use = in_use_context.delete(1).await; + #[tokio::test] + async fn delete_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; + + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - assert!(matches!( - deleted_in_use.unwrap_err(), - DbErr::RecordNotFound(_) - )) + let deleted_in_use = in_use_context.delete(in_use.model_id).await.unwrap(); + + let all_in_uses = in_use::Entity::find() + .all(&in_use_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(in_use, deleted_in_use); + assert!(all_in_uses.is_empty()); + } + + #[tokio::test] + async fn delete_non_existing_id_test() { + let (in_use_context, _, _, _, _) = seed_db().await; + + let deleted_in_use = in_use_context.delete(1).await; + + assert!(matches!( + deleted_in_use.unwrap_err(), + DbErr::RecordNotFound(_) + )) + } } diff --git a/src/tests/database/model_context.rs b/src/tests/database/model_context.rs index d1279ea..454c440 100644 --- a/src/tests/database/model_context.rs +++ b/src/tests/database/model_context.rs @@ -1,421 +1,338 @@ -use crate::api::server::server::ModelInfo; -use crate::database::model_context::ModelContextTrait; -use crate::tests::database::helpers::*; -use crate::{ - database::{entity_context::EntityContextTrait, model_context::ModelContext}, - entities::{access, in_use, model, query, session, user}, - to_active_models, -}; -use sea_orm::error::DbErr; -use sea_orm::{entity::prelude::*, IntoActiveModel}; -use std::{matches, vec}; - -async fn seed_db() -> (ModelContext, model::Model, user::Model) { - let db_context = get_reset_database_context().await; - - let model_context = ModelContext::new(db_context); - - let user = create_users(1)[0].clone(); - let model = create_models(1, user.id)[0].clone(); - - user::Entity::insert(user.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - (model_context, model, user) -} +#[cfg(test)] +mod database_tests { + use crate::tests::database::helpers::*; + use crate::{ + database::{entity_context::EntityContextTrait, model_context::ModelContext}, + entities::{access, in_use, model, query, session, user}, + to_active_models, + }; + use sea_orm::error::DbErr; + use sea_orm::{entity::prelude::*, IntoActiveModel}; + use std::matches; -#[tokio::test] -async fn create_test() { - let (model_context, model, _) = seed_db().await; + async fn seed_db() -> (ModelContext, model::Model, user::Model) { + let db_context = get_reset_database_context().await; - let created_model = model_context.create(model.clone()).await.unwrap(); + let model_context = ModelContext::new(db_context); - let fetched_model = model::Entity::find_by_id(created_model.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let user = create_users(1)[0].clone(); + let model = create_models(1, user.id)[0].clone(); - assert_eq!(model, created_model); - assert_eq!(fetched_model, created_model); -} - -#[tokio::test] -async fn create_auto_increment_test() { - let (model_context, model, _) = seed_db().await; + user::Entity::insert(user.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let models = create_models(2, model.owner_id); + (model_context, model, user) + } - let created_model1 = model_context.create(models[0].clone()).await.unwrap(); - let created_model2 = model_context.create(models[1].clone()).await.unwrap(); + #[tokio::test] + async fn create_test() { + let (model_context, model, _) = seed_db().await; - let fetched_model1 = model::Entity::find_by_id(created_model1.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let created_model = model_context.create(model.clone()).await.unwrap(); - let fetched_model2 = model::Entity::find_by_id(created_model2.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let fetched_model = model::Entity::find_by_id(created_model.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - assert_ne!(fetched_model1.id, fetched_model2.id); - assert_ne!(created_model1.id, created_model2.id); - assert_eq!(created_model1.id, fetched_model1.id); - assert_eq!(created_model2.id, fetched_model2.id); -} + assert_eq!(model, created_model); + assert_eq!(fetched_model, created_model); + } -#[tokio::test] -async fn get_by_id_test() { - let (model_context, model, _) = seed_db().await; + #[tokio::test] + async fn create_auto_increment_test() { + let (model_context, model, _) = seed_db().await; - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let models = create_models(2, model.owner_id); - let fetched_model = model_context.get_by_id(model.id).await.unwrap().unwrap(); + let created_model1 = model_context.create(models[0].clone()).await.unwrap(); + let created_model2 = model_context.create(models[1].clone()).await.unwrap(); - assert_eq!(model, fetched_model); -} + let fetched_model1 = model::Entity::find_by_id(created_model1.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); -#[tokio::test] -async fn get_by_non_existing_id_test() { - let (model_context, _, _) = seed_db().await; + let fetched_model2 = model::Entity::find_by_id(created_model2.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - let fetched_model = model_context.get_by_id(1).await.unwrap(); + assert_ne!(fetched_model1.id, fetched_model2.id); + assert_ne!(created_model1.id, created_model2.id); + assert_eq!(created_model1.id, fetched_model1.id); + assert_eq!(created_model2.id, fetched_model2.id); + } - assert!(fetched_model.is_none()); -} + #[tokio::test] + async fn get_by_id_test() { + let (model_context, model, _) = seed_db().await; -#[tokio::test] -async fn get_all_test() { - let (model_context, _, user) = seed_db().await; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let new_models = create_models(3, user.id); + let fetched_model = model_context.get_by_id(model.id).await.unwrap().unwrap(); - model::Entity::insert_many(to_active_models!(new_models.clone())) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + assert_eq!(model, fetched_model); + } - assert_eq!(model_context.get_all().await.unwrap().len(), 3); + #[tokio::test] + async fn get_by_non_existing_id_test() { + let (model_context, _, _) = seed_db().await; - let mut sorted = new_models.clone(); - sorted.sort_by_key(|k| k.id); + let fetched_model = model_context.get_by_id(1).await.unwrap(); - for (i, model) in sorted.into_iter().enumerate() { - assert_eq!(model, new_models[i]); + assert!(fetched_model.is_none()); } -} -#[tokio::test] -async fn get_all_empty_test() { - let (model_context, _, _) = seed_db().await; + #[tokio::test] + async fn get_all_test() { + let (model_context, _, user) = seed_db().await; - let result = model_context.get_all().await.unwrap(); - let empty_models: Vec = vec![]; + let new_models = create_models(3, user.id); - assert_eq!(empty_models, result); -} + model::Entity::insert_many(to_active_models!(new_models.clone())) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); -#[tokio::test] -async fn update_test() { - let (model_context, model, _) = seed_db().await; + assert_eq!(model_context.get_all().await.unwrap().len(), 3); - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let mut sorted = new_models.clone(); + sorted.sort_by_key(|k| k.id); - let new_model = model::Model { ..model }; + for (i, model) in sorted.into_iter().enumerate() { + assert_eq!(model, new_models[i]); + } + } - let updated_model = model_context.update(new_model.clone()).await.unwrap(); + #[tokio::test] + async fn get_all_empty_test() { + let (model_context, _, _) = seed_db().await; - let fetched_model = model::Entity::find_by_id(updated_model.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let result = model_context.get_all().await.unwrap(); + let empty_models: Vec = vec![]; - assert_eq!(new_model, updated_model); - assert_eq!(updated_model, fetched_model); -} + assert_eq!(empty_models, result); + } -#[tokio::test] -async fn update_modifies_name_test() { - let (model_context, model, _) = seed_db().await; + #[tokio::test] + async fn update_test() { + let (model_context, model, _) = seed_db().await; - let model = model::Model { - name: "model1".into(), - ..model.clone() - }; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let new_model = model::Model { ..model }; - let new_model = model::Model { - name: "model2".into(), - ..model.clone() - }; + let updated_model = model_context.update(new_model.clone()).await.unwrap(); - let updated_model = model_context.update(new_model.clone()).await.unwrap(); + let fetched_model = model::Entity::find_by_id(updated_model.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - assert_ne!(model, updated_model); - assert_ne!(model, new_model); -} + assert_eq!(new_model, updated_model); + assert_eq!(updated_model, fetched_model); + } -#[tokio::test] -async fn update_modifies_components_info_test() { - let (model_context, model, _) = seed_db().await; + #[tokio::test] + async fn update_modifies_name_test() { + let (model_context, model, _) = seed_db().await; - let model = model::Model { - components_info: "{\"a\":1}".to_owned().parse().unwrap(), - ..model.clone() - }; + let model = model::Model { + name: "model1".into(), + ..model.clone() + }; - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let new_model = model::Model { - components_info: "{\"a\":2}".to_owned().parse().unwrap(), - ..model.clone() - }; + let new_model = model::Model { + name: "model2".into(), + ..model.clone() + }; - let updated_model = model_context.update(new_model.clone()).await.unwrap(); + let updated_model = model_context.update(new_model.clone()).await.unwrap(); - assert_ne!(model, updated_model); - assert_ne!(model, new_model); -} + assert_ne!(model, updated_model); + assert_ne!(model, new_model); + } -#[tokio::test] -async fn update_does_not_modify_id_test() { - let (model_context, model, _) = seed_db().await; + #[tokio::test] + async fn update_modifies_components_info_test() { + let (model_context, model, _) = seed_db().await; - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let model = model::Model { + components_info: "{\"a\":1}".to_owned().parse().unwrap(), + ..model.clone() + }; - let new_model = model::Model { - id: &model.id + 1, - ..model.clone() - }; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let res = model_context.update(new_model.clone()).await; + let new_model = model::Model { + components_info: "{\"a\":2}".to_owned().parse().unwrap(), + ..model.clone() + }; - assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); -} + let updated_model = model_context.update(new_model.clone()).await.unwrap(); -#[tokio::test] -async fn update_does_not_modify_owner_id_test() { - let (model_context, model, _) = seed_db().await; + assert_ne!(model, updated_model); + assert_ne!(model, new_model); + } - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + #[tokio::test] + async fn update_does_not_modify_id_test() { + let (model_context, model, _) = seed_db().await; - let new_model = model::Model { - owner_id: &model.owner_id + 1, - ..model.clone() - }; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let res = model_context.update(new_model.clone()).await.unwrap(); + let new_model = model::Model { + id: &model.id + 1, + ..model.clone() + }; - assert_eq!(model, res); -} + let res = model_context.update(new_model.clone()).await; -#[tokio::test] -async fn update_check_query_outdated_test() { - let (model_context, model, _) = seed_db().await; + assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); + } - let mut query = create_queries(1, model.id)[0].clone(); + #[tokio::test] + async fn update_does_not_modify_owner_id_test() { + let (model_context, model, _) = seed_db().await; - query.outdated = false; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let new_model = model::Model { + owner_id: &model.owner_id + 1, + ..model.clone() + }; - query::Entity::insert(query.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let res = model_context.update(new_model.clone()).await.unwrap(); - let new_model = model::Model { ..model }; + assert_eq!(model, res); + } - let updated_model = model_context.update(new_model.clone()).await.unwrap(); + #[tokio::test] + async fn update_check_query_outdated_test() { + let (model_context, model, _) = seed_db().await; - let fetched_query = query::Entity::find_by_id(updated_model.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let mut query = create_queries(1, model.id)[0].clone(); - assert!(fetched_query.outdated); -} + query.outdated = false; -#[tokio::test] -async fn update_non_existing_id_test() { - let (model_context, model, _) = seed_db().await; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let updated_model = model_context.update(model.clone()).await; + query::Entity::insert(query.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - assert!(matches!( - updated_model.unwrap_err(), - DbErr::RecordNotUpdated - )); -} + let new_model = model::Model { ..model }; -#[tokio::test] -async fn delete_test() { - // Setting up database and user context - let (model_context, model, _) = seed_db().await; + let updated_model = model_context.update(new_model.clone()).await.unwrap(); - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + let fetched_query = query::Entity::find_by_id(updated_model.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - let deleted_model = model_context.delete(model.id).await.unwrap(); + assert!(fetched_query.outdated); + } - let all_models = model::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); + #[tokio::test] + async fn update_non_existing_id_test() { + let (model_context, model, _) = seed_db().await; - assert_eq!(model, deleted_model); - assert_eq!(all_models.len(), 0); -} + let updated_model = model_context.update(model.clone()).await; -#[tokio::test] -async fn delete_cascade_query_test() { - let (model_context, model, _) = seed_db().await; - - let query = create_queries(1, model.clone().id)[0].clone(); - - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - query::Entity::insert(query.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - model_context.delete(model.id).await.unwrap(); - - let all_queries = query::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); - let all_models = model::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); - - assert_eq!(all_queries.len(), 0); - assert_eq!(all_models.len(), 0); -} + assert!(matches!( + updated_model.unwrap_err(), + DbErr::RecordNotUpdated + )); + } -#[tokio::test] -async fn delete_cascade_access_test() { - let (model_context, model, _) = seed_db().await; - - let access = create_accesses(1, 1, model.clone().id)[0].clone(); - - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - access::Entity::insert(access.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - model_context.delete(model.id).await.unwrap(); - - let all_models = model::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); - let all_accesses = access::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); - - assert_eq!(all_models.len(), 0); - assert_eq!(all_accesses.len(), 0); -} + #[tokio::test] + async fn delete_test() { + // Setting up database and user context + let (model_context, model, _) = seed_db().await; -#[tokio::test] -async fn delete_cascade_in_use_test() { - let (model_context, model, user) = seed_db().await; - - let session = create_sessions(1, user.clone().id)[0].clone(); - let in_use = create_in_uses(1, model.clone().id, 1)[0].clone(); - - session::Entity::insert(session.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - model_context.delete(model.id).await.unwrap(); - - let all_models = model::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); - let all_in_uses = in_use::Entity::find() - .all(&model_context.db_context.get_connection()) - .await - .unwrap(); - - assert_eq!(all_models.len(), 0); - assert_eq!(all_in_uses.len(), 0); -} + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); -#[tokio::test] -async fn delete_non_existing_id_test() { - let (model_context, _, _) = seed_db().await; + let deleted_model = model_context.delete(model.id).await.unwrap(); - let deleted_model = model_context.delete(1).await; + let all_models = model::Entity::find() + .all(&model_context.db_context.get_connection()) + .await + .unwrap(); - assert!(matches!( - deleted_model.unwrap_err(), - DbErr::RecordNotFound(_) - )); + assert_eq!(model, deleted_model); + assert_eq!(all_models.len(), 0); + } #[tokio::test] - async fn get_model_info_by_uid_test() { - let (model_context, model, user) = seed_db().await; + async fn delete_cascade_query_test() { + let (model_context, model, _) = seed_db().await; - let access = create_accesses(1, user.id, model.id)[0].clone(); + let query = create_queries(1, model.clone().id)[0].clone(); - let expected_model_info = vec![ModelInfo { - model_id: model.id, - model_name: model.name.clone(), - model_owner_id: model.owner_id, - user_role_on_model: access.role.clone(), - }]; + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); + query::Entity::insert(query.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); + + model_context.delete(model.id).await.unwrap(); + + let all_queries = query::Entity::find() + .all(&model_context.db_context.get_connection()) + .await + .unwrap(); + let all_models = model::Entity::find() + .all(&model_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(all_queries.len(), 0); + assert_eq!(all_models.len(), 0); + } + + #[tokio::test] + async fn delete_cascade_access_test() { + let (model_context, model, _) = seed_db().await; + + let access = create_accesses(1, 1, model.clone().id)[0].clone(); model::Entity::insert(model.clone().into_active_model()) .exec(&model_context.db_context.get_connection()) @@ -426,20 +343,65 @@ async fn delete_non_existing_id_test() { .await .unwrap(); - let model_info = model_context - .get_models_info_by_uid(model.id) + model_context.delete(model.id).await.unwrap(); + + let all_models = model::Entity::find() + .all(&model_context.db_context.get_connection()) + .await + .unwrap(); + let all_accesses = access::Entity::find() + .all(&model_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(all_models.len(), 0); + assert_eq!(all_accesses.len(), 0); + } + + #[tokio::test] + async fn delete_cascade_in_use_test() { + let (model_context, model, user) = seed_db().await; + + let session = create_sessions(1, user.clone().id)[0].clone(); + let in_use = create_in_uses(1, model.clone().id, 1)[0].clone(); + + session::Entity::insert(session.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); + + model_context.delete(model.id).await.unwrap(); + + let all_models = model::Entity::find() + .all(&model_context.db_context.get_connection()) + .await + .unwrap(); + let all_in_uses = in_use::Entity::find() + .all(&model_context.db_context.get_connection()) .await .unwrap(); - assert_eq!(model_info, expected_model_info); + assert_eq!(all_models.len(), 0); + assert_eq!(all_in_uses.len(), 0); } #[tokio::test] - async fn get_model_info_by_uid_non_existing_id_test() { + async fn delete_non_existing_id_test() { let (model_context, _, _) = seed_db().await; - let model_info = model_context.get_models_info_by_uid(1).await; + let deleted_model = model_context.delete(1).await; - assert_eq!(model_info.unwrap().len(), 0); + assert!(matches!( + deleted_model.unwrap_err(), + DbErr::RecordNotFound(_) + )); } } diff --git a/src/tests/database/session_context.rs b/src/tests/database/session_context.rs index 88178db..12d05fd 100644 --- a/src/tests/database/session_context.rs +++ b/src/tests/database/session_context.rs @@ -341,7 +341,7 @@ async fn delete_non_existing_id_test() { } #[tokio::test] -async fn get_by_refresh_token_test() { +async fn get_by_token_refresh_test() { let (session_context, session, _, _) = seed_db().await; session::Entity::insert(session.clone().into_active_model()) @@ -359,3 +359,20 @@ async fn get_by_refresh_token_test() { session.refresh_token ); } + +#[tokio::test] +async fn get_by_token_access_test() { + let (session_context, session, _, _) = seed_db().await; + + session::Entity::insert(session.clone().into_active_model()) + .exec(&session_context.db_context.get_connection()) + .await + .unwrap(); + + let fetched_session = session_context + .get_by_token(TokenType::AccessToken, session.access_token.clone()) + .await + .unwrap(); + + assert_eq!(fetched_session.unwrap().access_token, session.access_token); +}