Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests for pure methods #189

Merged
merged 27 commits into from
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fe55750
Add test for json_insert macro and generate_random_string function.
ramsayleung Feb 26, 2021
89e142b
add test for headers module.
ramsayleung Feb 26, 2021
cd1f9c5
add test_read_token_cache test, and move all tests in oauth2.rs to te…
ramsayleung Feb 27, 2021
2cd8564
Add tests for append_device_id function.
ramsayleung Feb 27, 2021
b59982e
add test for endpoint_url and auth_headers function.
ramsayleung Feb 27, 2021
8d202ff
Fix cargo fmt error.
ramsayleung Feb 27, 2021
3f4960e
Fix clippy error.
ramsayleung Feb 27, 2021
0afba9e
add #[cfg(test)] attribute to fix unused import warning.
ramsayleung Feb 27, 2021
7cd65ad
update test_generate_random_string.
ramsayleung Feb 27, 2021
faf6543
add macro to create HashSet.
ramsayleung Feb 27, 2021
f78abf5
Replace macro `hashset!` to spotify-scope specific macro `scope!`.
ramsayleung Feb 28, 2021
10244b9
Fix cargo fmt error.
ramsayleung Feb 28, 2021
502b14f
Fix failed doc test
ramsayleung Feb 28, 2021
1177832
Fix cargo fmt error
ramsayleung Feb 28, 2021
275e56a
use scope to replace existing scope definitions.
ramsayleung Feb 28, 2021
582c3a3
Add spaceline between import statement and test functions.
ramsayleung Feb 28, 2021
6f75f8a
remove `#[doc(hidden)]` attr
ramsayleung Feb 28, 2021
2d0f555
recover `#[doc(hidden)]` attribute.
ramsayleung Mar 2, 2021
bae7f07
fix cargo check error.
ramsayleung Mar 2, 2021
5809eb9
move macros into `macros.rs`
ramsayleung Mar 2, 2021
b3b603b
Update CHANGELOG
ramsayleung Mar 3, 2021
c8b595f
rename scope! to scopes!
ramsayleung Mar 9, 2021
ccaac0a
Merge branch 'master' into ramsay_add_unit_tests
ramsayleung Mar 9, 2021
49e288b
Add reference to scope macro
ramsayleung Mar 9, 2021
82ff0db
Remove useless tests
ramsayleung Mar 9, 2021
c8d7d11
fix cargo check error
ramsayleung Mar 9, 2021
fffd831
fix cargo check error
ramsayleung Mar 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Cargo.lock
.DS_Store
.spotify_cache/
**/target/
/.test_read_token_cache.json
8 changes: 5 additions & 3 deletions examples/current_user_recently_played.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rspotify::client::SpotifyBuilder;
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
use rspotify::scope;
marioortizmanero marked this conversation as resolved.
Show resolved Hide resolved

use std::collections::HashSet;

Expand Down Expand Up @@ -31,9 +32,10 @@ async fn main() {
// .redirect_uri("http://localhost:8888/callback")
// .build()
// .unwrap();
let mut scopes = HashSet::new();
scopes.insert("user-read-recently-played".to_owned());
let oauth = OAuthBuilder::from_env().scope(scopes).build().unwrap();
let oauth = OAuthBuilder::from_env()
.scope(scope!("user-read-recently-played"))
.build()
.unwrap();

let mut spotify = SpotifyBuilder::default()
.credentials(creds)
Expand Down
31 changes: 20 additions & 11 deletions examples/oauth_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,26 @@ async fn main() {
let creds = CredentialsBuilder::from_env().build().unwrap();

// Using every possible scope
let scope = "user-read-email user-read-private user-top-read \
user-read-recently-played user-follow-read user-library-read \
user-read-currently-playing user-read-playback-state \
user-read-playback-position playlist-read-collaborative \
playlist-read-private user-follow-modify user-library-modify \
user-modify-playback-state playlist-modify-public \
playlist-modify-private ugc-image-upload";
let oauth = OAuthBuilder::from_env()
.scope(scope.split_whitespace().map(|x| x.to_owned()).collect())
.build()
.unwrap();
let scope = scope!(
"user-read-email",
"user-read-private",
"user-top-read",
"user-read-recently-played",
"user-follow-read",
"user-library-read",
"user-read-currently-playing",
"user-read-playback-state",
"user-read-playback-position",
"playlist-read-collaborative",
"playlist-read-private",
"user-follow-modify",
"user-library-modify",
"user-modify-playback-state",
"playlist-modify-public",
"playlist-modify-private",
"ugc-image-upload"
);
let oauth = OAuthBuilder::from_env().scope(scope).build().unwrap();

let mut spotify = SpotifyBuilder::default()
.credentials(creds)
Expand Down
8 changes: 5 additions & 3 deletions examples/ureq/device.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rspotify::client::SpotifyBuilder;
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
use rspotify::scope;

use std::collections::HashSet;

Expand Down Expand Up @@ -30,9 +31,10 @@ fn main() {
// .redirect_uri("http://localhost:8888/callback")
// .build()
// .unwrap();
let mut scope = HashSet::new();
scope.insert("user-read-playback-state".to_owned());
let oauth = OAuthBuilder::from_env().scope(scope).build().unwrap();
let oauth = OAuthBuilder::from_env()
.scope(scope!("user-read-playback-state"))
.build()
.unwrap();

let mut spotify = SpotifyBuilder::default()
.credentials(creds)
Expand Down
8 changes: 5 additions & 3 deletions examples/ureq/me.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rspotify::client::SpotifyBuilder;
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
use rspotify::scope;

use std::collections::HashSet;

Expand Down Expand Up @@ -30,9 +31,10 @@ fn main() {
// .redirect_uri("http://localhost:8888/callback")
// .build()
// .unwrap();
let mut scope = HashSet::new();
scope.insert("user-read-playback-state".to_owned());
let oauth = OAuthBuilder::from_env().scope(scope).build().unwrap();
let oauth = OAuthBuilder::from_env()
.scope(scope!("user-read-playback-state"))
.build()
.unwrap();

let mut spotify = SpotifyBuilder::default()
.credentials(creds)
Expand Down
8 changes: 5 additions & 3 deletions examples/ureq/search.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rspotify::client::SpotifyBuilder;
use rspotify::model::{Country, Market, SearchType};
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
use rspotify::scope;

use std::collections::HashSet;

Expand Down Expand Up @@ -31,9 +32,10 @@ fn main() {
// .redirect_uri("http://localhost:8888/callback")
// .build()
// .unwrap();
let mut scope = HashSet::new();
scope.insert("user-read-playback-state".to_owned());
let oauth = OAuthBuilder::from_env().scope(scope).build().unwrap();
let oauth = OAuthBuilder::from_env()
.scope(scope!("user-read-playback-state"))
.build()
.unwrap();

let mut spotify = SpotifyBuilder::default()
.credentials(creds)
Expand Down
8 changes: 5 additions & 3 deletions examples/ureq/seek_track.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rspotify::client::SpotifyBuilder;
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
use rspotify::scope;

use std::collections::HashSet;

Expand Down Expand Up @@ -30,9 +31,10 @@ fn main() {
// .redirect_uri("http://localhost:8888/callback")
// .build()
// .unwrap();
let mut scope = HashSet::new();
scope.insert("user-read-playback-state".to_owned());
let oauth = OAuthBuilder::from_env().scope(scope).build().unwrap();
let oauth = OAuthBuilder::from_env()
.scope(scope!("user-read-playback-state"))
.build()
.unwrap();

let mut spotify = SpotifyBuilder::default()
.credentials(creds)
Expand Down
5 changes: 3 additions & 2 deletions examples/webapp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rocket_contrib::json::JsonValue;
use rocket_contrib::templates::Template;
use rspotify::client::{ClientError, SpotifyBuilder};
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder, TokenBuilder};
use rspotify::scope;

use std::fs;
use std::{
Expand Down Expand Up @@ -75,10 +76,10 @@ fn check_cache_path_exists(cookies: &Cookies) -> (bool, PathBuf) {
fn init_spotify() -> SpotifyBuilder {
// Please notice that protocol of redirect_uri, make sure it's http
// (or https). It will fail if you mix them up.
let scope = "user-read-currently-playing playlist-modify-private";
let scope = scope!("user-read-currently-playing playlist-modify-private");
let oauth = OAuthBuilder::default()
.redirect_uri("http://localhost:8000/callback")
.scope(scope.split_whitespace().map(|x| x.to_owned()).collect())
.scope(scope)
.build()
.unwrap();

Expand Down
8 changes: 3 additions & 5 deletions examples/with_refresh_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

use rspotify::client::{Spotify, SpotifyBuilder};
use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
use rspotify::scope;

// Sample request that will follow some artists, print the user's
// followed artists, and then unfollow the artists.
Expand Down Expand Up @@ -56,11 +57,8 @@ async fn main() {

// The default credentials from the `.env` file will be used by default.
let creds = CredentialsBuilder::from_env().build().unwrap();
let scope = "user-follow-read user-follow-modify";
let oauth = OAuthBuilder::from_env()
.scope(scope.split_whitespace().map(|x| x.to_owned()).collect())
.build()
.unwrap();
let scope = scope!("user-follow-read user-follow-modify");
let oauth = OAuthBuilder::from_env().scope(scope).build().unwrap();
let mut spotify = SpotifyBuilder::default()
.credentials(creds.clone())
.oauth(oauth.clone())
Expand Down
23 changes: 22 additions & 1 deletion src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2133,7 +2133,7 @@ impl Spotify {
}

#[cfg(test)]
mod tests {
mod test {
use super::*;

#[test]
Expand Down Expand Up @@ -2190,4 +2190,25 @@ mod tests {
assert_eq!(track_id1, uri1);
assert_eq!("spotify:track:1301WleyT98MSxVHPZCA6M", &uri2);
}

#[test]
fn test_append_device_id_without_question_mark() {
let path = "me/player/play";
let device_id = Some("fdafdsadfa".to_owned());
let spotify = SpotifyBuilder::default().build().unwrap();
let new_path = spotify.append_device_id(path, device_id);
assert_eq!(new_path, "me/player/play?device_id=fdafdsadfa");
}

#[test]
fn test_append_device_id_with_question_mark() {
let path = "me/player/shuffle?state=true";
let device_id = Some("fdafdsadfa".to_owned());
let spotify = SpotifyBuilder::default().build().unwrap();
let new_path = spotify.append_device_id(path, device_id);
assert_eq!(
new_path,
"me/player/shuffle?state=true&device_id=fdafdsadfa"
);
}
}
66 changes: 66 additions & 0 deletions src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,69 @@ impl Spotify {
self.delete(url, Some(&headers), payload).await
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::client::SpotifyBuilder;
use crate::oauth2::TokenBuilder;
use crate::scope;
use chrono::prelude::*;
use chrono::Duration;

#[test]
marioortizmanero marked this conversation as resolved.
Show resolved Hide resolved
fn test_bearer_auth() {
let access_token = "access_token";
let tok = TokenBuilder::default()
.access_token(access_token)
.build()
.unwrap();
let (auth, value) = headers::bearer_auth(&tok);
assert_eq!(auth, "authorization");
assert_eq!(value, "Bearer access_token");
}

#[test]
fn test_basic_auth() {
let (auth, value) = headers::basic_auth("ramsay", "123456");
assert_eq!(auth, "authorization");
assert_eq!(value, "Basic cmFtc2F5OjEyMzQ1Ng==");
}

#[test]
fn test_endpoint_url() {
let spotify = SpotifyBuilder::default().build().unwrap();
assert_eq!(
spotify.endpoint_url("me/player/play"),
"https://api.spotify.com/v1/me/player/play"
);
assert_eq!(
spotify.endpoint_url("http://api.spotify.com/v1/me/player/play"),
"http://api.spotify.com/v1/me/player/play"
);
assert_eq!(
spotify.endpoint_url("https://api.spotify.com/v1/me/player/play"),
"https://api.spotify.com/v1/me/player/play"
);
}

#[test]
fn test_auth_headers() {
let tok = TokenBuilder::default()
.access_token("test-access_token")
.expires_in(Duration::seconds(1))
.expires_at(Utc::now())
.scope(scope!("playlist-read-private"))
.refresh_token("...")
.build()
.unwrap();

let spotify = SpotifyBuilder::default().token(tok).build().unwrap();

let headers = spotify.auth_headers().unwrap();
assert_eq!(
headers.get("authorization"),
Some(&"Bearer test-access_token".to_owned())
);
}
}
66 changes: 66 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,38 @@ compile_error!(

#[doc(hidden)]
marioortizmanero marked this conversation as resolved.
Show resolved Hide resolved
mod macros {
/// Create a **Hashset** from a list of &str(which will be converted to
/// String internally), be used to create scope
/// for (Token)[crate::oauth2::Token]
/// Example
/// ```
/// use rspotify::oauth2::TokenBuilder;
/// use rspotify::scope;
/// use std::collections::HashSet;
/// use chrono::prelude::*;
/// use chrono::Duration;
///
/// let scope: HashSet<String> = scope!("playlist-read-private", "playlist-read-collaborative");
/// let tok = TokenBuilder::default()
/// .access_token("test-access_token")
/// .expires_in(Duration::seconds(1))
/// .expires_at(Utc::now())
/// .scope(scope)
/// .refresh_token("...")
/// .build()
/// .unwrap();
/// ```
#[macro_export]
macro_rules! scope {
($($key:expr),*) => {{
let mut container = ::std::collections::HashSet::new();
$(
let _ = container.insert($key.to_owned());
marioortizmanero marked this conversation as resolved.
Show resolved Hide resolved
)*
container
}
};
}
ramsayleung marked this conversation as resolved.
Show resolved Hide resolved
/// Reduce boilerplate when inserting new elements in a JSON object.
#[macro_export]
macro_rules! json_insert {
Expand All @@ -197,3 +229,37 @@ pub(in crate) fn generate_random_string(length: usize) -> String {
.map(|byte| alphanum[*byte as usize % range] as char)
.collect()
}

#[cfg(test)]
mod test {
use super::{generate_random_string, json_insert, scope};
use serde_json::json;
use std::collections::HashSet;

#[test]
fn test_hashset() {
let scope = scope!("hello", "world", "foo", "bar");
assert_eq!(scope.len(), 4);
assert!(scope.contains(&"hello".to_owned()));
assert!(scope.contains(&"world".to_owned()));
assert!(scope.contains(&"foo".to_owned()));
assert!(scope.contains(&"bar".to_owned()));
}

#[test]
fn test_generate_random_string() {
let mut containers = HashSet::new();
for _ in 1..101 {
containers.insert(generate_random_string(10));
}
assert_eq!(containers.len(), 100);
}

#[test]
fn test_json_insert() {
let mut params = json!({});
let name = "ramsay";
json_insert!(params, "name", name);
assert_eq!(params["name"], name);
}
}
Loading