Add unit tests and url checking
This commit is contained in:
parent
c8c259ab7a
commit
97c9080d50
123
src/lib.rs
123
src/lib.rs
@ -44,6 +44,20 @@ pub trait IUuid {
|
||||
fn uuid(&self) -> &str;
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum UrlType {
|
||||
MusicBrainz,
|
||||
MusicButler,
|
||||
Bandcamp,
|
||||
Qobuz,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct InvalidUrlError {
|
||||
url_type: UrlType,
|
||||
url: String,
|
||||
}
|
||||
|
||||
/// MusicBrainz reference.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
pub struct MusicBrainz {
|
||||
@ -54,18 +68,25 @@ pub struct MusicBrainz {
|
||||
impl MusicBrainz {
|
||||
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
let mbid: Mbid = match url.path_segments().and_then(|mut ps| ps.nth(2)) {
|
||||
Some(segment) => Mbid::new(segment)?,
|
||||
None => {
|
||||
return Err(Error::UrlParseError(format!(
|
||||
"invalid MusicBrainz URL: {}",
|
||||
url.as_str()
|
||||
)))
|
||||
|
||||
if !url.domain().map(|u| u.ends_with("musicbrainz.org")).unwrap_or(false) {
|
||||
return Err(Self::invalid_url_error(url).into())
|
||||
}
|
||||
|
||||
let mbid: Mbid = match url.path_segments().and_then(|mut ps| ps.nth(1)) {
|
||||
Some(segment) => Mbid::new(segment)?,
|
||||
None => return Err(Self::invalid_url_error(url).into()),
|
||||
};
|
||||
|
||||
Ok(MusicBrainz { url, mbid })
|
||||
}
|
||||
|
||||
fn invalid_url_error<S: Into<String>>(url: S) -> InvalidUrlError {
|
||||
InvalidUrlError {
|
||||
url_type: UrlType::MusicBrainz,
|
||||
url: url.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IUrl for MusicBrainz {
|
||||
@ -89,8 +110,20 @@ pub struct MusicButler {
|
||||
impl MusicButler {
|
||||
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
|
||||
if !url.domain().map(|u| u.ends_with("musicbutler.io")).unwrap_or(false) {
|
||||
return Err(Self::invalid_url_error(url).into())
|
||||
}
|
||||
|
||||
Ok(MusicButler { url })
|
||||
}
|
||||
|
||||
fn invalid_url_error<S: Into<String>>(url: S) -> InvalidUrlError {
|
||||
InvalidUrlError {
|
||||
url_type: UrlType::MusicButler,
|
||||
url: url.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IUrl for MusicButler {
|
||||
@ -108,8 +141,20 @@ pub struct Bandcamp {
|
||||
impl Bandcamp {
|
||||
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
|
||||
if !url.domain().map(|u| u.ends_with("bandcamp.com")).unwrap_or(false) {
|
||||
return Err(Self::invalid_url_error(url).into())
|
||||
}
|
||||
|
||||
Ok(Bandcamp { url })
|
||||
}
|
||||
|
||||
fn invalid_url_error<S: Into<String>>(url: S) -> InvalidUrlError {
|
||||
InvalidUrlError {
|
||||
url_type: UrlType::Bandcamp,
|
||||
url: url.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IUrl for Bandcamp {
|
||||
@ -127,8 +172,20 @@ pub struct Qobuz {
|
||||
impl Qobuz {
|
||||
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
|
||||
if !url.domain().map(|u| u.ends_with("qobuz.com")).unwrap_or(false) {
|
||||
return Err(Self::invalid_url_error(url).into())
|
||||
}
|
||||
|
||||
Ok(Qobuz { url })
|
||||
}
|
||||
|
||||
fn invalid_url_error<S: Into<String>>(url: S) -> InvalidUrlError {
|
||||
InvalidUrlError {
|
||||
url_type: UrlType::Qobuz,
|
||||
url: url.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IUrl for Qobuz {
|
||||
@ -323,6 +380,8 @@ pub enum Error {
|
||||
DatabaseError(String),
|
||||
/// The [`MusicHoard`] failed to parse a user-provided URL.
|
||||
UrlParseError(String),
|
||||
/// The user-provided URL is not valid.
|
||||
InvalidUrlError(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@ -333,6 +392,7 @@ impl fmt::Display for Error {
|
||||
write!(f, "failed to read/write from/to the database: {s}")
|
||||
}
|
||||
Self::UrlParseError(ref s) => write!(f, "failed to parse a user-provided URL: {s}"),
|
||||
Self::InvalidUrlError(ref s) => write!(f, "user-provided URL is invalid: {s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,6 +427,12 @@ impl From<uuid::Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InvalidUrlError> for Error {
|
||||
fn from(err: InvalidUrlError) -> Error {
|
||||
Error::InvalidUrlError(format!("{:?} - {}", err.url_type, err.url))
|
||||
}
|
||||
}
|
||||
|
||||
/// The Music Hoard. It is responsible for pulling information from both the library and the
|
||||
/// database, ensuring its consistent and writing back any changes.
|
||||
pub struct MusicHoard<LIB, DB> {
|
||||
@ -545,6 +611,49 @@ mod tests {
|
||||
items
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn musicbrainz() {
|
||||
let uuid = "d368baa8-21ca-4759-9731-0b2753071ad8";
|
||||
let url = format!("https://musicbrainz.org/artist/{uuid}");
|
||||
let mb = MusicBrainz::new(&url).unwrap();
|
||||
assert_eq!(url, mb.url());
|
||||
assert_eq!(uuid, mb.uuid());
|
||||
|
||||
let url = format!("https://musicbrainz.org/artist/i-am-not-a-uuid");
|
||||
assert!(MusicBrainz::new(&url).is_err());
|
||||
|
||||
let url = format!("https://musicbrainz.org/artist");
|
||||
assert!(MusicBrainz::new(&url).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn urls() {
|
||||
let musicbrainz = "https://musicbrainz.org/artist/d368baa8-21ca-4759-9731-0b2753071ad8";
|
||||
let musicbutler = "https://www.musicbutler.io/artist-page/483340948";
|
||||
let bandcamp = "https://thelasthangmen.bandcamp.com/";
|
||||
let qobuz = "https://www.qobuz.com/nl-nl/interpreter/the-last-hangmen/1244413";
|
||||
|
||||
assert!(MusicBrainz::new(&musicbrainz).is_ok());
|
||||
assert!(MusicBrainz::new(&musicbutler).is_err());
|
||||
assert!(MusicBrainz::new(&bandcamp).is_err());
|
||||
assert!(MusicBrainz::new(&qobuz).is_err());
|
||||
|
||||
assert!(MusicButler::new(&musicbrainz).is_err());
|
||||
assert!(MusicButler::new(&musicbutler).is_ok());
|
||||
assert!(MusicButler::new(&bandcamp).is_err());
|
||||
assert!(MusicButler::new(&qobuz).is_err());
|
||||
|
||||
assert!(Bandcamp::new(&musicbrainz).is_err());
|
||||
assert!(Bandcamp::new(&musicbutler).is_err());
|
||||
assert!(Bandcamp::new(&bandcamp).is_ok());
|
||||
assert!(Bandcamp::new(&qobuz).is_err());
|
||||
|
||||
assert!(Qobuz::new(&musicbrainz).is_err());
|
||||
assert!(Qobuz::new(&musicbutler).is_err());
|
||||
assert!(Qobuz::new(&bandcamp).is_err());
|
||||
assert!(Qobuz::new(&qobuz).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_track() {
|
||||
let left = Track {
|
||||
|
Loading…
Reference in New Issue
Block a user