use chrono::prelude::*;
use chrono::Duration;
use rspotify::{
prelude::*, scopes, AuthCodeSpotify, ClientCredsSpotify, Config, Credentials, OAuth, Token,
};
use std::{collections::HashMap, fs, io::Read, path::PathBuf};
use url::Url;
use wasm_bindgen_test::*;
#[test]
#[wasm_bindgen_test]
fn test_get_authorize_url() {
let oauth = OAuth {
state: "fdsafdsfa".to_owned(),
redirect_uri: "localhost".to_owned(),
scopes: scopes!("playlist-read-private"),
..Default::default()
};
let creds = Credentials::new("this-is-my-client-id", "this-is-my-client-secret");
let spotify = AuthCodeSpotify::new(creds, oauth);
let authorize_url = spotify.get_authorize_url(false).unwrap();
let hash_query: HashMap<_, _> = Url::parse(&authorize_url)
.unwrap()
.query_pairs()
.into_owned()
.collect();
assert_eq!(hash_query.get("client_id").unwrap(), "this-is-my-client-id");
assert_eq!(hash_query.get("response_type").unwrap(), "code");
assert_eq!(hash_query.get("redirect_uri").unwrap(), "localhost");
assert_eq!(hash_query.get("scope").unwrap(), "playlist-read-private");
assert_eq!(hash_query.get("state").unwrap(), "fdsafdsfa");
}
#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))]
async fn test_read_token_cache() {
let expires_in = Duration::try_seconds(3600).unwrap();
let expires_at = Some(Utc::now() + expires_in);
let scopes = scopes!("playlist-read-private", "playlist-read-collaborative");
let tok = Token {
expires_in,
expires_at,
access_token: "test-access_token".to_owned(),
scopes: scopes.clone(),
refresh_token: Some("...".to_owned()),
};
let config = Config {
token_cached: true,
cache_path: PathBuf::from(".test_read_token_cache.json"),
..Default::default()
};
let mut predefined_spotify = ClientCredsSpotify::from_token(tok);
predefined_spotify.config = config.clone();
predefined_spotify.write_token_cache().await.unwrap();
assert!(predefined_spotify.config.cache_path.exists());
let mut spotify = ClientCredsSpotify::default();
spotify.config = config;
let tok_from_file = spotify.read_token_cache().await.unwrap().unwrap();
assert_eq!(tok_from_file.scopes, scopes);
assert_eq!(tok_from_file.refresh_token.unwrap(), "...");
assert_eq!(
tok_from_file.expires_in,
Duration::try_seconds(3600).unwrap()
);
assert_eq!(tok_from_file.expires_at, expires_at);
fs::remove_file(&spotify.config.cache_path).unwrap();
}
#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))]
async fn test_write_token() {
let now = Utc::now();
let scopes = scopes!("playlist-read-private", "playlist-read-collaborative");
let tok = Token {
access_token: "test-access_token".to_owned(),
expires_in: Duration::try_seconds(3600).unwrap(),
expires_at: Some(now),
scopes: scopes.clone(),
refresh_token: Some("...".to_owned()),
};
let config = Config {
token_cached: true,
cache_path: PathBuf::from(".test_write_token_cache.json"),
..Default::default()
};
let mut spotify = ClientCredsSpotify::from_token(tok.clone());
spotify.config = config;
let tok_str = serde_json::to_string(&tok).unwrap();
spotify.write_token_cache().await.unwrap();
let mut file = fs::File::open(&spotify.config.cache_path).unwrap();
let mut tok_str_file = String::new();
file.read_to_string(&mut tok_str_file).unwrap();
assert_eq!(tok_str, tok_str_file);
let tok_from_file: Token = serde_json::from_str(&tok_str_file).unwrap();
assert_eq!(tok_from_file.scopes, scopes);
assert_eq!(
tok_from_file.expires_in,
Duration::try_seconds(3600).unwrap()
);
assert_eq!(tok_from_file.expires_at.unwrap(), now);
fs::remove_file(&spotify.config.cache_path).unwrap();
}
#[test]
#[wasm_bindgen_test]
fn test_token_is_expired() {
let expires_in = Duration::try_seconds(20).unwrap();
let tok = Token {
scopes: scopes!("playlist-read-private", "playlist-read-collaborative"),
access_token: "test-access_token".to_owned(),
expires_in,
expires_at: Some(Utc::now() + expires_in),
refresh_token: Some("...".to_owned()),
};
assert!(!tok.is_expired());
let expires_in = Duration::try_seconds(3).unwrap(); let tok = Token {
scopes: scopes!("playlist-read-private", "playlist-read-collaborative"),
access_token: "test-access_token".to_owned(),
expires_in,
expires_at: Some(Utc::now() + expires_in),
refresh_token: Some("...".to_owned()),
};
assert!(tok.is_expired());
}
#[test]
#[wasm_bindgen_test]
fn test_parse_response_code() {
let spotify = AuthCodeSpotify::default();
let url = "http://localhost:8888/callback";
let code = spotify.parse_response_code(url);
assert_eq!(code, None);
let url = "http://localhost:8888/callback?code=AQD0yXvFEOvw";
let code = spotify.parse_response_code(url);
assert_eq!(code, None);
let url = "http://localhost:8888/callback?code=AQD0yXvFEOvw?state=abc";
let code = spotify.parse_response_code(url);
assert_eq!(code, None);
let url = format!(
"http://localhost:8888/callback?code=AQD0yXvFEOvw&state={}",
spotify.oauth.state
);
let code = spotify.parse_response_code(&url);
assert_eq!(code, Some("AQD0yXvFEOvw".to_string()));
let url = format!(
"http://localhost:8888/callback?state={}&code=AQD0yXvFEOvw",
spotify.oauth.state
);
let code = spotify.parse_response_code(&url);
assert_eq!(code, Some("AQD0yXvFEOvw".to_string()));
}