use bson::doc; use bson::oid::ObjectId; use mongo_data::document::document::BaseDocument; use mongo_data::document::pageable::PageableRequest; use mongo_data::repository::base_repository::Repository; use mongodb::options::IndexOptions; use mongodb::{Collection, IndexModel}; use serde::{Deserialize, Serialize}; use testcontainers::clients; use testcontainers::images::generic::GenericImage; #[derive(Deserialize, Serialize, Debug, Clone)] pub struct TestEntity { #[serde(rename = "_id", skip_serializing_if = "Option::is_none")] pub id: Option, pub pid: String, } impl BaseDocument for TestEntity { fn set_id(&mut self, id: Option) { self.id = id } fn get_id(&self) -> Option { self.id } } #[tokio::test(flavor = "multi_thread")] async fn test_database_connection() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); assert_eq!(database_name, db.name()) } #[tokio::test(flavor = "multi_thread")] async fn test_create_index_connection() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let pid_index_name = "pid_index"; let test_collection: Collection = db.collection(collection_name); let options = IndexOptions::builder() .unique(true) .name(Some(String::from(pid_index_name))) .build(); let pid_index = IndexModel::builder() .keys(doc! {"pid": 1}) .options(options.clone()) .build(); let indexes: Vec = vec![pid_index]; mongo_data::config::create_indexes(test_collection.clone(), indexes, None).await; let index_names = match test_collection.clone().list_index_names().await { Ok(index_names) => index_names, Err(err) => panic!("{:?}", err), }; let created_index: Vec = index_names .into_iter() .filter(|index| index == pid_index_name) .collect(); assert_eq!(created_index.len(), 1); if let Some(idx) = created_index.get(0) { assert_eq!(idx.as_str(), pid_index_name) } } #[tokio::test(flavor = "multi_thread")] async fn test_save() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository.save(to_be_saved, None).await; match response { Ok(saved) => { assert_eq!(saved, obj_id) } Err(err) => panic!("{:?}", err), } } #[tokio::test(flavor = "multi_thread")] async fn test_save_many() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let to_be_saved = vec![TestEntity { id: None, pid: "12345".to_string(), }]; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository.save_many(to_be_saved, None, None).await; match response { Ok(saved) => { assert_eq!(saved.len(), 1); if let Some(id) = saved.get(0) { println!("{:#?}", id); assert_ne!(id.to_hex(), "") } } Err(err) => panic!("{:?}", err), } } #[tokio::test(flavor = "multi_thread")] async fn test_find_by_raw_id() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository .save(to_be_saved, None) .await .expect("could not save documents"); let found = repository .find_by_raw_id(response.clone(), None) .await .expect("could not get document"); assert_eq!(found.id, Some(response)) } #[tokio::test(flavor = "multi_thread")] async fn test_find_by_str_id() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository .save(to_be_saved, None) .await .expect("could not save documents"); let found = repository .find_by_id(response.clone().to_hex().as_str(), None) .await .expect("could not get document"); assert_eq!(found.id, Some(response)) } #[tokio::test(flavor = "multi_thread")] async fn test_find_by_str_ids() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository .save(to_be_saved, None) .await .expect("could not save documents"); let found = repository .find_by_ids(vec![response.clone().to_hex()], None) .await .expect("could not get document"); assert_eq!(found.len(), 1); if let Some(entity) = found.get(0) { assert_eq!(entity.id, Some(obj_id)) } } #[tokio::test(flavor = "multi_thread")] async fn test_find_by_raw_ids() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository .save(to_be_saved, None) .await .expect("could not save documents"); let found = repository .find_by_raw_ids(vec![response.clone()], None) .await .expect("could not get document"); assert_eq!(found.len(), 1); if let Some(entity) = found.get(0) { assert_eq!(entity.id, Some(obj_id)) } } #[tokio::test(flavor = "multi_thread")] async fn test_update() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let response = repository .save(to_be_saved, None) .await .expect("could not save documents"); let to_be_updated = TestEntity { id: Some(response.clone()), pid: "Updated".to_string(), }; let _ = repository .update(&to_be_updated, None) .await .expect("could not update document"); let found = repository .find_by_raw_id(response, None) .await .expect("could not find entity"); assert_eq!(to_be_updated.pid, found.pid) } #[tokio::test(flavor = "multi_thread")] async fn test_delete_by_id() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let _ = repository .save_many( vec![ to_be_saved, TestEntity { id: None, pid: "samba".to_string(), }, ], None, None, ) .await .expect("could not save documents"); let _ = repository .delete_by_id(obj_id, None) .await .expect("could not delete document"); let docs_in_collection = repository .count_documents_in_collection(None) .await .expect("could not count docs in collection"); assert_eq!(1, docs_in_collection) } #[tokio::test(flavor = "multi_thread")] async fn test_delete_by_ids() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let obj_id2 = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let _ = repository .save_many( vec![ to_be_saved, TestEntity { id: Some(obj_id2), pid: "samba".to_string(), }, ], None, None, ) .await .expect("could not save documents"); let _ = repository .delete_by_ids(vec![obj_id, obj_id2], None) .await .expect("could not delete document"); let docs_in_collection = repository .count_documents_in_collection(None) .await .expect("could not count docs in collection"); assert_eq!(0, docs_in_collection) } #[tokio::test(flavor = "multi_thread")] async fn test_find_all_pageable() { let _ = pretty_env_logger::try_init(); let docker = clients::Cli::docker(); let target_port = 27017; let username = "test"; let password = "test"; let database_name = "test"; let collection_name = "test"; let init_database = "admin"; let mongo = GenericImage::new("mongo", "6") .with_env_var("MONGO_INITDB_ROOT_USERNAME", username) .with_env_var("MONGO_INITDB_ROOT_PASSWORD", password) .with_env_var("MONGO_INITDB_DATABASE", init_database); let node = docker.run(mongo); let port = node.get_host_port_ipv4(target_port); let mongo_uri = format!("mongodb://{}:{}@localhost:{}/", username, password, port); let db = mongo_data::config::init_db(mongo_uri, database_name) .await .expect("could not connect to database"); let test_collection: Collection = db.collection(collection_name); let obj_id = ObjectId::new(); let obj_id2 = ObjectId::new(); let to_be_saved = TestEntity { id: Some(obj_id), pid: "12345".to_string(), }; let repository = mongo_data::repository::mongo_repository::MongoRepository { collection: test_collection, }; let _ = repository .save_many( vec![ to_be_saved, TestEntity { id: Some(obj_id2), pid: "samba".to_string(), }, ], None, None, ) .await .expect("could not save documents"); let request = PageableRequest { number_per_page: 1, last_item_id: None, }; let response = repository .get_all_pageable(request, None) .await .expect("Could not get documents from repo"); assert_eq!(response.clone().data.len(), 1); let batch_2 = repository .get_all_pageable( PageableRequest { number_per_page: 1, last_item_id: response.clone().last_item_id, }, None, ) .await .expect("Could not get documents from repository"); assert_eq!(batch_2.data.len(), 1); assert_ne!(batch_2.last_item_id, response.last_item_id) }