From 4012d38f7fd3961e18be6a9c7a80db94faea5e0c Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sat, 27 May 2023 05:50:07 -0400 Subject: [PATCH] add integration test in model --- .../native-utils/crates/database/src/lib.rs | 4 +- .../crates/model/src/repository/mod.rs | 2 +- .../crates/model/src/schema/antenna.rs | 21 +++-- .../crates/model/src/schema/app.rs | 8 +- .../native-utils/crates/model/tests/common.rs | 88 +++++++++++++++++++ .../crates/model/tests/repository/antenna.rs | 60 +++++++++++++ .../crates/model/tests/repository/mod.rs | 1 + .../native-utils/crates/util/src/id.rs | 2 +- .../native-utils/crates/util/src/random.rs | 2 +- 9 files changed, 173 insertions(+), 15 deletions(-) create mode 100644 packages/backend/native-utils/crates/model/tests/common.rs create mode 100644 packages/backend/native-utils/crates/model/tests/repository/antenna.rs create mode 100644 packages/backend/native-utils/crates/model/tests/repository/mod.rs diff --git a/packages/backend/native-utils/crates/database/src/lib.rs b/packages/backend/native-utils/crates/database/src/lib.rs index d0e7b2577..36d4a532a 100644 --- a/packages/backend/native-utils/crates/database/src/lib.rs +++ b/packages/backend/native-utils/crates/database/src/lib.rs @@ -22,12 +22,12 @@ mod tests { use crate::{error::Error, init_database}; #[test] - fn error_uninitialized() { + fn unit_lib_error_uninitialized() { assert_eq!(get_database().unwrap_err(), Error::Uninitialized); } #[tokio::test] - async fn connect_in_memory_sqlite() -> Result<(), Error> { + async fn unit_lib_connect_in_memory_sqlite() -> Result<(), Error> { init_database("sqlite::memory:").await?; get_database()?; Ok(()) diff --git a/packages/backend/native-utils/crates/model/src/repository/mod.rs b/packages/backend/native-utils/crates/model/src/repository/mod.rs index b720d1d48..01e11412d 100644 --- a/packages/backend/native-utils/crates/model/src/repository/mod.rs +++ b/packages/backend/native-utils/crates/model/src/repository/mod.rs @@ -6,6 +6,6 @@ use schemars::JsonSchema; use crate::error::Error; #[async_trait] -trait Repository { +pub trait Repository { async fn pack(self) -> Result; } diff --git a/packages/backend/native-utils/crates/model/src/schema/antenna.rs b/packages/backend/native-utils/crates/model/src/schema/antenna.rs index a8065d09e..3f4c40ccb 100644 --- a/packages/backend/native-utils/crates/model/src/schema/antenna.rs +++ b/packages/backend/native-utils/crates/model/src/schema/antenna.rs @@ -7,7 +7,7 @@ use utoipa::ToSchema; use super::{Keyword, Schema, StringList}; use crate::entity::sea_orm_active_enums::AntennaSrcEnum; -#[derive(Debug, JsonSchema, ToSchema)] +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] #[serde(rename_all = "camelCase")] pub struct Antenna { pub id: String, @@ -33,9 +33,10 @@ pub struct Antenna { pub has_unread_note: bool, } -#[derive(Debug, FromStr, JsonSchema, ToSchema)] -#[serde(rename_all = "lowercase")] -#[display(style = "lowercase")] +#[derive(Clone, Debug, FromStr, PartialEq, Eq, JsonSchema, ToSchema)] +#[serde(rename_all = "camelCase")] +#[display(style = "camelCase")] +#[display("'{}'")] pub enum AntennaSrc { Home, All, @@ -62,10 +63,18 @@ pub static VALIDATOR: Lazy = Lazy::new(|| Antenna::validator()); mod tests { use serde_json::json; + use crate::{entity::sea_orm_active_enums::AntennaSrcEnum, schema::antenna::AntennaSrc}; + use super::VALIDATOR; #[test] - fn valid() { + fn unit_schema_src_from_active_enum() { + let src = AntennaSrc::try_from(AntennaSrcEnum::All).unwrap(); + assert_eq!(src, AntennaSrc::All); + } + + #[test] + fn unit_schema_antenna_valid() { let instance = json!({ "id": "9f4x0bkx1u", "createdAt": "2023-05-24T06:56:14.323Z", @@ -89,7 +98,7 @@ mod tests { } #[test] - fn invalid() { + fn unit_schema_antenna_invalid() { let instance = json!({ // "id" is required "id": null, diff --git a/packages/backend/native-utils/crates/model/src/schema/app.rs b/packages/backend/native-utils/crates/model/src/schema/app.rs index adc404eb9..0b18ebeda 100644 --- a/packages/backend/native-utils/crates/model/src/schema/app.rs +++ b/packages/backend/native-utils/crates/model/src/schema/app.rs @@ -5,7 +5,7 @@ use utoipa::ToSchema; use super::Schema; -#[derive(Debug, JsonSchema, ToSchema)] +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] #[serde(rename_all = "camelCase")] pub struct App { pub id: String, @@ -19,7 +19,7 @@ pub struct App { } /// This represents `permissions` in `packages/calckey-js/src/consts.ts`. -#[derive(Debug, JsonSchema, ToSchema)] +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] pub enum Permission { #[serde(rename = "read:account")] ReadAccount, @@ -96,12 +96,12 @@ pub static VALIDATOR: Lazy = Lazy::new(|| App::validator()); #[cfg(test)] mod tests { #[test] - fn valid() { + fn unit_schema_app_valid() { todo!(); } #[test] - fn invalid() { + fn unit_shcmea_app_invalid() { todo!(); } } diff --git a/packages/backend/native-utils/crates/model/tests/common.rs b/packages/backend/native-utils/crates/model/tests/common.rs new file mode 100644 index 000000000..9fd8815d3 --- /dev/null +++ b/packages/backend/native-utils/crates/model/tests/common.rs @@ -0,0 +1,88 @@ +extern crate model; + +mod repository; + +use chrono::Utc; +use model::entity::{antenna, sea_orm_active_enums::AntennaSrcEnum, user}; +use sea_orm::{ + ActiveModelTrait, ActiveValue::Set, DatabaseConnection, DbErr, EntityTrait, TransactionTrait, +}; +use serde_json::json; +use std::env; +use util::{ + id::{create_id, init_id}, + random::gen_string, +}; + +/// Insert predefined entries in the database. +async fn prepare() { + let conn_uri = env::var("DATABASE_URL") + .unwrap_or("postgres://calckey:calckey@localhost/calckey".to_string()); + database::init_database(conn_uri) + .await + .expect("Unable to initialize database connection"); + let db = database::get_database().expect("Unable to get database connection from pool"); + setup_model(db).await; +} + +/// Delete all entries in the database. +async fn cleanup() { + let db = database::get_database().unwrap(); + db.transaction::<_, (), DbErr>(|txn| { + Box::pin(async move { + user::Entity::delete_many().exec(txn).await.unwrap(); + antenna::Entity::delete_many().exec(txn).await.unwrap(); + + Ok(()) + }) + }) + .await + .expect("Unable to delete predefined models"); +} + +async fn setup_model(db: &DatabaseConnection) { + init_id(12); + + db.transaction::<_, (), DbErr>(|txn| { + Box::pin(async move { + let user_id = create_id().unwrap(); + let name = "Alice"; + let user_model = user::ActiveModel { + id: Set(user_id.to_owned()), + created_at: Set(Utc::now().into()), + username: Set(name.to_lowercase().to_string()), + username_lower: Set(name.to_lowercase().to_string()), + name: Set(Some(name.to_string())), + token: Set(Some(gen_string(16))), + is_admin: Set(true), + ..Default::default() + }; + user_model.insert(txn).await?; + let antenna_model = antenna::ActiveModel { + id: Set(create_id().unwrap()), + created_at: Set(Utc::now().into()), + user_id: Set(user_id.to_owned()), + name: Set("Test Antenna".to_string()), + src: Set(AntennaSrcEnum::All), + keywords: Set(json!([["foo", "bar"], ["foobar"]])), + exclude_keywords: Set(json!([["abc"], ["def", "ghi"]])), + with_file: Set(false), + notify: Set(true), + case_sensitive: Set(true), + with_replies: Set(false), + ..Default::default() + }; + antenna_model.insert(txn).await?; + + Ok(()) + }) + }) + .await + .expect("Unable to setup predefined models"); +} + +#[tokio::test] +async fn inte_common_prepare_and_cleanup() { + prepare().await; + cleanup().await; +} diff --git a/packages/backend/native-utils/crates/model/tests/repository/antenna.rs b/packages/backend/native-utils/crates/model/tests/repository/antenna.rs new file mode 100644 index 000000000..42fd3b4bd --- /dev/null +++ b/packages/backend/native-utils/crates/model/tests/repository/antenna.rs @@ -0,0 +1,60 @@ +use model::{ + entity::{antenna, user}, + repository::Repository, + schema, +}; +use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; + +use crate::{cleanup, prepare}; + +#[tokio::test] +async fn inte_repository_antenna_can_pack() { + prepare().await; + + let db = database::get_database().unwrap(); + + let alice_antenna = user::Entity::find() + .filter(user::Column::Username.eq("alice")) + .find_also_related(antenna::Entity) + .one(db) + .await + .unwrap() + .expect("alice not found") + .1 + .expect("alice's antenna not found"); + + let packed = alice_antenna + .to_owned() + .pack() + .await + .expect("Unable to pack"); + + assert_eq!( + packed, + schema::antenna::Antenna { + id: alice_antenna.id, + created_at: alice_antenna.created_at.into(), + name: "Test Antenna".to_string(), + keywords: vec![ + vec!["foo".to_string(), "bar".to_string()], + vec!["foobar".to_string()] + ], + exclude_keywords: vec![ + vec!["abc".to_string()], + vec!["def".to_string(), "ghi".to_string()] + ], + src: schema::antenna::AntennaSrc::All, + user_list_id: None, + user_group_id: None, + users: vec![], + instances: vec![], + case_sensitive: true, + notify: true, + with_replies: false, + with_file: false, + has_unread_note: false, + } + ); + + cleanup().await; +} diff --git a/packages/backend/native-utils/crates/model/tests/repository/mod.rs b/packages/backend/native-utils/crates/model/tests/repository/mod.rs new file mode 100644 index 000000000..c11ef7687 --- /dev/null +++ b/packages/backend/native-utils/crates/model/tests/repository/mod.rs @@ -0,0 +1 @@ +mod antenna; diff --git a/packages/backend/native-utils/crates/util/src/id.rs b/packages/backend/native-utils/crates/util/src/id.rs index f82b64652..94f20a847 100644 --- a/packages/backend/native-utils/crates/util/src/id.rs +++ b/packages/backend/native-utils/crates/util/src/id.rs @@ -27,7 +27,7 @@ mod tests { use crate::id; #[test] - fn can_generate() { + fn unit_id_can_generate() { assert_eq!(id::create_id(), Err(id::ErrorUninitialized)); id::init_id(12); assert_eq!(id::create_id().unwrap().len(), 12); diff --git a/packages/backend/native-utils/crates/util/src/random.rs b/packages/backend/native-utils/crates/util/src/random.rs index fb2f02147..c197298c7 100644 --- a/packages/backend/native-utils/crates/util/src/random.rs +++ b/packages/backend/native-utils/crates/util/src/random.rs @@ -15,7 +15,7 @@ mod tests { use super::gen_string; #[test] - fn can_generate_string() { + fn unit_random_can_generate_string() { assert_eq!(gen_string(16).len(), 16); assert_ne!(gen_string(16), gen_string(16)); let s1 = thread::spawn(|| gen_string(16));