From b8e24a248e1e45145506e24e863cf258527ce7c8 Mon Sep 17 00:00:00 2001
From: kirbylife <gabriel13m@gmail.com>
Date: Wed, 3 Feb 2021 17:43:56 -0600
Subject: [PATCH] add a way to change the http method

---
 src/request.rs      | 31 ++++++++++++++++++++++++++-----
 src/response.rs     |  7 ++++---
 tests/unit_tests.rs | 14 ++++++++++++--
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/src/request.rs b/src/request.rs
index 1945e5a..8901ac8 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -1,4 +1,4 @@
-use http::status::StatusCode;
+use http::Method;
 use url::{ParseError, Url};
 
 use crate::response;
@@ -13,21 +13,35 @@ pub trait RequestBase {
 #[derive(Debug)]
 pub struct Request {
     pub url: url::Url,
+    method: Method,
 }
 
 impl RequestBase for Request {
     fn new(url: &'static str) -> Result<Request, ParseError> {
         match Url::parse(url) {
-            Ok(url_parsed) => Ok(Request { url: url_parsed }),
+            Ok(url_parsed) => Ok(Request {
+                url: url_parsed,
+                method: Method::GET,
+            }),
             Err(error) => Err(error),
         }
     }
 
     fn launch(&self) -> response::Response {
-        let resp = reqwest::blocking::get(self.url.as_str()).unwrap();
+        let client = reqwest::blocking::Client::new();
+        let resp = (match self.method {
+            Method::GET => client.get(self.url.as_str()),
+            Method::POST => client.post(self.url.as_str()),
+            Method::PUT => client.put(self.url.as_str()),
+            Method::PATCH => client.patch(self.url.as_str()),
+            Method::DELETE => client.delete(self.url.as_str()),
+            _ => unimplemented!(),
+        })
+        .send()
+        .unwrap();
 
-        let text: String = resp.text().unwrap();
-        let status = StatusCode::OK;
+        let status = resp.status();
+        let text = resp.text().unwrap();
 
         let url = self.url.clone();
 
@@ -38,3 +52,10 @@ impl RequestBase for Request {
         }
     }
 }
+
+impl Request {
+    pub fn method(&mut self, method: Method) -> &mut Self {
+        self.method = method;
+        self
+    }
+}
diff --git a/src/response.rs b/src/response.rs
index 1cc3f27..8c15fbd 100644
--- a/src/response.rs
+++ b/src/response.rs
@@ -1,5 +1,6 @@
 use http::StatusCode;
-use serde_json::{Result, Value};
+use serde::de::DeserializeOwned;
+use serde_json::Result;
 use url::Url;
 
 use crate::selector::SelectorBase;
@@ -13,7 +14,7 @@ pub struct Response {
 
 impl SelectorBase for Response {
     fn from_html(_: String) -> Self {
-        panic!("Not implemented")
+        unimplemented!()
     }
 
     fn html(&self) -> String {
@@ -22,7 +23,7 @@ impl SelectorBase for Response {
 }
 
 impl Response {
-    pub fn to_json(&self) -> Result<Value> {
+    pub fn to_json<T: DeserializeOwned>(&self) -> Result<T> {
         let plain_text: &[u8] = self.text.as_ref();
         let json = serde_json::from_slice(plain_text)?;
         Ok(json)
diff --git a/tests/unit_tests.rs b/tests/unit_tests.rs
index 1dc1095..1ee8304 100644
--- a/tests/unit_tests.rs
+++ b/tests/unit_tests.rs
@@ -1,6 +1,8 @@
+use http::Method;
 use http::StatusCode;
 use raspa::request::{Request, RequestBase};
 use raspa::selector::{Selector, SelectorBase};
+use serde_json::Value;
 
 #[test]
 fn plain_text_selector() {
@@ -80,8 +82,16 @@ fn complex_selectors() {
 
 #[test]
 fn simple_json_test() {
-    let req: Request = RequestBase::new("https://httpbin.org/json").unwrap();
-    let resp = req.launch().to_json().expect("cannot parse json");
+    let req = Request::new("https://httpbin.org/json").unwrap();
+    let resp: Value = req.launch().to_json().expect("cannot parse json");
 
     assert_eq!(resp["slideshow"]["title"], "Sample Slide Show");
 }
+
+#[test]
+fn simple_post_request() {
+    let mut req = Request::new("https://httpbin.org/post").unwrap();
+    req.method(Method::POST);
+    let resp: Value = req.launch().to_json().expect("cannot parse json");
+    assert_eq!(resp["url"].as_str().unwrap(), "https://httpbin.org/post");
+}