Decide carefully where external::musicbrainz
belongs
#196
@ -133,6 +133,11 @@ mod tests {
|
|||||||
assert_eq!(url_str, mb.url().as_ref());
|
assert_eq!(url_str, mb.url().as_ref());
|
||||||
assert_eq!(uuid, mb.mbid().uuid().to_string());
|
assert_eq!(uuid, mb.mbid().uuid().to_string());
|
||||||
|
|
||||||
|
let mbid: Mbid = TryInto::<Uuid>::try_into(uuid).unwrap().into();
|
||||||
|
let mb: MbArtistRef = mbid.into();
|
||||||
|
assert_eq!(url_str, mb.url().as_ref());
|
||||||
|
assert_eq!(uuid, mb.mbid().uuid().to_string());
|
||||||
|
|
||||||
let url: Url = url_str.as_str().try_into().unwrap();
|
let url: Url = url_str.as_str().try_into().unwrap();
|
||||||
let mb: MbArtistRef = url.try_into().unwrap();
|
let mb: MbArtistRef = url.try_into().unwrap();
|
||||||
assert_eq!(url_str, mb.url().as_ref());
|
assert_eq!(url_str, mb.url().as_ref());
|
||||||
@ -152,6 +157,11 @@ mod tests {
|
|||||||
assert_eq!(url_str, mb.url().as_ref());
|
assert_eq!(url_str, mb.url().as_ref());
|
||||||
assert_eq!(uuid, mb.mbid().uuid().to_string());
|
assert_eq!(uuid, mb.mbid().uuid().to_string());
|
||||||
|
|
||||||
|
let mbid: Mbid = TryInto::<Uuid>::try_into(uuid).unwrap().into();
|
||||||
|
let mb: MbAlbumRef = mbid.into();
|
||||||
|
assert_eq!(url_str, mb.url().as_ref());
|
||||||
|
assert_eq!(uuid, mb.mbid().uuid().to_string());
|
||||||
|
|
||||||
let url: Url = url_str.as_str().try_into().unwrap();
|
let url: Url = url_str.as_str().try_into().unwrap();
|
||||||
let mb: MbAlbumRef = url.try_into().unwrap();
|
let mb: MbAlbumRef = url.try_into().unwrap();
|
||||||
assert_eq!(url_str, mb.url().as_ref());
|
assert_eq!(url_str, mb.url().as_ref());
|
||||||
|
@ -48,7 +48,6 @@ try_from_impl_for_mbid!(&str);
|
|||||||
try_from_impl_for_mbid!(&String);
|
try_from_impl_for_mbid!(&String);
|
||||||
try_from_impl_for_mbid!(String);
|
try_from_impl_for_mbid!(String);
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn errors() {
|
fn errors() {
|
||||||
let mbid_err: MbidError = TryInto::<Mbid>::try_into("i-am-not-a-uuid").unwrap_err();
|
let mbid_err: MbidError = TryInto::<Mbid>::try_into("i-am-not-a-uuid").unwrap_err();
|
||||||
|
64
src/external/musicbrainz/api/lookup.rs
vendored
64
src/external/musicbrainz/api/lookup.rs
vendored
@ -54,7 +54,7 @@ impl<'a> LookupArtistRequest<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct LookupArtistResponse {
|
pub struct LookupArtistResponse {
|
||||||
pub release_groups: Vec<LookupArtistResponseReleaseGroup>,
|
pub release_groups: Vec<LookupArtistResponseReleaseGroup>,
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ impl From<DeserializeLookupArtistResponse> for LookupArtistResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct LookupArtistResponseReleaseGroup {
|
pub struct LookupArtistResponseReleaseGroup {
|
||||||
pub id: Mbid,
|
pub id: Mbid,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
@ -82,7 +82,7 @@ pub struct LookupArtistResponseReleaseGroup {
|
|||||||
pub secondary_types: Vec<AlbumSecondaryType>,
|
pub secondary_types: Vec<AlbumSecondaryType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
#[serde(rename_all(deserialize = "kebab-case"))]
|
#[serde(rename_all(deserialize = "kebab-case"))]
|
||||||
struct DeserializeLookupArtistResponseReleaseGroup {
|
struct DeserializeLookupArtistResponseReleaseGroup {
|
||||||
id: SerdeMbid,
|
id: SerdeMbid,
|
||||||
@ -103,3 +103,61 @@ impl From<DeserializeLookupArtistResponseReleaseGroup> for LookupArtistResponseR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use mockall::predicate;
|
||||||
|
|
||||||
|
use crate::external::musicbrainz::MockIMusicBrainzHttp;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lookup_artist() {
|
||||||
|
let mut http = MockIMusicBrainzHttp::new();
|
||||||
|
let url = format!(
|
||||||
|
"https://musicbrainz.org/ws/2/artist/{mbid}?inc=release-groups",
|
||||||
|
mbid = "00000000-0000-0000-0000-000000000000",
|
||||||
|
);
|
||||||
|
|
||||||
|
let de_release_group = DeserializeLookupArtistResponseReleaseGroup {
|
||||||
|
id: SerdeMbid("11111111-1111-1111-1111-111111111111".try_into().unwrap()),
|
||||||
|
title: String::from("an album"),
|
||||||
|
first_release_date: SerdeAlbumDate((1986, 4).into()),
|
||||||
|
primary_type: SerdeAlbumPrimaryType(AlbumPrimaryType::Album),
|
||||||
|
secondary_types: vec![SerdeAlbumSecondaryType(AlbumSecondaryType::Compilation)],
|
||||||
|
};
|
||||||
|
let de_response = DeserializeLookupArtistResponse {
|
||||||
|
release_groups: vec![de_release_group.clone()],
|
||||||
|
};
|
||||||
|
|
||||||
|
let release_group = LookupArtistResponseReleaseGroup {
|
||||||
|
id: de_release_group.id.0,
|
||||||
|
title: de_release_group.title,
|
||||||
|
first_release_date: de_release_group.first_release_date.0,
|
||||||
|
primary_type: de_release_group.primary_type.0,
|
||||||
|
secondary_types: de_release_group
|
||||||
|
.secondary_types
|
||||||
|
.into_iter()
|
||||||
|
.map(|st| st.0)
|
||||||
|
.collect(),
|
||||||
|
};
|
||||||
|
let response = LookupArtistResponse {
|
||||||
|
release_groups: vec![release_group],
|
||||||
|
};
|
||||||
|
|
||||||
|
http.expect_get()
|
||||||
|
.times(1)
|
||||||
|
.with(predicate::eq(url))
|
||||||
|
.return_once(|_| Ok(de_response));
|
||||||
|
|
||||||
|
let mut client = MusicBrainzClient::new(http);
|
||||||
|
|
||||||
|
let mbid: Mbid = "00000000-0000-0000-0000-000000000000".try_into().unwrap();
|
||||||
|
let mut request = LookupArtistRequest::new(&mbid);
|
||||||
|
request.include_release_groups();
|
||||||
|
let result = client.lookup_artist(request).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(result, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
109
src/external/musicbrainz/api/mod.rs
vendored
109
src/external/musicbrainz/api/mod.rs
vendored
@ -68,6 +68,7 @@ impl<Http> MusicBrainzClient<Http> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct SerdeMbid(Mbid);
|
pub struct SerdeMbid(Mbid);
|
||||||
|
|
||||||
impl From<SerdeMbid> for Mbid {
|
impl From<SerdeMbid> for Mbid {
|
||||||
@ -105,6 +106,7 @@ impl<'de> Deserialize<'de> for SerdeMbid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct SerdeAlbumDate(AlbumDate);
|
pub struct SerdeAlbumDate(AlbumDate);
|
||||||
|
|
||||||
impl From<SerdeAlbumDate> for AlbumDate {
|
impl From<SerdeAlbumDate> for AlbumDate {
|
||||||
@ -170,7 +172,7 @@ pub enum AlbumPrimaryTypeDef {
|
|||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub struct SerdeAlbumPrimaryType(#[serde(with = "AlbumPrimaryTypeDef")] AlbumPrimaryType);
|
pub struct SerdeAlbumPrimaryType(#[serde(with = "AlbumPrimaryTypeDef")] AlbumPrimaryType);
|
||||||
|
|
||||||
impl From<SerdeAlbumPrimaryType> for AlbumPrimaryType {
|
impl From<SerdeAlbumPrimaryType> for AlbumPrimaryType {
|
||||||
@ -179,12 +181,6 @@ impl From<SerdeAlbumPrimaryType> for AlbumPrimaryType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AlbumPrimaryType> for SerdeAlbumPrimaryType {
|
|
||||||
fn from(value: AlbumPrimaryType) -> Self {
|
|
||||||
SerdeAlbumPrimaryType(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(remote = "AlbumSecondaryType")]
|
#[serde(remote = "AlbumSecondaryType")]
|
||||||
pub enum AlbumSecondaryTypeDef {
|
pub enum AlbumSecondaryTypeDef {
|
||||||
@ -206,7 +202,7 @@ pub enum AlbumSecondaryTypeDef {
|
|||||||
FieldRecording,
|
FieldRecording,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub struct SerdeAlbumSecondaryType(#[serde(with = "AlbumSecondaryTypeDef")] AlbumSecondaryType);
|
pub struct SerdeAlbumSecondaryType(#[serde(with = "AlbumSecondaryTypeDef")] AlbumSecondaryType);
|
||||||
|
|
||||||
impl From<SerdeAlbumSecondaryType> for AlbumSecondaryType {
|
impl From<SerdeAlbumSecondaryType> for AlbumSecondaryType {
|
||||||
@ -215,8 +211,99 @@ impl From<SerdeAlbumSecondaryType> for AlbumSecondaryType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AlbumSecondaryType> for SerdeAlbumSecondaryType {
|
#[cfg(test)]
|
||||||
fn from(value: AlbumSecondaryType) -> Self {
|
mod tests {
|
||||||
SerdeAlbumSecondaryType(value)
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn errors() {
|
||||||
|
let http_err = HttpError::Client(String::from("a http error"));
|
||||||
|
let http_err: Error = http_err.into();
|
||||||
|
assert!(matches!(http_err, Error::Http(_)));
|
||||||
|
assert!(!http_err.to_string().is_empty());
|
||||||
|
assert!(!format!("{http_err:?}").is_empty());
|
||||||
|
|
||||||
|
let rate_err = HttpError::Status(MB_RATE_LIMIT_CODE);
|
||||||
|
let rate_err: Error = rate_err.into();
|
||||||
|
assert!(matches!(rate_err, Error::RateLimit));
|
||||||
|
assert!(!rate_err.to_string().is_empty());
|
||||||
|
assert!(!format!("{rate_err:?}").is_empty());
|
||||||
|
|
||||||
|
let unk_err = HttpError::Status(404);
|
||||||
|
let unk_err: Error = unk_err.into();
|
||||||
|
assert!(matches!(unk_err, Error::Unknown(_)));
|
||||||
|
assert!(!unk_err.to_string().is_empty());
|
||||||
|
assert!(!format!("{unk_err:?}").is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn format_album_date() {
|
||||||
|
struct Null;
|
||||||
|
assert_eq!(
|
||||||
|
MusicBrainzClient::<Null>::format_album_date(&AlbumDate::new(None, None, None)),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
MusicBrainzClient::<Null>::format_album_date(&(1986).into()),
|
||||||
|
Some(String::from("1986"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
MusicBrainzClient::<Null>::format_album_date(&(1986, 4).into()),
|
||||||
|
Some(String::from("1986-04"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
MusicBrainzClient::<Null>::format_album_date(&(1986, 4, 21).into()),
|
||||||
|
Some(String::from("1986-04-21"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde() {
|
||||||
|
let mbid = "\"d368baa8-21ca-4759-9731-0b2753071ad8\"";
|
||||||
|
let mbid: SerdeMbid = serde_json::from_str(mbid).unwrap();
|
||||||
|
let mbid: Mbid = mbid.into();
|
||||||
|
assert_eq!(
|
||||||
|
mbid,
|
||||||
|
"d368baa8-21ca-4759-9731-0b2753071ad8".try_into().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mbid = "0";
|
||||||
|
let result: Result<SerdeMbid, _> = serde_json::from_str(mbid);
|
||||||
|
assert!(result
|
||||||
|
.unwrap_err()
|
||||||
|
.to_string()
|
||||||
|
.contains("a valid MusicBrainz identifier"));
|
||||||
|
|
||||||
|
let album_date = "\"1986-04-21\"";
|
||||||
|
let album_date: SerdeAlbumDate = serde_json::from_str(album_date).unwrap();
|
||||||
|
let album_date: AlbumDate = album_date.into();
|
||||||
|
assert_eq!(album_date, AlbumDate::new(Some(1986), Some(4), Some(21)));
|
||||||
|
|
||||||
|
let album_date = "\"1986-04\"";
|
||||||
|
let album_date: SerdeAlbumDate = serde_json::from_str(album_date).unwrap();
|
||||||
|
let album_date: AlbumDate = album_date.into();
|
||||||
|
assert_eq!(album_date, AlbumDate::new(Some(1986), Some(4), None));
|
||||||
|
|
||||||
|
let album_date = "\"1986\"";
|
||||||
|
let album_date: SerdeAlbumDate = serde_json::from_str(album_date).unwrap();
|
||||||
|
let album_date: AlbumDate = album_date.into();
|
||||||
|
assert_eq!(album_date, AlbumDate::new(Some(1986), None, None));
|
||||||
|
|
||||||
|
let album_date = "0";
|
||||||
|
let result: Result<SerdeAlbumDate, _> = serde_json::from_str(album_date);
|
||||||
|
assert!(result
|
||||||
|
.unwrap_err()
|
||||||
|
.to_string()
|
||||||
|
.contains("a valid YYYY(-MM-(-DD)) date"));
|
||||||
|
|
||||||
|
let primary_type = "\"EP\"";
|
||||||
|
let primary_type: SerdeAlbumPrimaryType = serde_json::from_str(primary_type).unwrap();
|
||||||
|
let primary_type: AlbumPrimaryType = primary_type.into();
|
||||||
|
assert_eq!(primary_type, AlbumPrimaryType::Ep);
|
||||||
|
|
||||||
|
let secondary_type = "\"Field recording\"";
|
||||||
|
let secondary_type: SerdeAlbumSecondaryType = serde_json::from_str(secondary_type).unwrap();
|
||||||
|
let secondary_type: AlbumSecondaryType = secondary_type.into();
|
||||||
|
assert_eq!(secondary_type, AlbumSecondaryType::FieldRecording);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
140
src/external/musicbrainz/api/search.rs
vendored
140
src/external/musicbrainz/api/search.rs
vendored
@ -26,7 +26,7 @@ impl<Http: IMusicBrainzHttp> MusicBrainzClient<Http> {
|
|||||||
let mut query: Vec<String> = vec![];
|
let mut query: Vec<String> = vec![];
|
||||||
|
|
||||||
if let Some(arid) = request.arid {
|
if let Some(arid) = request.arid {
|
||||||
query.push(format!("arid:{}", arid.uuid().as_hyphenated().to_string()));
|
query.push(format!("arid:{}", arid.uuid().as_hyphenated()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(date) = request.first_release_date {
|
if let Some(date) = request.first_release_date {
|
||||||
@ -40,7 +40,7 @@ impl<Http: IMusicBrainzHttp> MusicBrainzClient<Http> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rgid) = request.rgid {
|
if let Some(rgid) = request.rgid {
|
||||||
query.push(format!("rgid:{}", rgid.uuid().as_hyphenated().to_string()));
|
query.push(format!("rgid:{}", rgid.uuid().as_hyphenated()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let query: String =
|
let query: String =
|
||||||
@ -86,12 +86,12 @@ impl<'a> SearchReleaseGroupRequest<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct SearchReleaseGroupResponse {
|
pub struct SearchReleaseGroupResponse {
|
||||||
pub release_groups: Vec<SearchReleaseGroupResponseReleaseGroup>,
|
pub release_groups: Vec<SearchReleaseGroupResponseReleaseGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
#[serde(rename_all(deserialize = "kebab-case"))]
|
#[serde(rename_all(deserialize = "kebab-case"))]
|
||||||
struct DeserializeSearchReleaseGroupResponse {
|
struct DeserializeSearchReleaseGroupResponse {
|
||||||
release_groups: Vec<DeserializeSearchReleaseGroupResponseReleaseGroup>,
|
release_groups: Vec<DeserializeSearchReleaseGroupResponseReleaseGroup>,
|
||||||
@ -105,7 +105,7 @@ impl From<DeserializeSearchReleaseGroupResponse> for SearchReleaseGroupResponse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct SearchReleaseGroupResponseReleaseGroup {
|
pub struct SearchReleaseGroupResponseReleaseGroup {
|
||||||
pub score: u8,
|
pub score: u8,
|
||||||
pub id: Mbid,
|
pub id: Mbid,
|
||||||
@ -115,7 +115,7 @@ pub struct SearchReleaseGroupResponseReleaseGroup {
|
|||||||
pub secondary_types: Option<Vec<AlbumSecondaryType>>,
|
pub secondary_types: Option<Vec<AlbumSecondaryType>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
#[serde(rename_all(deserialize = "kebab-case"))]
|
#[serde(rename_all(deserialize = "kebab-case"))]
|
||||||
struct DeserializeSearchReleaseGroupResponseReleaseGroup {
|
struct DeserializeSearchReleaseGroupResponseReleaseGroup {
|
||||||
score: u8,
|
score: u8,
|
||||||
@ -142,3 +142,131 @@ impl From<DeserializeSearchReleaseGroupResponseReleaseGroup>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use mockall::{predicate, Sequence};
|
||||||
|
|
||||||
|
use crate::{collection::album::AlbumId, external::musicbrainz::MockIMusicBrainzHttp};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn search_release_group() {
|
||||||
|
let mut http = MockIMusicBrainzHttp::new();
|
||||||
|
let url_title = format!(
|
||||||
|
"https://musicbrainz.org/ws/2\
|
||||||
|
/release-group\
|
||||||
|
?query=arid%3A{arid}+AND+firstreleasedate%3A{date}+AND+releasegroup%3A%22{title}%22",
|
||||||
|
arid = "00000000-0000-0000-0000-000000000000",
|
||||||
|
date = "1986-04",
|
||||||
|
title = "an+album",
|
||||||
|
);
|
||||||
|
let url_rgid = format!(
|
||||||
|
"https://musicbrainz.org/ws/2\
|
||||||
|
/release-group\
|
||||||
|
?query=rgid%3A{rgid}",
|
||||||
|
rgid = "11111111-1111-1111-1111-111111111111",
|
||||||
|
);
|
||||||
|
|
||||||
|
let de_release_group = DeserializeSearchReleaseGroupResponseReleaseGroup {
|
||||||
|
score: 67,
|
||||||
|
id: SerdeMbid("11111111-1111-1111-1111-111111111111".try_into().unwrap()),
|
||||||
|
title: String::from("an album"),
|
||||||
|
first_release_date: SerdeAlbumDate((1986, 4).into()),
|
||||||
|
primary_type: SerdeAlbumPrimaryType(AlbumPrimaryType::Album),
|
||||||
|
secondary_types: Some(vec![SerdeAlbumSecondaryType(AlbumSecondaryType::Live)]),
|
||||||
|
};
|
||||||
|
let de_response = DeserializeSearchReleaseGroupResponse {
|
||||||
|
release_groups: vec![de_release_group.clone()],
|
||||||
|
};
|
||||||
|
|
||||||
|
let release_group = SearchReleaseGroupResponseReleaseGroup {
|
||||||
|
score: 67,
|
||||||
|
id: de_release_group.id.0,
|
||||||
|
title: de_release_group.title,
|
||||||
|
first_release_date: de_release_group.first_release_date.0,
|
||||||
|
primary_type: de_release_group.primary_type.0,
|
||||||
|
secondary_types: de_release_group
|
||||||
|
.secondary_types
|
||||||
|
.map(|v| v.into_iter().map(|st| st.0).collect()),
|
||||||
|
};
|
||||||
|
let response = SearchReleaseGroupResponse {
|
||||||
|
release_groups: vec![release_group.clone()],
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut seq = Sequence::new();
|
||||||
|
|
||||||
|
let title_response = de_response.clone();
|
||||||
|
http.expect_get()
|
||||||
|
.times(1)
|
||||||
|
.with(predicate::eq(url_title))
|
||||||
|
.return_once(|_| Ok(title_response))
|
||||||
|
.in_sequence(&mut seq);
|
||||||
|
|
||||||
|
let rgid_response = de_response;
|
||||||
|
http.expect_get()
|
||||||
|
.times(1)
|
||||||
|
.with(predicate::eq(url_rgid))
|
||||||
|
.return_once(|_| Ok(rgid_response))
|
||||||
|
.in_sequence(&mut seq);
|
||||||
|
|
||||||
|
let mut client = MusicBrainzClient::new(http);
|
||||||
|
|
||||||
|
let arid: Mbid = "00000000-0000-0000-0000-000000000000".try_into().unwrap();
|
||||||
|
let title: AlbumId = AlbumId::new("an album");
|
||||||
|
let date = (1986, 4).into();
|
||||||
|
|
||||||
|
let mut request = SearchReleaseGroupRequest::new();
|
||||||
|
request
|
||||||
|
.arid(&arid)
|
||||||
|
.release_group(&title.title)
|
||||||
|
.first_release_date(&date);
|
||||||
|
|
||||||
|
let matches = client.search_release_group(request).unwrap();
|
||||||
|
assert_eq!(matches, response);
|
||||||
|
|
||||||
|
let rgid: Mbid = "11111111-1111-1111-1111-111111111111".try_into().unwrap();
|
||||||
|
|
||||||
|
let mut request = SearchReleaseGroupRequest::new();
|
||||||
|
request.rgid(&rgid);
|
||||||
|
|
||||||
|
let matches = client.search_release_group(request).unwrap();
|
||||||
|
assert_eq!(matches, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn search_release_group_empty_date() {
|
||||||
|
let mut http = MockIMusicBrainzHttp::new();
|
||||||
|
let url = format!(
|
||||||
|
"https://musicbrainz.org/ws/2\
|
||||||
|
/release-group\
|
||||||
|
?query=arid%3A{arid}+AND+releasegroup%3A%22{title}%22",
|
||||||
|
arid = "00000000-0000-0000-0000-000000000000",
|
||||||
|
title = "an+album",
|
||||||
|
);
|
||||||
|
|
||||||
|
let de_response = DeserializeSearchReleaseGroupResponse {
|
||||||
|
release_groups: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
http.expect_get()
|
||||||
|
.times(1)
|
||||||
|
.with(predicate::eq(url))
|
||||||
|
.return_once(|_| Ok(de_response));
|
||||||
|
|
||||||
|
let mut client = MusicBrainzClient::new(http);
|
||||||
|
|
||||||
|
let arid: Mbid = "00000000-0000-0000-0000-000000000000".try_into().unwrap();
|
||||||
|
let title: AlbumId = AlbumId::new("an album");
|
||||||
|
let date = AlbumDate::default();
|
||||||
|
|
||||||
|
let mut request = SearchReleaseGroupRequest::new();
|
||||||
|
request
|
||||||
|
.arid(&arid)
|
||||||
|
.release_group(&title.title)
|
||||||
|
.first_release_date(&date);
|
||||||
|
|
||||||
|
let _ = client.search_release_group(request).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
193
src/external/musicbrainz/mod.rs
vendored
193
src/external/musicbrainz/mod.rs
vendored
@ -17,196 +17,3 @@ pub enum HttpError {
|
|||||||
Client(String),
|
Client(String),
|
||||||
Status(u16),
|
Status(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
|
||||||
// mod tests {
|
|
||||||
// use mockall::{predicate, Sequence};
|
|
||||||
|
|
||||||
// use crate::collection::album::AlbumId;
|
|
||||||
|
|
||||||
// use super::*;
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn errors() {
|
|
||||||
// let client_err: Error = Error::Client(String::from("a client error"));
|
|
||||||
// assert!(!client_err.to_string().is_empty());
|
|
||||||
// assert!(!format!("{client_err:?}").is_empty());
|
|
||||||
|
|
||||||
// let rate_err: Error = Error::RateLimit;
|
|
||||||
// assert!(!rate_err.to_string().is_empty());
|
|
||||||
// assert!(!format!("{rate_err:?}").is_empty());
|
|
||||||
|
|
||||||
// let unk_err: Error = Error::Unknown(404);
|
|
||||||
// assert!(!unk_err.to_string().is_empty());
|
|
||||||
// assert!(!format!("{unk_err:?}").is_empty());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn lookup_artist_release_group() {
|
|
||||||
// let mut client = MockIMusicBrainzClient::new();
|
|
||||||
// let url = format!(
|
|
||||||
// "https://musicbrainz.org/ws/2/artist/{mbid}?inc=release-groups",
|
|
||||||
// mbid = "00000000-0000-0000-0000-000000000000",
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let release_group = LookupReleaseGroup {
|
|
||||||
// id: String::from("11111111-1111-1111-1111-111111111111"),
|
|
||||||
// title: String::from("an album"),
|
|
||||||
// first_release_date: String::from("1986-04"),
|
|
||||||
// primary_type: SerdeAlbumPrimaryType(AlbumPrimaryType::Album),
|
|
||||||
// secondary_types: vec![SerdeAlbumSecondaryType(AlbumSecondaryType::Compilation)],
|
|
||||||
// };
|
|
||||||
// let response = ResponseLookupArtist {
|
|
||||||
// release_groups: vec![release_group],
|
|
||||||
// };
|
|
||||||
|
|
||||||
// client
|
|
||||||
// .expect_get()
|
|
||||||
// .times(1)
|
|
||||||
// .with(predicate::eq(url))
|
|
||||||
// .return_once(|_| Ok(response));
|
|
||||||
|
|
||||||
// let mut api = MusicBrainz::new(client);
|
|
||||||
|
|
||||||
// let mbid: Mbid = "00000000-0000-0000-0000-000000000000".try_into().unwrap();
|
|
||||||
// let results = api.lookup_artist_release_groups(&mbid).unwrap();
|
|
||||||
|
|
||||||
// let mut album = Album::new(
|
|
||||||
// AlbumId::new("an album"),
|
|
||||||
// (1986, 4),
|
|
||||||
// Some(AlbumPrimaryType::Album),
|
|
||||||
// vec![AlbumSecondaryType::Compilation],
|
|
||||||
// );
|
|
||||||
// album.set_musicbrainz_ref(
|
|
||||||
// MbAlbumRef::from_uuid_str("11111111-1111-1111-1111-111111111111").unwrap(),
|
|
||||||
// );
|
|
||||||
// let expected = vec![album];
|
|
||||||
|
|
||||||
// assert_eq!(results, expected);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn search_release_group() {
|
|
||||||
// let mut client = MockIMusicBrainzClient::new();
|
|
||||||
// let url_title = format!(
|
|
||||||
// "https://musicbrainz.org/ws/2\
|
|
||||||
// /release-group\
|
|
||||||
// ?query=arid%3A{arid}+AND+releasegroup%3A%22{title}%22+AND+firstreleasedate%3A{year}",
|
|
||||||
// arid = "00000000-0000-0000-0000-000000000000",
|
|
||||||
// title = "an+album",
|
|
||||||
// year = "1986"
|
|
||||||
// );
|
|
||||||
// let url_rgid = format!(
|
|
||||||
// "https://musicbrainz.org/ws/2\
|
|
||||||
// /release-group\
|
|
||||||
// ?query=arid%3A{arid}+AND+rgid%3A{rgid}",
|
|
||||||
// arid = "00000000-0000-0000-0000-000000000000",
|
|
||||||
// rgid = "11111111-1111-1111-1111-111111111111",
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let release_group = SearchReleaseGroup {
|
|
||||||
// score: 67,
|
|
||||||
// id: String::from("11111111-1111-1111-1111-111111111111"),
|
|
||||||
// title: String::from("an album"),
|
|
||||||
// first_release_date: String::from("1986-04"),
|
|
||||||
// primary_type: SerdeAlbumPrimaryType(AlbumPrimaryType::Album),
|
|
||||||
// secondary_types: Some(vec![SerdeAlbumSecondaryType(AlbumSecondaryType::Live)]),
|
|
||||||
// };
|
|
||||||
// let response = ResponseSearchReleaseGroup {
|
|
||||||
// release_groups: vec![release_group],
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // For code coverage of derive(Debug).
|
|
||||||
// assert!(!format!("{response:?}").is_empty());
|
|
||||||
|
|
||||||
// let mut seq = Sequence::new();
|
|
||||||
|
|
||||||
// let title_response = response.clone();
|
|
||||||
// client
|
|
||||||
// .expect_get()
|
|
||||||
// .times(1)
|
|
||||||
// .with(predicate::eq(url_title))
|
|
||||||
// .return_once(|_| Ok(title_response))
|
|
||||||
// .in_sequence(&mut seq);
|
|
||||||
|
|
||||||
// let rgid_response = response;
|
|
||||||
// client
|
|
||||||
// .expect_get()
|
|
||||||
// .times(1)
|
|
||||||
// .with(predicate::eq(url_rgid))
|
|
||||||
// .return_once(|_| Ok(rgid_response))
|
|
||||||
// .in_sequence(&mut seq);
|
|
||||||
|
|
||||||
// let mut album = Album::new(
|
|
||||||
// AlbumId::new("an album"),
|
|
||||||
// (1986, 4),
|
|
||||||
// Some(AlbumPrimaryType::Album),
|
|
||||||
// vec![AlbumSecondaryType::Live],
|
|
||||||
// );
|
|
||||||
// album.set_musicbrainz_ref(
|
|
||||||
// MbAlbumRef::from_uuid_str("11111111-1111-1111-1111-111111111111").unwrap(),
|
|
||||||
// );
|
|
||||||
// let expected = vec![Match::new(67, album)];
|
|
||||||
|
|
||||||
// let mut api = MusicBrainz::new(client);
|
|
||||||
|
|
||||||
// let arid: Mbid = "00000000-0000-0000-0000-000000000000".try_into().unwrap();
|
|
||||||
// let mut album = Album::new(AlbumId::new("an album"), (1986, 4), None, vec![]);
|
|
||||||
// let matches = api.search_release_group(&arid, &album).unwrap();
|
|
||||||
// assert_eq!(matches, expected);
|
|
||||||
|
|
||||||
// let rgid = MbAlbumRef::from_uuid_str("11111111-1111-1111-1111-111111111111").unwrap();
|
|
||||||
// album.set_musicbrainz_ref(rgid);
|
|
||||||
// let matches = api.search_release_group(&arid, &album).unwrap();
|
|
||||||
// assert_eq!(matches, expected);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn client_errors() {
|
|
||||||
// let mut client = MockIMusicBrainzClient::new();
|
|
||||||
|
|
||||||
// let error = ClientError::Client(String::from("get rekt"));
|
|
||||||
// assert!(!format!("{error:?}").is_empty());
|
|
||||||
|
|
||||||
// client
|
|
||||||
// .expect_get::<ResponseLookupArtist>()
|
|
||||||
// .times(1)
|
|
||||||
// .return_once(|_| Err(ClientError::Client(String::from("get rekt scrub"))));
|
|
||||||
|
|
||||||
// client
|
|
||||||
// .expect_get::<ResponseLookupArtist>()
|
|
||||||
// .times(1)
|
|
||||||
// .return_once(|_| Err(ClientError::Status(503)));
|
|
||||||
|
|
||||||
// client
|
|
||||||
// .expect_get::<ResponseLookupArtist>()
|
|
||||||
// .times(1)
|
|
||||||
// .return_once(|_| Err(ClientError::Status(504)));
|
|
||||||
|
|
||||||
// let mut api = MusicBrainz::new(client);
|
|
||||||
|
|
||||||
// let mbid: Mbid = "00000000-0000-0000-0000-000000000000".try_into().unwrap();
|
|
||||||
|
|
||||||
// let error = api.lookup_artist_release_groups(&mbid).unwrap_err();
|
|
||||||
// assert_eq!(error, Error::Client(String::from("get rekt scrub")));
|
|
||||||
|
|
||||||
// let error = api.lookup_artist_release_groups(&mbid).unwrap_err();
|
|
||||||
// assert_eq!(error, Error::RateLimit);
|
|
||||||
|
|
||||||
// let error = api.lookup_artist_release_groups(&mbid).unwrap_err();
|
|
||||||
// assert_eq!(error, Error::Unknown(504));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn serde() {
|
|
||||||
// let primary_type = "\"EP\"";
|
|
||||||
// let primary_type: SerdeAlbumPrimaryType = serde_json::from_str(primary_type).unwrap();
|
|
||||||
// let primary_type: AlbumPrimaryType = primary_type.into();
|
|
||||||
// assert_eq!(primary_type, AlbumPrimaryType::Ep);
|
|
||||||
|
|
||||||
// let secondary_type = "\"Field recording\"";
|
|
||||||
// let secondary_type: SerdeAlbumSecondaryType = serde_json::from_str(secondary_type).unwrap();
|
|
||||||
// let secondary_type: AlbumSecondaryType = secondary_type.into();
|
|
||||||
// assert_eq!(secondary_type, AlbumSecondaryType::FieldRecording);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
@ -8,8 +8,8 @@ mod ui;
|
|||||||
pub use app::App;
|
pub use app::App;
|
||||||
pub use event::EventChannel;
|
pub use event::EventChannel;
|
||||||
pub use handler::EventHandler;
|
pub use handler::EventHandler;
|
||||||
pub use listener::EventListener;
|
|
||||||
pub use lib::external::musicbrainz::MusicBrainz;
|
pub use lib::external::musicbrainz::MusicBrainz;
|
||||||
|
pub use listener::EventListener;
|
||||||
pub use ui::Ui;
|
pub use ui::Ui;
|
||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
|
Loading…
Reference in New Issue
Block a user