use crate::json_test;
use crate::json_test::JsonExpectation;
use crate::parser::types::{RequestType, StatusCode};
use crate::static_vars::set_err_true;
use crate::tester::Tester;
use colored::Colorize;
use curl::easy::Easy;
use serde_json::Value;
use std::io::Read;
use std::str::from_utf8;
pub fn run(link: String, tester: Tester) {
let full_url = full_url_or_panic(&link, &tester);
let req_type = req_type_or_panic(&tester);
let req_content = req_content_or_empty(&tester);
let test_expectations = tester.response_tester.free_testers;
let mut easy = Easy::new();
easy.url(full_url.as_str()).unwrap();
test_response(&mut easy, test_expectations);
send_request(&mut easy, req_type, req_content);
test_response_status(&mut easy, tester.response_tester.res_type);
}
fn run_testers(response: String, testers: &Vec<JsonExpectation>) -> Result<(), ()> {
let json: Value = serde_json::from_str(response.as_str()).map_err(|_| {
println!("The response is not a json object");
()
})?;
match json_test::check_all(&json, &testers) {
Ok(()) => Ok(()),
Err(errors) => {
errors.iter().for_each(|e| {
println!("{}", e);
});
Err(())
}
}
}
fn send_request(easy: &mut Easy, req_type: RequestType, data: String) {
match req_type {
RequestType::POST => send_post_request(easy, data),
RequestType::GET => easy.perform().unwrap(),
RequestType::PUT => {
}
RequestType::DELETE => {
}
}
}
fn send_post_request(easy: &mut Easy, data: String) {
easy.post(true).unwrap();
let mut transfer = easy.transfer();
transfer
.read_function(|buf| Ok(data.as_bytes().read(buf).unwrap_or(0)))
.unwrap();
transfer.perform().unwrap();
}
fn test_response(easy: &mut Easy, expectations: Vec<JsonExpectation>) {
easy.write_function(move |data| {
let response = from_utf8(data).unwrap().to_string();
if run_testers(response, &expectations).is_err() {
set_err_true();
}
Ok(data.len())
})
.unwrap();
}
fn test_response_status(easy: &mut Easy, code: Option<StatusCode>) {
match code {
Some(StatusCode::OK) => test_response_status_by_value(easy, 200),
Some(StatusCode::BAD_REQUEST) => test_response_status_by_value(easy, 400),
Some(StatusCode::NOT_FOUND) => test_response_status_by_value(easy, 404),
None => (),
}
}
fn test_response_status_by_value(easy: &mut Easy, code: u32) {
if let Ok(easycode) = easy.response_code() {
if easycode != code {
let err_msg = format!("\tExpected status code:{}\n\tFound: {}", code, easycode).red();
println!("{}", err_msg);
set_err_true();
}
}
}
fn full_url_or_panic(link: &String, tester: &Tester) -> String {
match &tester.request_info.url_postfix {
None => panic!(
"Test failed because of missing url_postfix. \n\n{:?}",
tester
),
Some(postfix) => format!("{}{}", link, postfix),
}
}
fn req_type_or_panic(tester: &Tester) -> RequestType {
match &tester.request_info.req_type {
None => panic!(
"Test failed because of missing request type. \n\n{:?}",
tester
),
Some(req_type) => req_type.clone(),
}
}
fn req_content_or_empty(tester: &Tester) -> String {
match &tester.request_info.content {
None => "".to_string(),
Some(content) => content.clone(),
}
}