Skip to content

Commit

Permalink
basic integration test
Browse files Browse the repository at this point in the history
basic test is passing, but pagination is not due to differing use case. for marketstack, pagination is actually part of query parameters, so I will leave them as such. its easy to use as part of the builder anyway.
  • Loading branch information
reubenwong97 committed Oct 16, 2023
1 parent 758c284 commit a8a9b54
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 20 deletions.
46 changes: 36 additions & 10 deletions src/api/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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<DummyResult, _> = Dummy.query(&client);
Expand All @@ -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<DummyResult, _> = Dummy.query(&client);
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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!({
Expand All @@ -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!({
Expand All @@ -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!({
Expand Down
4 changes: 4 additions & 0 deletions src/api/eod/eod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 10 additions & 5 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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(())
}
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
3 changes: 0 additions & 3 deletions src/marketstack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -228,7 +226,6 @@ impl api::RestClient for Marketstack {
type Error = RestError;

fn rest_endpoint(&self, endpoint: &str) -> Result<Url, api::ApiError<Self::Error>> {
debug!(target: "marketstack", "REST api call {}", endpoint);
Ok(self.rest_url.join(endpoint)?)
}

Expand Down
3 changes: 1 addition & 2 deletions src/test/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down Expand Up @@ -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);

Expand Down
23 changes: 23 additions & 0 deletions tests/eod_test.rs
Original file line number Diff line number Diff line change
@@ -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();
}

0 comments on commit a8a9b54

Please sign in to comment.