✅ test: add tests for scraper API test endpoint
parent
0737edd8f8
commit
9c7b2b7a86
|
@ -102,7 +102,7 @@ pub async fn handle_scraper_api (
|
|||
#[cfg (test)]
|
||||
mod tests {
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
convert::{TryFrom, TryInto},
|
||||
};
|
||||
|
||||
use tokio::runtime::Runtime;
|
||||
|
@ -112,35 +112,140 @@ mod tests {
|
|||
};
|
||||
use super::*;
|
||||
|
||||
#[derive (Clone)]
|
||||
struct TestCase {
|
||||
// Inputs
|
||||
path_rest: &'static str,
|
||||
valid_key: Option <&'static str>,
|
||||
input_key: Option <&'static str>,
|
||||
|
||||
// Expected
|
||||
expected_status: StatusCode,
|
||||
expected_headers: Vec <(&'static str, &'static str)>,
|
||||
expected_body: &'static str,
|
||||
}
|
||||
|
||||
impl TestCase {
|
||||
fn path_rest (&self, v: &'static str) -> Self {
|
||||
let mut x = self.clone ();
|
||||
x.path_rest = v;
|
||||
x
|
||||
}
|
||||
|
||||
fn valid_key (&self, v: Option <&'static str>) -> Self {
|
||||
let mut x = self.clone ();
|
||||
x.valid_key = v;
|
||||
x
|
||||
}
|
||||
|
||||
fn input_key (&self, v: Option <&'static str>) -> Self {
|
||||
let mut x = self.clone ();
|
||||
x.input_key = v;
|
||||
x
|
||||
}
|
||||
|
||||
fn expected_status (&self, v: StatusCode) -> Self {
|
||||
let mut x = self.clone ();
|
||||
x.expected_status = v;
|
||||
x
|
||||
}
|
||||
|
||||
fn expected_headers (&self, v: Vec <(&'static str, &'static str)>) -> Self {
|
||||
let mut x = self.clone ();
|
||||
x.expected_headers = v;
|
||||
x
|
||||
}
|
||||
|
||||
fn expected_body (&self, v: &'static str) -> Self {
|
||||
let mut x = self.clone ();
|
||||
x.expected_body = v;
|
||||
x
|
||||
}
|
||||
|
||||
fn expected (&self, sc: StatusCode, body: &'static str) -> Self {
|
||||
self
|
||||
.expected_status (sc)
|
||||
.expected_body (body)
|
||||
}
|
||||
|
||||
async fn test (&self) {
|
||||
let mut input = Request::builder ()
|
||||
.method ("GET")
|
||||
.uri (format! ("http://127.0.0.1:4000/scraper/{}", self.path_rest));
|
||||
|
||||
if let Some (input_key) = self.input_key {
|
||||
input = input.header ("X-ApiKey", input_key);
|
||||
}
|
||||
let input = input.body (Body::empty ()).unwrap ();
|
||||
|
||||
let config_file = config::file::Config {
|
||||
port: Some (4000),
|
||||
servers: vec! [],
|
||||
iso: config::file::Isomorphic {
|
||||
enable_scraper_auth: true,
|
||||
dev_mode: self.valid_key.map (|key| config::file::DevMode {
|
||||
scraper_key: Some (key_validity::ScraperKey::new (key.as_bytes ())),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
let config = config::Config::try_from (config_file).expect ("Can't load config");
|
||||
|
||||
let relay_state = Arc::new (RelayState::try_from (config).expect ("Can't create relay state"));
|
||||
|
||||
let actual = handle_scraper_api (input, relay_state, self.path_rest).await;
|
||||
let actual = actual.expect ("Relay didn't respond");
|
||||
let (actual_head, actual_body) = actual.into_parts ();
|
||||
|
||||
let mut expected_headers = hyper::header::HeaderMap::new ();
|
||||
|
||||
for (key, value) in &self.expected_headers {
|
||||
expected_headers.insert (*key, (*value).try_into ().expect ("Couldn't convert header value"));
|
||||
}
|
||||
|
||||
assert_eq! (actual_head.status, self.expected_status);
|
||||
assert_eq! (actual_head.headers, expected_headers);
|
||||
|
||||
let actual_body = hyper::body::to_bytes (actual_body).await;
|
||||
let actual_body = actual_body.expect ("Body should be convertible to bytes");
|
||||
let actual_body = actual_body.to_vec ();
|
||||
let actual_body = String::from_utf8 (actual_body).expect ("Body should be UTF-8");
|
||||
|
||||
assert_eq! (&actual_body, self.expected_body);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn auth () {
|
||||
let input = Request::builder ()
|
||||
.method ("GET")
|
||||
.uri ("http://127.0.0.1:4000/scraper/v1/test")
|
||||
.header ("X-ApiKey", "bogus")
|
||||
.body (Body::empty ())
|
||||
.unwrap ();
|
||||
|
||||
let config_file = config::file::Config {
|
||||
port: Some (4000),
|
||||
servers: vec! [],
|
||||
iso: config::file::Isomorphic {
|
||||
enable_scraper_auth: true,
|
||||
dev_mode: Some (config::file::DevMode {
|
||||
scraper_key: Some (key_validity::ScraperKey::new (b"bogus")),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
let config = config::Config::try_from (config_file).expect ("Can't load config");
|
||||
|
||||
let relay_state = Arc::new (RelayState::try_from (config).expect ("Can't create relay state"));
|
||||
|
||||
let mut rt = Runtime::new ().expect ("Can't create runtime for testing");
|
||||
|
||||
rt.block_on (async move {
|
||||
let actual = handle_scraper_api (input, relay_state, "").await;
|
||||
let actual = actual.expect ("Relay didn't respond");
|
||||
let base_case = TestCase {
|
||||
path_rest: "v1/test",
|
||||
valid_key: Some ("bogus"),
|
||||
input_key: Some ("bogus"),
|
||||
expected_status: StatusCode::OK,
|
||||
expected_headers: vec! [
|
||||
("content-type", "text/plain"),
|
||||
],
|
||||
expected_body: "You're valid!\n",
|
||||
};
|
||||
|
||||
for case in &[
|
||||
base_case.clone (),
|
||||
base_case.path_rest ("v9999/test")
|
||||
.expected (StatusCode::NOT_FOUND, "Unknown scraper API version\n"),
|
||||
base_case.valid_key (None)
|
||||
.expected (StatusCode::FORBIDDEN, "403 Forbidden\n"),
|
||||
base_case.input_key (Some ("borgus"))
|
||||
.expected (StatusCode::FORBIDDEN, "403 Forbidden\n"),
|
||||
base_case.path_rest ("v1/toast")
|
||||
.expected (StatusCode::NOT_FOUND, "Unknown API endpoint\n"),
|
||||
base_case.input_key (None)
|
||||
.expected (StatusCode::FORBIDDEN, "Can't run scraper without an API key\n"),
|
||||
] {
|
||||
case.test ().await;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
22
src/tests.rs
22
src/tests.rs
|
@ -179,8 +179,26 @@ fn scraper_endpoints () {
|
|||
.timeout (Duration::from_secs (2))
|
||||
.build ().expect ("Couldn't build HTTP client");
|
||||
|
||||
let resp = client.get (&format! ("{}/scraper/api/test", relay_url))
|
||||
.send ().await.expect ("Couldn't check if relay is up").bytes ().await.expect ("Couldn't check if relay is up");
|
||||
let mut resp = None;
|
||||
for _ in 0usize..5 {
|
||||
let x = client.get (&format! ("{}/scraper/api/test", relay_url))
|
||||
.send ().await;
|
||||
match x {
|
||||
Err (_) => {
|
||||
// Probably a reqwest error cause the port is in
|
||||
// use or something. Try again.
|
||||
()
|
||||
},
|
||||
Ok (x) => {
|
||||
resp = Some (x);
|
||||
break;
|
||||
},
|
||||
};
|
||||
|
||||
delay_for (Duration::from_millis (200)).await;
|
||||
}
|
||||
let resp = resp.expect ("Reqwest repeatedly failed to connect to the relay");
|
||||
let resp = resp.bytes ().await.expect ("Couldn't check if relay is up");
|
||||
|
||||
assert_eq! (resp, "You're valid!\n");
|
||||
|
||||
|
|
Loading…
Reference in New Issue