diff --git a/Ecdar-ProtoBuf b/Ecdar-ProtoBuf index 6626d09..c7e1155 160000 --- a/Ecdar-ProtoBuf +++ b/Ecdar-ProtoBuf @@ -1 +1 @@ -Subproject commit 6626d096d9364f6c682a96b082c2f00d25d6419f +Subproject commit c7e115515797e9e6f39990f04e4fb6d41d73a2bd diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 361bfa6..c090e55 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -1,7 +1,7 @@ pub use sea_orm_migration::prelude::*; mod m20231012_094213_create_user_table; -mod m20231012_094228_create_model_table; +mod m20231012_094228_create_project_table; mod m20231012_094242_create_query_table; mod m20231012_094303_create_in_use_table; mod m20231012_094422_create_session_table; @@ -15,7 +15,7 @@ impl MigratorTrait for Migrator { fn migrations() -> Vec> { vec![ Box::new(m20231012_094213_create_user_table::Migration), - Box::new(m20231012_094228_create_model_table::Migration), + Box::new(m20231012_094228_create_project_table::Migration), Box::new(m20231012_094242_create_query_table::Migration), Box::new(m20231012_094422_create_session_table::Migration), Box::new(m20231012_094303_create_in_use_table::Migration), diff --git a/migration/src/m20231012_094228_create_model_table.rs b/migration/src/m20231012_094228_create_project_table.rs similarity index 67% rename from migration/src/m20231012_094228_create_model_table.rs rename to migration/src/m20231012_094228_create_project_table.rs index 1111237..eb8e42a 100644 --- a/migration/src/m20231012_094228_create_model_table.rs +++ b/migration/src/m20231012_094228_create_project_table.rs @@ -11,27 +11,27 @@ impl MigrationTrait for Migration { manager .create_table( Table::create() - .table(Model::Table) + .table(Project::Table) .if_not_exists() .col( - ColumnDef::new(Model::Id) + ColumnDef::new(Project::Id) .integer() .not_null() .auto_increment() .primary_key(), ) - .col(ColumnDef::new(Model::Name).string().not_null()) - .col(ColumnDef::new(Model::ComponentsInfo).json().not_null()) - .col(ColumnDef::new(Model::OwnerId).integer().not_null()) + .col(ColumnDef::new(Project::Name).string().not_null()) + .col(ColumnDef::new(Project::ComponentsInfo).json().not_null()) + .col(ColumnDef::new(Project::OwnerId).integer().not_null()) .index( Index::create() - .col(Model::OwnerId) - .col(Model::Name) + .col(Project::OwnerId) + .col(Project::Name) .unique(), ) .foreign_key( ForeignKey::create() - .from(Model::Table, Model::OwnerId) + .from(Project::Table, Project::OwnerId) .to(User::Table, User::Id) .on_delete(ForeignKeyAction::Cascade), ) @@ -42,13 +42,13 @@ impl MigrationTrait for Migration { async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { manager - .drop_table(Table::drop().table(Model::Table).to_owned()) + .drop_table(Table::drop().table(Project::Table).to_owned()) .await } } #[derive(DeriveIden)] -pub enum Model { +pub enum Project { Table, Id, Name, diff --git a/migration/src/m20231012_094242_create_query_table.rs b/migration/src/m20231012_094242_create_query_table.rs index d6d22f9..27c676d 100644 --- a/migration/src/m20231012_094242_create_query_table.rs +++ b/migration/src/m20231012_094242_create_query_table.rs @@ -1,6 +1,6 @@ use sea_orm_migration::prelude::*; -use super::m20231012_094228_create_model_table::Model; +use super::m20231012_094228_create_project_table::Project; #[derive(DeriveMigrationName)] pub struct Migration; @@ -28,11 +28,11 @@ impl MigrationTrait for Migration { .not_null() .default(true), ) - .col(ColumnDef::new(Query::ModelId).integer().not_null()) + .col(ColumnDef::new(Query::ProjectId).integer().not_null()) .foreign_key( ForeignKey::create() - .from(Query::Table, Query::ModelId) - .to(Model::Table, Model::Id) + .from(Query::Table, Query::ProjectId) + .to(Project::Table, Project::Id) .on_delete(ForeignKeyAction::Cascade), ) .to_owned(), @@ -53,6 +53,6 @@ enum Query { Id, String, Result, - ModelId, + ProjectId, Outdated, } diff --git a/migration/src/m20231012_094303_create_in_use_table.rs b/migration/src/m20231012_094303_create_in_use_table.rs index 6a40a79..2077ee9 100644 --- a/migration/src/m20231012_094303_create_in_use_table.rs +++ b/migration/src/m20231012_094303_create_in_use_table.rs @@ -1,6 +1,6 @@ use sea_orm_migration::prelude::*; -use super::m20231012_094228_create_model_table::Model; +use super::m20231012_094228_create_project_table::Project; use super::m20231012_094422_create_session_table::Session; #[derive(DeriveMigrationName)] @@ -15,7 +15,7 @@ impl MigrationTrait for Migration { .table(InUse::Table) .if_not_exists() .col( - ColumnDef::new(InUse::ModelId) + ColumnDef::new(InUse::ProjectId) .integer() .not_null() .primary_key(), @@ -29,8 +29,8 @@ impl MigrationTrait for Migration { ) .foreign_key( ForeignKey::create() - .from(InUse::Table, InUse::ModelId) - .to(Model::Table, Model::Id) + .from(InUse::Table, InUse::ProjectId) + .to(Project::Table, Project::Id) .on_delete(ForeignKeyAction::Cascade), ) .foreign_key( @@ -54,7 +54,7 @@ impl MigrationTrait for Migration { #[derive(DeriveIden)] enum InUse { Table, - ModelId, + ProjectId, SessionId, LatestActivity, } diff --git a/migration/src/m20231012_094533_create_access_table.rs b/migration/src/m20231012_094533_create_access_table.rs index f3d3aa2..c3dff0e 100644 --- a/migration/src/m20231012_094533_create_access_table.rs +++ b/migration/src/m20231012_094533_create_access_table.rs @@ -1,7 +1,7 @@ use sea_orm_migration::prelude::*; use super::m20231012_094213_create_user_table::User; -use super::m20231012_094228_create_model_table::Model; +use super::m20231012_094228_create_project_table::Project; use super::m20231111_205633_create_role_table::Role; #[derive(DeriveMigrationName)] @@ -23,11 +23,11 @@ impl MigrationTrait for Migration { .primary_key(), ) .col(ColumnDef::new(Access::Role).string().not_null()) - .col(ColumnDef::new(Access::ModelId).integer().not_null()) + .col(ColumnDef::new(Access::ProjectId).integer().not_null()) .col(ColumnDef::new(Access::UserId).integer().not_null()) .index( Index::create() - .col(Access::ModelId) + .col(Access::ProjectId) .col(Access::UserId) .unique(), ) @@ -39,8 +39,8 @@ impl MigrationTrait for Migration { ) .foreign_key( ForeignKey::create() - .from(Access::Table, Access::ModelId) - .to(Model::Table, Model::Id) + .from(Access::Table, Access::ProjectId) + .to(Project::Table, Project::Id) .on_delete(ForeignKeyAction::Cascade), ) .foreign_key( @@ -66,6 +66,6 @@ enum Access { Id, Table, Role, - ModelId, + ProjectId, UserId, } diff --git a/src/api/context_collection.rs b/src/api/context_collection.rs index 7e76c20..01b4ebc 100644 --- a/src/api/context_collection.rs +++ b/src/api/context_collection.rs @@ -2,7 +2,7 @@ use crate::api::hashing_context::HashingContextTrait; use crate::api::server::server::ecdar_backend_server::EcdarBackend; use crate::database::access_context::AccessContextTrait; use crate::database::in_use_context::InUseContextTrait; -use crate::database::model_context::ModelContextTrait; +use crate::database::project_context::ProjectContextTrait; use crate::database::query_context::QueryContextTrait; use crate::database::session_context::SessionContextTrait; use crate::database::user_context::UserContextTrait; @@ -12,7 +12,7 @@ use std::sync::Arc; pub struct ContextCollection { pub(crate) access_context: Arc, pub(crate) in_use_context: Arc, - pub(crate) model_context: Arc, + pub(crate) project_context: Arc, pub(crate) query_context: Arc, pub(crate) session_context: Arc, pub(crate) user_context: Arc, diff --git a/src/api/ecdar_api.rs b/src/api/ecdar_api.rs index 0af9ee1..29fa7bc 100644 --- a/src/api/ecdar_api.rs +++ b/src/api/ecdar_api.rs @@ -4,22 +4,24 @@ use super::server::server::{ ecdar_backend_server::EcdarBackend, get_auth_token_request::{user_credentials, UserCredentials}, get_users_response::UserInfo, - CreateAccessRequest, CreateModelRequest, CreateModelResponse, CreateQueryRequest, - CreateUserRequest, DeleteAccessRequest, DeleteModelRequest, DeleteQueryRequest, - GetAuthTokenRequest, GetAuthTokenResponse, GetModelRequest, GetModelResponse, GetUsersRequest, - GetUsersResponse, ListModelsInfoResponse, Query, QueryRequest, QueryResponse, SendQueryRequest, - SendQueryResponse, SimulationStartRequest, SimulationStepRequest, SimulationStepResponse, - UpdateAccessRequest, UpdateModelRequest, UpdateQueryRequest, UpdateUserRequest, - UserTokenResponse, + CreateAccessRequest, CreateAccessRequest, CreateProjectRequest, CreateProjectResponse, + CreateQueryRequest, CreateQueryRequest, CreateUserRequest, CreateUserRequest, + DeleteAccessRequest, DeleteAccessRequest, DeleteProjectRequest, DeleteQueryRequest, + DeleteQueryRequest, GetAuthTokenRequest, GetAuthTokenRequest, GetAuthTokenResponse, + GetAuthTokenResponse, GetProjectRequest, GetProjectResponse, GetUsersRequest, GetUsersResponse, + ListProjectsInfoResponse, Query, Query, QueryRequest, QueryRequest, QueryResponse, + QueryResponse, SendQueryRequest, SendQueryRequest, SendQueryResponse, SimulationStartRequest, + SimulationStepRequest, SimulationStepResponse, UpdateAccessRequest, UpdateProjectRequest, + UpdateQueryRequest, UpdateUserRequest, UserTokenResponse, }; use crate::api::auth::TokenError; use crate::api::context_collection::ContextCollection; use crate::api::{ auth::{RequestExt, Token, TokenType}, - server::server::Model, + server::server::Project, }; use crate::database::{session_context::SessionContextTrait, user_context::UserContextTrait}; -use crate::entities::{access, in_use, model, query, session, user}; +use crate::entities::{access, in_use, project, query, session, user}; use chrono::{Duration, Utc}; use regex::Regex; @@ -47,13 +49,13 @@ impl EcdarApi for ConcreteEcdarApi { /// /// If the Model is not in use, it will now be in use by the requestees session, /// given that they are an Editor. - async fn get_model( + async fn get_project( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let message = request.get_ref().clone(); - let model_id = message.id; + let project_id = message.id; let uid = request .uid() @@ -62,32 +64,35 @@ impl EcdarApi for ConcreteEcdarApi { let access = self .contexts .access_context - .get_access_by_uid_and_model_id(uid, model_id) + .get_access_by_uid_and_project_id(uid, project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| { - Status::new(Code::PermissionDenied, "User does not have access to model") + Status::new( + Code::PermissionDenied, + "User does not have access to project", + ) })?; - let model = self + let project = self .contexts - .model_context - .get_by_id(model_id) + .project_context + .get_by_id(project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| Status::new(Code::Internal, "Model not found"))?; - let model = Model { - id: model.id, - name: model.name, - components_info: serde_json::from_value(model.components_info).unwrap(), - owner_id: model.owner_id, + let project = Project { + id: project.id, + name: project.name, + components_info: serde_json::from_value(project.components_info).unwrap(), + owner_id: project.owner_id, }; let mut in_use_bool = true; - match self.contexts.in_use_context.get_by_id(model_id).await { + match self.contexts.in_use_context.get_by_id(project_id).await { Ok(Some(in_use)) => { - // If model is not in use and user is an Editor, update the in use with the users session. + // If project is not in use and user is an Editor, update the in use with the users session. if in_use.latest_activity <= (Utc::now().naive_utc() - Duration::minutes(IN_USE_DURATION_MINUTES)) { @@ -108,7 +113,7 @@ impl EcdarApi for ConcreteEcdarApi { })?; let in_use = in_use::Model { - model_id: in_use.model_id, + project_id: in_use.project_id, session_id: session.id, latest_activity: Utc::now().naive_utc(), }; @@ -121,14 +126,14 @@ impl EcdarApi for ConcreteEcdarApi { } } } - Ok(None) => return Err(Status::new(Code::Internal, "No in use found for model")), + Ok(None) => return Err(Status::new(Code::Internal, "No in use found for project")), Err(err) => return Err(Status::new(Code::Internal, err.to_string())), } let queries = self .contexts .query_context - .get_all_by_model_id(model_id) + .get_all_by_project_id(project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))?; @@ -136,7 +141,7 @@ impl EcdarApi for ConcreteEcdarApi { .into_iter() .map(|query| Query { id: query.id, - model_id: query.model_id, + project_id: query.project_id, query: query.string, result: match query.result { Some(result) => serde_json::from_value(result).unwrap(), @@ -146,17 +151,17 @@ impl EcdarApi for ConcreteEcdarApi { }) .collect::>(); - Ok(Response::new(GetModelResponse { - model: Some(model), + Ok(Response::new(GetProjectResponse { + project: Some(project), queries, in_use: in_use_bool, })) } - async fn create_model( + async fn create_project( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let message = request.get_ref().clone(); let uid = request .uid() @@ -167,20 +172,20 @@ impl EcdarApi for ConcreteEcdarApi { None => return Err(Status::invalid_argument("No components info provided")), }; - let mut model = model::Model { + let mut project = project::Model { id: Default::default(), name: message.clone().name, components_info, owner_id: uid, }; - model = match self.contexts.model_context.create(model).await { - Ok(model) => model, + project = match self.contexts.project_context.create(project).await { + Ok(project) => project, 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", + _ if e.contains("name") => "A project with that name already exists", _ => "Model already exists", }; println!("{}", e); @@ -189,7 +194,7 @@ impl EcdarApi for ConcreteEcdarApi { 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", + _ => "Could not create project", }; println!("{}", e); Err(Status::invalid_argument(error_msg)) @@ -202,7 +207,7 @@ impl EcdarApi for ConcreteEcdarApi { let access = access::Model { id: Default::default(), role: "Editor".to_string(), //todo!("Use role enum") - model_id: model.clone().id, + project_id: project.clone().id, user_id: uid, }; @@ -215,7 +220,7 @@ impl EcdarApi for ConcreteEcdarApi { .unwrap(); let in_use = in_use::Model { - model_id: model.clone().id, + project_id: project.clone().id, session_id: session.id, latest_activity: Default::default(), }; @@ -223,35 +228,35 @@ 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(CreateProjectResponse { id: project.id })) } /// Updates a Model in the database given its id. /// /// # Errors - /// This function will return an error if the model does not exist in the database - /// or if the user does not have access to the model with role 'Editor'. - async fn update_model( + /// This function will return an error if the project does not exist in the database + /// or if the user does not have access to the project with role 'Editor'. + async fn update_project( &self, - request: Request, + request: Request, ) -> Result, Status> { let message = request.get_ref().clone(); let uid = request .uid() .ok_or(Status::internal("Could not get uid from request metadata"))?; - // Check if the model exists - let model = match self.contexts.model_context.get_by_id(message.id).await { - Ok(Some(model)) => model, - Ok(None) => return Err(Status::not_found("No model found with given id")), + // Check if the project exists + let project = match self.contexts.project_context.get_by_id(message.id).await { + Ok(Some(project)) => project, + Ok(None) => return Err(Status::not_found("No project found with given id")), Err(error) => return Err(Status::internal(error.to_string())), }; - // Check if the user has access to the model + // Check if the user has access to the project match self .contexts .access_context - .get_access_by_uid_and_model_id(uid, model.id) + .get_access_by_uid_and_project_id(uid, project.id) .await { Ok(access) => { @@ -266,7 +271,7 @@ impl EcdarApi for ConcreteEcdarApi { if !is_editor || access.is_none() { return Err(Status::permission_denied( - "You do not have permission to update this model", + "You do not have permission to update this project", )); } } @@ -289,8 +294,8 @@ impl EcdarApi for ConcreteEcdarApi { Err(error) => return Err(Status::internal(error.to_string())), }; - // Get in_use for model - match self.contexts.in_use_context.get_by_id(model.id).await { + // Get in_use for project + match self.contexts.in_use_context.get_by_id(project.id).await { Ok(Some(in_use)) => { // Check if in_use latest activity is older than the max allowed if in_use.latest_activity @@ -303,7 +308,7 @@ impl EcdarApi for ConcreteEcdarApi { } let new_in_use = in_use::Model { - model_id: in_use.model_id, + project_id: in_use.project_id, session_id: session.id, latest_activity: Utc::now().naive_utc(), }; @@ -313,35 +318,35 @@ impl EcdarApi for ConcreteEcdarApi { Err(error) => return Err(Status::internal(error.to_string())), } } - Ok(None) => return Err(Status::internal("No in_use found for model")), + Ok(None) => return Err(Status::internal("No in_use found for project")), Err(error) => return Err(Status::internal(error.to_string())), }; - let new_model = model::Model { - id: model.id, + let new_project = project::Model { + id: project.id, name: match message.clone().name { Some(name) => name, - None => model.name, + None => project.name, }, components_info: match message.clone().components_info { Some(components_info) => serde_json::to_value(components_info).unwrap(), - None => model.components_info, + None => project.components_info, }, owner_id: match message.clone().owner_id { Some(new_owner_id) => { - if model.owner_id == uid { + if project.owner_id == uid { new_owner_id } else { return Err(Status::permission_denied( - "You do not have permission to change the owner of this model", + "You do not have permission to change the owner of this project", )); } } - None => model.owner_id, + None => project.owner_id, }, }; - match self.contexts.model_context.update(new_model).await { + match self.contexts.project_context.update(new_project).await { Ok(_) => Ok(Response::new(())), Err(error) => Err(Status::new(Code::Internal, error.to_string())), } @@ -350,32 +355,37 @@ impl EcdarApi for ConcreteEcdarApi { /// Deletes a Model from the database. /// /// # Errors - /// This function will return an error if the model does not exist in the database - /// or if the user is not the model owner. - async fn delete_model( + /// This function will return an error if the project does not exist in the database + /// or if the user is not the project owner. + async fn delete_project( &self, - request: Request, + request: Request, ) -> Result, Status> { let uid = request .uid() .ok_or(Status::internal("Could not get uid from request metadata"))?; - let model_id = request.get_ref().id; + let project_id = request.get_ref().id; - let model = match self.contexts.model_context.get_by_id(model_id).await { - Ok(Some(model)) => model, - Ok(None) => return Err(Status::new(Code::NotFound, "No model found with given id")), + let project = match self.contexts.project_context.get_by_id(project_id).await { + Ok(Some(project)) => project, + Ok(None) => { + return Err(Status::new( + Code::NotFound, + "No project found with given id", + )); + } Err(err) => return Err(Status::new(Code::Internal, err.to_string())), }; - // Check if user is owner and thereby has permission to delete model - if model.owner_id != uid { + // Check if user is owner and thereby has permission to delete project + if project.owner_id != uid { return Err(Status::new( Code::PermissionDenied, - "You do not have permission to delete this model", + "You do not have permission to delete this project", )); } - match self.contexts.model_context.delete(model_id).await { + match self.contexts.project_context.delete(project_id).await { Ok(_) => Ok(Response::new(())), Err(error) => match error { sea_orm::DbErr::RecordNotFound(message) => { @@ -386,28 +396,30 @@ impl EcdarApi for ConcreteEcdarApi { } } - async fn list_models_info( + async fn list_projects_info( &self, request: Request<()>, - ) -> Result, Status> { + ) -> Result, Status> { let uid = request .uid() .ok_or(Status::internal("Could not get uid from request metadata"))?; match self .contexts - .model_context - .get_models_info_by_uid(uid) + .project_context + .get_project_info_by_uid(uid) .await { - Ok(model_info_list) => { - if model_info_list.is_empty() { + Ok(project_info_list) => { + if project_info_list.is_empty() { return Err(Status::new( Code::NotFound, "No access found for given user", )); } else { - Ok(Response::new(ListModelsInfoResponse { model_info_list })) + Ok(Response::new(ListProjectsInfoResponse { + project_info_list, + })) } } Err(error) => Err(Status::new(Code::Internal, error.to_string())), @@ -426,7 +438,7 @@ impl EcdarApi for ConcreteEcdarApi { let access = access::Model { id: Default::default(), role: access.role.to_string(), - model_id: access.model_id, + project_id: access.project_id, user_id: access.user_id, }; @@ -442,7 +454,7 @@ impl EcdarApi for ConcreteEcdarApi { /// /// Returns a `Status` as response /// - /// `model_id` and `user_id` is set to 'default' since they won't be updated in the database. + /// `project_id` and `user_id` is set to 'default' since they won't be updated in the database. async fn update_access( &self, request: Request, @@ -452,7 +464,7 @@ impl EcdarApi for ConcreteEcdarApi { let access = access::Model { id: message.id, role: message.role, - model_id: Default::default(), + project_id: Default::default(), user_id: Default::default(), }; @@ -598,11 +610,14 @@ impl EcdarApi for ConcreteEcdarApi { let access = self .contexts .access_context - .get_access_by_uid_and_model_id(request.uid().unwrap(), query_request.model_id) + .get_access_by_uid_and_project_id(request.uid().unwrap(), query_request.project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| { - Status::new(Code::PermissionDenied, "User does not have access to model") + Status::new( + Code::PermissionDenied, + "User does not have access to project", + ) })?; if access.role != "Editor" { @@ -617,7 +632,7 @@ impl EcdarApi for ConcreteEcdarApi { string: query_request.string.to_string(), result: Default::default(), outdated: Default::default(), - model_id: query_request.model_id, + project_id: query_request.project_id, }; match self.contexts.query_context.create(query).await { @@ -652,11 +667,14 @@ impl EcdarApi for ConcreteEcdarApi { let access = self .contexts .access_context - .get_access_by_uid_and_model_id(request.uid().unwrap(), old_query.model_id) + .get_access_by_uid_and_project_id(request.uid().unwrap(), old_query.project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| { - Status::new(Code::PermissionDenied, "User does not have access to model") + Status::new( + Code::PermissionDenied, + "User does not have access to project", + ) })?; if access.role != "Editor" { @@ -668,7 +686,7 @@ impl EcdarApi for ConcreteEcdarApi { let query = query::Model { id: message.id, - model_id: Default::default(), + project_id: Default::default(), string: message.string, result: old_query.result, outdated: old_query.outdated, @@ -700,11 +718,14 @@ impl EcdarApi for ConcreteEcdarApi { let access = self .contexts .access_context - .get_access_by_uid_and_model_id(request.uid().unwrap(), query.model_id) + .get_access_by_uid_and_project_id(request.uid().unwrap(), query.project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| { - Status::new(Code::PermissionDenied, "User does not have access to model") + Status::new( + Code::PermissionDenied, + "User does not have access to project", + ) })?; if access.role != "Editor" { @@ -740,18 +761,21 @@ impl EcdarApi for ConcreteEcdarApi { // Verify user access self.contexts .access_context - .get_access_by_uid_and_model_id(uid, message.model_id) + .get_access_by_uid_and_project_id(uid, message.project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| { - Status::new(Code::PermissionDenied, "User does not have access to model") + Status::new( + Code::PermissionDenied, + "User does not have access to project", + ) })?; - // Get model from database - let model = self + // Get project from database + let project = self .contexts - .model_context - .get_by_id(message.model_id) + .project_context + .get_by_id(message.project_id) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))? .ok_or_else(|| Status::new(Code::NotFound, "Model not found"))?; @@ -770,7 +794,7 @@ impl EcdarApi for ConcreteEcdarApi { user_id: uid, query_id: message.id, query: query.string.clone(), - components_info: serde_json::from_value(model.components_info).unwrap(), + components_info: serde_json::from_value(project.components_info).unwrap(), settings: Default::default(), //TODO }); @@ -791,7 +815,7 @@ impl EcdarApi for ConcreteEcdarApi { serde_json::to_value(query_result.get_ref().result.clone().unwrap()).unwrap(), ), outdated: false, - model_id: query.model_id, + project_id: query.project_id, }) .await .map_err(|err| Status::new(Code::Internal, err.to_string()))?; @@ -1048,8 +1072,8 @@ mod query_logic_tests; mod access_logic_tests; #[cfg(test)] -#[path = "../tests/api/model_logic.rs"] -mod model_logic_tests; +#[path = "../tests/api/project_logic.rs"] +mod project_logic_tests; #[cfg(test)] #[path = "../tests/api/user_logic.rs"] diff --git a/src/build.rs b/src/build.rs index 34b7975..4f1834a 100644 --- a/src/build.rs +++ b/src/build.rs @@ -8,7 +8,7 @@ fn main() { "Component", "#[derive(serde::Serialize, serde::Deserialize)]", ) - .type_attribute("ModelInfo", "#[derive(sea_orm::FromQueryResult)]") + .type_attribute("ProjectInfo", "#[derive(sea_orm::FromQueryResult)]") .type_attribute("Error", "#[derive(serde::Serialize, serde::Deserialize)]") .type_attribute( "ComponentsNotInCache", diff --git a/src/database/access_context.rs b/src/database/access_context.rs index a1bad6b..c979d81 100644 --- a/src/database/access_context.rs +++ b/src/database/access_context.rs @@ -12,25 +12,25 @@ pub struct AccessContext { #[async_trait] pub trait AccessContextTrait: EntityContextTrait { - async fn get_access_by_uid_and_model_id( + async fn get_access_by_uid_and_project_id( &self, uid: i32, - model_id: i32, + project_id: i32, ) -> Result, DbErr>; } #[async_trait] impl AccessContextTrait for AccessContext { - async fn get_access_by_uid_and_model_id( + async fn get_access_by_uid_and_project_id( &self, uid: i32, - model_id: i32, + project_id: i32, ) -> Result, DbErr> { access::Entity::find() .filter( Condition::all() .add(access::Column::UserId.eq(uid)) - .add(access::Column::ModelId.eq(model_id)), + .add(access::Column::ProjectId.eq(project_id)), ) .one(&self.db_context.get_connection()) .await @@ -61,7 +61,7 @@ impl EntityContextTrait for AccessContext { let access = access::ActiveModel { id: Default::default(), role: Set(entity.role), - model_id: Set(entity.model_id), + project_id: Set(entity.project_id), user_id: Set(entity.user_id), }; let access: access::Model = access.insert(&self.db_context.get_connection()).await?; @@ -110,7 +110,7 @@ impl EntityContextTrait for AccessContext { access::ActiveModel { id: Unchanged(entity.id), role: Set(entity.role), - model_id: Unchanged(entity.model_id), + project_id: Unchanged(entity.project_id), user_id: Unchanged(entity.user_id), } .update(&self.db_context.get_connection()) diff --git a/src/database/in_use_context.rs b/src/database/in_use_context.rs index d2f78c1..f9b5d72 100644 --- a/src/database/in_use_context.rs +++ b/src/database/in_use_context.rs @@ -24,7 +24,7 @@ impl EntityContextTrait for InUseContext { /// Used for creating a Model entity async fn create(&self, entity: in_use::Model) -> Result { let in_use = in_use::ActiveModel { - model_id: Set(entity.model_id), + project_id: Set(entity.project_id), session_id: Set(entity.session_id), latest_activity: Set(Utc::now().naive_local()), }; @@ -46,7 +46,7 @@ impl EntityContextTrait for InUseContext { async fn update(&self, entity: in_use::Model) -> Result { in_use::ActiveModel { - model_id: Unchanged(entity.model_id), + project_id: Unchanged(entity.project_id), session_id: Set(entity.session_id), latest_activity: Set(entity.latest_activity), } diff --git a/src/database/mod.rs b/src/database/mod.rs index 3e2a418..23ee4dc 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -2,7 +2,7 @@ pub mod access_context; pub mod database_context; pub mod entity_context; pub mod in_use_context; -pub mod model_context; +pub mod project_context; pub mod query_context; pub mod session_context; pub mod user_context; diff --git a/src/database/model_context.rs b/src/database/model_context.rs deleted file mode 100644 index 0f710ca..0000000 --- a/src/database/model_context.rs +++ /dev/null @@ -1,158 +0,0 @@ -use crate::database::database_context::DatabaseContextTrait; -use crate::entities::{access, model, query}; - -use crate::api::server::server::ModelInfo; -use crate::EntityContextTrait; -use async_trait::async_trait; -use sea_orm::{ - ActiveModelTrait, ColumnTrait, DbErr, EntityTrait, IntoActiveModel, JoinType, ModelTrait, - QueryFilter, QuerySelect, RelationTrait, Set, Unchanged, -}; -use std::sync::Arc; - -pub struct ModelContext { - db_context: Arc, -} - -#[async_trait] -pub trait ModelContextTrait: EntityContextTrait { - async fn get_models_info_by_uid(&self, uid: i32) -> Result, DbErr>; -} - -#[async_trait] -impl ModelContextTrait for ModelContext { - async fn get_models_info_by_uid(&self, uid: i32) -> Result, DbErr> { - //join model, access and role tables - access::Entity::find() - .select_only() - .column_as(model::Column::Id, "model_id") - .column_as(model::Column::Name, "model_name") - .column_as(model::Column::OwnerId, "model_owner_id") - .column_as(access::Column::Role, "user_role_on_model") - .join(JoinType::InnerJoin, access::Relation::Model.def()) - .join(JoinType::InnerJoin, access::Relation::Role.def()) - .group_by(model::Column::Id) - .group_by(access::Column::Role) - .filter(access::Column::UserId.eq(uid)) - .into_model::() - .all(&self.db_context.get_connection()) - .await - } -} - -impl ModelContext { - pub fn new(db_context: Arc) -> ModelContext { - ModelContext { db_context } - } -} - -#[async_trait] -impl EntityContextTrait for ModelContext { - /// Used for creating a model::Model entity - /// # Example - /// ``` - /// let model = model::Model { - /// id: Default::default(), - /// name: "model::Model name".to_owned(), - /// components_info: "{}".to_owned().parse().unwrap(), - /// owner_id: 1 - /// }; - /// let model_context: ModelContext = ModelContext::new(...); - /// model_context.create(model); - /// ``` - async fn create(&self, entity: model::Model) -> Result { - let model = model::ActiveModel { - id: Default::default(), - name: Set(entity.name), - components_info: Set(entity.components_info), - owner_id: Set(entity.owner_id), - }; - let model: model::Model = model.insert(&self.db_context.get_connection()).await?; - Ok(model) - } - - /// Returns a single model entity (Uses primary key) - /// # Example - /// ``` - /// let model_context: ModelContext = ModelContext::new(...); - /// let model = model_context.get_by_id(1).unwrap(); - /// ``` - async fn get_by_id(&self, entity_id: i32) -> Result, DbErr> { - model::Entity::find_by_id(entity_id) - .one(&self.db_context.get_connection()) - .await - } - - /// Returns a all model entities (Uses primary key) - /// # Example - /// ``` - /// let model_context: ModelContext = ModelContext::new(...); - /// let model = model_context.get_all().unwrap(); - /// ``` - async fn get_all(&self) -> Result, DbErr> { - model::Entity::find() - .all(&self.db_context.get_connection()) - .await - } - - /// Updates a single model entity - /// # Example - /// ``` - /// let update_model = model::Model { - /// name: "new name", - /// ..original_model - /// }; - /// - /// let model_context: ModelContext = ModelContext::new(...); - /// let model = model_context.update(update_model).unwrap(); - /// ``` - async fn update(&self, entity: model::Model) -> Result { - let existing_model = self.get_by_id(entity.id).await?; - - return match existing_model { - None => Err(DbErr::RecordNotUpdated), - Some(existing_model) => { - let queries: Vec = existing_model - .find_related(query::Entity) - .all(&self.db_context.get_connection()) - .await?; - for q in queries.iter() { - let mut aq = q.clone().into_active_model(); - aq.outdated = Set(true); - aq.update(&self.db_context.get_connection()).await?; - } - model::ActiveModel { - id: Unchanged(entity.id), - name: Set(entity.name), - components_info: Set(entity.components_info), - owner_id: Unchanged(entity.id), - } - .update(&self.db_context.get_connection()) - .await - } - }; - } - - /// Returns and deletes a single model entity - /// # Example - /// ``` - /// let model_context: ModelContext = ModelContext::new(...); - /// let model = model_context.delete().unwrap(); - /// ``` - async fn delete(&self, entity_id: i32) -> Result { - let model = self.get_by_id(entity_id).await?; - match model { - None => Err(DbErr::RecordNotFound("No record was deleted".into())), - Some(model) => { - model::Entity::delete_by_id(entity_id) - .exec(&self.db_context.get_connection()) - .await?; - Ok(model) - } - } - } -} - -#[cfg(test)] -#[path = "../tests/database/model_context.rs"] -mod model_context_tests; diff --git a/src/database/project_context.rs b/src/database/project_context.rs new file mode 100644 index 0000000..2e19580 --- /dev/null +++ b/src/database/project_context.rs @@ -0,0 +1,158 @@ +use crate::database::database_context::DatabaseContextTrait; +use crate::entities::{access, project, query}; + +use crate::api::server::server::ProjectInfo; +use crate::EntityContextTrait; +use async_trait::async_trait; +use sea_orm::{ + ActiveModelTrait, ColumnTrait, DbErr, EntityTrait, IntoActiveModel, JoinType, ModelTrait, + QueryFilter, QuerySelect, RelationTrait, Set, Unchanged, +}; +use std::sync::Arc; + +pub struct ProjectContext { + db_context: Arc, +} + +#[async_trait] +pub trait ProjectContextTrait: EntityContextTrait { + async fn get_project_info_by_uid(&self, uid: i32) -> Result, DbErr>; +} + +#[async_trait] +impl ProjectContextTrait for ProjectContext { + async fn get_project_info_by_uid(&self, uid: i32) -> Result, DbErr> { + //join project, access and role tables + access::Entity::find() + .select_only() + .column_as(project::Column::Id, "project_id") + .column_as(project::Column::Name, "project_name") + .column_as(project::Column::OwnerId, "project_owner_id") + .column_as(access::Column::Role, "user_role_on_project") + .join(JoinType::InnerJoin, access::Relation::Project.def()) + .join(JoinType::InnerJoin, access::Relation::Role.def()) + .group_by(project::Column::Id) + .group_by(access::Column::Role) + .filter(access::Column::UserId.eq(uid)) + .into_model::() + .all(&self.db_context.get_connection()) + .await + } +} + +impl ProjectContext { + pub fn new(db_context: Arc) -> ProjectContext { + ProjectContext { db_context } + } +} + +#[async_trait] +impl EntityContextTrait for ProjectContext { + /// Used for creating a project::Model entity + /// # Example + /// ``` + /// let project = project::Model { + /// id: Default::default(), + /// name: "project::Model name".to_owned(), + /// components_info: "{}".to_owned().parse().unwrap(), + /// owner_id: 1 + /// }; + /// let project_context: ProjectContext = ProjectContext::new(...); + /// project_context.create(project); + /// ``` + async fn create(&self, entity: project::Model) -> Result { + let project = project::ActiveModel { + id: Default::default(), + name: Set(entity.name), + components_info: Set(entity.components_info), + owner_id: Set(entity.owner_id), + }; + let project: project::Model = project.insert(&self.db_context.get_connection()).await?; + Ok(project) + } + + /// Returns a single project entity (Uses primary key) + /// # Example + /// ``` + /// let project_context: ProjectContext = ProjectContext::new(...); + /// let project = project_context.get_by_id(1).unwrap(); + /// ``` + async fn get_by_id(&self, entity_id: i32) -> Result, DbErr> { + project::Entity::find_by_id(entity_id) + .one(&self.db_context.get_connection()) + .await + } + + /// Returns a all project entities (Uses primary key) + /// # Example + /// ``` + /// let project_context: ProjectContext = ProjectContext::new(...); + /// let project = project_context.get_all().unwrap(); + /// ``` + async fn get_all(&self) -> Result, DbErr> { + project::Entity::find() + .all(&self.db_context.get_connection()) + .await + } + + /// Updates a single project entity + /// # Example + /// ``` + /// let update_project = project::Model { + /// name: "new name", + /// ..original_project + /// }; + /// + /// let project_context: ProjectContext = ProjectContext::new(...); + /// let project = project_context.update(update_project).unwrap(); + /// ``` + async fn update(&self, entity: project::Model) -> Result { + let existing_project = self.get_by_id(entity.id).await?; + + return match existing_project { + None => Err(DbErr::RecordNotUpdated), + Some(existing_project) => { + let queries: Vec = existing_project + .find_related(query::Entity) + .all(&self.db_context.get_connection()) + .await?; + for q in queries.iter() { + let mut aq = q.clone().into_active_model(); + aq.outdated = Set(true); + aq.update(&self.db_context.get_connection()).await?; + } + project::ActiveModel { + id: Unchanged(entity.id), + name: Set(entity.name), + components_info: Set(entity.components_info), + owner_id: Unchanged(entity.id), + } + .update(&self.db_context.get_connection()) + .await + } + }; + } + + /// Returns and deletes a single project entity + /// # Example + /// ``` + /// let project_context: ProjectContext = ProjectContext::new(...); + /// let project = project_context.delete().unwrap(); + /// ``` + async fn delete(&self, entity_id: i32) -> Result { + let project = self.get_by_id(entity_id).await?; + match project { + None => Err(DbErr::RecordNotFound("No record was deleted".into())), + Some(project) => { + project::Entity::delete_by_id(entity_id) + .exec(&self.db_context.get_connection()) + .await?; + Ok(project) + } + } + } +} + +#[cfg(test)] +#[path = "../tests/database/project_context.rs"] +mod project_context_tests; diff --git a/src/database/query_context.rs b/src/database/query_context.rs index f87abff..682fbe0 100644 --- a/src/database/query_context.rs +++ b/src/database/query_context.rs @@ -12,14 +12,14 @@ pub struct QueryContext { #[async_trait] pub trait QueryContextTrait: EntityContextTrait { - async fn get_all_by_model_id(&self, model_id: i32) -> Result, DbErr>; + async fn get_all_by_project_id(&self, project_id: i32) -> Result, DbErr>; } #[async_trait] impl QueryContextTrait for QueryContext { - async fn get_all_by_model_id(&self, model_id: i32) -> Result, DbErr> { + async fn get_all_by_project_id(&self, project_id: i32) -> Result, DbErr> { query::Entity::find() - .filter(query::Column::ModelId.eq(model_id)) + .filter(query::Column::ProjectId.eq(project_id)) .all(&self.db_context.get_connection()) .await } @@ -50,7 +50,7 @@ impl EntityContextTrait for QueryContext { let query = query::ActiveModel { id: Default::default(), string: Set(entity.string), - model_id: Set(entity.model_id), + project_id: Set(entity.project_id), result: NotSet, outdated: NotSet, }; @@ -112,7 +112,7 @@ impl EntityContextTrait for QueryContext { string: Set(entity.string), result: Set(entity.result), outdated: Set(entity.outdated), - model_id: Unchanged(entity.model_id), + project_id: Unchanged(entity.project_id), } .update(&self.db_context.get_connection()) .await diff --git a/src/database/user_context.rs b/src/database/user_context.rs index 42c2aff..9584665 100644 --- a/src/database/user_context.rs +++ b/src/database/user_context.rs @@ -58,14 +58,14 @@ impl EntityContextTrait for UserContext { /// Used for creating a User entity /// # Example /// ``` - /// let model : Model = { + /// let user : Model = { /// id: Default::default(), /// email: "anders@aau.dk".into(), /// username: "Anders".into(), /// password: "qwerty".into() /// } /// let context : UserContext = UserContext::new(...); - /// context.create(model); + /// context.create(user); /// ``` async fn create(&self, entity: user::Model) -> Result { let user = user::ActiveModel { @@ -82,8 +82,8 @@ impl EntityContextTrait for UserContext { /// # Example /// ``` /// let context : UserContext = UserContext::new(...); - /// let model : Model = context.get_by_id(1).unwrap(); - /// assert_eq!(model.username,"Anders".into()); + /// let user : Model = context.get_by_id(1).unwrap(); + /// assert_eq!(user.username,"Anders".into()); /// ``` async fn get_by_id(&self, entity_id: i32) -> Result, DbErr> { user::Entity::find_by_id(entity_id) @@ -95,8 +95,8 @@ impl EntityContextTrait for UserContext { /// # Example /// ``` /// let context : UserContext = UserContext::new(...); - /// let model : vec = context.get_all().unwrap(); - /// assert_eq!(model.len(),1); + /// let user : vec = context.get_all().unwrap(); + /// assert_eq!(user.len(),1); /// ``` async fn get_all(&self) -> Result, DbErr> { user::Entity::find() diff --git a/src/entities/access.rs b/src/entities/access.rs index ff60d08..e3bfdc4 100644 --- a/src/entities/access.rs +++ b/src/entities/access.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; @@ -8,20 +8,20 @@ pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub role: String, - pub model_id: i32, + pub project_id: i32, pub user_id: i32, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { #[sea_orm( - belongs_to = "super::model::Entity", - from = "Column::ModelId", - to = "super::model::Column::Id", + belongs_to = "super::project::Entity", + from = "Column::ProjectId", + to = "super::project::Column::Id", on_update = "NoAction", on_delete = "Cascade" )] - Model, + Project, #[sea_orm( belongs_to = "super::role::Entity", from = "Column::Role", @@ -40,9 +40,9 @@ pub enum Relation { User, } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::Model.def() + Relation::Project.def() } } diff --git a/src/entities/in_use.rs b/src/entities/in_use.rs index 5716499..f543374 100644 --- a/src/entities/in_use.rs +++ b/src/entities/in_use.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; @@ -6,7 +6,7 @@ use sea_orm::entity::prelude::*; #[sea_orm(table_name = "in_use")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] - pub model_id: i32, + pub project_id: i32, pub session_id: i32, pub latest_activity: DateTime, } @@ -14,13 +14,13 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { #[sea_orm( - belongs_to = "super::model::Entity", - from = "Column::ModelId", - to = "super::model::Column::Id", + belongs_to = "super::project::Entity", + from = "Column::ProjectId", + to = "super::project::Column::Id", on_update = "NoAction", on_delete = "Cascade" )] - Model, + Project, #[sea_orm( belongs_to = "super::session::Entity", from = "Column::SessionId", @@ -31,9 +31,9 @@ pub enum Relation { Session, } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::Model.def() + Relation::Project.def() } } diff --git a/src/entities/mod.rs b/src/entities/mod.rs index c9f558e..7b1a53f 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -1,10 +1,10 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 pub mod prelude; pub mod access; pub mod in_use; -pub mod model; +pub mod project; pub mod query; pub mod role; pub mod session; diff --git a/src/entities/prelude.rs b/src/entities/prelude.rs index 5385e4d..81d4066 100644 --- a/src/entities/prelude.rs +++ b/src/entities/prelude.rs @@ -1,8 +1,8 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 pub use super::access::Entity as Access; pub use super::in_use::Entity as InUse; -pub use super::model::Entity as Model; +pub use super::project::Entity as Project; pub use super::query::Entity as Query; pub use super::role::Entity as Role; pub use super::session::Entity as Session; diff --git a/src/entities/model.rs b/src/entities/project.rs similarity index 92% rename from src/entities/model.rs rename to src/entities/project.rs index f33954a..b3d9e75 100644 --- a/src/entities/model.rs +++ b/src/entities/project.rs @@ -1,9 +1,9 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "model")] +#[sea_orm(table_name = "project")] pub struct Model { #[sea_orm(primary_key)] pub id: i32, diff --git a/src/entities/query.rs b/src/entities/query.rs index be729a3..1460949 100644 --- a/src/entities/query.rs +++ b/src/entities/query.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; @@ -10,24 +10,24 @@ pub struct Model { pub string: String, pub result: Option, pub outdated: bool, - pub model_id: i32, + pub project_id: i32, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { #[sea_orm( - belongs_to = "super::model::Entity", - from = "Column::ModelId", - to = "super::model::Column::Id", + belongs_to = "super::project::Entity", + from = "Column::ProjectId", + to = "super::project::Column::Id", on_update = "NoAction", on_delete = "Cascade" )] - Model, + Project, } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::Model.def() + Relation::Project.def() } } diff --git a/src/entities/role.rs b/src/entities/role.rs index 9d1505f..311faf1 100644 --- a/src/entities/role.rs +++ b/src/entities/role.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; diff --git a/src/entities/session.rs b/src/entities/session.rs index 5eff426..ae6b51f 100644 --- a/src/entities/session.rs +++ b/src/entities/session.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; diff --git a/src/entities/user.rs b/src/entities/user.rs index 2e3a7ac..52821a4 100644 --- a/src/entities/user.rs +++ b/src/entities/user.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.5 use sea_orm::entity::prelude::*; @@ -18,8 +18,8 @@ pub struct Model { pub enum Relation { #[sea_orm(has_many = "super::access::Entity")] Access, - #[sea_orm(has_many = "super::model::Entity")] - Model, + #[sea_orm(has_many = "super::project::Entity")] + Project, #[sea_orm(has_many = "super::session::Entity")] Session, } @@ -30,9 +30,9 @@ impl Related for Entity { } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::Model.def() + Relation::Project.def() } } diff --git a/src/main.rs b/src/main.rs index 15bbcd4..ed4a191 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use crate::api::reveaal_context::ReveaalContext; use crate::database::access_context::AccessContext; use crate::database::database_context::{PostgresDatabaseContext, SQLiteDatabaseContext}; use crate::database::in_use_context::InUseContext; -use crate::database::model_context::ModelContext; +use crate::database::project_context::ProjectContext; use crate::database::query_context::QueryContext; use crate::database::session_context::SessionContext; use crate::database::user_context::UserContext; @@ -37,7 +37,7 @@ async fn main() -> Result<(), Box> { let contexts = ContextCollection { access_context: Arc::new(AccessContext::new(db_context.clone())), in_use_context: Arc::new(InUseContext::new(db_context.clone())), - model_context: Arc::new(ModelContext::new(db_context.clone())), + project_context: Arc::new(ProjectContext::new(db_context.clone())), query_context: Arc::new(QueryContext::new(db_context.clone())), session_context: Arc::new(SessionContext::new(db_context.clone())), user_context: Arc::new(UserContext::new(db_context.clone())), diff --git a/src/tests/api/access_logic.rs b/src/tests/api/access_logic.rs index 4515825..0040c85 100644 --- a/src/tests/api/access_logic.rs +++ b/src/tests/api/access_logic.rs @@ -13,7 +13,7 @@ async fn create_invalid_access_returns_err() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; @@ -25,7 +25,7 @@ async fn create_invalid_access_returns_err() { let request = Request::new(CreateAccessRequest { role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }); @@ -43,7 +43,7 @@ async fn create_access_returns_ok() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; @@ -55,7 +55,7 @@ async fn create_access_returns_ok() { let request = Request::new(CreateAccessRequest { role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }); @@ -73,7 +73,7 @@ async fn update_invalid_access_returns_err() { let access = access::Model { id: 1, role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: Default::default(), }; @@ -102,7 +102,7 @@ async fn update_access_returns_ok() { let access = access::Model { id: 1, role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: Default::default(), }; @@ -150,7 +150,7 @@ async fn delete_access_returns_ok() { let access = access::Model { id: 1, role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: Default::default(), }; diff --git a/src/tests/api/helpers.rs b/src/tests/api/helpers.rs index 0d4edb2..8f41df8 100644 --- a/src/tests/api/helpers.rs +++ b/src/tests/api/helpers.rs @@ -5,7 +5,7 @@ use crate::api::context_collection::ContextCollection; use crate::api::ecdar_api::ConcreteEcdarApi; use crate::api::hashing_context::HashingContextTrait; use crate::api::server::server::ecdar_backend_server::EcdarBackend; -use crate::api::server::server::ModelInfo; +use crate::api::server::server::ProjectInfo; use crate::api::server::server::{ QueryRequest, QueryResponse, SimulationStartRequest, SimulationStepRequest, SimulationStepResponse, UserTokenResponse, @@ -13,11 +13,11 @@ use crate::api::server::server::{ use crate::database::access_context::AccessContextTrait; use crate::database::entity_context::EntityContextTrait; use crate::database::in_use_context::InUseContextTrait; -use crate::database::model_context::ModelContextTrait; +use crate::database::project_context::ProjectContextTrait; use crate::database::query_context::QueryContextTrait; use crate::database::session_context::SessionContextTrait; use crate::database::user_context::UserContextTrait; -use crate::entities::{access, in_use, model, query, session, user}; +use crate::entities::{access, in_use, project, query, session, user}; use async_trait::async_trait; use mockall::mock; use sea_orm::DbErr; @@ -28,7 +28,7 @@ pub fn get_mock_concrete_ecdar_api(mock_services: MockServices) -> ConcreteEcdar let contexts = ContextCollection { access_context: Arc::new(mock_services.access_context_mock), in_use_context: Arc::new(mock_services.in_use_context_mock), - model_context: Arc::new(mock_services.model_context_mock), + project_context: Arc::new(mock_services.project_context_mock), query_context: Arc::new(mock_services.query_context_mock), session_context: Arc::new(mock_services.session_context_mock), user_context: Arc::new(mock_services.user_context_mock), @@ -42,7 +42,7 @@ pub fn get_mock_services() -> MockServices { MockServices { access_context_mock: MockAccessContext::new(), in_use_context_mock: MockInUseContext::new(), - model_context_mock: MockModelContext::new(), + project_context_mock: MockProjectContext::new(), query_context_mock: MockQueryContext::new(), session_context_mock: MockSessionContext::new(), user_context_mock: MockUserContext::new(), @@ -54,7 +54,7 @@ pub fn get_mock_services() -> MockServices { pub struct MockServices { pub(crate) access_context_mock: MockAccessContext, pub(crate) in_use_context_mock: MockInUseContext, - pub(crate) model_context_mock: MockModelContext, + pub(crate) project_context_mock: MockProjectContext, pub(crate) query_context_mock: MockQueryContext, pub(crate) session_context_mock: MockSessionContext, pub(crate) user_context_mock: MockUserContext, @@ -74,10 +74,10 @@ mock! { } #[async_trait] impl AccessContextTrait for AccessContext { - async fn get_access_by_uid_and_model_id( + async fn get_access_by_uid_and_project_id( &self, uid: i32, - model_id: i32, + project_id: i32, ) -> Result, DbErr>; } } @@ -97,18 +97,18 @@ mock! { } mock! { - pub ModelContext {} + pub ProjectContext {} #[async_trait] - impl EntityContextTrait for ModelContext { - async fn create(&self, entity: model::Model) -> Result; - async fn get_by_id(&self, entity_id: i32) -> Result, DbErr>; - async fn get_all(&self) -> Result, DbErr>; - async fn update(&self, entity: model::Model) -> Result; - async fn delete(&self, entity_id: i32) -> Result; + impl EntityContextTrait for ProjectContext { + async fn create(&self, entity: project::Model) -> Result; + async fn get_by_id(&self, entity_id: i32) -> Result, DbErr>; + async fn get_all(&self) -> Result, DbErr>; + async fn update(&self, entity: project::Model) -> Result; + async fn delete(&self, entity_id: i32) -> Result; } #[async_trait] - impl ModelContextTrait for ModelContext { - async fn get_models_info_by_uid(&self, uid: i32) -> Result, DbErr>; + impl ProjectContextTrait for ProjectContext { + async fn get_project_info_by_uid(&self, uid: i32) -> Result, DbErr>; } } @@ -124,12 +124,7 @@ mock! { } #[async_trait] impl QueryContextTrait for QueryContext { - async fn get_all_by_model_id(&self, model_id: i32) -> Result, DbErr> { - query::Entity::find() - .filter(query::Column::ModelId.eq(model_id)) - .all(&self.db_context.get_connection()) - .await - } + async fn get_all_by_project_id(&self, project_id: i32) -> Result, DbErr>; } } diff --git a/src/tests/api/model_logic.rs b/src/tests/api/project_logic.rs similarity index 75% rename from src/tests/api/model_logic.rs rename to src/tests/api/project_logic.rs index 54518c2..b0b88e8 100644 --- a/src/tests/api/model_logic.rs +++ b/src/tests/api/project_logic.rs @@ -3,10 +3,11 @@ use crate::{ auth::TokenType, server::server::{ component::Rep, ecdar_api_server::EcdarApi, Component, ComponentsInfo, - CreateModelRequest, DeleteModelRequest, GetModelRequest, ModelInfo, UpdateModelRequest, + CreateProjectRequest, DeleteProjectRequest, GetProjectRequest, ProjectInfo, + UpdateProjectRequest, }, }, - entities::{access, in_use, model, query, session}, + entities::{access, in_use, project, query, session}, tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}, }; use chrono::Utc; @@ -16,7 +17,7 @@ use std::str::FromStr; use tonic::{metadata, Code, Request}; #[tokio::test] -async fn create_model_returns_ok() { +async fn create_project_returns_ok() { let mut mock_services = get_mock_services(); let uid = 0; @@ -26,7 +27,7 @@ async fn create_model_returns_ok() { components_hash: 0, }; - let model = model::Model { + let project = project::Model { id: Default::default(), name: Default::default(), components_info: serde_json::to_value(components_info.clone()).unwrap(), @@ -37,7 +38,7 @@ async fn create_model_returns_ok() { id: Default::default(), role: "Editor".to_string(), user_id: uid, - model_id: model.id, + project_id: project.id, }; let session = session::Model { @@ -49,16 +50,16 @@ async fn create_model_returns_ok() { }; let in_use = in_use::Model { - model_id: model.id, + project_id: project.id, session_id: session.id, latest_activity: Default::default(), }; mock_services - .model_context_mock + .project_context_mock .expect_create() - .with(predicate::eq(model.clone())) - .returning(move |_| Ok(model.clone())); + .with(predicate::eq(project.clone())) + .returning(move |_| Ok(project.clone())); mock_services .access_context_mock @@ -81,7 +82,7 @@ async fn create_model_returns_ok() { .with(predicate::eq(in_use.clone())) .returning(move |_| Ok(in_use.clone())); - let mut request = Request::new(CreateModelRequest { + let mut request = Request::new(CreateProjectRequest { name: Default::default(), components_info: Option::from(components_info), }); @@ -97,32 +98,32 @@ async fn create_model_returns_ok() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.create_model(request).await; + let res = api.create_project(request).await; assert!(res.is_ok()); } #[tokio::test] -async fn create_model_existing_name_returns_err() { +async fn create_project_existing_name_returns_err() { let mut mock_services = get_mock_services(); let uid = 0; - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: uid, }; mock_services - .model_context_mock + .project_context_mock .expect_create() - .with(predicate::eq(model.clone())) + .with(predicate::eq(project.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(), + let mut request = Request::new(CreateProjectRequest { + name: "project".to_string(), components_info: Default::default(), }); @@ -132,18 +133,18 @@ async fn create_model_existing_name_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.create_model(request).await; + let res = api.create_project(request).await; assert_eq!(res.unwrap_err().code(), Code::InvalidArgument); //todo!("Needs to be code AlreadyExists when mocked Error is corrected) } #[tokio::test] -async fn get_model_user_has_access_returns_ok() { +async fn get_project_user_has_access_returns_ok() { let mut mock_services = get_mock_services(); - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; @@ -151,12 +152,12 @@ async fn get_model_user_has_access_returns_ok() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; let in_use = in_use::Model { - model_id: Default::default(), + project_id: Default::default(), session_id: 0, latest_activity: Utc::now().naive_utc(), }; @@ -165,15 +166,15 @@ async fn get_model_user_has_access_returns_ok() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(0), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .in_use_context_mock @@ -183,17 +184,17 @@ async fn get_model_user_has_access_returns_ok() { mock_services .query_context_mock - .expect_get_all_by_model_id() + .expect_get_all_by_project_id() .with(predicate::eq(0)) .returning(move |_| Ok(queries.clone())); - let mut request = Request::new(GetModelRequest { id: 0 }); + let mut request = Request::new(GetProjectRequest { id: 0 }); request.metadata_mut().insert("uid", "0".parse().unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.get_model(request).await; + let res = api.get_project(request).await; assert!(res.is_ok()); } @@ -203,11 +204,11 @@ async fn delete_not_owner_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -215,7 +216,7 @@ async fn delete_not_owner_returns_err() { })) }); - let mut request = Request::new(DeleteModelRequest { id: 1 }); + let mut request = Request::new(DeleteProjectRequest { id: 1 }); request .metadata_mut() @@ -223,22 +224,22 @@ async fn delete_not_owner_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.delete_model(request).await.unwrap_err(); + let res = api.delete_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::PermissionDenied); } #[tokio::test] -async fn delete_invalid_model_returns_err() { +async fn delete_invalid_project_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(2)) .returning(move |_| Ok(None)); - let mut request = Request::new(DeleteModelRequest { id: 2 }); + let mut request = Request::new(DeleteProjectRequest { id: 2 }); request .metadata_mut() @@ -246,21 +247,21 @@ async fn delete_invalid_model_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.delete_model(request).await.unwrap_err(); + let res = api.delete_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::NotFound); } #[tokio::test] -async fn delete_model_returns_ok() { +async fn delete_project_returns_ok() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -269,11 +270,11 @@ async fn delete_model_returns_ok() { }); mock_services - .model_context_mock + .project_context_mock .expect_delete() .with(predicate::eq(1)) .returning(move |_| { - Ok(model::Model { + Ok(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -281,7 +282,7 @@ async fn delete_model_returns_ok() { }) }); - let mut request = Request::new(DeleteModelRequest { id: 1 }); + let mut request = Request::new(DeleteProjectRequest { id: 1 }); request .metadata_mut() @@ -289,24 +290,24 @@ async fn delete_model_returns_ok() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.delete_model(request).await; + let res = api.delete_project(request).await; assert!(res.is_ok()); } #[tokio::test] -async fn get_model_user_has_no_access_returns_err() { +async fn get_project_user_has_no_access_returns_err() { let mut mock_services = get_mock_services(); - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; let in_use = in_use::Model { - model_id: Default::default(), + project_id: Default::default(), session_id: 0, latest_activity: Default::default(), }; @@ -315,15 +316,15 @@ async fn get_model_user_has_no_access_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(0), predicate::eq(0)) .returning(move |_, _| Ok(None)); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .in_use_context_mock @@ -333,28 +334,28 @@ async fn get_model_user_has_no_access_returns_err() { mock_services .query_context_mock - .expect_get_all_by_model_id() + .expect_get_all_by_project_id() .with(predicate::eq(0)) .returning(move |_| Ok(queries.clone())); - let mut request = Request::new(GetModelRequest { id: 0 }); + let mut request = Request::new(GetProjectRequest { id: 0 }); request.metadata_mut().insert("uid", "0".parse().unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.get_model(request).await.unwrap_err(); + let res = api.get_project(request).await.unwrap_err(); assert!(res.code() == Code::PermissionDenied); } #[tokio::test] -async fn get_model_is_in_use_is_true() { +async fn get_project_is_in_use_is_true() { let mut mock_services = get_mock_services(); - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; @@ -362,12 +363,12 @@ async fn get_model_is_in_use_is_true() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; let in_use = in_use::Model { - model_id: Default::default(), + project_id: Default::default(), session_id: 0, latest_activity: Utc::now().naive_utc(), }; @@ -376,15 +377,15 @@ async fn get_model_is_in_use_is_true() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(0), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .in_use_context_mock @@ -394,28 +395,28 @@ async fn get_model_is_in_use_is_true() { mock_services .query_context_mock - .expect_get_all_by_model_id() + .expect_get_all_by_project_id() .with(predicate::eq(0)) .returning(move |_| Ok(queries.clone())); - let mut request = Request::new(GetModelRequest { id: 0 }); + let mut request = Request::new(GetProjectRequest { id: 0 }); request.metadata_mut().insert("uid", "0".parse().unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.get_model(request).await; + let res = api.get_project(request).await; assert!(res.unwrap().get_ref().in_use); } #[tokio::test] -async fn get_model_is_in_use_is_false() { +async fn get_project_is_in_use_is_false() { let mut mock_services = get_mock_services(); - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; @@ -423,18 +424,18 @@ async fn get_model_is_in_use_is_false() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; let in_use = in_use::Model { - model_id: 0, + project_id: 0, session_id: 0, latest_activity: Default::default(), }; let updated_in_use = in_use::Model { - model_id: 0, + project_id: 0, session_id: 1, latest_activity: Default::default(), }; @@ -451,15 +452,15 @@ async fn get_model_is_in_use_is_false() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(0), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .in_use_context_mock @@ -478,7 +479,7 @@ async fn get_model_is_in_use_is_false() { mock_services .query_context_mock - .expect_get_all_by_model_id() + .expect_get_all_by_project_id() .with(predicate::eq(0)) .returning(move |_| Ok(queries.clone())); @@ -487,7 +488,7 @@ async fn get_model_is_in_use_is_false() { .expect_update() .returning(move |_| Ok(updated_in_use.clone())); - let mut request = Request::new(GetModelRequest { id: 0 }); + let mut request = Request::new(GetProjectRequest { id: 0 }); request .metadata_mut() @@ -496,18 +497,18 @@ async fn get_model_is_in_use_is_false() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.get_model(request).await; + let res = api.get_project(request).await; assert!(!res.unwrap().get_ref().in_use); } #[tokio::test] -async fn get_model_model_has_no_queries_queries_are_empty() { +async fn get_project_project_has_no_queries_queries_are_empty() { let mut mock_services = get_mock_services(); - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; @@ -515,12 +516,12 @@ async fn get_model_model_has_no_queries_queries_are_empty() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; let in_use = in_use::Model { - model_id: Default::default(), + project_id: Default::default(), session_id: 0, latest_activity: Utc::now().naive_utc(), }; @@ -529,15 +530,15 @@ async fn get_model_model_has_no_queries_queries_are_empty() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(0), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .in_use_context_mock @@ -547,28 +548,28 @@ async fn get_model_model_has_no_queries_queries_are_empty() { mock_services .query_context_mock - .expect_get_all_by_model_id() + .expect_get_all_by_project_id() .with(predicate::eq(0)) .returning(move |_| Ok(queries.clone())); - let mut request = Request::new(GetModelRequest { id: 0 }); + let mut request = Request::new(GetProjectRequest { id: 0 }); request.metadata_mut().insert("uid", "0".parse().unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.get_model(request).await; + let res = api.get_project(request).await; assert!(res.unwrap().get_ref().queries.is_empty()); } #[tokio::test] -async fn get_model_query_has_no_result_query_is_empty() { +async fn get_project_query_has_no_result_query_is_empty() { let mut mock_services = get_mock_services(); - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; @@ -576,19 +577,19 @@ async fn get_model_query_has_no_result_query_is_empty() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; let in_use = in_use::Model { - model_id: Default::default(), + project_id: Default::default(), session_id: 0, latest_activity: Utc::now().naive_utc(), }; let query = query::Model { id: 0, - model_id: 1, + project_id: 1, string: "query".to_owned(), result: None, outdated: false, @@ -598,15 +599,15 @@ async fn get_model_query_has_no_result_query_is_empty() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(0), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .in_use_context_mock @@ -616,70 +617,70 @@ async fn get_model_query_has_no_result_query_is_empty() { mock_services .query_context_mock - .expect_get_all_by_model_id() + .expect_get_all_by_project_id() .with(predicate::eq(0)) .returning(move |_| Ok(queries.clone())); - let mut request = Request::new(GetModelRequest { id: 0 }); + let mut request = Request::new(GetProjectRequest { id: 0 }); request.metadata_mut().insert("uid", "0".parse().unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.get_model(request).await; + let res = api.get_project(request).await; assert!(res.unwrap().get_ref().queries[0].result.is_empty()); } #[tokio::test] -async fn list_models_info_returns_ok() { +async fn list_projects_info_returns_ok() { let mut mock_services = get_mock_services(); - let model_info = ModelInfo { - model_id: 1, - model_name: "model::Model name".to_owned(), - model_owner_id: 1, - user_role_on_model: "Editor".to_owned(), + let project_info = ProjectInfo { + project_id: 1, + project_name: "project::Model name".to_owned(), + project_owner_id: 1, + user_role_on_project: "Editor".to_owned(), }; mock_services - .model_context_mock - .expect_get_models_info_by_uid() + .project_context_mock + .expect_get_project_info_by_uid() .with(predicate::eq(1)) - .returning(move |_| Ok(vec![model_info.clone()])); + .returning(move |_| Ok(vec![project_info.clone()])); - let mut list_models_info_request = Request::new(()); + let mut list_projects_info_request = Request::new(()); - list_models_info_request + list_projects_info_request .metadata_mut() .insert("uid", metadata::MetadataValue::from_str("1").unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.list_models_info(list_models_info_request).await; + let res = api.list_projects_info(list_projects_info_request).await; assert!(res.is_ok()); } #[tokio::test] -async fn list_models_info_returns_err() { +async fn list_projects_info_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock - .expect_get_models_info_by_uid() + .project_context_mock + .expect_get_project_info_by_uid() .with(predicate::eq(1)) .returning(move |_| Ok(vec![])); - let mut list_models_info_request = Request::new(()); + let mut list_projects_info_request = Request::new(()); - list_models_info_request + list_projects_info_request .metadata_mut() .insert("uid", metadata::MetadataValue::from_str("1").unwrap()); let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.list_models_info(list_models_info_request).await; + let res = api.list_projects_info(list_projects_info_request).await; assert!(res.is_err()); } @@ -689,33 +690,33 @@ async fn update_name_returns_ok() { let mut mock_services = get_mock_services(); let user_id = 1; - let model_id = 1; - let new_model_name = "new_name".to_string(); + let project_id = 1; + let new_project_name = "new_name".to_string(); - let mut update_model_request = Request::new(UpdateModelRequest { - id: model_id, - name: Some(new_model_name.clone()), + let mut update_project_request = Request::new(UpdateProjectRequest { + id: project_id, + name: Some(new_project_name.clone()), components_info: None, owner_id: None, }); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "authorization", metadata::MetadataValue::from_str("Bearer access_token").unwrap(), ); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "uid", metadata::MetadataValue::from_str(user_id.to_string().as_str()).unwrap(), ); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() - .with(predicate::eq(model_id)) + .with(predicate::eq(project_id)) .returning(move |_| { - Ok(Some(model::Model { - id: model_id, + Ok(Some(project::Model { + id: project_id, name: "old_name".to_owned(), components_info: Default::default(), owner_id: user_id, @@ -724,13 +725,13 @@ async fn update_name_returns_ok() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() - .with(predicate::eq(1), predicate::eq(model_id)) + .expect_get_access_by_uid_and_project_id() + .with(predicate::eq(1), predicate::eq(project_id)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id, - model_id, + project_id, role: "Editor".to_string(), })) }); @@ -753,12 +754,12 @@ async fn update_name_returns_ok() { }); mock_services - .model_context_mock + .project_context_mock .expect_update() .returning(move |_| { - Ok(model::Model { - id: model_id, - name: new_model_name.clone(), + Ok(project::Model { + id: project_id, + name: new_project_name.clone(), components_info: Default::default(), owner_id: user_id, }) @@ -769,7 +770,7 @@ async fn update_name_returns_ok() { .expect_get_by_id() .returning(move |_| { Ok(Some(in_use::Model { - model_id, + project_id, session_id: 1, latest_activity: Utc::now().naive_utc(), })) @@ -780,7 +781,7 @@ async fn update_name_returns_ok() { .expect_update() .returning(move |_| { Ok(in_use::Model { - model_id: 1, + project_id: 1, session_id: 1, latest_activity: Utc::now().naive_utc(), }) @@ -788,7 +789,7 @@ async fn update_name_returns_ok() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(update_model_request).await; + let res = api.update_project(update_project_request).await; assert!(res.is_ok()); } @@ -798,7 +799,7 @@ async fn update_components_info_returns_ok() { let mut mock_services = get_mock_services(); let user_id = 1; - let model_id = 1; + let project_id = 1; let components_info_non_json = ComponentsInfo { components: vec![Component { rep: Some(Rep::Json("a".to_owned())), @@ -807,30 +808,30 @@ async fn update_components_info_returns_ok() { }; let components_info = serde_json::to_value(components_info_non_json.clone()).unwrap(); - let mut update_model_request = Request::new(UpdateModelRequest { - id: model_id, + let mut update_project_request = Request::new(UpdateProjectRequest { + id: project_id, name: None, components_info: Some(components_info_non_json.clone()), owner_id: None, }); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "authorization", metadata::MetadataValue::from_str("Bearer access_token").unwrap(), ); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "uid", metadata::MetadataValue::from_str(user_id.to_string().as_str()).unwrap(), ); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() - .with(predicate::eq(model_id)) + .with(predicate::eq(project_id)) .returning(move |_| { - Ok(Some(model::Model { - id: model_id, + Ok(Some(project::Model { + id: project_id, name: Default::default(), components_info: Default::default(), owner_id: user_id, @@ -839,13 +840,13 @@ async fn update_components_info_returns_ok() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() - .with(predicate::eq(1), predicate::eq(model_id)) + .expect_get_access_by_uid_and_project_id() + .with(predicate::eq(1), predicate::eq(project_id)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id, - model_id, + project_id, role: "Editor".to_string(), })) }); @@ -868,11 +869,11 @@ async fn update_components_info_returns_ok() { }); mock_services - .model_context_mock + .project_context_mock .expect_update() .returning(move |_| { - Ok(model::Model { - id: model_id, + Ok(project::Model { + id: project_id, name: Default::default(), components_info: components_info.clone(), owner_id: user_id, @@ -884,7 +885,7 @@ async fn update_components_info_returns_ok() { .expect_get_by_id() .returning(move |_| { Ok(Some(in_use::Model { - model_id, + project_id, session_id: 1, latest_activity: Utc::now().naive_utc(), })) @@ -895,7 +896,7 @@ async fn update_components_info_returns_ok() { .expect_update() .returning(move |_| { Ok(in_use::Model { - model_id: 1, + project_id: 1, session_id: 1, latest_activity: Utc::now().naive_utc(), }) @@ -903,7 +904,7 @@ async fn update_components_info_returns_ok() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(update_model_request).await; + let res = api.update_project(update_project_request).await; assert!(res.is_ok()); } @@ -913,33 +914,33 @@ async fn update_owner_id_returns_ok() { let mut mock_services = get_mock_services(); let user_id = 1; - let model_id = 1; + let project_id = 1; let new_owner_id = 2; - let mut update_model_request = Request::new(UpdateModelRequest { - id: model_id, + let mut update_project_request = Request::new(UpdateProjectRequest { + id: project_id, name: None, components_info: None, owner_id: Some(new_owner_id), }); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "authorization", metadata::MetadataValue::from_str("Bearer access_token").unwrap(), ); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "uid", metadata::MetadataValue::from_str(user_id.to_string().as_str()).unwrap(), ); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() - .with(predicate::eq(model_id)) + .with(predicate::eq(project_id)) .returning(move |_| { - Ok(Some(model::Model { - id: model_id, + Ok(Some(project::Model { + id: project_id, name: Default::default(), components_info: Default::default(), owner_id: user_id, @@ -948,13 +949,13 @@ async fn update_owner_id_returns_ok() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() - .with(predicate::eq(1), predicate::eq(model_id)) + .expect_get_access_by_uid_and_project_id() + .with(predicate::eq(1), predicate::eq(project_id)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id, - model_id, + project_id, role: "Editor".to_string(), })) }); @@ -977,11 +978,11 @@ async fn update_owner_id_returns_ok() { }); mock_services - .model_context_mock + .project_context_mock .expect_update() .returning(move |_| { - Ok(model::Model { - id: model_id, + Ok(project::Model { + id: project_id, name: Default::default(), components_info: Default::default(), owner_id: new_owner_id, @@ -993,7 +994,7 @@ async fn update_owner_id_returns_ok() { .expect_get_by_id() .returning(move |_| { Ok(Some(in_use::Model { - model_id, + project_id, session_id: 1, latest_activity: Utc::now().naive_utc(), })) @@ -1004,7 +1005,7 @@ async fn update_owner_id_returns_ok() { .expect_update() .returning(move |_| { Ok(in_use::Model { - model_id: 1, + project_id: 1, session_id: 1, latest_activity: Utc::now().naive_utc(), }) @@ -1012,7 +1013,7 @@ async fn update_owner_id_returns_ok() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(update_model_request).await; + let res = api.update_project(update_project_request).await; assert!(res.is_ok()); } @@ -1022,8 +1023,8 @@ async fn update_returns_ok() { let mut mock_services = get_mock_services(); let user_id = 1; - let model_id = 1; - let new_model_name = "new_name".to_string(); + let project_id = 1; + let new_project_name = "new_name".to_string(); let new_components_info_non_json = ComponentsInfo { components: vec![Component { rep: Some(Rep::Json("a".to_owned())), @@ -1033,30 +1034,30 @@ async fn update_returns_ok() { let new_components_info = serde_json::to_value(new_components_info_non_json.clone()).unwrap(); let new_owner_id = 2; - let mut update_model_request = Request::new(UpdateModelRequest { - id: model_id, - name: Some(new_model_name.clone()), + let mut update_project_request = Request::new(UpdateProjectRequest { + id: project_id, + name: Some(new_project_name.clone()), components_info: Some(new_components_info_non_json.clone()), owner_id: Some(new_owner_id), }); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "authorization", metadata::MetadataValue::from_str("Bearer access_token").unwrap(), ); - update_model_request.metadata_mut().insert( + update_project_request.metadata_mut().insert( "uid", metadata::MetadataValue::from_str(user_id.to_string().as_str()).unwrap(), ); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() - .with(predicate::eq(model_id)) + .with(predicate::eq(project_id)) .returning(move |_| { - Ok(Some(model::Model { - id: model_id, + Ok(Some(project::Model { + id: project_id, name: "old_name".to_owned(), components_info: serde_json::to_value("{\"old_components\":1}".clone()).unwrap(), owner_id: user_id, @@ -1065,13 +1066,13 @@ async fn update_returns_ok() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() - .with(predicate::eq(1), predicate::eq(model_id)) + .expect_get_access_by_uid_and_project_id() + .with(predicate::eq(1), predicate::eq(project_id)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id, - model_id, + project_id, role: "Editor".to_string(), })) }); @@ -1094,12 +1095,12 @@ async fn update_returns_ok() { }); mock_services - .model_context_mock + .project_context_mock .expect_update() .returning(move |_| { - Ok(model::Model { - id: model_id, - name: new_model_name.clone(), + Ok(project::Model { + id: project_id, + name: new_project_name.clone(), components_info: new_components_info.clone(), owner_id: new_owner_id, }) @@ -1110,7 +1111,7 @@ async fn update_returns_ok() { .expect_get_by_id() .returning(move |_| { Ok(Some(in_use::Model { - model_id, + project_id, session_id: 1, latest_activity: Utc::now().naive_utc(), })) @@ -1121,7 +1122,7 @@ async fn update_returns_ok() { .expect_update() .returning(move |_| { Ok(in_use::Model { - model_id: 1, + project_id: 1, session_id: 1, latest_activity: Utc::now().naive_utc(), }) @@ -1129,7 +1130,7 @@ async fn update_returns_ok() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(update_model_request).await; + let res = api.update_project(update_project_request).await; assert!(res.is_ok()); } @@ -1139,11 +1140,11 @@ async fn update_owner_not_owner_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -1153,13 +1154,13 @@ async fn update_owner_not_owner_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id: 1, - model_id: 1, + project_id: 1, role: "Editor".to_owned(), })) }); @@ -1189,7 +1190,7 @@ async fn update_owner_not_owner_returns_err() { Ok(Some(in_use::Model { session_id: 1, latest_activity: Default::default(), - model_id: 1, + project_id: 1, })) }); @@ -1200,11 +1201,11 @@ async fn update_owner_not_owner_returns_err() { Ok(in_use::Model { session_id: 1, latest_activity: Default::default(), - model_id: 1, + project_id: 1, }) }); - let mut request = Request::new(UpdateModelRequest { + let mut request = Request::new(UpdateProjectRequest { id: 1, name: None, components_info: None, @@ -1222,7 +1223,7 @@ async fn update_owner_not_owner_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(request).await.unwrap_err(); + let res = api.update_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::PermissionDenied); } @@ -1232,11 +1233,11 @@ async fn update_no_in_use_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -1246,13 +1247,13 @@ async fn update_no_in_use_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id: 1, - model_id: 1, + project_id: 1, role: "Editor".to_owned(), })) }); @@ -1282,11 +1283,11 @@ async fn update_no_in_use_returns_err() { Ok(Some(in_use::Model { session_id: 2, latest_activity: Utc::now().naive_utc(), - model_id: 1, + project_id: 1, })) }); - let mut request = Request::new(UpdateModelRequest { + let mut request = Request::new(UpdateProjectRequest { id: 1, name: None, components_info: None, @@ -1304,7 +1305,7 @@ async fn update_no_in_use_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(request).await.unwrap_err(); + let res = api.update_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::FailedPrecondition); } @@ -1314,11 +1315,11 @@ async fn update_no_access_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -1328,11 +1329,11 @@ async fn update_no_access_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| Ok(None)); - let mut request = Request::new(UpdateModelRequest { + let mut request = Request::new(UpdateProjectRequest { id: 1, name: None, components_info: None, @@ -1345,7 +1346,7 @@ async fn update_no_access_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(request).await.unwrap_err(); + let res = api.update_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::PermissionDenied); } @@ -1355,11 +1356,11 @@ async fn update_incorrect_role_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -1369,18 +1370,18 @@ async fn update_incorrect_role_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id: 1, - model_id: 1, + project_id: 1, role: "Viewer".to_owned(), })) }); - let mut request = Request::new(UpdateModelRequest { + let mut request = Request::new(UpdateProjectRequest { id: 1, name: None, components_info: None, @@ -1393,7 +1394,7 @@ async fn update_incorrect_role_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(request).await.unwrap_err(); + let res = api.update_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::PermissionDenied); } @@ -1403,11 +1404,11 @@ async fn update_no_session_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(1)) .returning(move |_| { - Ok(Some(model::Model { + Ok(Some(project::Model { id: 1, name: Default::default(), components_info: Default::default(), @@ -1417,13 +1418,13 @@ async fn update_no_session_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| { Ok(Some(access::Model { id: 1, user_id: 1, - model_id: 1, + project_id: 1, role: "Editor".to_owned(), })) }); @@ -1437,7 +1438,7 @@ async fn update_no_session_returns_err() { ) .returning(move |_, _| Ok(None)); - let mut request = Request::new(UpdateModelRequest { + let mut request = Request::new(UpdateProjectRequest { id: 1, name: None, components_info: None, @@ -1455,22 +1456,22 @@ async fn update_no_session_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(request).await.unwrap_err(); + let res = api.update_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::Unauthenticated); } #[tokio::test] -async fn update_no_model_returns_err() { +async fn update_no_project_returns_err() { let mut mock_services = get_mock_services(); mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(2)) .returning(move |_| Ok(None)); - let mut request = Request::new(UpdateModelRequest { + let mut request = Request::new(UpdateProjectRequest { id: 2, name: None, components_info: None, @@ -1483,7 +1484,7 @@ async fn update_no_model_returns_err() { let api = get_mock_concrete_ecdar_api(mock_services); - let res = api.update_model(request).await.unwrap_err(); + let res = api.update_project(request).await.unwrap_err(); assert_eq!(res.code(), Code::NotFound); } diff --git a/src/tests/api/query_logic.rs b/src/tests/api/query_logic.rs index 37ce371..3bfc707 100644 --- a/src/tests/api/query_logic.rs +++ b/src/tests/api/query_logic.rs @@ -5,7 +5,7 @@ use crate::api::server::server::query_response::{self, Result}; use crate::api::server::server::{ CreateQueryRequest, DeleteQueryRequest, QueryResponse, SendQueryRequest, UpdateQueryRequest, }; -use crate::entities::{access, model, query}; +use crate::entities::{access, project, query}; use crate::tests::api::helpers::{get_mock_concrete_ecdar_api, get_mock_services}; use mockall::predicate; use sea_orm::DbErr; @@ -19,20 +19,20 @@ async fn create_invalid_query_returns_err() { id: Default::default(), string: "".to_string(), result: Default::default(), - model_id: 1, + project_id: 1, outdated: Default::default(), }; let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -44,7 +44,7 @@ async fn create_invalid_query_returns_err() { let mut request = Request::new(CreateQueryRequest { string: "".to_string(), - model_id: 1, + project_id: 1, }); request @@ -66,20 +66,20 @@ async fn create_query_returns_ok() { id: Default::default(), string: "".to_string(), result: Default::default(), - model_id: 1, + project_id: 1, outdated: Default::default(), }; let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: 1, }; mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -91,7 +91,7 @@ async fn create_query_returns_ok() { let mut request = Request::new(CreateQueryRequest { string: "".to_string(), - model_id: 1, + project_id: 1, }); request @@ -113,7 +113,7 @@ async fn update_invalid_query_returns_err() { id: 1, string: "".to_string(), result: None, - model_id: Default::default(), + project_id: Default::default(), outdated: true, }; @@ -125,7 +125,7 @@ async fn update_invalid_query_returns_err() { let access = access::Model { id: 1, role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; @@ -137,7 +137,7 @@ async fn update_invalid_query_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -171,7 +171,7 @@ async fn update_query_returns_ok() { id: 1, string: "".to_string(), result: None, - model_id: Default::default(), + project_id: Default::default(), outdated: true, }; @@ -183,13 +183,13 @@ async fn update_query_returns_ok() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -228,7 +228,7 @@ async fn delete_invalid_query_returns_err() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; @@ -236,13 +236,13 @@ async fn delete_invalid_query_returns_err() { id: 1, string: "".to_string(), result: Default::default(), - model_id: Default::default(), + project_id: Default::default(), outdated: Default::default(), }; mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -279,7 +279,7 @@ async fn delete_query_returns_ok() { id: 1, string: "".to_string(), result: Default::default(), - model_id: Default::default(), + project_id: Default::default(), outdated: Default::default(), }; @@ -288,7 +288,7 @@ async fn delete_query_returns_ok() { let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; @@ -300,7 +300,7 @@ async fn delete_query_returns_ok() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -331,20 +331,20 @@ async fn create_query_invalid_role_returns_err() { id: 1, string: "".to_string(), result: Default::default(), - model_id: Default::default(), + project_id: Default::default(), outdated: Default::default(), }; let access = access::Model { id: Default::default(), role: "Viewer".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(1)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -356,7 +356,7 @@ async fn create_query_invalid_role_returns_err() { let mut request = Request::new(CreateQueryRequest { string: "".to_string(), - model_id: 1, + project_id: 1, }); request @@ -378,7 +378,7 @@ async fn delete_query_invalid_role_returns_err() { id: 1, string: "".to_string(), result: Default::default(), - model_id: Default::default(), + project_id: Default::default(), outdated: Default::default(), }; @@ -387,7 +387,7 @@ async fn delete_query_invalid_role_returns_err() { let access = access::Model { id: Default::default(), role: "Viewer".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; @@ -399,7 +399,7 @@ async fn delete_query_invalid_role_returns_err() { mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -430,7 +430,7 @@ async fn update_query_invalid_role_returns_err() { id: 1, string: "".to_string(), result: None, - model_id: Default::default(), + project_id: Default::default(), outdated: true, }; @@ -442,13 +442,13 @@ async fn update_query_invalid_role_returns_err() { let access = access::Model { id: Default::default(), role: "Viewer".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -488,20 +488,20 @@ async fn send_query_returns_ok() { id: Default::default(), string: "".to_string(), result: Default::default(), - model_id: Default::default(), + project_id: Default::default(), outdated: Default::default(), }; let access = access::Model { id: Default::default(), role: "Editor".to_string(), - model_id: Default::default(), + project_id: Default::default(), user_id: 1, }; - let model = model::Model { + let project = project::Model { id: Default::default(), - name: "model".to_string(), + name: "project".to_string(), components_info: Default::default(), owner_id: 0, }; @@ -518,14 +518,14 @@ async fn send_query_returns_ok() { }; mock_services - .model_context_mock + .project_context_mock .expect_get_by_id() .with(predicate::eq(0)) - .returning(move |_| Ok(Some(model.clone()))); + .returning(move |_| Ok(Some(project.clone()))); mock_services .access_context_mock - .expect_get_access_by_uid_and_model_id() + .expect_get_access_by_uid_and_project_id() .with(predicate::eq(1), predicate::eq(0)) .returning(move |_, _| Ok(Some(access.clone()))); @@ -548,7 +548,7 @@ async fn send_query_returns_ok() { let mut request = Request::new(SendQueryRequest { id: Default::default(), - model_id: Default::default(), + project_id: Default::default(), }); request diff --git a/src/tests/database/access_context.rs b/src/tests/database/access_context.rs index cc2c13c..7874ab9 100644 --- a/src/tests/database/access_context.rs +++ b/src/tests/database/access_context.rs @@ -1,33 +1,33 @@ use crate::database::access_context::AccessContextTrait; use crate::tests::database::helpers::{ - create_accesses, create_models, create_users, get_reset_database_context, + create_accesses, create_projects, create_users, get_reset_database_context, }; use crate::{ database::{access_context::AccessContext, entity_context::EntityContextTrait}, - entities::{access, model, user}, + entities::{access, project, user}, to_active_models, }; use sea_orm::{entity::prelude::*, IntoActiveModel}; -async fn seed_db() -> (AccessContext, access::Model, user::Model, model::Model) { +async fn seed_db() -> (AccessContext, access::Model, user::Model, project::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(); + let project = create_projects(1, user.id)[0].clone(); + let access = create_accesses(1, user.id, project.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()) + project::Entity::insert(project.clone().into_active_model()) .exec(&access_context.db_context.get_connection()) .await .unwrap(); - (access_context, access, user, model) + (access_context, access, user, project) } // Test the functionality of the 'create' function, which creates a access in the database @@ -49,7 +49,7 @@ async fn create_test() { } #[tokio::test] -async fn create_check_unique_pair_model_id_user_id_test() { +async fn create_check_unique_pair_project_id_user_id_test() { let (access_context, access, _, _) = seed_db().await; let _created_access_1 = access_context.create(access.clone()).await.unwrap(); @@ -77,13 +77,13 @@ async fn create_invalid_role_test() { #[tokio::test] async fn create_auto_increment_test() { - let (access_context, _, user, model_1) = seed_db().await; + let (access_context, _, user, project_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(); + let mut project_2 = create_projects(1, user.id)[0].clone(); + project_2.id = project_1.id + 1; + project_2.name = "project_2".to_string(); - model::Entity::insert(model_2.into_active_model()) + project::Entity::insert(project_2.into_active_model()) .exec(&access_context.db_context.get_connection()) .await .unwrap(); @@ -91,14 +91,14 @@ async fn create_auto_increment_test() { let access_1 = access::Model { id: 0, role: "Editor".to_string(), - model_id: 1, + project_id: 1, user_id: user.id, }; let access_2 = access::Model { id: 0, role: "Editor".to_string(), - model_id: 2, + project_id: 2, user_id: user.id, }; @@ -150,10 +150,10 @@ async fn get_by_non_existing_id_test() { #[tokio::test] async fn get_all_test() { - let (access_context, _, user, model) = seed_db().await; + let (access_context, _, user, project) = seed_db().await; // Creates a model of the access which will be created - let new_accesses = create_accesses(1, user.id, model.id); + let new_accesses = create_accesses(1, user.id, project.id); // Creates the access in the database using the 'create' function access::Entity::insert_many(to_active_models!(new_accesses.clone())) @@ -247,7 +247,7 @@ async fn update_does_not_modify_id_test() { } #[tokio::test] -async fn update_does_not_modify_model_id_test() { +async fn update_does_not_modify_project_id_test() { let (access_context, access, _, _) = seed_db().await; access::Entity::insert(access.clone().into_active_model()) @@ -256,7 +256,7 @@ async fn update_does_not_modify_model_id_test() { .unwrap(); let updated_access = access::Model { - model_id: &access.model_id + 1, + project_id: &access.project_id + 1, ..access.clone() }; let res = access_context.update(updated_access.clone()).await.unwrap(); @@ -346,8 +346,8 @@ async fn delete_non_existing_id_test() { } #[tokio::test] -async fn get_by_uid_and_model_id_test() { - let (access_context, expected_access, user, model) = seed_db().await; +async fn get_by_uid_and_project_id_test() { + let (access_context, expected_access, user, project) = seed_db().await; access::Entity::insert(expected_access.clone().into_active_model()) .exec(&access_context.db_context.get_connection()) @@ -355,8 +355,8 @@ async fn get_by_uid_and_model_id_test() { .unwrap(); let access = access_context - .get_access_by_uid_and_model_id(user.id, model.id) + .get_access_by_uid_and_project_id(user.id, project.id) .await; - assert!(access.unwrap().unwrap() == expected_access); + assert_eq!(access.unwrap().unwrap(), expected_access); } diff --git a/src/tests/database/helpers.rs b/src/tests/database/helpers.rs index 623a974..b10e817 100644 --- a/src/tests/database/helpers.rs +++ b/src/tests/database/helpers.rs @@ -3,7 +3,7 @@ use crate::database::database_context::{ DatabaseContextTrait, PostgresDatabaseContext, SQLiteDatabaseContext, }; -use crate::entities::{access, in_use, model, query, session, user}; +use crate::entities::{access, in_use, project, query, session, user}; use dotenv::dotenv; use sea_orm::{ConnectionTrait, Database, DbBackend}; use std::env; @@ -63,8 +63,8 @@ pub fn create_users(amount: i32) -> Vec { }) } -pub fn create_models(amount: i32, user_id: i32) -> Vec { - create_entities(amount, |i| model::Model { +pub fn create_projects(amount: i32, user_id: i32) -> Vec { + create_entities(amount, |i| project::Model { id: i + 1, name: format!("name {}", i), components_info: "{}".to_owned().parse().unwrap(), @@ -72,11 +72,11 @@ pub fn create_models(amount: i32, user_id: i32) -> Vec { }) } -pub fn create_accesses(amount: i32, user_id: i32, model_id: i32) -> Vec { +pub fn create_accesses(amount: i32, user_id: i32, project_id: i32) -> Vec { create_entities(amount, |i| access::Model { id: i + 1, role: "Reader".into(), - model_id: model_id + i, + project_id: project_id + i, user_id: user_id + i, }) } @@ -91,21 +91,21 @@ pub fn create_sessions(amount: i32, user_id: i32) -> Vec { }) } -pub fn create_in_uses(amount: i32, model_id: i32, session_id: i32) -> Vec { +pub fn create_in_uses(amount: i32, project_id: i32, session_id: i32) -> Vec { create_entities(amount, |i| in_use::Model { - model_id: model_id + i, + project_id: project_id + i, session_id, latest_activity: Default::default(), }) } -pub fn create_queries(amount: i32, model_id: i32) -> Vec { +pub fn create_queries(amount: i32, project_id: i32) -> Vec { create_entities(amount, |i| query::Model { id: i + 1, string: "".to_string(), result: None, outdated: true, - model_id, + project_id, }) } diff --git a/src/tests/database/in_use_context.rs b/src/tests/database/in_use_context.rs index 72b1cab..b752318 100644 --- a/src/tests/database/in_use_context.rs +++ b/src/tests/database/in_use_context.rs @@ -4,7 +4,7 @@ use crate::{ entity_context::EntityContextTrait, in_use_context::{DbErr, InUseContext}, }, - entities::{in_use, model, session, user}, + entities::{in_use, project, session, user}, to_active_models, }; use chrono::{Duration, Utc}; @@ -16,7 +16,7 @@ async fn seed_db() -> ( InUseContext, in_use::Model, session::Model, - model::Model, + project::Model, user::Model, ) { let db_context = get_reset_database_context().await; @@ -24,15 +24,15 @@ async fn seed_db() -> ( 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 project = create_projects(1, user.id)[0].clone(); let session = create_sessions(1, user.id)[0].clone(); - let in_use = create_in_uses(1, model.id, session.id)[0].clone(); + let in_use = create_in_uses(1, project.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()) + project::Entity::insert(project.clone().into_active_model()) .exec(&in_use_context.db_context.get_connection()) .await .unwrap(); @@ -41,7 +41,7 @@ async fn seed_db() -> ( .await .unwrap(); - (in_use_context, in_use, session, model, user) + (in_use_context, in_use, session, project, user) } #[tokio::test] @@ -52,7 +52,7 @@ async fn create_test() { in_use.latest_activity = inserted_in_use.latest_activity; - let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.clone().model_id) + let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.clone().project_id) .one(&in_use_context.db_context.get_connection()) .await .unwrap() @@ -70,7 +70,7 @@ async fn create_default_latest_activity_test() { 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) + let fetched_in_use = in_use::Entity::find_by_id(inserted_in_use.project_id) .one(&in_use_context.db_context.get_connection()) .await .unwrap() @@ -93,7 +93,7 @@ async fn get_by_id_test() { .unwrap(); let fetched_in_use = in_use_context - .get_by_id(in_use.model_id) + .get_by_id(in_use.project_id) .await .unwrap() .unwrap(); @@ -112,9 +112,9 @@ 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, project, _user) = seed_db().await; - let in_uses = create_in_uses(1, model.id, session.id); + let in_uses = create_in_uses(1, project.id, session.id); in_use::Entity::insert_many(to_active_models!(in_uses.clone())) .exec(&in_use_context.db_context.get_connection()) @@ -146,7 +146,7 @@ async fn update_test() { let updated_in_use = in_use_context.update(new_in_use.clone()).await.unwrap(); - let fetched_in_use = in_use::Entity::find_by_id(updated_in_use.model_id) + let fetched_in_use = in_use::Entity::find_by_id(updated_in_use.project_id) .one(&in_use_context.db_context.get_connection()) .await .unwrap() @@ -207,7 +207,7 @@ async fn update_modifies_session_id_test() { } #[tokio::test] -async fn update_does_not_modify_model_id_test() { +async fn update_does_not_modify_project_id_test() { let (in_use_context, in_use, _, _, _) = seed_db().await; in_use::Entity::insert(in_use.clone().into_active_model()) @@ -216,7 +216,7 @@ async fn update_does_not_modify_model_id_test() { .unwrap(); let updated_in_use = in_use::Model { - model_id: in_use.model_id + 1, + project_id: in_use.project_id + 1, ..in_use.clone() }; @@ -249,7 +249,7 @@ async fn delete_test() { .await .unwrap(); - let deleted_in_use = in_use_context.delete(in_use.model_id).await.unwrap(); + let deleted_in_use = in_use_context.delete(in_use.project_id).await.unwrap(); let all_in_uses = in_use::Entity::find() .all(&in_use_context.db_context.get_connection()) diff --git a/src/tests/database/model_context.rs b/src/tests/database/model_context.rs deleted file mode 100644 index d32dd26..0000000 --- a/src/tests/database/model_context.rs +++ /dev/null @@ -1,404 +0,0 @@ -use crate::tests::database::helpers::*; -use crate::{ - database::{entity_context::EntityContextTrait, model_context::ModelContext}, - entities::{access, in_use, model, query, session, user}, - to_active_models, -}; -use sea_orm::error::DbErr; -use sea_orm::{entity::prelude::*, IntoActiveModel}; -use std::matches; - -async fn seed_db() -> (ModelContext, model::Model, user::Model) { - let db_context = get_reset_database_context().await; - - let model_context = ModelContext::new(db_context); - - let user = create_users(1)[0].clone(); - let model = create_models(1, user.id)[0].clone(); - - user::Entity::insert(user.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - (model_context, model, user) -} - -#[tokio::test] -async fn create_test() { - let (model_context, model, _) = seed_db().await; - - let created_model = model_context.create(model.clone()).await.unwrap(); - - let fetched_model = model::Entity::find_by_id(created_model.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); - - assert_eq!(model, created_model); - assert_eq!(fetched_model, created_model); -} - -#[tokio::test] -async fn create_auto_increment_test() { - let (model_context, model, _) = seed_db().await; - - 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()) - .await - .unwrap() - .unwrap(); - - let fetched_model2 = model::Entity::find_by_id(created_model2.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); - - assert_ne!(fetched_model1.id, fetched_model2.id); - assert_ne!(created_model1.id, created_model2.id); - assert_eq!(created_model1.id, fetched_model1.id); - assert_eq!(created_model2.id, fetched_model2.id); -} - -#[tokio::test] -async fn get_by_id_test() { - let (model_context, model, _) = seed_db().await; - - model::Entity::insert(model.clone().into_active_model()) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - let fetched_model = model_context.get_by_id(model.id).await.unwrap().unwrap(); - - assert_eq!(model, fetched_model); -} - -#[tokio::test] -async fn get_by_non_existing_id_test() { - let (model_context, _, _) = seed_db().await; - - let fetched_model = model_context.get_by_id(1).await.unwrap(); - - 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); - - model::Entity::insert_many(to_active_models!(new_models.clone())) - .exec(&model_context.db_context.get_connection()) - .await - .unwrap(); - - assert_eq!(model_context.get_all().await.unwrap().len(), 3); - - 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; - - let result = model_context.get_all().await.unwrap(); - let empty_models: Vec = vec![]; - - assert_eq!(empty_models, result); -} - -#[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(); - - let new_model = model::Model { ..model }; - - let updated_model = model_context.update(new_model.clone()).await.unwrap(); - - let fetched_model = model::Entity::find_by_id(updated_model.id) - .one(&model_context.db_context.get_connection()) - .await - .unwrap() - .unwrap(); - - assert_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; - - 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(); - - let new_model = model::Model { - name: "model2".into(), - ..model.clone() - }; - - let updated_model = model_context.update(new_model.clone()).await.unwrap(); - - 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; - - 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(); - - 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(); - - 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; - - 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 res = model_context.update(new_model.clone()).await; - - 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; - - 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 res = model_context.update(new_model.clone()).await.unwrap(); - - assert_eq!(model, res); -} - -#[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(); - - query.outdated = false; - - 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(); - - let new_model = model::Model { ..model }; - - 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(); - - assert!(fetched_query.outdated); -} - -#[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; - - 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; - - 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 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); -} - -#[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_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; - - let deleted_model = model_context.delete(1).await; - - assert!(matches!( - deleted_model.unwrap_err(), - DbErr::RecordNotFound(_) - )); -} diff --git a/src/tests/database/project_context.rs b/src/tests/database/project_context.rs new file mode 100644 index 0000000..76dda4e --- /dev/null +++ b/src/tests/database/project_context.rs @@ -0,0 +1,408 @@ +use crate::tests::database::helpers::*; +use crate::{ + database::{entity_context::EntityContextTrait, project_context::ProjectContext}, + entities::{access, in_use, project, query, session, user}, + to_active_models, +}; +use sea_orm::error::DbErr; +use sea_orm::{entity::prelude::*, IntoActiveModel}; +use std::matches; + +async fn seed_db() -> (ProjectContext, project::Model, user::Model) { + let db_context = get_reset_database_context().await; + + let project_context = ProjectContext::new(db_context); + + let user = create_users(1)[0].clone(); + let project = create_projects(1, user.id)[0].clone(); + + user::Entity::insert(user.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + (project_context, project, user) +} + +#[tokio::test] +async fn create_test() { + let (project_context, project, _) = seed_db().await; + + let created_project = project_context.create(project.clone()).await.unwrap(); + + let fetched_project = project::Entity::find_by_id(created_project.id) + .one(&project_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + assert_eq!(project, created_project); + assert_eq!(fetched_project, created_project); +} + +#[tokio::test] +async fn create_auto_increment_test() { + let (project_context, project, _) = seed_db().await; + + let projects = create_projects(2, project.owner_id); + + let created_project1 = project_context.create(projects[0].clone()).await.unwrap(); + let created_project2 = project_context.create(projects[1].clone()).await.unwrap(); + + let fetched_project1 = project::Entity::find_by_id(created_project1.id) + .one(&project_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + let fetched_project2 = project::Entity::find_by_id(created_project2.id) + .one(&project_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + assert_ne!(fetched_project1.id, fetched_project2.id); + assert_ne!(created_project1.id, created_project2.id); + assert_eq!(created_project1.id, fetched_project1.id); + assert_eq!(created_project2.id, fetched_project2.id); +} + +#[tokio::test] +async fn get_by_id_test() { + let (project_context, project, _) = seed_db().await; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let fetched_project = project_context + .get_by_id(project.id) + .await + .unwrap() + .unwrap(); + + assert_eq!(project, fetched_project); +} + +#[tokio::test] +async fn get_by_non_existing_id_test() { + let (project_context, _, _) = seed_db().await; + + let fetched_project = project_context.get_by_id(1).await.unwrap(); + + assert!(fetched_project.is_none()); +} + +#[tokio::test] +async fn get_all_test() { + let (project_context, _, user) = seed_db().await; + + let new_projects = create_projects(3, user.id); + + project::Entity::insert_many(to_active_models!(new_projects.clone())) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(project_context.get_all().await.unwrap().len(), 3); + + let mut sorted = new_projects.clone(); + sorted.sort_by_key(|k| k.id); + + for (i, project) in sorted.into_iter().enumerate() { + assert_eq!(project, new_projects[i]); + } +} + +#[tokio::test] +async fn get_all_empty_test() { + let (project_context, _, _) = seed_db().await; + + let result = project_context.get_all().await.unwrap(); + let empty_projects: Vec = vec![]; + + assert_eq!(empty_projects, result); +} + +#[tokio::test] +async fn update_test() { + let (project_context, project, _) = seed_db().await; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let new_project = project::Model { ..project }; + + let updated_project = project_context.update(new_project.clone()).await.unwrap(); + + let fetched_project = project::Entity::find_by_id(updated_project.id) + .one(&project_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + assert_eq!(new_project, updated_project); + assert_eq!(updated_project, fetched_project); +} + +#[tokio::test] +async fn update_modifies_name_test() { + let (project_context, project, _) = seed_db().await; + + let project = project::Model { + name: "project1".into(), + ..project.clone() + }; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let new_project = project::Model { + name: "project2".into(), + ..project.clone() + }; + + let updated_project = project_context.update(new_project.clone()).await.unwrap(); + + assert_ne!(project, updated_project); + assert_ne!(project, new_project); +} + +#[tokio::test] +async fn update_modifies_components_info_test() { + let (project_context, project, _) = seed_db().await; + + let project = project::Model { + components_info: "{\"a\":1}".to_owned().parse().unwrap(), + ..project.clone() + }; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let new_project = project::Model { + components_info: "{\"a\":2}".to_owned().parse().unwrap(), + ..project.clone() + }; + + let updated_project = project_context.update(new_project.clone()).await.unwrap(); + + assert_ne!(project, updated_project); + assert_ne!(project, new_project); +} + +#[tokio::test] +async fn update_does_not_modify_id_test() { + let (project_context, project, _) = seed_db().await; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let new_project = project::Model { + id: &project.id + 1, + ..project.clone() + }; + + let res = project_context.update(new_project.clone()).await; + + assert!(matches!(res.unwrap_err(), DbErr::RecordNotUpdated)); +} + +#[tokio::test] +async fn update_does_not_modify_owner_id_test() { + let (project_context, project, _) = seed_db().await; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let new_project = project::Model { + owner_id: &project.owner_id + 1, + ..project.clone() + }; + + let res = project_context.update(new_project.clone()).await.unwrap(); + + assert_eq!(project, res); +} + +#[tokio::test] +async fn update_check_query_outdated_test() { + let (project_context, project, _) = seed_db().await; + + let mut query = create_queries(1, project.id)[0].clone(); + + query.outdated = false; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + query::Entity::insert(query.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let new_project = project::Model { ..project }; + + let updated_project = project_context.update(new_project.clone()).await.unwrap(); + + let fetched_query = query::Entity::find_by_id(updated_project.id) + .one(&project_context.db_context.get_connection()) + .await + .unwrap() + .unwrap(); + + assert!(fetched_query.outdated); +} + +#[tokio::test] +async fn update_non_existing_id_test() { + let (project_context, project, _) = seed_db().await; + + let updated_project = project_context.update(project.clone()).await; + + assert!(matches!( + updated_project.unwrap_err(), + DbErr::RecordNotUpdated + )); +} + +#[tokio::test] +async fn delete_test() { + // Setting up database and user context + let (project_context, project, _) = seed_db().await; + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + let deleted_project = project_context.delete(project.id).await.unwrap(); + + let all_projects = project::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(project, deleted_project); + assert_eq!(all_projects.len(), 0); +} + +#[tokio::test] +async fn delete_cascade_query_test() { + let (project_context, project, _) = seed_db().await; + + let query = create_queries(1, project.clone().id)[0].clone(); + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + query::Entity::insert(query.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + project_context.delete(project.id).await.unwrap(); + + let all_queries = query::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + let all_projects = project::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(all_queries.len(), 0); + assert_eq!(all_projects.len(), 0); +} + +#[tokio::test] +async fn delete_cascade_access_test() { + let (project_context, project, _) = seed_db().await; + + let access = create_accesses(1, 1, project.clone().id)[0].clone(); + + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + access::Entity::insert(access.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + project_context.delete(project.id).await.unwrap(); + + let all_projects = project::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + let all_accesses = access::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(all_projects.len(), 0); + assert_eq!(all_accesses.len(), 0); +} + +#[tokio::test] +async fn delete_cascade_in_use_test() { + let (project_context, project, user) = seed_db().await; + + let session = create_sessions(1, user.clone().id)[0].clone(); + let in_use = create_in_uses(1, project.clone().id, 1)[0].clone(); + + session::Entity::insert(session.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + project::Entity::insert(project.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + in_use::Entity::insert(in_use.clone().into_active_model()) + .exec(&project_context.db_context.get_connection()) + .await + .unwrap(); + + project_context.delete(project.id).await.unwrap(); + + let all_projects = project::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + let all_in_uses = in_use::Entity::find() + .all(&project_context.db_context.get_connection()) + .await + .unwrap(); + + assert_eq!(all_projects.len(), 0); + assert_eq!(all_in_uses.len(), 0); +} + +#[tokio::test] +async fn delete_non_existing_id_test() { + let (project_context, _, _) = seed_db().await; + + let deleted_project = project_context.delete(1).await; + + assert!(matches!( + deleted_project.unwrap_err(), + DbErr::RecordNotFound(_) + )); +} diff --git a/src/tests/database/query_context.rs b/src/tests/database/query_context.rs index 90c30d5..6dc3e9a 100644 --- a/src/tests/database/query_context.rs +++ b/src/tests/database/query_context.rs @@ -1,32 +1,32 @@ use crate::tests::database::helpers::{ - create_models, create_queries, create_users, get_reset_database_context, + create_projects, create_queries, create_users, get_reset_database_context, }; use crate::{ database::{entity_context::EntityContextTrait, query_context::QueryContext}, - entities::{model, query, user}, + entities::{project, query, user}, to_active_models, }; use sea_orm::{entity::prelude::*, IntoActiveModel}; -async fn seed_db() -> (QueryContext, query::Model, model::Model) { +async fn seed_db() -> (QueryContext, query::Model, project::Model) { let db_context = get_reset_database_context().await; let query_context = QueryContext::new(db_context); let user = create_users(1)[0].clone(); - let model = create_models(1, user.id)[0].clone(); - let query = create_queries(1, model.id)[0].clone(); + let project = create_projects(1, user.id)[0].clone(); + let query = create_queries(1, project.id)[0].clone(); user::Entity::insert(user.clone().into_active_model()) .exec(&query_context.db_context.get_connection()) .await .unwrap(); - model::Entity::insert(model.clone().into_active_model()) + project::Entity::insert(project.clone().into_active_model()) .exec(&query_context.db_context.get_connection()) .await .unwrap(); - (query_context, query, model) + (query_context, query, project) } #[tokio::test] @@ -52,7 +52,7 @@ async fn create_default_outdated_test() { let _inserted_query = query_context.create(query.clone()).await.unwrap(); - let fetched_query = query::Entity::find_by_id(query.model_id) + let fetched_query = query::Entity::find_by_id(query.project_id) .one(&query_context.db_context.get_connection()) .await .unwrap() @@ -96,7 +96,7 @@ async fn get_by_id_test() { .unwrap(); let fetched_in_use = query_context - .get_by_id(query.model_id) + .get_by_id(query.project_id) .await .unwrap() .unwrap(); @@ -115,9 +115,9 @@ async fn get_by_non_existing_id_test() { #[tokio::test] async fn get_all_test() { - let (query_context, _, model) = seed_db().await; + let (query_context, _, project) = seed_db().await; - let queries = create_queries(10, model.id); + let queries = create_queries(10, project.id); query::Entity::insert_many(to_active_models!(queries.clone())) .exec(&query_context.db_context.get_connection()) @@ -127,7 +127,7 @@ async fn get_all_test() { assert_eq!(query_context.get_all().await.unwrap().len(), 10); let mut sorted = queries.clone(); - sorted.sort_by_key(|k| k.model_id); + sorted.sort_by_key(|k| k.project_id); for (i, query) in sorted.into_iter().enumerate() { assert_eq!(query, queries[i]); @@ -156,7 +156,7 @@ async fn update_test() { let updated_query = query_context.update(new_query.clone()).await.unwrap(); - let fetched_query = query::Entity::find_by_id(updated_query.model_id) + let fetched_query = query::Entity::find_by_id(updated_query.project_id) .one(&query_context.db_context.get_connection()) .await .unwrap() @@ -251,7 +251,7 @@ async fn update_does_not_modify_id_test() { } #[tokio::test] -async fn update_does_not_modify_model_id_test() { +async fn update_does_not_modify_project_id_test() { let (query_context, query, _) = seed_db().await; query::Entity::insert(query.clone().into_active_model()) @@ -260,7 +260,7 @@ async fn update_does_not_modify_model_id_test() { .unwrap(); let new_query = query::Model { - model_id: query.model_id + 1, + project_id: query.project_id + 1, ..query.clone() }; @@ -290,7 +290,7 @@ async fn delete_test() { .await .unwrap(); - let deleted_query = query_context.delete(query.model_id).await.unwrap(); + let deleted_query = query_context.delete(query.project_id).await.unwrap(); let all_queries = query::Entity::find() .all(&query_context.db_context.get_connection()) diff --git a/src/tests/database/session_context.rs b/src/tests/database/session_context.rs index 95d022f..4a87077 100644 --- a/src/tests/database/session_context.rs +++ b/src/tests/database/session_context.rs @@ -4,32 +4,32 @@ use std::ops::Add; use crate::{ database::{entity_context::EntityContextTrait, session_context::SessionContext}, - entities::{in_use, model, session, user}, + entities::{in_use, project, session, user}, to_active_models, }; use crate::database::session_context::SessionContextTrait; use chrono::{Duration, Utc}; -async fn seed_db() -> (SessionContext, session::Model, user::Model, model::Model) { +async fn seed_db() -> (SessionContext, session::Model, user::Model, project::Model) { let db_context = get_reset_database_context().await; let session_context = SessionContext::new(db_context); let user = create_users(1)[0].clone(); - let model = create_models(1, user.id)[0].clone(); + let project = create_projects(1, user.id)[0].clone(); let session = create_sessions(1, user.id)[0].clone(); user::Entity::insert(user.clone().into_active_model()) .exec(&session_context.db_context.get_connection()) .await .unwrap(); - model::Entity::insert(model.clone().into_active_model()) + project::Entity::insert(project.clone().into_active_model()) .exec(&session_context.db_context.get_connection()) .await .unwrap(); - (session_context, session, user, model) + (session_context, session, user, project) } #[tokio::test] @@ -300,9 +300,9 @@ async fn delete_test() { #[tokio::test] async fn delete_cascade_in_use_test() { - let (session_context, session, _, model) = seed_db().await; + let (session_context, session, _, project) = seed_db().await; - let in_use = create_in_uses(1, model.id, session.id)[0].clone(); + let in_use = create_in_uses(1, project.id, session.id)[0].clone(); session::Entity::insert(session.clone().into_active_model()) .exec(&session_context.db_context.get_connection()) diff --git a/src/tests/database/user_context.rs b/src/tests/database/user_context.rs index 6dd5652..7b0f67d 100644 --- a/src/tests/database/user_context.rs +++ b/src/tests/database/user_context.rs @@ -5,7 +5,7 @@ use crate::{ entity_context::EntityContextTrait, user_context::{DbErr, UserContext}, }, - entities::{access, model, session, user}, + entities::{access, project, session, user}, to_active_models, }; use sea_orm::{entity::prelude::*, IntoActiveModel}; @@ -384,17 +384,17 @@ async fn delete_test() { } #[tokio::test] -async fn delete_cascade_model_test() { +async fn delete_cascade_project_test() { // Setting up database and user context let (user_context, user) = seed_db().await; - let model = create_models(1, user.clone().id)[0].clone(); + let project = create_projects(1, user.clone().id)[0].clone(); user::Entity::insert(user.clone().into_active_model()) .exec(&user_context.db_context.get_connection()) .await .unwrap(); - model::Entity::insert(model.clone().into_active_model()) + project::Entity::insert(project.clone().into_active_model()) .exec(&user_context.db_context.get_connection()) .await .unwrap(); @@ -405,28 +405,28 @@ async fn delete_cascade_model_test() { .all(&user_context.db_context.get_connection()) .await .unwrap(); - let all_models = model::Entity::find() + let all_projects = project::Entity::find() .all(&user_context.db_context.get_connection()) .await .unwrap(); assert_eq!(all_users.len(), 0); - assert_eq!(all_models.len(), 0); + assert_eq!(all_projects.len(), 0); } #[tokio::test] -async fn delete_access_model_test() { +async fn delete_cascade_access_test() { // Setting up database and user context let (user_context, user) = seed_db().await; - let model = create_models(1, user.clone().id)[0].clone(); - let access = create_accesses(1, user.clone().id, model.clone().id)[0].clone(); + let project = create_projects(1, user.clone().id)[0].clone(); + let access = create_accesses(1, user.clone().id, project.clone().id)[0].clone(); user::Entity::insert(user.clone().into_active_model()) .exec(&user_context.db_context.get_connection()) .await .unwrap(); - model::Entity::insert(model.clone().into_active_model()) + project::Entity::insert(project.clone().into_active_model()) .exec(&user_context.db_context.get_connection()) .await .unwrap(); @@ -441,7 +441,7 @@ async fn delete_access_model_test() { .all(&user_context.db_context.get_connection()) .await .unwrap(); - let all_models = model::Entity::find() + let all_projects = project::Entity::find() .all(&user_context.db_context.get_connection()) .await .unwrap(); @@ -451,7 +451,7 @@ async fn delete_access_model_test() { .unwrap(); assert_eq!(all_users.len(), 0); - assert_eq!(all_models.len(), 0); + assert_eq!(all_projects.len(), 0); assert_eq!(all_accesses.len(), 0); }