use crate::{model::Model, test_db::test_error::TestError, test_error};
use mongodb::{
bson::{oid::ObjectId, Document},
ClientSession,
};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
pub struct AssertModel<'am, D>
where
D: Serialize + for<'a> Deserialize<'a> + Send + Sync + Unpin,
{
pub model: &'am Model<D>,
}
impl<'am, D> AssertModel<'am, D>
where
D: Serialize + for<'a> Deserialize<'a> + Send + Sync + Unpin,
{
pub fn from(model: &'am Model<D>) -> AssertModel<'am, D> {
AssertModel { model }
}
pub async fn assert_exists(
&self,
filter: Document,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>> {
if !self.model.exists(filter.clone(), None, session).await? {
test_error!(
"Document by filter: {:?} in collection {} does not exist",
filter,
self.model.collection.name()
);
}
Ok(self)
}
pub async fn assert_does_not_exists(
&self,
filter: Document,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>> {
if self.model.exists(filter.clone(), None, session).await? {
test_error!(
"Document by filter: {:?} in collection {} exists",
filter,
self.model.collection.name()
);
}
Ok(self)
}
pub async fn assert_exists_by_oid(
&self,
oid: &ObjectId,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>> {
if !self.model.exists_by_oid(oid, None, session).await? {
test_error!(
"Document by ObjectId: {:?} in collection {} does not exist",
oid,
self.model.collection.name()
);
}
Ok(self)
}
pub async fn assert_does_not_exist_by_oid(
&self,
oid: &ObjectId,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>> {
if self.model.exists_by_oid(oid, None, session).await? {
test_error!(
"Document by ObjectId: {:?} in collection {} exists",
oid,
self.model.collection.name()
);
}
Ok(self)
}
pub async fn assert_exists_by_field_value<F, V>(
&self,
field: F,
value: V,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>>
where
F: Into<std::string::String> + Debug + Clone,
std::string::String: From<F>,
V: Into<mongodb::bson::Bson> + Debug + Clone,
mongodb::bson::Bson: From<V>,
{
if !self
.model
.exists_by_field_value(field.clone(), value.clone(), None, session)
.await?
{
test_error!(
"Document by field: {:?} value: {:?} in collection {} does not exist",
field,
value,
self.model.collection.name()
);
}
Ok(self)
}
pub async fn assert_does_not_exist_by_field_value<F, V>(
&self,
field: F,
value: V,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>>
where
F: Into<std::string::String> + Debug + Clone,
std::string::String: From<F>,
V: Into<mongodb::bson::Bson> + Debug + Clone,
mongodb::bson::Bson: From<V>,
{
if self
.model
.exists_by_field_value(field.clone(), value.clone(), None, session)
.await?
{
test_error!(
"Document by field: {:?} value: {:?} in collection {} exists",
field,
value,
self.model.collection.name()
);
}
Ok(self)
}
pub async fn assert_count(
&self,
filter: Document,
count: usize,
session: Option<&mut ClientSession>,
) -> Result<&AssertModel<'am, D>, Box<dyn std::error::Error>> {
let document_count = self
.model
.count_documents(filter.clone(), None, session)
.await?;
if document_count != count {
test_error!(
"Document count by filter: {:?} in collection {} has {} documents, but expected: {}",
filter,
self.model.collection.name(),
document_count,
count
);
}
Ok(self)
}
}