248 lines
6.4 KiB
Rust
248 lines
6.4 KiB
Rust
use std::collections::HashSet;
|
|
|
|
use bandcamp::{
|
|
models::{SearchFilter, SearchItem, TrAlbumType, Track},
|
|
Bandcamp, ImageUrl,
|
|
};
|
|
use reqwest::{header, Client};
|
|
|
|
const BAND_WINTERGATAN: u64 = 2464198920;
|
|
const BAND_ONESHOTPOD: u64 = 3760769193;
|
|
|
|
const ALBUM_WINTERGATAN: u64 = 2572654767;
|
|
const ALBUM_SKYJACKS: u64 = 1493086082;
|
|
|
|
#[tokio::test]
|
|
async fn band1() {
|
|
let bc = Bandcamp::new();
|
|
let band = bc.band(BAND_WINTERGATAN).await.unwrap();
|
|
insta::assert_ron_snapshot!(&band);
|
|
check_image(&band.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn band2() {
|
|
let bc = Bandcamp::new();
|
|
let band = bc.band(BAND_ONESHOTPOD).await.unwrap();
|
|
insta::assert_ron_snapshot!(&band);
|
|
check_image(&band.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn band3() {
|
|
let bc = Bandcamp::new();
|
|
let band = bc.band(3453236550).await.unwrap();
|
|
insta::assert_ron_snapshot!(&band);
|
|
check_image(&band.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn album1() {
|
|
let bc = Bandcamp::new();
|
|
let album = bc
|
|
.album(BAND_WINTERGATAN, ALBUM_WINTERGATAN, TrAlbumType::Album)
|
|
.await
|
|
.unwrap();
|
|
|
|
insta::assert_ron_snapshot!(&album, {
|
|
".tracks[].streaming_url" => "[streaming_url]"
|
|
});
|
|
check_stream_urls(&album.tracks);
|
|
check_image(&album.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn album2() {
|
|
let bc = Bandcamp::new();
|
|
let album = bc
|
|
.album_uid(format!("{}a{}", BAND_ONESHOTPOD, ALBUM_SKYJACKS))
|
|
.await
|
|
.unwrap();
|
|
|
|
insta::assert_ron_snapshot!(&album, {
|
|
".tracks[].streaming_url" => "[streaming_url]"
|
|
});
|
|
check_stream_urls(&album.tracks);
|
|
check_image(&album.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn album_track() {
|
|
let bc = Bandcamp::new();
|
|
let album = bc
|
|
.album_uid(format!("{}t{}", BAND_WINTERGATAN, 716010980))
|
|
.await
|
|
.unwrap();
|
|
|
|
insta::assert_ron_snapshot!(&album, {
|
|
".tracks[].streaming_url" => "[streaming_url]"
|
|
});
|
|
check_stream_urls(&album.tracks);
|
|
check_image(&album.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn album_track2() {
|
|
let bc = Bandcamp::new();
|
|
let album = bc.album_uid("3453236550t3835153004").await.unwrap();
|
|
|
|
insta::assert_ron_snapshot!(&album, {
|
|
".tracks[].streaming_url" => "[streaming_url]"
|
|
});
|
|
check_stream_urls(&album.tracks);
|
|
check_image(&album.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn search() {
|
|
let bc = Bandcamp::new();
|
|
let res = bc.search("skyjacks", SearchFilter::All).await.unwrap();
|
|
|
|
assert!(res.results.len() > 40, "got {} results", res.results.len());
|
|
|
|
let album = res
|
|
.results
|
|
.iter()
|
|
.find_map(|it| match it {
|
|
SearchItem::Album(album) => {
|
|
if album.id == 2856844961 {
|
|
Some(album)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
_ => None,
|
|
})
|
|
.unwrap();
|
|
|
|
let track = res
|
|
.results
|
|
.iter()
|
|
.find_map(|it| match it {
|
|
SearchItem::Track(track) => {
|
|
if track.id == 2988986230 {
|
|
Some(track)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
_ => None,
|
|
})
|
|
.unwrap();
|
|
|
|
assert_eq!(album.name, "Skyjacks: Call of the Sky");
|
|
assert_eq!(album.art_id, Some(3000513536));
|
|
assert_eq!(album.band_id, BAND_ONESHOTPOD);
|
|
assert_eq!(album.band_name, "Arne Parrott");
|
|
check_image(&album.img_url().unwrap()).await;
|
|
|
|
assert_eq!(track.name, "Skyjacks");
|
|
assert_eq!(track.art_id, Some(3000513536));
|
|
assert_eq!(track.band_id, BAND_ONESHOTPOD);
|
|
assert_eq!(track.band_name, "Arne Parrott");
|
|
assert_eq!(track.album_id, Some(2856844961));
|
|
assert_eq!(
|
|
track.album_name.as_deref().unwrap(),
|
|
"Skyjacks: Call of the Sky"
|
|
);
|
|
check_image(&track.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn search2() {
|
|
let bc = Bandcamp::new();
|
|
let res = bc
|
|
.search("wintergatan proof of concept", SearchFilter::All)
|
|
.await
|
|
.unwrap();
|
|
|
|
let track = res
|
|
.results
|
|
.iter()
|
|
.find_map(|it| match it {
|
|
SearchItem::Track(track) => {
|
|
if track.id == 1672155926 {
|
|
Some(track)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
_ => None,
|
|
})
|
|
.unwrap();
|
|
|
|
assert_eq!(track.name, "Proof of Concept");
|
|
assert_eq!(track.art_id, Some(4030354464));
|
|
assert_eq!(track.band_id, BAND_WINTERGATAN);
|
|
assert_eq!(track.band_name, "Wintergatan");
|
|
assert_eq!(track.album_id, None);
|
|
assert_eq!(track.album_name, None);
|
|
check_image(&track.img_url().unwrap()).await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn feed() {
|
|
let bc = Bandcamp::new();
|
|
let feed = bc.feed().await.unwrap();
|
|
let stories = feed.stories.featured;
|
|
|
|
assert!(stories.len() > 8, "got {} results", stories.len());
|
|
let story_ids = stories.iter().map(|s| s.ntid).collect::<HashSet<_>>();
|
|
|
|
let ctoken = &stories.last().unwrap().story_token;
|
|
let feed_cont = bc.feed_cont(ctoken).await.unwrap();
|
|
let stories_cont = feed_cont.stories.featured;
|
|
|
|
assert!(stories_cont.len() > 8, "got {} results", stories_cont.len());
|
|
// Check for duplicates in the continuation
|
|
stories_cont.iter().for_each(|s| {
|
|
assert!(
|
|
!story_ids.contains(&s.ntid),
|
|
"found duplicate story {} in cont",
|
|
s.ntid
|
|
)
|
|
});
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn band_from_url() {
|
|
let bc = Bandcamp::new();
|
|
let band_id = bc
|
|
.band_id_from_url("https://oneshotpodcast.bandcamp.com")
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(band_id, BAND_ONESHOTPOD);
|
|
}
|
|
|
|
// TEST UTILS
|
|
|
|
fn check_stream_urls(tracks: &[Track]) {
|
|
for t in tracks {
|
|
let url = t.streaming_url.get("mp3-128").expect("no mp3-128 track");
|
|
assert!(
|
|
url.starts_with("https://bandcamp.com/stream_redirect"),
|
|
"invalid url: {url}"
|
|
)
|
|
}
|
|
}
|
|
|
|
async fn check_image(url: &str) {
|
|
let client = Client::new();
|
|
let resp = client
|
|
.get(url)
|
|
.send()
|
|
.await
|
|
.unwrap()
|
|
.error_for_status()
|
|
.unwrap();
|
|
let img_type = resp
|
|
.headers()
|
|
.get(header::CONTENT_TYPE)
|
|
.unwrap()
|
|
.to_str()
|
|
.unwrap();
|
|
assert!(
|
|
img_type == "image/jpeg" || img_type == "image/png",
|
|
"image type: {img_type}"
|
|
);
|
|
}
|