From 98ea497f4cd5870549e3081c32349d7f7b67dd36 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Tue, 28 Nov 2023 13:05:24 +0100 Subject: [PATCH 01/23] add tests --- Cargo.toml | 2 + src/api/ecdar_api.rs | 27 ++++++++++- src/tests/api/model_logic.rs | 87 ++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/tests/api/model_logic.rs diff --git a/Cargo.toml b/Cargo.toml index 3881ade..4d8af53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,8 @@ regex = "1.10.2" mockall = "0.11.4" bcrypt = "0.15.0" serde_json = "1.0.108" +sqlx = "0.7.3" +sqlx-postgres = "0.7.3" [build-dependencies] tonic-build = "0.10.2" diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index c5033f8..0120ae6 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use tonic::{Code, Request, Response, Status}; use crate::api::auth::{RequestExt, Token, TokenType}; +use crate::api::server::server::component::Rep; use crate::database::{ access_context::AccessContextTrait, in_use_context::InUseContextTrait, model_context::ModelContextTrait, query_context::QueryContextTrait, @@ -18,7 +19,7 @@ use super::server::server::{ ecdar_api_server::EcdarApi, ecdar_backend_server::EcdarBackend, get_auth_token_request::{user_credentials, UserCredentials}, - CreateAccessRequest, CreateModelRequest, CreateModelResponse, CreateQueryRequest, + Component, CreateAccessRequest, CreateModelRequest, CreateModelResponse, CreateQueryRequest, CreateUserRequest, DeleteAccessRequest, DeleteModelRequest, DeleteQueryRequest, GetAuthTokenRequest, GetAuthTokenResponse, QueryRequest, QueryResponse, SimulationStartRequest, SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, @@ -153,7 +154,25 @@ impl EcdarApi for ConcreteEcdarApi { match self.model_context.create(model).await { Ok(model) => Ok(Response::new(CreateModelResponse { id: model.id })), - Err(error) => Err(Status::internal(error.to_string())), + Err(error) => 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())), + }, } } @@ -563,3 +582,7 @@ mod tests; #[cfg(test)] #[path = "../tests/api/query_logic.rs"] mod query_logic; + +#[cfg(test)] +#[path = "../tests/api/model_logic.rs"] +mod model_logic; diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs new file mode 100644 index 0000000..fbd20a4 --- /dev/null +++ b/src/tests/api/model_logic.rs @@ -0,0 +1,87 @@ +#[cfg(test)] +use crate::api::server::server::ecdar_api_server::EcdarApi; +use crate::api::server::server::{Component, ComponentsInfo, CreateModelRequest}; +use crate::entities::{model, user}; +use crate::tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}; +use mockall::predicate; +use sea_orm::DbErr; +use tonic::{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.clone(), + }; + + mock_services + .model_context_mock + .expect_create() + .with(predicate::eq(model.clone())) + .returning(move |_| Ok(model.clone())); + + let mut request = Request::new(CreateModelRequest { + name: Default::default(), + components_info: Option::from(components_info), + owner_id: uid.clone(), + }); + + request + .metadata_mut() + .insert("uid", uid.to_string().parse().unwrap()); + + println!("{:?}", request); + + 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.clone(), + }; + + 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(), + owner_id: uid.clone(), + }); + + 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) +} From 2171ec9cff71aa94f9815ad0ced85c9b2b2f6767 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Tue, 28 Nov 2023 13:09:52 +0100 Subject: [PATCH 02/23] fmt --- src/api/ecdar_api.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 238a7a5..26f0644 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -19,7 +19,7 @@ use super::server::server::{ SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, UpdateUserRequest, UserTokenResponse, }; -use crate::entities::{access, query, session, user, model}; +use crate::entities::{access, model, query, session, user}; #[derive(Clone)] pub struct ConcreteEcdarApi { @@ -425,7 +425,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { Arc::clone(&self.contexts.user_context), user_credentials, ) - .await?; + .await?; // Check if password in request matches users password if input_password != user_from_db.password { @@ -464,7 +464,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { refresh_token.clone(), uid, ) - .await?; + .await?; Ok(Response::new(GetAuthTokenResponse { access_token, From 3cb26aed72d41f3d328ad53ea5afadd97ecaa774 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Tue, 28 Nov 2023 13:32:55 +0100 Subject: [PATCH 03/23] Fix tests --- src/database/model_context.rs | 1 + src/tests/database/access_context.rs | 4 ++++ src/tests/database/in_use_context.rs | 21 +++------------------ src/tests/database/model_context.rs | 6 ++++-- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/database/model_context.rs b/src/database/model_context.rs index 931e7c9..7f4a0cd 100644 --- a/src/database/model_context.rs +++ b/src/database/model_context.rs @@ -18,6 +18,7 @@ impl ModelContext { ModelContext { db_context } } } + #[async_trait] impl EntityContextTrait for ModelContext { /// Used for creating a model::Model entity diff --git a/src/tests/database/access_context.rs b/src/tests/database/access_context.rs index 0fda812..959dacd 100644 --- a/src/tests/database/access_context.rs +++ b/src/tests/database/access_context.rs @@ -28,6 +28,7 @@ async fn seed_db() -> (AccessContext, access::Model, user::Model, model::Model) (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() { @@ -79,6 +80,7 @@ async fn create_auto_increment_test() { let mut model_2 = create_models(1, user.id)[0].clone(); model_2.id = model_1.id + 1; + model_2.name = "model_2".into(); model::Entity::insert(model_2.into_active_model()) .exec(&access_context.db_context.get_connection()) @@ -242,6 +244,7 @@ async fn update_does_not_modify_id_test() { 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; @@ -259,6 +262,7 @@ async fn update_does_not_modify_model_id_test() { assert_eq!(access, res); } + #[tokio::test] async fn update_does_not_modify_user_id_test() { let (access_context, access, _, _) = seed_db().await; diff --git a/src/tests/database/in_use_context.rs b/src/tests/database/in_use_context.rs index a62f6b5..ca3e204 100644 --- a/src/tests/database/in_use_context.rs +++ b/src/tests/database/in_use_context.rs @@ -112,31 +112,16 @@ async fn get_by_non_existing_id_test() { #[tokio::test] async fn get_all_test() { - let (in_use_context, _in_use, session, model, user) = seed_db().await; + let (in_use_context, _in_use, session, model, _user) = seed_db().await; - let mut models = create_models(2, user.id); - models[0].id = 3; - - let in_uses = create_in_uses(3, model.id, session.id); - - model::Entity::insert_many(to_active_models!(models.clone())) - .exec(&in_use_context.db_context.get_connection()) - .await - .unwrap(); + let in_uses = create_in_uses(1, model.id, session.id); in_use::Entity::insert_many(to_active_models!(in_uses.clone())) .exec(&in_use_context.db_context.get_connection()) .await .unwrap(); - assert_eq!(in_use_context.get_all().await.unwrap().len(), 3); - - let mut sorted = in_uses.clone(); - sorted.sort_by_key(|k| k.model_id); - - for (i, in_use) in sorted.into_iter().enumerate() { - assert_eq!(in_use, in_uses[i]); - } + assert_eq!(in_use_context.get_all().await.unwrap().len(), 1); } #[tokio::test] diff --git a/src/tests/database/model_context.rs b/src/tests/database/model_context.rs index 29464d4..d32dd26 100644 --- a/src/tests/database/model_context.rs +++ b/src/tests/database/model_context.rs @@ -44,8 +44,10 @@ async fn create_test() { async fn create_auto_increment_test() { let (model_context, model, _) = seed_db().await; - let created_model1 = model_context.create(model.clone()).await.unwrap(); - let created_model2 = model_context.create(model.clone()).await.unwrap(); + 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 fetched_model1 = model::Entity::find_by_id(created_model1.id) .one(&model_context.db_context.get_connection()) From d680c35dfbf2de73620f835a6a70ef93b656c23a Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Tue, 28 Nov 2023 13:39:57 +0100 Subject: [PATCH 04/23] fmt --- src/api/ecdar_api.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 1b05324..b09e29f 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -447,7 +447,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { Arc::clone(&self.contexts.user_context), user_credentials, ) - .await?; + .await?; // Check if password in request matches users password if input_password != user_from_db.password { @@ -486,7 +486,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { refresh_token.clone(), uid, ) - .await?; + .await?; Ok(Response::new(GetAuthTokenResponse { access_token, From 03538250e2417c04fbba1cc7a0d3abf5448dd4a1 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Tue, 28 Nov 2023 13:41:07 +0100 Subject: [PATCH 05/23] fmt --- src/api/ecdar_api.rs | 6 +----- src/tests/api/model_logic.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index b09e29f..b086250 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -6,11 +6,7 @@ use std::sync::Arc; use tonic::{Code, Request, Response, Status}; use crate::api::auth::{RequestExt, Token, TokenType}; -use crate::database::{ - access_context::AccessContextTrait, in_use_context::InUseContextTrait, - model_context::ModelContextTrait, query_context::QueryContextTrait, - session_context::SessionContextTrait, user_context::UserContextTrait, -}; +use crate::database::{session_context::SessionContextTrait, user_context::UserContextTrait}; use super::server::server::{ ecdar_api_auth_server::EcdarApiAuth, diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index fbd20a4..7a9c7d7 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -1,7 +1,7 @@ #[cfg(test)] use crate::api::server::server::ecdar_api_server::EcdarApi; -use crate::api::server::server::{Component, ComponentsInfo, CreateModelRequest}; -use crate::entities::{model, user}; +use crate::api::server::server::{ComponentsInfo, CreateModelRequest}; +use crate::entities::model; use crate::tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}; use mockall::predicate; use sea_orm::DbErr; @@ -22,7 +22,7 @@ async fn create_model_returns_ok() { id: Default::default(), name: Default::default(), components_info: serde_json::to_value(components_info.clone()).unwrap(), - owner_id: uid.clone(), + owner_id: uid, }; mock_services @@ -34,7 +34,7 @@ async fn create_model_returns_ok() { let mut request = Request::new(CreateModelRequest { name: Default::default(), components_info: Option::from(components_info), - owner_id: uid.clone(), + owner_id: uid, }); request @@ -60,7 +60,7 @@ async fn create_model_existing_name_returns_err() { id: Default::default(), name: "model".to_string(), components_info: Default::default(), - owner_id: uid.clone(), + owner_id: uid, }; mock_services @@ -72,7 +72,7 @@ async fn create_model_existing_name_returns_err() { let mut request = Request::new(CreateModelRequest { name: "model".to_string(), components_info: Default::default(), - owner_id: uid.clone(), + owner_id: uid, }); request From 51af8b19afd4789ffa85a5142f150f54cc542438 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 08:25:59 +0100 Subject: [PATCH 06/23] Add import --- src/tests/api/model_logic.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index f758f2f..83f40aa 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -1,11 +1,12 @@ use std::str::FromStr; use mockall::predicate; +use sea_orm::DbErr; use tonic::{metadata, Code, Request}; use crate::{ api::server::server::{ - ecdar_api_server::EcdarApi, ComponentsInfo, DeleteModelRequest, CreateModelRequest, + ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, }, entities::model, tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}, From 223bee4d02ece04ba9ec403456e70c54114feae4 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 08:44:34 +0100 Subject: [PATCH 07/23] Remove duplicate test mod load --- src/api/ecdar_api.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 1d80081..a6421d3 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -475,7 +475,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { Arc::clone(&self.contexts.user_context), user_credentials, ) - .await?; + .await?; // Check if password in request matches users password if input_password != user_from_db.password { @@ -514,7 +514,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { refresh_token.clone(), uid, ) - .await?; + .await?; Ok(Response::new(GetAuthTokenResponse { access_token, @@ -616,8 +616,4 @@ mod model_logic_tests; #[cfg(test)] #[path = "../tests/api/session_logic.rs"] -mod session_logic_tests; - -#[cfg(test)] -#[path = "../tests/api/model_logic.rs"] -mod model_logic; +mod session_logic_tests; \ No newline at end of file From 5fcb1fab7c0c32abc2bf43502c08ef80a65af06f Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 08:57:54 +0100 Subject: [PATCH 08/23] WIP --- src/api/ecdar_api.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index a6421d3..dcd2b19 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -19,7 +19,7 @@ use super::server::server::{ SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, UpdateUserRequest, UserTokenResponse, }; -use crate::entities::{access, model, query, session, user}; +use crate::entities::{access, model, query, session, user, in_use}; #[derive(Clone)] pub struct ConcreteEcdarApi { @@ -118,15 +118,16 @@ 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 })), + + model = match self.contexts.model_context.create(model).await { + Ok(model) => model, Err(error) => match error.sql_err() { Some(SqlErr::UniqueConstraintViolation(e)) => { let error_msg = match e.to_lowercase() { @@ -146,7 +147,21 @@ impl EcdarApi for ConcreteEcdarApi { } _ => Err(Status::internal(error.to_string())), }, - } + }?; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), //todo!("Use role enum") + model_id: model.id, + user_id: uid, + }; + + + let in_use = in_use::Model { + model_id: model.id, + session_id: Default::default(), + latest_activity: Default::default(), + }; } async fn update_model(&self, _request: Request<()>) -> Result, Status> { From 92d30bfd4951484adb7c65d2b35c7d743f6ca8fd Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:00:40 +0100 Subject: [PATCH 09/23] Merge session ctx from 18 --- src/database/session_context.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/database/session_context.rs b/src/database/session_context.rs index 833b0d6..586efba 100644 --- a/src/database/session_context.rs +++ b/src/database/session_context.rs @@ -4,6 +4,7 @@ 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; @@ -14,22 +15,34 @@ pub struct SessionContext { #[async_trait] pub trait SessionContextTrait: EntityContextTrait { - async fn get_by_refresh_token( + async fn get_by_token( &self, - refresh_token: String, + token_type: TokenType, + token: String, ) -> Result, DbErr>; } #[async_trait] impl SessionContextTrait for SessionContext { - async fn get_by_refresh_token( + async fn get_by_token( &self, - refresh_token: String, + token_type: TokenType, + token: String, ) -> Result, DbErr> { - session::Entity::find() - .filter(session::Column::RefreshToken.eq(refresh_token)) - .one(&self.db_context.get_connection()) - .await + match token_type { + TokenType::AccessToken => { + session::Entity::find() + .filter(session::Column::AccessToken.eq(token)) + .one(&self.db_context.get_connection()) + .await + } + TokenType::RefreshToken => { + session::Entity::find() + .filter(session::Column::RefreshToken.eq(token)) + .one(&self.db_context.get_connection()) + .await + } + } } } From f77907e26c53a4d1acff294db42469c98a5e20d2 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:13:48 +0100 Subject: [PATCH 10/23] Merge session logic tests from 18 --- src/api/ecdar_api.rs | 21 +++++++++++++++------ src/tests/api/helpers.rs | 2 +- src/tests/api/session_logic.rs | 11 +++++++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index dcd2b19..6143e0d 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -56,7 +56,7 @@ pub async fn handle_session( }; } else { let mut session = match session_context - .get_by_refresh_token(request.token_string().unwrap()) + .get_by_token(TokenType::RefreshToken, request.token_string().unwrap()) .await { Ok(Some(session)) => session, @@ -128,7 +128,7 @@ impl EcdarApi for ConcreteEcdarApi { model = match self.contexts.model_context.create(model).await { Ok(model) => model, - Err(error) => match error.sql_err() { + 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", @@ -147,21 +147,30 @@ impl EcdarApi for ConcreteEcdarApi { } _ => Err(Status::internal(error.to_string())), }, - }?; + }; + let access = access::Model { id: Default::default(), role: "Editor".to_string(), //todo!("Use role enum") - model_id: model.id, + 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.id, - session_id: Default::default(), + 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(&self, _request: Request<()>) -> Result, Status> { diff --git a/src/tests/api/helpers.rs b/src/tests/api/helpers.rs index d8ef4c8..1694b5a 100644 --- a/src/tests/api/helpers.rs +++ b/src/tests/api/helpers.rs @@ -128,7 +128,7 @@ mock! { } #[async_trait] impl SessionContextTrait for SessionContext { - async fn get_by_refresh_token(&self, refresh_token: String) -> Result, DbErr>; + async fn get_by_token(&self, token_type: TokenType, token: String) -> Result, DbErr>; } } diff --git a/src/tests/api/session_logic.rs b/src/tests/api/session_logic.rs index 3945c39..4513531 100644 --- a/src/tests/api/session_logic.rs +++ b/src/tests/api/session_logic.rs @@ -1,5 +1,5 @@ -use crate::api::ecdar_api::handle_session; use crate::api::server::server::GetAuthTokenRequest; +use crate::api::{auth::TokenType, ecdar_api::handle_session}; use crate::entities::session; use crate::tests::api::helpers::get_mock_services; use mockall::predicate; @@ -30,9 +30,12 @@ async fn handle_session_updated_session_contains_correct_fields_returns_ok() { mock_services .session_context_mock - .expect_get_by_refresh_token() - .with(predicate::eq("old_refresh_token".to_string())) - .returning(move |_| Ok(Some(old_session.clone()))); + .expect_get_by_token() + .with( + predicate::eq(TokenType::RefreshToken), + predicate::eq("old_refresh_token".to_string()), + ) + .returning(move |_, _| Ok(Some(old_session.clone()))); mock_services .session_context_mock From 10ecbca093d9feb79f6289d5199bb5bf7976503a Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:15:35 +0100 Subject: [PATCH 11/23] Merge api test helpers from 18 --- src/tests/api/helpers.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/api/helpers.rs b/src/tests/api/helpers.rs index 1694b5a..aefa456 100644 --- a/src/tests/api/helpers.rs +++ b/src/tests/api/helpers.rs @@ -1,5 +1,6 @@ #![cfg(test)] +use crate::api::auth::TokenType; use crate::api::context_collection::ContextCollection; use crate::api::ecdar_api::ConcreteEcdarApi; use crate::api::hashing_context::HashingContextTrait; @@ -71,7 +72,9 @@ mock! { async fn delete(&self, entity_id: i32) -> Result; } #[async_trait] - impl AccessContextTrait for AccessContext {} + impl AccessContextTrait for AccessContext { + async fn get_access_by_uid_and_model_id(&self, uid: i32, model_id: i32) -> Result, DbErr>; + } } mock! { From cd951039992ba61b7ac897126adcd3131628b948 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:17:02 +0100 Subject: [PATCH 12/23] Merge db test from 18 --- src/tests/database/access_context.rs | 549 +++++++++++----------- src/tests/database/in_use_context.rs | 415 ++++++++-------- src/tests/database/model_context.rs | 653 +++++++++++++------------- src/tests/database/session_context.rs | 23 +- 4 files changed, 833 insertions(+), 807 deletions(-) diff --git a/src/tests/database/access_context.rs b/src/tests/database/access_context.rs index 959dacd..23207f1 100644 --- a/src/tests/database/access_context.rs +++ b/src/tests/database/access_context.rs @@ -1,345 +1,348 @@ -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) -} +#[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}; -// 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; + async fn seed_db() -> (AccessContext, access::Model, user::Model, model::Model) { + let db_context = get_reset_database_context().await; - let created_access = access_context.create(access.clone()).await.unwrap(); + let access_context = AccessContext::new(db_context); - let fetched_access = access::Entity::find_by_id(created_access.id) - .one(&access_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); + 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(); - // Assert if the fetched access is the same as the created access - assert_eq!(access, created_access); - assert_eq!(fetched_access, created_access); -} + 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(); -#[tokio::test] -async fn create_check_unique_pair_model_id_user_id_test() { - let (access_context, access, _, _) = seed_db().await; + (access_context, access, user, model) + } - let _created_access_1 = access_context.create(access.clone()).await.unwrap(); - let _created_access_2 = access_context.create(access.clone()).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; - assert!(matches!( - _created_access_2.unwrap_err().sql_err(), - Some(SqlErr::UniqueConstraintViolation(_)) - )); -} + let created_access = access_context.create(access.clone()).await.unwrap(); -#[tokio::test] -async fn create_invalid_role_test() { - let (access_context, mut access, _, _) = seed_db().await; + let fetched_access = access::Entity::find_by_id(created_access.id) + .one(&access_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - access.role = "abc".into(); + // Assert if the fetched access is the same as the created access + assert_eq!(access, created_access); + assert_eq!(fetched_access, created_access); + } - let created_access = access_context.create(access.clone()).await; + #[tokio::test] + async fn create_check_unique_pair_model_id_user_id_test() { + let (access_context, access, _, _) = seed_db().await; - assert!(matches!( - created_access.unwrap_err().sql_err(), - Some(SqlErr::ForeignKeyConstraintViolation(_)) - )); -} + let _created_access_1 = access_context.create(access.clone()).await.unwrap(); + let _created_access_2 = access_context.create(access.clone()).await; -#[tokio::test] -async fn create_auto_increment_test() { - let (access_context, _, user, model_1) = seed_db().await; + assert!(matches!( + _created_access_2.unwrap_err().sql_err(), + Some(SqlErr::UniqueConstraintViolation(_)) + )); + } - let mut model_2 = create_models(1, user.id)[0].clone(); - model_2.id = model_1.id + 1; - model_2.name = "model_2".into(); + #[tokio::test] + async fn create_invalid_role_test() { + let (access_context, mut access, _, _) = seed_db().await; - model::Entity::insert(model_2.into_active_model()) - .exec(&access_context.db_context.get_connection()) - .await - .unwrap(); + access.role = "abc".into(); - let access_1 = access::Model { - id: 0, - role: "Editor".to_string(), - model_id: 1, - user_id: user.id, - }; + let created_access = access_context.create(access.clone()).await; - let access_2 = access::Model { - id: 0, - role: "Editor".to_string(), - model_id: 2, - user_id: user.id, - }; + assert!(matches!( + created_access.unwrap_err().sql_err(), + Some(SqlErr::ForeignKeyConstraintViolation(_)) + )); + } - 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 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); + } -#[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_all_empty_test() { - let (access_context, _, _, _) = 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![]; + let result = access_context.get_all().await.unwrap(); + let empty_accesses: Vec = vec![]; - assert_eq!(empty_accesses, result); -} - -#[tokio::test] -async fn update_test() { - let (access_context, access, _, _) = seed_db().await; + assert_eq!(empty_accesses, result); + } - access::Entity::insert(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 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 { ..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); -} + let fetched_access = access::Entity::find_by_id(updated_access.id) + .one(&access_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); -#[tokio::test] -async fn update_modifies_role_test() { - let (access_context, access, _, _) = seed_db().await; + assert_eq!(new_access, updated_access); + assert_eq!(updated_access, fetched_access); + } - let access = access::Model { - role: "Editor".into(), - ..access - }; + #[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 { - role: "Commenter".into(), - ..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 + }; - assert_ne!(access, updated_access); - assert_ne!(access, new_access); -} + let updated_access = access_context.update(new_access.clone()).await.unwrap(); -#[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_ne!(access, updated_access); + assert_ne!(access, new_access); + } - assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); -} + #[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)); + } -#[tokio::test] -async fn update_does_not_modify_model_id_test() { - let (access_context, access, _, _) = seed_db().await; + #[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 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 { + model_id: &access.model_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_does_not_modify_user_id_test() { - let (access_context, access, _, _) = seed_db().await; + #[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(); + 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(); + 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 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 d32dd26..454c440 100644 --- a/src/tests/database/model_context.rs +++ b/src/tests/database/model_context.rs @@ -1,404 +1,407 @@ -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) -} +#[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); -} + user::Entity::insert(user.clone().into_active_model()) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); -#[tokio::test] -async fn create_auto_increment_test() { - let (model_context, model, _) = seed_db().await; + (model_context, model, user) + } - let models = create_models(2, model.owner_id); + #[tokio::test] + async fn create_test() { + let (model_context, model, _) = seed_db().await; - let created_model1 = model_context.create(models[0].clone()).await.unwrap(); - let created_model2 = model_context.create(models[1].clone()).await.unwrap(); + let created_model = model_context.create(model.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_model = model::Entity::find_by_id(created_model.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_eq!(model, created_model); + assert_eq!(fetched_model, created_model); + } - 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 create_auto_increment_test() { + let (model_context, model, _) = seed_db().await; -#[tokio::test] -async fn get_by_id_test() { - let (model_context, model, _) = seed_db().await; + let models = create_models(2, model.owner_id); - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .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_model = model_context.get_by_id(model.id).await.unwrap().unwrap(); + let fetched_model1 = model::Entity::find_by_id(created_model1.id) + .one(&model_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); - assert_eq!(model, fetched_model); -} + let fetched_model2 = model::Entity::find_by_id(created_model2.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; + 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); + } - let fetched_model = model_context.get_by_id(1).await.unwrap(); + #[tokio::test] + async fn get_by_id_test() { + let (model_context, model, _) = seed_db().await; - assert!(fetched_model.is_none()); -} + 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(); + + assert_eq!(model, fetched_model); + } -#[tokio::test] -async fn get_all_test() { - let (model_context, _, user) = seed_db().await; + #[tokio::test] + async fn get_by_non_existing_id_test() { + let (model_context, _, _) = seed_db().await; - let new_models = create_models(3, user.id); + let fetched_model = model_context.get_by_id(1).await.unwrap(); - model::Entity::insert_many(to_active_models!(new_models.clone())) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); + assert!(fetched_model.is_none()); + } + + #[tokio::test] + async fn get_all_test() { + let (model_context, _, user) = seed_db().await; + + let new_models = create_models(3, user.id); - assert_eq!(model_context.get_all().await.unwrap().len(), 3); + model::Entity::insert_many(to_active_models!(new_models.clone())) + .exec(&model_context.db_context.get_connection()) + .await + .unwrap(); - let mut sorted = new_models.clone(); - sorted.sort_by_key(|k| k.id); + assert_eq!(model_context.get_all().await.unwrap().len(), 3); - for (i, model) in sorted.into_iter().enumerate() { - assert_eq!(model, new_models[i]); + 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]); + } } -} -#[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(_) + )); + } } diff --git a/src/tests/database/session_context.rs b/src/tests/database/session_context.rs index 6d4ee56..12d05fd 100644 --- a/src/tests/database/session_context.rs +++ b/src/tests/database/session_context.rs @@ -1,4 +1,4 @@ -use crate::tests::database::helpers::*; +use crate::{api::auth::TokenType, tests::database::helpers::*}; use sea_orm::{entity::prelude::*, IntoActiveModel}; use std::ops::Add; @@ -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()) @@ -350,7 +350,7 @@ async fn get_by_refresh_token_test() { .unwrap(); let fetched_session = session_context - .get_by_refresh_token(session.refresh_token.clone()) + .get_by_token(TokenType::RefreshToken, session.refresh_token.clone()) .await .unwrap(); @@ -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); +} From 48f12dd4169588504837daea0b62f184aed06b70 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:18:15 +0100 Subject: [PATCH 13/23] Merge db access ctx --- src/database/access_context.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/database/access_context.rs b/src/database/access_context.rs index 0165105..a1bad6b 100644 --- a/src/database/access_context.rs +++ b/src/database/access_context.rs @@ -3,16 +3,39 @@ use crate::database::entity_context::EntityContextTrait; use crate::entities::access; use sea_orm::prelude::async_trait::async_trait; use sea_orm::ActiveValue::{Set, Unchanged}; -use sea_orm::{ActiveModelTrait, DbErr, EntityTrait}; +use sea_orm::{ActiveModelTrait, ColumnTrait, Condition, DbErr, EntityTrait, QueryFilter}; use std::sync::Arc; pub struct AccessContext { db_context: Arc, } -pub trait AccessContextTrait: EntityContextTrait {} +#[async_trait] +pub trait AccessContextTrait: EntityContextTrait { + async fn get_access_by_uid_and_model_id( + &self, + uid: i32, + model_id: i32, + ) -> Result, DbErr>; +} -impl AccessContextTrait for AccessContext {} +#[async_trait] +impl AccessContextTrait for AccessContext { + 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 + } +} impl AccessContext { pub fn new(db_context: Arc) -> AccessContext { From 11a13c908043088a176336515ebc081c575f8173 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:32:14 +0100 Subject: [PATCH 14/23] Fix create model tests --- src/api/ecdar_api.rs | 60 +++++++++++++++++++----------------- src/tests/api/model_logic.rs | 51 ++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 30 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 6143e0d..02897e6 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -19,7 +19,7 @@ use super::server::server::{ SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, UpdateUserRequest, UserTokenResponse, }; -use crate::entities::{access, model, query, session, user, in_use}; +use crate::entities::{access, in_use, model, query, session, user}; #[derive(Clone)] pub struct ConcreteEcdarApi { @@ -125,31 +125,31 @@ impl EcdarApi for ConcreteEcdarApi { owner_id: uid, }; - 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(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())), } - _ => Err(Status::internal(error.to_string())), - }, + } }; - let access = access::Model { id: Default::default(), role: "Editor".to_string(), //todo!("Use role enum") @@ -157,7 +157,13 @@ impl EcdarApi for ConcreteEcdarApi { user_id: uid, }; - let session = self.contexts.session_context.get_by_token(TokenType::AccessToken, request.token_string().unwrap()).await.unwrap().unwrap(); + 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, @@ -168,9 +174,7 @@ impl EcdarApi for ConcreteEcdarApi { 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, - })) + Ok(Response::new(CreateModelResponse { id: model.id })) } async fn update_model(&self, _request: Request<()>) -> Result, Status> { @@ -499,7 +503,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { Arc::clone(&self.contexts.user_context), user_credentials, ) - .await?; + .await?; // Check if password in request matches users password if input_password != user_from_db.password { @@ -538,7 +542,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { refresh_token.clone(), uid, ) - .await?; + .await?; Ok(Response::new(GetAuthTokenResponse { access_token, @@ -640,4 +644,4 @@ mod model_logic_tests; #[cfg(test)] #[path = "../tests/api/session_logic.rs"] -mod session_logic_tests; \ No newline at end of file +mod session_logic_tests; diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index 83f40aa..c8c323d 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -4,6 +4,8 @@ use mockall::predicate; use sea_orm::DbErr; use tonic::{metadata, Code, Request}; +use crate::api::auth::TokenType; +use crate::entities::{access, in_use, session}; use crate::{ api::server::server::{ ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, @@ -27,7 +29,28 @@ async fn create_model_returns_ok() { id: Default::default(), name: Default::default(), components_info: serde_json::to_value(components_info.clone()).unwrap(), - owner_id: uid, + owner_id: uid.clone(), + }; + + let access = access::Model { + id: Default::default(), + role: "Editor".to_string(), + user_id: uid.clone(), + 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.clone(), + }; + + let in_use = in_use::Model { + model_id: model.id, + session_id: session.id, + latest_activity: Default::default(), }; mock_services @@ -36,6 +59,27 @@ async fn create_model_returns_ok() { .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), @@ -46,7 +90,10 @@ async fn create_model_returns_ok() { .metadata_mut() .insert("uid", uid.to_string().parse().unwrap()); - println!("{:?}", request); + request.metadata_mut().insert( + "authorization", + metadata::MetadataValue::from_str("Bearer access_token").unwrap(), + ); let api = get_mock_concrete_ecdar_api(mock_services); From 7d3b6b7388d2104859bcf10515e58572fffb6f9d Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:32:57 +0100 Subject: [PATCH 15/23] Fix create model tests --- src/tests/api/model_logic.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index c8c323d..aaab0c9 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -74,11 +74,11 @@ async fn create_model_returns_ok() { ) .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())); + // 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(), From 2446566f9cf6d000ffc342afe9e44912e2b52054 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:34:00 +0100 Subject: [PATCH 16/23] Fix create model tests --- src/tests/api/model_logic.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index aaab0c9..c8c323d 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -74,11 +74,11 @@ async fn create_model_returns_ok() { ) .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())); + 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(), From 7394a1408646c67ebb62630cda46eca5d12d916f Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:38:31 +0100 Subject: [PATCH 17/23] clippy --- src/tests/api/model_logic.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index c8c323d..3b03665 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -29,13 +29,13 @@ async fn create_model_returns_ok() { id: Default::default(), name: Default::default(), components_info: serde_json::to_value(components_info.clone()).unwrap(), - owner_id: uid.clone(), + owner_id: uid, }; let access = access::Model { id: Default::default(), role: "Editor".to_string(), - user_id: uid.clone(), + user_id: uid, model_id: model.id, }; @@ -44,7 +44,7 @@ async fn create_model_returns_ok() { refresh_token: "refresh_token".to_string(), access_token: "access_token".to_string(), updated_at: Default::default(), - user_id: uid.clone(), + user_id: uid, }; let in_use = in_use::Model { From df90da180bfa57cca766d4bfe601f4191af49137 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:48:55 +0100 Subject: [PATCH 18/23] Update protobuf --- src/api/ecdar_api.rs | 2 +- src/tests/api/model_logic.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 02897e6..c9ca28c 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -146,7 +146,7 @@ impl EcdarApi for ConcreteEcdarApi { Err(Status::invalid_argument(error_msg)) } _ => Err(Status::internal(error.to_string())), - } + }; } }; diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index 3b03665..0e40f31 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -83,7 +83,6 @@ async fn create_model_returns_ok() { let mut request = Request::new(CreateModelRequest { name: Default::default(), components_info: Option::from(components_info), - owner_id: uid, }); request @@ -124,7 +123,6 @@ async fn create_model_existing_name_returns_err() { let mut request = Request::new(CreateModelRequest { name: "model".to_string(), components_info: Default::default(), - owner_id: uid, }); request From b174a2ef74e8bc035e9c36cc44eeef66c64bbe11 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 09:56:52 +0100 Subject: [PATCH 19/23] Update submod --- Ecdar-ProtoBuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ecdar-ProtoBuf b/Ecdar-ProtoBuf index 2d01513..7aa53a0 160000 --- a/Ecdar-ProtoBuf +++ b/Ecdar-ProtoBuf @@ -1 +1 @@ -Subproject commit 2d01513339957ae116329a1c8098529354fc9d0e +Subproject commit 7aa53a077c8ff55a6b88108f743eee6a10014d7c From 3533c1015c15dc7aaba664cea5c0af9f047a9514 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 10:07:47 +0100 Subject: [PATCH 20/23] Fix proto changes --- Ecdar-ProtoBuf | 2 +- src/api/ecdar_api.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Ecdar-ProtoBuf b/Ecdar-ProtoBuf index 7aa53a0..6bce256 160000 --- a/Ecdar-ProtoBuf +++ b/Ecdar-ProtoBuf @@ -1 +1 @@ -Subproject commit 7aa53a077c8ff55a6b88108f743eee6a10014d7c +Subproject commit 6bce2563aa1f2072340f3678ade4482f96e39b27 diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index c9ca28c..85a2581 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -17,7 +17,7 @@ use super::server::server::{ CreateUserRequest, DeleteAccessRequest, DeleteModelRequest, DeleteQueryRequest, GetAuthTokenRequest, GetAuthTokenResponse, QueryRequest, QueryResponse, SimulationStartRequest, SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, - UpdateUserRequest, UserTokenResponse, + UpdateUserRequest, UserTokenResponse, ListModelsInfoResponse, GetModelRequest, GetModelResponse, }; use crate::entities::{access, in_use, model, query, session, user}; @@ -100,7 +100,7 @@ impl ConcreteEcdarApi { #[tonic::async_trait] impl EcdarApi for ConcreteEcdarApi { - async fn get_model(&self, _request: Request<()>) -> Result, Status> { + async fn get_model(&self, _request: Request) -> Result, Status> { todo!() } @@ -220,7 +220,7 @@ impl EcdarApi for ConcreteEcdarApi { } } - async fn list_models_info(&self, _request: Request<()>) -> Result, Status> { + async fn list_models_info(&self, _request: Request<()>) -> Result, Status> { todo!() } @@ -503,7 +503,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { Arc::clone(&self.contexts.user_context), user_credentials, ) - .await?; + .await?; // Check if password in request matches users password if input_password != user_from_db.password { @@ -542,7 +542,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { refresh_token.clone(), uid, ) - .await?; + .await?; Ok(Response::new(GetAuthTokenResponse { access_token, From 764072a1bd23800a7984ec795bbbd77fa0d023d5 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 10:09:11 +0100 Subject: [PATCH 21/23] f m t --- src/api/ecdar_api.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 85a2581..cad5ec1 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -15,9 +15,10 @@ use super::server::server::{ get_auth_token_request::{user_credentials, UserCredentials}, CreateAccessRequest, CreateModelRequest, CreateModelResponse, CreateQueryRequest, CreateUserRequest, DeleteAccessRequest, DeleteModelRequest, DeleteQueryRequest, - GetAuthTokenRequest, GetAuthTokenResponse, QueryRequest, QueryResponse, SimulationStartRequest, + GetAuthTokenRequest, GetAuthTokenResponse, GetModelRequest, GetModelResponse, + ListModelsInfoResponse, QueryRequest, QueryResponse, SimulationStartRequest, SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateQueryRequest, - UpdateUserRequest, UserTokenResponse, ListModelsInfoResponse, GetModelRequest, GetModelResponse, + UpdateUserRequest, UserTokenResponse, }; use crate::entities::{access, in_use, model, query, session, user}; @@ -100,7 +101,10 @@ impl ConcreteEcdarApi { #[tonic::async_trait] impl EcdarApi for ConcreteEcdarApi { - async fn get_model(&self, _request: Request) -> Result, Status> { + async fn get_model( + &self, + _request: Request, + ) -> Result, Status> { todo!() } @@ -220,7 +224,10 @@ impl EcdarApi for ConcreteEcdarApi { } } - async fn list_models_info(&self, _request: Request<()>) -> Result, Status> { + async fn list_models_info( + &self, + _request: Request<()>, + ) -> Result, Status> { todo!() } @@ -503,7 +510,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { Arc::clone(&self.contexts.user_context), user_credentials, ) - .await?; + .await?; // Check if password in request matches users password if input_password != user_from_db.password { @@ -542,7 +549,7 @@ impl EcdarApiAuth for ConcreteEcdarApi { refresh_token.clone(), uid, ) - .await?; + .await?; Ok(Response::new(GetAuthTokenResponse { access_token, From cf68ff51573375496feb74d42994fc0221c2310c Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 11:02:40 +0100 Subject: [PATCH 22/23] Merge with main --- src/tests/api/helpers.rs | 2 +- src/tests/api/model_logic.rs | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/tests/api/helpers.rs b/src/tests/api/helpers.rs index 3a1def9..f5b2040 100644 --- a/src/tests/api/helpers.rs +++ b/src/tests/api/helpers.rs @@ -74,7 +74,7 @@ mock! { } #[async_trait] impl AccessContextTrait for AccessContext { - async fn get_access_by_uid(&self, uid: i32) -> Result, DbErr>; + async fn get_access_by_uid_and_model_id(&self, uid: i32, model_id: i32) -> Result, DbErr>; } } diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index 0f17c68..1f8dda9 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -5,12 +5,9 @@ use sea_orm::DbErr; use tonic::{metadata, Code, Request}; use crate::api::auth::TokenType; -use crate::entities::{access, in_use, session}; -use crate::{ - api::server::server::{ - ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, - tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}, -}; +use crate::entities::{access, in_use, model, session}; +use crate::api::server::server::{ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, ModelInfo}; +use crate::tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}; #[tokio::test] async fn create_model_returns_ok() { From fb8df4c006e064e2046b9a50c85c57ba2aa3c325 Mon Sep 17 00:00:00 2001 From: Mads Risager Date: Wed, 29 Nov 2023 11:03:39 +0100 Subject: [PATCH 23/23] fm og t --- src/tests/api/model_logic.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/api/model_logic.rs b/src/tests/api/model_logic.rs index 1f8dda9..e6a2d88 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/model_logic.rs @@ -5,8 +5,10 @@ use sea_orm::DbErr; 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::api::server::server::{ecdar_api_server::EcdarApi, ComponentsInfo, CreateModelRequest, DeleteModelRequest, ModelInfo}; use crate::tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}; #[tokio::test]