82 lines
2.6 KiB
Rust
82 lines
2.6 KiB
Rust
use music::subsonic::{SubsonicCredential, auth_token, parse_now_playing};
|
|
|
|
#[test]
|
|
fn the_auth_token_is_md5_of_password_and_salt() {
|
|
assert_eq!(
|
|
auth_token("hunter2", "c19b2d"),
|
|
"1b41ecef65ff7799cf7a84cf2d505e08"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn a_different_salt_produces_a_different_token() {
|
|
assert_ne!(auth_token("hunter2", "aaa"), auth_token("hunter2", "bbb"));
|
|
}
|
|
|
|
#[test]
|
|
fn a_credential_needs_a_url_username_and_password() {
|
|
let valid = br#"{"url":"https://music.example/","username":"gabriel","password":"hunter2"}"#;
|
|
let credential = SubsonicCredential::parse(valid).unwrap();
|
|
|
|
assert_eq!(credential.base_url(), "https://music.example");
|
|
assert_eq!(credential.username, "gabriel");
|
|
}
|
|
|
|
#[test]
|
|
fn an_incomplete_credential_is_rejected() {
|
|
assert!(SubsonicCredential::parse(br#"{"url":"https://music.example"}"#).is_err());
|
|
assert!(SubsonicCredential::parse(br#"{"url":"","username":"g","password":"p"}"#).is_err());
|
|
assert!(SubsonicCredential::parse(b"not json").is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn a_credential_never_reveals_its_password_in_debug_output() {
|
|
let credential = SubsonicCredential::parse(
|
|
br#"{"url":"https://music.example","username":"gabriel","password":"hunter2"}"#,
|
|
)
|
|
.unwrap();
|
|
|
|
assert!(!format!("{credential:?}").contains("hunter2"));
|
|
}
|
|
|
|
#[test]
|
|
fn a_playing_track_becomes_a_song() {
|
|
let body = r#"{"subsonic-response":{"status":"ok","version":"1.16.1","nowPlaying":{"entry":[
|
|
{"title":"Paranoid Android","artist":"Radiohead","album":"OK Computer"}
|
|
]}}}"#;
|
|
|
|
let song = parse_now_playing(body).unwrap().unwrap();
|
|
|
|
assert_eq!(song.title().value(), "Paranoid Android");
|
|
assert_eq!(song.artist().value(), "Radiohead");
|
|
assert_eq!(song.album().map(|a| a.value()), Some("OK Computer"));
|
|
}
|
|
|
|
#[test]
|
|
fn nothing_playing_is_not_an_error() {
|
|
let empty = r#"{"subsonic-response":{"status":"ok","version":"1.16.1"}}"#;
|
|
let no_entries = r#"{"subsonic-response":{"status":"ok","nowPlaying":{"entry":[]}}}"#;
|
|
|
|
assert!(parse_now_playing(empty).unwrap().is_none());
|
|
assert!(parse_now_playing(no_entries).unwrap().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn a_failed_call_is_an_error_even_though_subsonic_answers_with_http_200() {
|
|
let body = r#"{"subsonic-response":{"status":"failed","version":"1.16.1",
|
|
"error":{"code":40,"message":"Wrong username or password."}}}"#;
|
|
|
|
let result = parse_now_playing(body);
|
|
|
|
assert!(result.is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn a_track_missing_its_artist_is_skipped_rather_than_half_stored() {
|
|
let body = r#"{"subsonic-response":{"status":"ok","nowPlaying":{"entry":[
|
|
{"title":"Untitled"}
|
|
]}}}"#;
|
|
|
|
assert!(parse_now_playing(body).unwrap().is_none());
|
|
}
|