diff --git a/src/api/endpoint.rs b/src/api/endpoint.rs index 938b518..6fd84c0 100644 --- a/src/api/endpoint.rs +++ b/src/api/endpoint.rs @@ -40,10 +40,11 @@ where } else { return Err(ApiError::auth_error()); }; - self.parameters().push("access_key", token); let mut url = client.rest_endpoint(&self.endpoint())?; - self.parameters().add_to_url(&mut url); - + // Mutate every query with parameters that pushes access_key by default. + self.parameters() + .push("access_key", token) + .add_to_url(&mut url); let req = Request::builder() .method(self.method()) .uri(query::url_to_http_uri(url)); @@ -81,9 +82,11 @@ where } else { return Err(ApiError::auth_error()); }; - self.parameters().push("access_key", token); let mut url = client.rest_endpoint(&self.endpoint())?; - self.parameters().add_to_url(&mut url); + // Mutate every query with parameters that pushes access_key by default. + self.parameters() + .push("access_key", token) + .add_to_url(&mut url); let req = Request::builder() .method(self.method()) @@ -138,7 +141,11 @@ mod tests { #[test] fn test_marketstack_non_json_response() { - let endpoint = ExpectedUrl::builder().endpoint("dummy").build().unwrap(); + let endpoint = ExpectedUrl::builder() + .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) + .build() + .unwrap(); let client = SingleTestClient::new_raw(endpoint, "not json"); let res: Result = Dummy.query(&client); @@ -152,7 +159,11 @@ mod tests { #[test] fn test_marketstack_empty_response() { - let endpoint = ExpectedUrl::builder().endpoint("dummy").build().unwrap(); + let endpoint = ExpectedUrl::builder() + .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) + .build() + .unwrap(); let client = SingleTestClient::new_raw(endpoint, ""); let res: Result = Dummy.query(&client); @@ -168,6 +179,7 @@ mod tests { fn test_marketstack_error_bad_json() { let endpoint = ExpectedUrl::builder() .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) .status(StatusCode::NOT_FOUND) .build() .unwrap(); @@ -186,6 +198,7 @@ mod tests { fn test_marketstack_error_detection() { let endpoint = ExpectedUrl::builder() .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) .status(StatusCode::NOT_FOUND) .build() .unwrap(); @@ -209,6 +222,7 @@ mod tests { fn test_marketstack_error_detection_unknown() { let endpoint = ExpectedUrl::builder() .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) .status(StatusCode::NOT_FOUND) .build() .unwrap(); @@ -228,7 +242,11 @@ mod tests { #[test] fn test_bad_serialization() { - let endpoint = ExpectedUrl::builder().endpoint("dummy").build().unwrap(); + let endpoint = ExpectedUrl::builder() + .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) + .build() + .unwrap(); let client = SingleTestClient::new_json( endpoint, &json!({ @@ -248,7 +266,11 @@ mod tests { #[test] fn test_good_deserialization() { - let endpoint = ExpectedUrl::builder().endpoint("dummy").build().unwrap(); + let endpoint = ExpectedUrl::builder() + .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) + .build() + .unwrap(); let client = SingleTestClient::new_json( endpoint, &json!({ @@ -262,7 +284,11 @@ mod tests { #[tokio::test] async fn test_good_deserialization_async() { - let endpoint = ExpectedUrl::builder().endpoint("dummy").build().unwrap(); + let endpoint = ExpectedUrl::builder() + .endpoint("dummy") + .add_query_params(&[("access_key", "123")]) + .build() + .unwrap(); let client = SingleTestClient::new_json( endpoint, &json!({ diff --git a/src/api/eod/eod.rs b/src/api/eod/eod.rs index b0c1984..5c3ae9b 100644 --- a/src/api/eod/eod.rs +++ b/src/api/eod/eod.rs @@ -40,6 +40,10 @@ impl<'a> Eod<'a> { impl<'a> EodBuilder<'a> { /// Search the given symbol. + /// + /// This provides sane defaults for the user to call symbol() + /// on the builder without needing to wrap his symbol in a + /// BTreeSet beforehand. pub fn symbol(&mut self, symbol: &'a str) -> &mut Self { self.symbols .get_or_insert_with(BTreeSet::new) diff --git a/src/auth.rs b/src/auth.rs index d34af60..d703d8f 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -5,13 +5,13 @@ use thiserror::Error; use crate::api::{self, Query}; -use crate::api::{AsyncQuery, BasicEndpoint}; -use crate::types::BasicPublic; +use crate::api::{eod, AsyncQuery}; +use crate::types::EodData; /// A Marketstack API token. /// /// Marketstack only supports one kind of token. -#[derive(Clone)] +#[derive(Debug, Clone)] pub enum Auth { /// A personal access token, obtained through Marketstack dashboard. Token(String), @@ -22,7 +22,11 @@ impl Auth { where C: api::Client, { - let _: BasicPublic = BasicEndpoint::builder().build().unwrap().query(api)?; + let eod_data: EodData = eod::Eod::builder() + .symbol("AAPL") + .build() + .unwrap() + .query(api)?; Ok(()) } @@ -31,7 +35,8 @@ impl Auth { where C: api::AsyncClient + Sync, { - let _: BasicPublic = BasicEndpoint::builder() + let eod_data: EodData = eod::Eod::builder() + .symbol("AAPL") .build() .unwrap() .query_async(api) diff --git a/src/lib.rs b/src/lib.rs index 35be258..6d87810 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,5 +5,11 @@ mod auth; mod marketstack; pub mod types; +pub use crate::auth::AuthError; +pub use crate::marketstack::{ + AsyncMarketstack, Marketstack, MarketstackBuilder, MarketstackError, RestError, +}; +pub use crate::types::*; + #[cfg(test)] mod test; diff --git a/src/marketstack.rs b/src/marketstack.rs index 9aa53c9..4dbe7c8 100644 --- a/src/marketstack.rs +++ b/src/marketstack.rs @@ -5,12 +5,10 @@ use std::fmt::{self, Debug}; use async_trait::async_trait; use bytes::Bytes; use http::{request, HeaderMap, Response as HttpResponse}; -use itertools::Itertools; use log::{debug, error, info}; use reqwest::blocking::Client; use reqwest::Client as AsyncClient; use serde::de::DeserializeOwned; -use serde::Deserialize; use thiserror::Error; use url::Url; @@ -228,7 +226,6 @@ impl api::RestClient for Marketstack { type Error = RestError; fn rest_endpoint(&self, endpoint: &str) -> Result> { - debug!(target: "marketstack", "REST api call {}", endpoint); Ok(self.rest_url.join(endpoint)?) } diff --git a/src/test/client.rs b/src/test/client.rs index 89cf9c5..2a5cefe 100644 --- a/src/test/client.rs +++ b/src/test/client.rs @@ -74,7 +74,6 @@ impl ExpectedUrl { continue; } - println!("{:?}", self.query.iter()); let found = self.query.iter().any(|(expected_key, expected_value)| { key == expected_key && value == expected_value }); @@ -136,7 +135,7 @@ impl SingleTestClient { status: expected.status, data: data.into(), }; - let auth = Auth::Token("".into()); + let auth = Auth::Token("123".into()); client.response_map.insert(request, response); diff --git a/tests/eod_test.rs b/tests/eod_test.rs index 0914885..be68ef1 100644 --- a/tests/eod_test.rs +++ b/tests/eod_test.rs @@ -1,6 +1,29 @@ +use marketstack::api::{self, eod, Query}; +use marketstack::{EodData, Marketstack}; + mod setup; #[test] +#[ignore] fn test_eod() { let api_key = setup::setup_key(); + let client = Marketstack::new_insecure("api.marketstack.com", api_key).unwrap(); + + let endpoint = eod::Eod::builder().symbol("AAPL").build().unwrap(); + let eod_result: EodData = endpoint.query(&client).unwrap(); + + assert_eq!(eod_result.pagination.limit, 100); + assert_eq!(eod_result.pagination.offset, 0); +} + +#[test] +#[ignore] +fn test_eod_paged() { + let api_key = setup::setup_key(); + let client = Marketstack::new_insecure("api.marketstack.com", api_key).unwrap(); + + let pageable_endpoint = eod::Eod::builder().symbol("AAPL").build().unwrap(); + let first_200: EodData = api::paged(pageable_endpoint, api::Pagination::Limit(200)) + .query(&client) + .unwrap(); }