diff --git a/Ecdar-ProtoBuf b/Ecdar-ProtoBuf index 6bce256..6600b15 160000 --- a/Ecdar-ProtoBuf +++ b/Ecdar-ProtoBuf @@ -1 +1 @@ -Subproject commit 6bce2563aa1f2072340f3678ade4482f96e39b27 +Subproject commit 6600b155ef58ca57187c28d7f570bf59bc9e4f6b diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index aefd72b..664be9e 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -1,13 +1,3 @@ -use crate::api::context_collection::ContextCollection; -use regex::Regex; -use sea_orm::SqlErr; -use serde_json; -use std::sync::Arc; -use tonic::{Code, Request, Response, Status}; - -use crate::api::auth::{RequestExt, Token, TokenType}; -use crate::database::{session_context::SessionContextTrait, user_context::UserContextTrait}; - use super::server::server::{ ecdar_api_auth_server::EcdarApiAuth, ecdar_api_server::EcdarApi, @@ -16,11 +6,25 @@ use super::server::server::{ CreateAccessRequest, CreateModelRequest, CreateModelResponse, CreateQueryRequest, CreateUserRequest, DeleteAccessRequest, DeleteModelRequest, DeleteQueryRequest, GetAuthTokenRequest, GetAuthTokenResponse, GetModelRequest, GetModelResponse, - ListModelsInfoResponse, QueryRequest, QueryResponse, SimulationStartRequest, - SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, - UpdateUserRequest, UserTokenResponse, + ListModelsInfoResponse, Query, QueryRequest, QueryResponse, SimulationStartRequest, + SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateModelRequest, + UpdateQueryRequest, UpdateUserRequest, UserTokenResponse, }; +use crate::api::context_collection::ContextCollection; +use crate::api::{ + auth::{RequestExt, Token, TokenType}, + server::server::Model, +}; +use crate::database::{session_context::SessionContextTrait, user_context::UserContextTrait}; use crate::entities::{access, in_use, model, query, session, user}; +use chrono::{Duration, Utc}; +use regex::Regex; +use sea_orm::SqlErr; +use serde_json; +use std::sync::Arc; +use tonic::{Code, Request, Response, Status}; + +const IN_USE_DURATION_MINUTES: i64 = 10; #[derive(Clone)] pub struct ConcreteEcdarApi { @@ -50,11 +54,8 @@ pub async fn handle_session( updated_at: Default::default(), user_id: uid.parse().unwrap(), }) - .await; - return match res { - Ok(_) => Ok(()), - Err(e) => Err(Status::new(Code::Internal, e.to_string())), - }; + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))?; } else { let mut session = match session_context .get_by_token(TokenType::RefreshToken, request.token_string().unwrap()) @@ -73,10 +74,10 @@ pub async fn handle_session( session.access_token = access_token.clone(); session.refresh_token = refresh_token.clone(); - match session_context.update(session).await { - Ok(_) => (), - Err(err) => return Err(Status::new(Code::Internal, err.to_string())), - }; + session_context + .update(session) + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))?; } Ok(()) } @@ -101,11 +102,114 @@ impl ConcreteEcdarApi { #[tonic::async_trait] impl EcdarApi for ConcreteEcdarApi { + /// Gets a Model and its queries from the database. + /// + /// If the Model is not in use, it will now be in use by the requestees session, + /// given that they are an Editor. async fn get_model( &self, - _request: Request, + request: Request, ) -> Result, Status> { - todo!() + let message = request.get_ref().clone(); + + let model_id = message.id; + + let uid = request + .uid() + .ok_or(Status::internal("Could not get uid from request metadata"))?; + + let access = self + .contexts + .access_context + .get_access_by_uid_and_model_id(uid, model_id) + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))? + .ok_or_else(|| { + Status::new(Code::PermissionDenied, "User does not have access to model") + })?; + + let model = self + .contexts + .model_context + .get_by_id(model_id) + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))? + .ok_or_else(|| Status::new(Code::Internal, "Model not found"))?; + + let model = Model { + id: model.id, + name: model.name, + components_info: serde_json::from_value(model.components_info).unwrap(), + owner_id: model.owner_id, + }; + + let mut in_use_bool = true; + match self.contexts.in_use_context.get_by_id(model_id).await { + Ok(Some(in_use)) => { + // If model is not in use and user is an Editor, update the in use with the users session. + if in_use.latest_activity + <= (Utc::now().naive_utc() - Duration::minutes(IN_USE_DURATION_MINUTES)) + { + in_use_bool = false; + + if access.role == "Editor" { + let session = self + .contexts + .session_context + .get_by_token(TokenType::AccessToken, request.token_string().unwrap()) + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))? + .ok_or_else(|| { + Status::new( + Code::Unauthenticated, + "No session found with given access token", + ) + })?; + + let in_use = in_use::Model { + model_id: in_use.model_id, + session_id: session.id, + latest_activity: Utc::now().naive_utc(), + }; + + self.contexts + .in_use_context + .update(in_use) + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))?; + } + } + } + Ok(None) => return Err(Status::new(Code::Internal, "No in use found for model")), + Err(err) => return Err(Status::new(Code::Internal, err.to_string())), + } + + let queries = self + .contexts + .query_context + .get_all_by_model_id(model_id) + .await + .map_err(|err| Status::new(Code::Internal, err.to_string()))?; + + let queries = queries + .into_iter() + .map(|query| Query { + id: query.id, + model_id: query.model_id, + query: query.string, + result: match query.result { + Some(result) => serde_json::from_value(result).unwrap(), + None => "".to_owned(), + }, + outdated: query.outdated, + }) + .collect::>(); + + Ok(Response::new(GetModelResponse { + model: Some(model), + queries, + in_use: in_use_bool, + })) } async fn create_model( @@ -181,7 +285,10 @@ impl EcdarApi for ConcreteEcdarApi { Ok(Response::new(CreateModelResponse { id: model.id })) } - async fn update_model(&self, _request: Request<()>) -> Result, Status> { + async fn update_model( + &self, + _request: Request, + ) -> Result, Status> { todo!() } @@ -690,14 +797,14 @@ mod query_logic_tests; #[path = "../tests/api/access_logic.rs"] mod access_logic_tests; -#[cfg(test)] -#[path = "../tests/api/user_logic.rs"] -mod user_logic_tests; - #[cfg(test)] #[path = "../tests/api/model_logic.rs"] mod model_logic_tests; +#[cfg(test)] +#[path = "../tests/api/user_logic.rs"] +mod user_logic_tests; + #[cfg(test)] #[path = "../tests/api/session_logic.rs"] mod session_logic_tests; diff --git a/src/database/query_context.rs b/src/database/query_context.rs index 5c56cb7..f87abff 100644 --- a/src/database/query_context.rs +++ b/src/database/query_context.rs @@ -3,16 +3,27 @@ use crate::database::entity_context::EntityContextTrait; use crate::entities::query; use sea_orm::prelude::async_trait::async_trait; use sea_orm::ActiveValue::{Set, Unchanged}; -use sea_orm::{ActiveModelTrait, DbErr, EntityTrait, NotSet}; +use sea_orm::{ActiveModelTrait, ColumnTrait, DbErr, EntityTrait, NotSet, QueryFilter}; use std::sync::Arc; pub struct QueryContext { db_context: Arc, } -pub trait QueryContextTrait: EntityContextTrait {} +#[async_trait] +pub trait QueryContextTrait: EntityContextTrait { + async fn get_all_by_model_id(&self, model_id: i32) -> Result, DbErr>; +} -impl QueryContextTrait for QueryContext {} +#[async_trait] +impl QueryContextTrait for QueryContext { + async fn get_all_by_model_id(&self, model_id: i32) -> Result, DbErr> { + query::Entity::find() + .filter(query::Column::ModelId.eq(model_id)) + .all(&self.db_context.get_connection()) + .await + } +} impl QueryContext { pub fn new(db_context: Arc) -> QueryContext { diff --git a/src/database/session_context.rs b/src/database/session_context.rs index 586efba..4709fc2 100644 --- a/src/database/session_context.rs +++ b/src/database/session_context.rs @@ -1,14 +1,13 @@ +use crate::api::auth::TokenType; +use crate::database::database_context::DatabaseContextTrait; +use crate::database::entity_context::EntityContextTrait; +use crate::entities::session; use chrono::Local; use sea_orm::prelude::async_trait::async_trait; use sea_orm::ActiveValue::{Set, Unchanged}; use sea_orm::{ActiveModelTrait, ColumnTrait, DbErr, EntityTrait, NotSet, QueryFilter}; use std::sync::Arc; -use crate::api::auth::TokenType; -use crate::database::database_context::DatabaseContextTrait; -use crate::database::entity_context::EntityContextTrait; -use crate::entities::session; - pub struct SessionContext { db_context: Arc, } diff --git a/src/tests/api/helpers.rs b/src/tests/api/helpers.rs index f5b2040..889d139 100644 --- a/src/tests/api/helpers.rs +++ b/src/tests/api/helpers.rs @@ -74,7 +74,20 @@ mock! { } #[async_trait] impl AccessContextTrait for AccessContext { - async fn get_access_by_uid_and_model_id(&self, uid: i32, model_id: i32) -> Result, DbErr>; + async fn get_access_by_uid_and_model_id( + &self, + uid: i32, + model_id: i32, + ) -> Result, DbErr> { + access::Entity::find() + .filter( + Condition::all() + .add(access::Column::UserId.eq(uid)) + .add(access::Column::ModelId.eq(model_id)), + ) + .one(&self.db_context.get_connection()) + .await + } } } @@ -119,7 +132,14 @@ mock! { async fn delete(&self, entity_id: i32) -> Result; } #[async_trait] - impl QueryContextTrait for QueryContext {} + impl QueryContextTrait for QueryContext { + async fn get_all_by_model_id(&self, model_id: i32) -> Result, DbErr> { + query::Entity::find() + .filter(query::Column::ModelId.eq(model_id)) + .all(&self.db_context.get_connection()) + .await + } + } } mock! { diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index e6a2d88..4761a69 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -1,16 +1,20 @@ -use std::str::FromStr; - +use crate::{ + api::{ + auth::TokenType, + server::server::{ + ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, + GetModelRequest, ModelInfo, + }, + }, + entities::{access, in_use, model, query, session}, + tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}, +}; +use chrono::Utc; use mockall::predicate; use sea_orm::DbErr; +use std::str::FromStr; use tonic::{metadata, Code, Request}; -use crate::api::auth::TokenType; -use crate::api::server::server::{ - ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, ModelInfo, -}; -use crate::entities::{access, in_use, model, session}; -use crate::tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}; - #[tokio::test] async fn create_model_returns_ok() { let mut mock_services = get_mock_services(); @@ -133,6 +137,67 @@ async fn create_model_existing_name_returns_err() { 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(); + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: 0, + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + model_id: 1, + user_id: 1, + }; + + let in_use = in_use::Model { + model_id: Default::default(), + session_id: 0, + latest_activity: Utc::now().naive_utc(), + }; + + let queries: Vec = vec![]; + + mock_services + .access_context_mock + .expect_get_access_by_uid_and_model_id() + .with(predicate::eq(0), predicate::eq(0)) + .returning(move |_, _| Ok(Some(access.clone()))); + + mock_services + .model_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(model.clone()))); + + mock_services + .in_use_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(in_use.clone()))); + + mock_services + .query_context_mock + .expect_get_all_by_model_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(queries.clone())); + + let mut request = Request::new(GetModelRequest { id: 0 }); + + request.metadata_mut().insert("uid", "0".parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.get_model(request).await; + + assert!(res.is_ok()); +} + #[tokio::test] async fn delete_not_owner_returns_err() { let mut mock_services = get_mock_services(); @@ -229,6 +294,343 @@ async fn delete_model_returns_ok() { assert!(res.is_ok()); } +#[tokio::test] +async fn get_model_user_has_no_access_returns_err() { + let mut mock_services = get_mock_services(); + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: 0, + }; + + let in_use = in_use::Model { + model_id: Default::default(), + session_id: 0, + latest_activity: Default::default(), + }; + + let queries: Vec = vec![]; + + mock_services + .access_context_mock + .expect_get_access_by_uid_and_model_id() + .with(predicate::eq(0), predicate::eq(0)) + .returning(move |_, _| Ok(None)); + + mock_services + .model_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(model.clone()))); + + mock_services + .in_use_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(in_use.clone()))); + + mock_services + .query_context_mock + .expect_get_all_by_model_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(queries.clone())); + + let mut request = Request::new(GetModelRequest { id: 0 }); + + request.metadata_mut().insert("uid", "0".parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.get_model(request).await.unwrap_err(); + + assert!(res.code() == Code::PermissionDenied); +} + +#[tokio::test] +async fn get_model_is_in_use_is_true() { + let mut mock_services = get_mock_services(); + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: 0, + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + model_id: 1, + user_id: 1, + }; + + let in_use = in_use::Model { + model_id: Default::default(), + session_id: 0, + latest_activity: Utc::now().naive_utc(), + }; + + let queries: Vec = vec![]; + + mock_services + .access_context_mock + .expect_get_access_by_uid_and_model_id() + .with(predicate::eq(0), predicate::eq(0)) + .returning(move |_, _| Ok(Some(access.clone()))); + + mock_services + .model_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(model.clone()))); + + mock_services + .in_use_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(in_use.clone()))); + + mock_services + .query_context_mock + .expect_get_all_by_model_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(queries.clone())); + + let mut request = Request::new(GetModelRequest { id: 0 }); + + request.metadata_mut().insert("uid", "0".parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.get_model(request).await; + + assert!(res.unwrap().get_ref().in_use); +} + +#[tokio::test] +async fn get_model_is_in_use_is_false() { + let mut mock_services = get_mock_services(); + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: 0, + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + model_id: 1, + user_id: 1, + }; + + let in_use = in_use::Model { + model_id: 0, + session_id: 0, + latest_activity: Default::default(), + }; + + let updated_in_use = in_use::Model { + model_id: 0, + session_id: 1, + latest_activity: Default::default(), + }; + + let session = session::Model { + id: 0, + refresh_token: "refresh_token".to_owned(), + access_token: "access_token".to_owned(), + updated_at: Default::default(), + user_id: Default::default(), + }; + + let queries: Vec = vec![]; + + mock_services + .access_context_mock + .expect_get_access_by_uid_and_model_id() + .with(predicate::eq(0), predicate::eq(0)) + .returning(move |_, _| Ok(Some(access.clone()))); + + mock_services + .model_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(model.clone()))); + + mock_services + .in_use_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(in_use.clone()))); + + mock_services + .session_context_mock + .expect_get_by_token() + .with( + predicate::eq(TokenType::AccessToken), + predicate::eq("access_token".to_owned()), + ) + .returning(move |_, _| Ok(Some(session.clone()))); + + mock_services + .query_context_mock + .expect_get_all_by_model_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(queries.clone())); + + mock_services + .in_use_context_mock + .expect_update() + .returning(move |_| Ok(updated_in_use.clone())); + + let mut request = Request::new(GetModelRequest { id: 0 }); + + request + .metadata_mut() + .insert("authorization", "Bearer access_token".parse().unwrap()); + request.metadata_mut().insert("uid", "0".parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.get_model(request).await; + + assert!(!res.unwrap().get_ref().in_use); +} + +#[tokio::test] +async fn get_model_model_has_no_queries_queries_are_empty() { + let mut mock_services = get_mock_services(); + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: 0, + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + model_id: 1, + user_id: 1, + }; + + let in_use = in_use::Model { + model_id: Default::default(), + session_id: 0, + latest_activity: Utc::now().naive_utc(), + }; + + let queries: Vec = vec![]; + + mock_services + .access_context_mock + .expect_get_access_by_uid_and_model_id() + .with(predicate::eq(0), predicate::eq(0)) + .returning(move |_, _| Ok(Some(access.clone()))); + + mock_services + .model_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(model.clone()))); + + mock_services + .in_use_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(in_use.clone()))); + + mock_services + .query_context_mock + .expect_get_all_by_model_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(queries.clone())); + + let mut request = Request::new(GetModelRequest { id: 0 }); + + request.metadata_mut().insert("uid", "0".parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.get_model(request).await; + + assert!(res.unwrap().get_ref().queries.is_empty()); +} + +#[tokio::test] +async fn get_model_query_has_no_result_query_is_empty() { + let mut mock_services = get_mock_services(); + + let model = model::Model { + id: Default::default(), + name: "model".to_string(), + components_info: Default::default(), + owner_id: 0, + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + model_id: 1, + user_id: 1, + }; + + let in_use = in_use::Model { + model_id: Default::default(), + session_id: 0, + latest_activity: Utc::now().naive_utc(), + }; + + let query = query::Model { + id: 0, + model_id: 1, + string: "query".to_owned(), + result: None, + outdated: false, + }; + + let queries: Vec = vec![query]; + + mock_services + .access_context_mock + .expect_get_access_by_uid_and_model_id() + .with(predicate::eq(0), predicate::eq(0)) + .returning(move |_, _| Ok(Some(access.clone()))); + + mock_services + .model_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(model.clone()))); + + mock_services + .in_use_context_mock + .expect_get_by_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(Some(in_use.clone()))); + + mock_services + .query_context_mock + .expect_get_all_by_model_id() + .with(predicate::eq(0)) + .returning(move |_| Ok(queries.clone())); + + let mut request = Request::new(GetModelRequest { id: 0 }); + + request.metadata_mut().insert("uid", "0".parse().unwrap()); + + let api = get_mock_concrete_ecdar_api(mock_services); + + let res = api.get_model(request).await; + + assert!(res.unwrap().get_ref().queries[0].result.is_empty()); +} + #[tokio::test] async fn list_models_info_returns_ok() { let mut mock_services = get_mock_services(); diff --git a/src/tests/database/access_context.rs b/src/tests/database/access_context.rs index 23207f1..1a5be5f 100644 --- a/src/tests/database/access_context.rs +++ b/src/tests/database/access_context.rs @@ -1,348 +1,358 @@ -#[cfg(test)] -mod database_tests { - use crate::tests::database::helpers::{ - create_accesses, create_models, create_users, get_reset_database_context, - }; - use crate::{ - database::{access_context::AccessContext, entity_context::EntityContextTrait}, - entities::{access, model, user}, - to_active_models, - }; - use sea_orm::{entity::prelude::*, IntoActiveModel}; - - async fn seed_db() -> (AccessContext, access::Model, user::Model, model::Model) { - let db_context = get_reset_database_context().await; - - let access_context = AccessContext::new(db_context); - - let user = create_users(1)[0].clone(); - let model = create_models(1, user.id)[0].clone(); - let access = create_accesses(1, user.id, model.id)[0].clone(); - - user::Entity::insert(user.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); - model::Entity::insert(model.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); +use crate::database::access_context::AccessContextTrait; +use crate::tests::database::helpers::{ + create_accesses, create_models, create_users, get_reset_database_context, +}; +use crate::{ + database::{access_context::AccessContext, entity_context::EntityContextTrait}, + entities::{access, model, user}, + to_active_models, +}; +use sea_orm::{entity::prelude::*, IntoActiveModel}; + +async fn seed_db() -> (AccessContext, access::Model, user::Model, model::Model) { + let db_context = get_reset_database_context().await; + + let access_context = AccessContext::new(db_context); + + let user = create_users(1)[0].clone(); + let model = create_models(1, user.id)[0].clone(); + let access = create_accesses(1, user.id, model.id)[0].clone(); + + user::Entity::insert(user.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); + model::Entity::insert(model.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); + + (access_context, access, user, model) +} +// Test the functionality of the 'create' function, which creates a access in the database +#[tokio::test] +async fn create_test() { + let (access_context, access, _, _) = seed_db().await; + + let created_access = access_context.create(access.clone()).await.unwrap(); + + let fetched_access = access::Entity::find_by_id(created_access.id) + .one(&access_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + // Assert if the fetched access is the same as the created access + assert_eq!(access, created_access); + assert_eq!(fetched_access, created_access); +} - (access_context, access, user, model) - } +#[tokio::test] +async fn create_check_unique_pair_model_id_user_id_test() { + let (access_context, access, _, _) = seed_db().await; - // Test the functionality of the 'create' function, which creates a access in the database - #[tokio::test] - async fn create_test() { - let (access_context, access, _, _) = seed_db().await; + let _created_access_1 = access_context.create(access.clone()).await.unwrap(); + let _created_access_2 = access_context.create(access.clone()).await; - let created_access = access_context.create(access.clone()).await.unwrap(); + assert!(matches!( + _created_access_2.unwrap_err().sql_err(), + Some(SqlErr::UniqueConstraintViolation(_)) + )); +} - let fetched_access = access::Entity::find_by_id(created_access.id) - .one(&access_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); +#[tokio::test] +async fn create_invalid_role_test() { + let (access_context, mut access, _, _) = seed_db().await; - // Assert if the fetched access is the same as the created access - assert_eq!(access, created_access); - assert_eq!(fetched_access, created_access); - } + access.role = "abc".into(); - #[tokio::test] - async fn create_check_unique_pair_model_id_user_id_test() { - let (access_context, access, _, _) = seed_db().await; + let created_access = access_context.create(access.clone()).await; - let _created_access_1 = access_context.create(access.clone()).await.unwrap(); - let _created_access_2 = access_context.create(access.clone()).await; + assert!(matches!( + created_access.unwrap_err().sql_err(), + Some(SqlErr::ForeignKeyConstraintViolation(_)) + )); +} - assert!(matches!( - _created_access_2.unwrap_err().sql_err(), - Some(SqlErr::UniqueConstraintViolation(_)) - )); - } +#[tokio::test] +async fn create_auto_increment_test() { + let (access_context, _, user, model_1) = seed_db().await; - #[tokio::test] - async fn create_invalid_role_test() { - let (access_context, mut access, _, _) = seed_db().await; + let mut model_2 = create_models(1, user.id)[0].clone(); + model_2.id = model_1.id + 1; + model_2.name = "model_2".into(); - access.role = "abc".into(); + model::Entity::insert(model_2.into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - let created_access = access_context.create(access.clone()).await; + let access_1 = access::Model { + id: 0, + role: "Editor".to_string(), + model_id: 1, + user_id: user.id, + }; - assert!(matches!( - created_access.unwrap_err().sql_err(), - Some(SqlErr::ForeignKeyConstraintViolation(_)) - )); - } + let access_2 = access::Model { + id: 0, + role: "Editor".to_string(), + model_id: 2, + user_id: user.id, + }; - #[tokio::test] - async fn create_auto_increment_test() { - let (access_context, _, user, model_1) = seed_db().await; - - let mut model_2 = create_models(1, user.id)[0].clone(); - model_2.id = model_1.id + 1; - model_2.name = "model_2".to_string(); - - model::Entity::insert(model_2.into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); - - let access_1 = access::Model { - id: 0, - role: "Editor".to_string(), - model_id: 1, - user_id: user.id, - }; - - let access_2 = access::Model { - id: 0, - role: "Editor".to_string(), - model_id: 2, - user_id: user.id, - }; - - let created_access1 = access_context.create(access_1.clone()).await.unwrap(); - let created_access2 = access_context.create(access_2.clone()).await.unwrap(); - - let fetched_access1 = access::Entity::find_by_id(created_access1.id) - .one(&access_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); - - let fetched_access2 = access::Entity::find_by_id(created_access2.id) - .one(&access_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); - - assert_ne!(fetched_access1.id, fetched_access2.id); - assert_ne!(created_access1.id, created_access2.id); - assert_eq!(created_access1.id, fetched_access1.id); - assert_eq!(created_access2.id, fetched_access2.id); - } + let created_access1 = access_context.create(access_1.clone()).await.unwrap(); + let created_access2 = access_context.create(access_2.clone()).await.unwrap(); + + let fetched_access1 = access::Entity::find_by_id(created_access1.id) + .one(&access_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + let fetched_access2 = access::Entity::find_by_id(created_access2.id) + .one(&access_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + assert_ne!(fetched_access1.id, fetched_access2.id); + assert_ne!(created_access1.id, created_access2.id); + assert_eq!(created_access1.id, fetched_access1.id); + assert_eq!(created_access2.id, fetched_access2.id); +} - #[tokio::test] - async fn get_by_id_test() { - let (access_context, access, _, _) = seed_db().await; +#[tokio::test] +async fn get_by_id_test() { + let (access_context, access, _, _) = seed_db().await; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - // Fetches the access created using the 'get_by_id' function - let fetched_access = access_context.get_by_id(access.id).await.unwrap().unwrap(); + // Fetches the access created using the 'get_by_id' function + let fetched_access = access_context.get_by_id(access.id).await.unwrap().unwrap(); - // Assert if the fetched access is the same as the created access - assert_eq!(access, fetched_access); - } + // Assert if the fetched access is the same as the created access + assert_eq!(access, fetched_access); +} - #[tokio::test] - async fn get_by_non_existing_id_test() { - let (access_context, _, _, _) = seed_db().await; +#[tokio::test] +async fn get_by_non_existing_id_test() { + let (access_context, _, _, _) = seed_db().await; - let fetched_access = access_context.get_by_id(1).await.unwrap(); + let fetched_access = access_context.get_by_id(1).await.unwrap(); - assert!(fetched_access.is_none()); - } + assert!(fetched_access.is_none()); +} - #[tokio::test] - async fn get_all_test() { - let (access_context, _, user, model) = seed_db().await; +#[tokio::test] +async fn get_all_test() { + let (access_context, _, user, model) = seed_db().await; - // Creates a model of the access which will be created - let new_accesses = create_accesses(1, user.id, model.id); + // Creates a model of the access which will be created + let new_accesses = create_accesses(1, user.id, model.id); - // Creates the access in the database using the 'create' function - access::Entity::insert_many(to_active_models!(new_accesses.clone())) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + // Creates the access in the database using the 'create' function + access::Entity::insert_many(to_active_models!(new_accesses.clone())) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - assert_eq!(access_context.get_all().await.unwrap().len(), 1); + assert_eq!(access_context.get_all().await.unwrap().len(), 1); - let mut sorted: Vec = new_accesses.clone(); - sorted.sort_by_key(|k| k.id); + let mut sorted: Vec = new_accesses.clone(); + sorted.sort_by_key(|k| k.id); - for (i, access) in sorted.into_iter().enumerate() { - assert_eq!(access, new_accesses[i]); - } + for (i, access) in sorted.into_iter().enumerate() { + assert_eq!(access, new_accesses[i]); } +} +#[tokio::test] +async fn get_by_uid_and_model_id_test() { + let (access_context, expected_access, user, model) = seed_db().await; - #[tokio::test] - async fn get_all_empty_test() { - let (access_context, _, _, _) = seed_db().await; - - let result = access_context.get_all().await.unwrap(); - let empty_accesses: Vec = vec![]; - - assert_eq!(empty_accesses, result); - } + access::Entity::insert(expected_access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - #[tokio::test] - async fn update_test() { - let (access_context, access, _, _) = seed_db().await; + let access = access_context + .get_access_by_uid_and_model_id(user.id, model.id) + .await; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + assert!(access.unwrap().unwrap() == expected_access); +} - let new_access = access::Model { ..access }; +#[tokio::test] +async fn get_all_empty_test() { + let (access_context, _, _, _) = seed_db().await; - let updated_access = access_context.update(new_access.clone()).await.unwrap(); + let result = access_context.get_all().await.unwrap(); + let empty_accesses: Vec = vec![]; - let fetched_access = access::Entity::find_by_id(updated_access.id) - .one(&access_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + assert_eq!(empty_accesses, result); +} - assert_eq!(new_access, updated_access); - assert_eq!(updated_access, fetched_access); - } +#[tokio::test] +async fn update_test() { + let (access_context, access, _, _) = seed_db().await; - #[tokio::test] - async fn update_modifies_role_test() { - let (access_context, access, _, _) = seed_db().await; + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - let access = access::Model { - role: "Editor".into(), - ..access - }; + let new_access = access::Model { ..access }; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + let updated_access = access_context.update(new_access.clone()).await.unwrap(); - let new_access = access::Model { - role: "Commenter".into(), - ..access - }; + let fetched_access = access::Entity::find_by_id(updated_access.id) + .one(&access_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - let updated_access = access_context.update(new_access.clone()).await.unwrap(); + assert_eq!(new_access, updated_access); + assert_eq!(updated_access, fetched_access); +} - assert_ne!(access, updated_access); - assert_ne!(access, new_access); - } +#[tokio::test] +async fn update_modifies_role_test() { + let (access_context, access, _, _) = seed_db().await; - #[tokio::test] - async fn update_does_not_modify_id_test() { - let (access_context, access, _, _) = seed_db().await; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); - - let updated_access = access::Model { - id: &access.id + 1, - ..access.clone() - }; - let res = access_context.update(updated_access.clone()).await; - - assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); - } + let access = access::Model { + role: "Editor".into(), + ..access + }; - #[tokio::test] - async fn update_does_not_modify_model_id_test() { - let (access_context, access, _, _) = seed_db().await; + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + let new_access = access::Model { + role: "Commenter".into(), + ..access + }; - let updated_access = access::Model { - model_id: &access.model_id + 1, - ..access.clone() - }; - let res = access_context.update(updated_access.clone()).await.unwrap(); + let updated_access = access_context.update(new_access.clone()).await.unwrap(); - assert_eq!(access, res); - } + assert_ne!(access, updated_access); + assert_ne!(access, new_access); +} - #[tokio::test] - async fn update_does_not_modify_user_id_test() { - let (access_context, access, _, _) = seed_db().await; +#[tokio::test] +async fn update_does_not_modify_id_test() { + let (access_context, access, _, _) = seed_db().await; + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); + + let updated_access = access::Model { + id: &access.id + 1, + ..access.clone() + }; + let res = access_context.update(updated_access.clone()).await; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); +} +#[tokio::test] +async fn update_does_not_modify_model_id_test() { + let (access_context, access, _, _) = seed_db().await; + + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); + + let updated_access = access::Model { + model_id: &access.model_id + 1, + ..access.clone() + }; + let res = access_context.update(updated_access.clone()).await.unwrap(); - let updated_access = access::Model { - user_id: &access.user_id + 1, - ..access.clone() - }; - let res = access_context.update(updated_access.clone()).await.unwrap(); + assert_eq!(access, res); +} +#[tokio::test] +async fn update_does_not_modify_user_id_test() { + let (access_context, access, _, _) = seed_db().await; + + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); + + let updated_access = access::Model { + user_id: &access.user_id + 1, + ..access.clone() + }; + let res = access_context.update(updated_access.clone()).await.unwrap(); - assert_eq!(access, res); - } + assert_eq!(access, res); +} - #[tokio::test] - async fn update_invalid_role_test() { - let (access_context, mut access, _, _) = seed_db().await; +#[tokio::test] +async fn update_invalid_role_test() { + let (access_context, mut access, _, _) = seed_db().await; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - access.role = "abc".into(); + access.role = "abc".into(); - let updated_access = access_context.update(access.clone()).await; + let updated_access = access_context.update(access.clone()).await; - assert!(matches!( - updated_access.unwrap_err().sql_err(), - Some(SqlErr::ForeignKeyConstraintViolation(_)) - )); - } + assert!(matches!( + updated_access.unwrap_err().sql_err(), + Some(SqlErr::ForeignKeyConstraintViolation(_)) + )); +} - #[tokio::test] - async fn update_non_existing_id_test() { - let (access_context, access, _, _) = seed_db().await; +#[tokio::test] +async fn update_non_existing_id_test() { + let (access_context, access, _, _) = seed_db().await; - let updated_access = access_context.update(access.clone()).await; + let updated_access = access_context.update(access.clone()).await; - assert!(matches!( - updated_access.unwrap_err(), - DbErr::RecordNotUpdated - )); - } + assert!(matches!( + updated_access.unwrap_err(), + DbErr::RecordNotUpdated + )); +} - #[tokio::test] - async fn delete_test() { - let (access_context, access, _, _) = seed_db().await; +#[tokio::test] +async fn delete_test() { + let (access_context, access, _, _) = seed_db().await; - access::Entity::insert(access.clone().into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + access::Entity::insert(access.clone().into_active_model()) + .exec(&access_context.db_context.get_connection()) + .await + .unwrap(); - let deleted_access = access_context.delete(access.id).await.unwrap(); + let deleted_access = access_context.delete(access.id).await.unwrap(); - let all_accesses = access::Entity::find() - .all(&access_context.db_context.get_connection()) - .await - .unwrap(); + let all_accesses = access::Entity::find() + .all(&access_context.db_context.get_connection()) + .await + .unwrap(); - assert_eq!(access, deleted_access); - assert!(all_accesses.is_empty()); - } + assert_eq!(access, deleted_access); + assert!(all_accesses.is_empty()); +} - #[tokio::test] - async fn delete_non_existing_id_test() { - let (access_context, _, _, _) = seed_db().await; +#[tokio::test] +async fn delete_non_existing_id_test() { + let (access_context, _, _, _) = seed_db().await; - let deleted_access = access_context.delete(1).await; + let deleted_access = access_context.delete(1).await; - assert!(matches!( - deleted_access.unwrap_err(), - DbErr::RecordNotFound(_) - )); - } + assert!(matches!( + deleted_access.unwrap_err(), + DbErr::RecordNotFound(_) + )); } diff --git a/src/tests/database/in_use_context.rs b/src/tests/database/in_use_context.rs index dee9275..ca3e204 100644 --- a/src/tests/database/in_use_context.rs +++ b/src/tests/database/in_use_context.rs @@ -1,264 +1,261 @@ -#[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; +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; - 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(); + 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(); - 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(); + assert_eq!(in_use, inserted_in_use); + assert_eq!(in_use, fetched_in_use); +} - (in_use_context, in_use, session, model, user) - } +#[tokio::test] +async fn create_default_latest_activity_test() { + let t_min = Utc::now().timestamp(); - #[tokio::test] - async fn create_test() { - let (in_use_context, mut in_use, _, _, _) = seed_db().await; + let (in_use_context, 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(); - in_use.latest_activity = inserted_in_use.latest_activity; + 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(); - 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_max = Utc::now().timestamp(); - assert_eq!(in_use, inserted_in_use); - assert_eq!(in_use, fetched_in_use); - } + let t_actual = fetched_in_use.clone().latest_activity.timestamp(); - #[tokio::test] - async fn create_default_latest_activity_test() { - let t_min = Utc::now().timestamp(); + assert!(t_min <= t_actual && t_actual <= t_max) +} - let (in_use_context, in_use, _, _, _) = seed_db().await; +#[tokio::test] +async fn get_by_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - let inserted_in_use = in_use_context.create(in_use.clone()).await.unwrap(); + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&in_use_context.db_context.get_connection()) + .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(); + let fetched_in_use = in_use_context + .get_by_id(in_use.model_id) + .await + .unwrap() + .unwrap(); - let t_max = Utc::now().timestamp(); + assert_eq!(fetched_in_use, in_use) +} - let t_actual = fetched_in_use.clone().latest_activity.timestamp(); +#[tokio::test] +async fn get_by_non_existing_id_test() { + let (in_use_context, _in_use, _, _, _) = seed_db().await; - assert!(t_min <= t_actual && t_actual <= t_max) - } + let in_use = in_use_context.get_by_id(1).await; - #[tokio::test] - async fn get_by_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + assert!(in_use.unwrap().is_none()) +} - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); +#[tokio::test] +async fn get_all_test() { + let (in_use_context, _in_use, session, model, _user) = seed_db().await; - let fetched_in_use = in_use_context - .get_by_id(in_use.model_id) - .await - .unwrap() - .unwrap(); + let in_uses = create_in_uses(1, model.id, session.id); - assert_eq!(fetched_in_use, in_use) - } + in_use::Entity::insert_many(to_active_models!(in_uses.clone())) + .exec(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - #[tokio::test] - async fn get_by_non_existing_id_test() { - let (in_use_context, _in_use, _, _, _) = seed_db().await; + assert_eq!(in_use_context.get_all().await.unwrap().len(), 1); +} - let in_use = in_use_context.get_by_id(1).await; +#[tokio::test] +async fn get_all_empty_test() { + let (in_use_context, _, _, _, _) = seed_db().await; - assert!(in_use.unwrap().is_none()) - } + let in_uses = in_use_context.get_all().await.unwrap(); - #[tokio::test] - async fn get_all_test() { - let (in_use_context, _in_use, session, model, _user) = seed_db().await; + assert_eq!(0, in_uses.len()) +} - let in_uses = create_in_uses(1, model.id, session.id); +#[tokio::test] +async fn update_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - in_use::Entity::insert_many(to_active_models!(in_uses.clone())) - .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(); - assert_eq!(in_use_context.get_all().await.unwrap().len(), 1); - } + let new_in_use = in_use::Model { ..in_use }; - #[tokio::test] - async fn get_all_empty_test() { - let (in_use_context, _, _, _, _) = seed_db().await; + let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); - let in_uses = in_use_context.get_all().await.unwrap(); + 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(); - assert_eq!(0, in_uses.len()) - } + assert_eq!(new_in_use, updated_in_use); + assert_eq!(updated_in_use, fetched_in_use); +} - #[tokio::test] - async fn update_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; +#[tokio::test] +async fn update_modifies_latest_activity_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 { ..in_use }; + let new_in_use = in_use::Model { + latest_activity: in_use.clone().latest_activity.add(Duration::seconds(1)), + ..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(); - 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(); + assert_ne!(in_use, updated_in_use); + assert_ne!(in_use, new_in_use); +} - assert_eq!(new_in_use, updated_in_use); - assert_eq!(updated_in_use, fetched_in_use); - } +#[tokio::test] +async fn update_does_not_modify_model_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - #[tokio::test] - async fn update_modifies_latest_activity_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 { + model_id: in_use.model_id + 1, + ..in_use.clone() + }; - let new_in_use = in_use::Model { - latest_activity: in_use.clone().latest_activity.add(Duration::seconds(1)), - ..in_use - }; + let updated_in_use = in_use_context.update(updated_in_use.clone()).await; - let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); + assert!(matches!( + updated_in_use.unwrap_err(), + DbErr::RecordNotUpdated + )); +} - assert_ne!(in_use, updated_in_use); - assert_ne!(in_use, new_in_use); - } +#[tokio::test] +async fn update_does_not_modify_session_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - #[tokio::test] - async fn update_does_not_modify_model_id_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 updated_in_use = in_use::Model { - model_id: in_use.model_id + 1, - ..in_use.clone() - }; + 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_context.update(updated_in_use.clone()).await; +#[tokio::test] +async fn update_non_existing_id_test() { + let (in_use_context, in_use, _, _, _) = seed_db().await; - assert!(matches!( - updated_in_use.unwrap_err(), - DbErr::RecordNotUpdated - )); - } + let updated_in_use = in_use_context.update(in_use.clone()).await; - #[tokio::test] - async fn update_does_not_modify_session_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + assert!(matches!( + updated_in_use.unwrap_err(), + DbErr::RecordNotUpdated + )); +} - in_use::Entity::insert(in_use.clone().into_active_model()) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); +#[tokio::test] +async fn delete_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 deleted_in_use = in_use_context.delete(in_use.model_id).await.unwrap(); - #[tokio::test] - async fn update_non_existing_id_test() { - let (in_use_context, in_use, _, _, _) = seed_db().await; + let all_in_uses = in_use::Entity::find() + .all(&in_use_context.db_context.get_connection()) + .await + .unwrap(); - let updated_in_use = in_use_context.update(in_use.clone()).await; + assert_eq!(in_use, deleted_in_use); + assert!(all_in_uses.is_empty()); +} - assert!(matches!( - updated_in_use.unwrap_err(), - DbErr::RecordNotUpdated - )); - } +#[tokio::test] +async fn delete_non_existing_id_test() { + let (in_use_context, _, _, _, _) = 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(); + let deleted_in_use = in_use_context.delete(1).await; - 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(_) - )) - } + 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 454c440..d32dd26 100644 --- a/src/tests/database/model_context.rs +++ b/src/tests/database/model_context.rs @@ -1,407 +1,404 @@ -#[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; - - 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) - } +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; + +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) +} - #[tokio::test] - async fn create_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn create_test() { + let (model_context, model, _) = seed_db().await; - let created_model = model_context.create(model.clone()).await.unwrap(); + let created_model = model_context.create(model.clone()).await.unwrap(); - let fetched_model = model::Entity::find_by_id(created_model.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_eq!(model, created_model); - assert_eq!(fetched_model, created_model); - } + 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; +#[tokio::test] +async fn create_auto_increment_test() { + let (model_context, model, _) = seed_db().await; - let models = create_models(2, model.owner_id); + let models = create_models(2, model.owner_id); - let created_model1 = model_context.create(models[0].clone()).await.unwrap(); - let created_model2 = model_context.create(models[1].clone()).await.unwrap(); + let created_model1 = model_context.create(models[0].clone()).await.unwrap(); + let created_model2 = model_context.create(models[1].clone()).await.unwrap(); - let fetched_model1 = model::Entity::find_by_id(created_model1.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let fetched_model1 = model::Entity::find_by_id(created_model1.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - let fetched_model2 = model::Entity::find_by_id(created_model2.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let fetched_model2 = model::Entity::find_by_id(created_model2.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_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); +} - #[tokio::test] - async fn get_by_id_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn get_by_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(); + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let fetched_model = model_context.get_by_id(model.id).await.unwrap().unwrap(); + let fetched_model = model_context.get_by_id(model.id).await.unwrap().unwrap(); - assert_eq!(model, fetched_model); - } + assert_eq!(model, fetched_model); +} - #[tokio::test] - async fn get_by_non_existing_id_test() { - let (model_context, _, _) = seed_db().await; +#[tokio::test] +async fn get_by_non_existing_id_test() { + let (model_context, _, _) = seed_db().await; - let fetched_model = model_context.get_by_id(1).await.unwrap(); + let fetched_model = model_context.get_by_id(1).await.unwrap(); - assert!(fetched_model.is_none()); - } + assert!(fetched_model.is_none()); +} - #[tokio::test] - async fn get_all_test() { - let (model_context, _, user) = seed_db().await; +#[tokio::test] +async fn get_all_test() { + let (model_context, _, user) = seed_db().await; - let new_models = create_models(3, user.id); + let new_models = create_models(3, user.id); - model::Entity::insert_many(to_active_models!(new_models.clone())) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + model::Entity::insert_many(to_active_models!(new_models.clone())) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - assert_eq!(model_context.get_all().await.unwrap().len(), 3); + assert_eq!(model_context.get_all().await.unwrap().len(), 3); - let mut sorted = new_models.clone(); - sorted.sort_by_key(|k| k.id); + let mut sorted = new_models.clone(); + sorted.sort_by_key(|k| k.id); - for (i, model) in sorted.into_iter().enumerate() { - assert_eq!(model, new_models[i]); - } + for (i, model) in sorted.into_iter().enumerate() { + assert_eq!(model, new_models[i]); } +} - #[tokio::test] - async fn get_all_empty_test() { - let (model_context, _, _) = seed_db().await; +#[tokio::test] +async fn get_all_empty_test() { + let (model_context, _, _) = seed_db().await; - let result = model_context.get_all().await.unwrap(); - let empty_models: Vec = vec![]; + let result = model_context.get_all().await.unwrap(); + let empty_models: Vec = vec![]; - assert_eq!(empty_models, result); - } + assert_eq!(empty_models, result); +} - #[tokio::test] - async fn update_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn update_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(); + 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 { ..model }; - 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(); + let fetched_model = model::Entity::find_by_id(updated_model.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - assert_eq!(new_model, updated_model); - assert_eq!(updated_model, fetched_model); - } + assert_eq!(new_model, updated_model); + assert_eq!(updated_model, fetched_model); +} - #[tokio::test] - async fn update_modifies_name_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 { - name: "model1".into(), - ..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 { - name: "model2".into(), - ..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_modifies_components_info_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn update_modifies_components_info_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 { + components_info: "{\"a\":1}".to_owned().parse().unwrap(), + ..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 { + components_info: "{\"a\":2}".to_owned().parse().unwrap(), + ..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_does_not_modify_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(); + model::Entity::insert(model.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let new_model = model::Model { - id: &model.id + 1, - ..model.clone() - }; + let new_model = model::Model { + id: &model.id + 1, + ..model.clone() + }; - let res = model_context.update(new_model.clone()).await; + let res = model_context.update(new_model.clone()).await; - assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); - } + assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); +} - #[tokio::test] - async fn update_does_not_modify_owner_id_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn update_does_not_modify_owner_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(); + 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() - }; + let new_model = model::Model { + owner_id: &model.owner_id + 1, + ..model.clone() + }; - let res = model_context.update(new_model.clone()).await.unwrap(); + let res = model_context.update(new_model.clone()).await.unwrap(); - assert_eq!(model, res); - } + assert_eq!(model, res); +} - #[tokio::test] - async fn update_check_query_outdated_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn update_check_query_outdated_test() { + let (model_context, model, _) = seed_db().await; - let mut query = create_queries(1, model.id)[0].clone(); + let mut query = create_queries(1, model.id)[0].clone(); - query.outdated = false; + 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(); - query::Entity::insert(query.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(); - let new_model = model::Model { ..model }; + let new_model = model::Model { ..model }; - let updated_model = model_context.update(new_model.clone()).await.unwrap(); + let updated_model = model_context.update(new_model.clone()).await.unwrap(); - let fetched_query = query::Entity::find_by_id(updated_model.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + let fetched_query = query::Entity::find_by_id(updated_model.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - assert!(fetched_query.outdated); - } + assert!(fetched_query.outdated); +} - #[tokio::test] - async fn update_non_existing_id_test() { - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn update_non_existing_id_test() { + let (model_context, model, _) = seed_db().await; - let updated_model = model_context.update(model.clone()).await; + let updated_model = model_context.update(model.clone()).await; - assert!(matches!( - updated_model.unwrap_err(), - DbErr::RecordNotUpdated - )); - } + assert!(matches!( + updated_model.unwrap_err(), + DbErr::RecordNotUpdated + )); +} - #[tokio::test] - async fn delete_test() { - // Setting up database and user context - let (model_context, model, _) = seed_db().await; +#[tokio::test] +async fn delete_test() { + // Setting up database and user context + let (model_context, model, _) = seed_db().await; - 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 deleted_model = model_context.delete(model.id).await.unwrap(); + let deleted_model = model_context.delete(model.id).await.unwrap(); - let all_models = model::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!(model, deleted_model); - assert_eq!(all_models.len(), 0); - } + assert_eq!(model, deleted_model); + assert_eq!(all_models.len(), 0); +} - #[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); - } +#[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); +} - #[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_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_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); - } +#[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); +} - #[tokio::test] - async fn delete_non_existing_id_test() { - let (model_context, _, _) = seed_db().await; +#[tokio::test] +async fn delete_non_existing_id_test() { + let (model_context, _, _) = seed_db().await; - let deleted_model = model_context.delete(1).await; + let deleted_model = model_context.delete(1).await; - assert!(matches!( - deleted_model.unwrap_err(), - DbErr::RecordNotFound(_) - )); - } + assert!(matches!( + deleted_model.unwrap_err(), + DbErr::RecordNotFound(_) + )); }