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<ObjectId>,
pub pid: String,
}
impl BaseDocument for TestEntity {
fn set_id(&mut self, id: Option<ObjectId>) {
self.id = id
}
fn get_id(&self) -> Option<ObjectId> {
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<TestEntity> = 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<IndexModel> = 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<String> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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<TestEntity> = 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)
}