use crate::entity::MongoEntity;
use crate::repo::MongoRepo;
use mongodb::{Client, Database};
use std::error::Error;
use std::sync::Arc;
#[derive(Debug)]
pub struct MongoInstance {
pub db: Arc<Database>,
pub client: Client,
}
impl MongoInstance {
pub async fn setup(uri: &str) -> Result<MongoInstance, Box<dyn Error + Send + Sync>> {
let client = Client::with_uri_str(uri).await?;
let db = client.default_database().unwrap();
Ok(MongoInstance {
db: Arc::new(db),
client,
})
}
pub async fn drop_database(&self) {
}
pub fn repo<T: MongoEntity>(&self, name: &str) -> MongoRepo<T> {
MongoRepo::new(self.db.clone().collection(name))
}
}
#[cfg(test)]
mod mongo_tests {
use crate::entity::MongoEntity;
use crate::instance::MongoInstance;
use crate::repo::{MongoRepo, MongoRepository};
use bson::doc;
use bson::oid::ObjectId;
use std::error::Error;
use mongo_orm_macro::mongo_doc;
struct Context {
instance: MongoInstance,
}
async fn setup() -> Context {
let instance = MongoInstance::setup("mongodb://localhost:27017/rust_test")
.await
.unwrap();
instance.drop_database().await;
Context { instance }
}
#[derive(mongo_doc)]
struct SampleStruct {
name: String,
value: i32,
#[foreign_key]
fid: String,
}
#[derive(mongo_doc)]
struct SampleStruct2 {
id: String,
name: String,
#[foreign_key]
fid: String,
}
#[tokio::test]
async fn should_setup_db() -> Result<(), Box<dyn Error + Send + Sync>> {
let context = setup().await;
Ok(())
}
#[tokio::test]
async fn should_insert_item() -> Result<(), Box<dyn Error + Send + Sync>> {
let context = setup().await;
let repo: MongoRepo<SampleStruct> = context.instance.repo("sample");
let item = SampleStruct {
name: "test".to_string(),
value: 12,
fid: ObjectId::new().to_hex(),
};
let id = repo.insert(&item).await;
let res = repo.find_by_id(&id).await;
assert!(res.is_some(), "Item not inserted");
Ok(())
}
#[tokio::test]
async fn should_insert_multiple_items() -> Result<(), Box<dyn Error + Send + Sync>> {
let context = setup().await;
let repo: MongoRepo<SampleStruct> = context.instance.repo("sample");
let items = vec![
SampleStruct {
name: "a".to_string(),
value: 42,
fid: ObjectId::new().to_hex(),
},
SampleStruct {
name: "b".to_string(),
value: 42,
fid: ObjectId::new().to_hex(),
},
];
repo.insert_many(&items).await;
let res = repo.count(None).await;
assert_eq!(res, 2, "Items not inserted properly");
Ok(())
}
#[tokio::test]
async fn should_find_items_properly() -> Result<(), Box<dyn Error + Send + Sync>> {
let context = setup().await;
let repo: MongoRepo<SampleStruct> = context.instance.repo("sample");
let items = vec![
SampleStruct {
name: "a".to_string(),
value: 12,
fid: ObjectId::new().to_hex(),
},
SampleStruct {
name: "b".to_string(),
value: 18,
fid: ObjectId::new().to_hex(),
},
];
repo.insert_many(&items).await;
let res = repo
.count(Some(doc! {
"value":{"$gt":12}
}))
.await;
assert_eq!(res, 1, "Items not inserted properly");
Ok(())
}
#[tokio::test]
async fn should_store_id_properly() -> Result<(), Box<dyn Error + Send + Sync>> {
let context = setup().await;
let repo: MongoRepo<SampleStruct2> = context.instance.repo("sample_2");
let item = SampleStruct2 {
id: "unique".to_string(),
name: "a".to_string(),
fid: ObjectId::new().to_hex(),
};
let id = repo.insert(&item).await;
assert_eq!(id, "unique", "id not set properly");
Ok(())
}
#[tokio::test]
async fn should_store_id_properly_2() -> Result<(), Box<dyn Error + Send + Sync>> {
let context = setup().await;
let repo: MongoRepo<SampleStruct2> = context.instance.repo("sample_2");
let i = ObjectId::new().to_hex();
let item = SampleStruct2 {
id: i.clone(),
name: "a".to_string(),
fid: ObjectId::new().to_hex(),
};
let id = repo.insert(&item).await;
assert_eq!(id, i.clone(), "id not set properly");
assert_eq!(
repo.find_by_id(&i).await.unwrap().id,
i.clone(),
"id not set properly"
);
Ok(())
}
}