use once_cell::sync::Lazy;
use regex::Regex;
use crate::hash::Hash;
use crate::operation::plain::{PlainFields, PlainValue};
use crate::schema::validate::error::BlobError;
pub fn validate_mime_type(value: &str) -> bool {
static NAME_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new("^[a-z-]{1,12}\\/(([a-z0-9]{1,18})[\\.|+|-]){0,6}[a-z0-9]{1,16}$").unwrap()
});
NAME_REGEX.is_match(value)
}
pub fn validate_pieces(value: &[Vec<Hash>]) -> bool {
!value.is_empty()
}
pub fn validate_blob_v1_fields(fields: &PlainFields) -> Result<(), BlobError> {
match fields.get("mime_type") {
Some(PlainValue::String(value)) => {
if validate_mime_type(value) {
Ok(())
} else {
Err(BlobError::MimeTypeInvalid)
}
}
_ => Ok(()),
}?;
match fields.get("pieces") {
Some(PlainValue::PinnedRelationList(value)) => {
if validate_pieces(value) {
Ok(())
} else {
Err(BlobError::PiecesEmpty)
}
}
_ => Ok(()),
}?;
Ok(())
}
#[cfg(test)]
mod test {
use rstest::rstest;
use crate::document::DocumentViewId;
use crate::operation::plain::PlainFields;
use crate::test_utils::fixtures::random_document_view_id;
use super::{validate_blob_v1_fields, validate_mime_type};
#[rstest]
#[case(vec![
("length", 1.into()),
("mime_type", "image/png".into()),
("pieces", vec![random_document_view_id()].into()),
].into())]
#[case(vec![
("length", 1000.into()),
("mime_type", "application/x-zip-compressed".into()),
("pieces", vec![random_document_view_id()].into()),
].into())]
#[should_panic]
#[case::invalid_mime_type(vec![
("length", 100.into()),
("mime_type", "not a mime type".into()),
("pieces", vec![random_document_view_id()].into()),
].into())]
#[should_panic]
#[case::empty_pieces(vec![
("length", 1.into()),
("mime_type", "image/png".into()),
("pieces", Vec::<DocumentViewId>::new().into()),
].into())]
fn check_fields(#[case] fields: PlainFields) {
assert!(validate_blob_v1_fields(&fields).is_ok());
}
#[rstest]
#[case("video/webm")]
#[case("image/webp")]
#[case("x-conference/x-cooltalk")]
#[case("application/vnd.cluetrust.cartomobile-config-pkg")]
#[case("application/emma+xml")]
#[case("my/made.up.mime.type")] #[should_panic]
#[case("wrong format")]
#[should_panic]
#[case("wrong_format")]
#[should_panic]
#[case("wrong/f o r m a t")]
#[should_panic]
#[case("wrong/!format!")]
#[should_panic]
#[case("wrong/for..mat")]
#[should_panic]
#[case("wro.ng/for..mat")]
#[should_panic]
#[case("this/mime.type.has.one.too.many.elements.yes")]
#[should_panic]
#[case("this/mime.type.hasoneelementwhichiswaytoolong")]
#[should_panic]
#[case("thismimetypealsohasonelongelement/one.element.too.long")]
fn check_mime_type_field(#[case] name_str: &str) {
assert!(validate_mime_type(name_str));
}
}