diff --git a/integration-tests/src/client/http.rs b/integration-tests/src/client/http.rs index 6d26279..c40ab7a 100644 --- a/integration-tests/src/client/http.rs +++ b/integration-tests/src/client/http.rs @@ -22,6 +22,16 @@ impl<'a> HttpClient<'a> { where S: serde::de::DeserializeOwned, { + let response = self.raw_http_request_response(method, params); + + serde_json::from_slice(&response.body).unwrap() + } + + pub fn raw_http_request_response( + &self, + method: &str, + params: serde_json::Value, + ) -> HttpResponse { let mut headers: HashMap, Cow<'static, str>> = Default::default(); headers.insert( Cow::Borrowed("content-type"), @@ -40,16 +50,13 @@ impl<'a> HttpClient<'a> { body: ByteBuf::from(body.to_string()), }; - let response: HttpResponse = self - .env + self.env .query( self.principal, admin(), "http_request", Encode!(&request).unwrap(), ) - .unwrap(); - - serde_json::from_slice(&response.body).unwrap() + .unwrap() } } diff --git a/integration-tests/tests/http/deferred.rs b/integration-tests/tests/http/deferred.rs index 1f56d4a..abee7f6 100644 --- a/integration-tests/tests/http/deferred.rs +++ b/integration-tests/tests/http/deferred.rs @@ -7,7 +7,7 @@ use integration_tests::TestEnv; #[test] #[serial_test::serial] -fn test_should_get_contracts() { +fn test_http_should_get_contracts() { let env = TestEnv::init(); let contract_id = init_contract(&env); @@ -18,82 +18,53 @@ fn test_should_get_contracts() { assert_eq!(contracts[0], contract_id); // get contract by id - - let contract: serde_json::Value = http_client.http_request( + let contract: Contract = http_client.http_request( "getContract", serde_json::json!({ "id": contract_id, }), ); - // get contract - let contract: Option = serde_json::from_value( - contract - .as_object() - .unwrap() - .get("contract") - .unwrap() - .clone(), - ) - .unwrap(); - assert_eq!(contract.unwrap().id, contract_id); + assert_eq!(contract.id, contract_id); // get unexisting contract - let contract: serde_json::Value = http_client.http_request( + let response = http_client.raw_http_request_response( "getContract", serde_json::json!({ "id": 5000_u64, }), ); - // get contract - let contract: Option = serde_json::from_value( - contract - .as_object() - .unwrap() - .get("contract") - .unwrap() - .clone(), - ) - .unwrap(); - assert!(contract.is_none()); + assert_eq!(response.status_code, 404); } #[test] #[serial_test::serial] -fn test_should_get_token() { +fn test_http_should_get_token() { let env = TestEnv::init(); let contract_id = init_contract(&env); let http_client = HttpClient::new(env.deferred_id, &env); - let token: serde_json::Value = http_client.http_request( + let token_info: TokenInfo = http_client.http_request( "getToken", serde_json::json!({ "id": 1, }), ); - let token_info: Option = - serde_json::from_value(token.as_object().unwrap().get("token").unwrap().clone()).unwrap(); - assert!(token_info.is_some()); - - let token_info = token_info.unwrap(); assert_eq!(token_info.token.id, 1u64); assert_eq!(token_info.token.contract_id, contract_id); // get unexisting token - let token: serde_json::Value = http_client.http_request( + let response = http_client.raw_http_request_response( "getToken", serde_json::json!({ "id": 5000_u64, }), ); - - let token_info: Option = - serde_json::from_value(token.as_object().unwrap().get("token").unwrap().clone()).unwrap(); - assert!(token_info.is_none()); + assert_eq!(response.status_code, 404); } #[test] #[serial_test::serial] -fn test_should_get_agencies() { +fn test_http_should_get_agencies() { let env = TestEnv::init(); let deferred_client = DeferredClient::from(&env); diff --git a/src/deferred/src/http.rs b/src/deferred/src/http.rs index d9dbdcc..316c571 100644 --- a/src/deferred/src/http.rs +++ b/src/deferred/src/http.rs @@ -1,11 +1,10 @@ -mod get_agencies; mod get_contract; mod get_token; use did::{HttpRequest, HttpResponse}; -use self::get_contract::{GetContractRequest, GetContractResponse}; -use self::get_token::{GetTokenRequest, GetTokenResponse}; +use self::get_contract::GetContractRequest; +use self::get_token::GetTokenRequest; use crate::app::Deferred; pub struct HttpApi; @@ -38,9 +37,7 @@ impl HttpApi { } fn get_contracts() -> HttpResponse { - let response = get_contract::GetContractsResponse::from(Deferred::get_signed_contracts()); - - HttpResponse::ok(response) + HttpResponse::ok(Deferred::get_signed_contracts()) } fn get_contract(req: HttpRequest) -> HttpResponse { @@ -48,9 +45,9 @@ impl HttpApi { Ok(request) => request, Err(response) => return response, }; - let response = GetContractResponse::from(Deferred::get_contract(¶ms.id)); - - HttpResponse::ok(response) + Deferred::get_contract(¶ms.id) + .map(HttpResponse::ok) + .unwrap_or_else(HttpResponse::not_found) } fn get_token(req: HttpRequest) -> HttpResponse { @@ -58,14 +55,12 @@ impl HttpApi { Ok(request) => request, Err(response) => return response, }; - let response = GetTokenResponse::from(Deferred::get_token(¶ms.id)); - - HttpResponse::ok(response) + Deferred::get_token(¶ms.id) + .map(HttpResponse::ok) + .unwrap_or_else(HttpResponse::not_found) } fn get_agencies() -> HttpResponse { - let response = get_agencies::GetAgenciesResponse::from(Deferred::get_agencies()); - - HttpResponse::ok(response) + HttpResponse::ok(Deferred::get_agencies()) } } diff --git a/src/deferred/src/http/get_agencies.rs b/src/deferred/src/http/get_agencies.rs deleted file mode 100644 index 7fbf194..0000000 --- a/src/deferred/src/http/get_agencies.rs +++ /dev/null @@ -1,3 +0,0 @@ -use did::deferred::Agency; - -pub type GetAgenciesResponse = Vec; diff --git a/src/deferred/src/http/get_contract.rs b/src/deferred/src/http/get_contract.rs index 5f0eb51..22fa187 100644 --- a/src/deferred/src/http/get_contract.rs +++ b/src/deferred/src/http/get_contract.rs @@ -1,21 +1,7 @@ -use did::deferred::Contract; use did::ID; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; #[derive(Clone, Debug, Deserialize)] pub struct GetContractRequest { pub id: ID, } - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct GetContractResponse { - contract: Option, -} - -impl From> for GetContractResponse { - fn from(contract: Option) -> Self { - Self { contract } - } -} - -pub type GetContractsResponse = Vec; diff --git a/src/deferred/src/http/get_token.rs b/src/deferred/src/http/get_token.rs index 2d8cda7..fccd6bc 100644 --- a/src/deferred/src/http/get_token.rs +++ b/src/deferred/src/http/get_token.rs @@ -1,18 +1,7 @@ -use did::deferred::{TokenIdentifier, TokenInfo}; -use serde::{Deserialize, Serialize}; +use did::deferred::TokenIdentifier; +use serde::Deserialize; #[derive(Clone, Debug, Deserialize)] pub struct GetTokenRequest { pub id: TokenIdentifier, } - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct GetTokenResponse { - token: Option, -} - -impl From> for GetTokenResponse { - fn from(token: Option) -> Self { - Self { token } - } -} diff --git a/src/did/src/common/http.rs b/src/did/src/common/http.rs index e4e3a1d..f91015f 100644 --- a/src/did/src/common/http.rs +++ b/src/did/src/common/http.rs @@ -5,6 +5,12 @@ use candid::CandidType; use serde::{Deserialize, Serialize}; use serde_bytes::ByteBuf; +const HTTP_OK: u16 = 200; +const HTTP_UPGRADE: u16 = 204; +const HTTP_BAD_REQUEST: u16 = 400; +const HTTP_NOT_FOUND: u16 = 404; +const HTTP_INTERNAL_ERROR: u16 = 500; + /// A HTTP response. #[derive(Clone, Debug, CandidType, Deserialize)] pub struct HttpResponse { @@ -41,7 +47,7 @@ impl HttpResponse { }; Self { - status_code: 500, + status_code: HTTP_INTERNAL_ERROR, headers: HashMap::from([("content-type".into(), "application/json".into())]), body, upgrade: None, @@ -56,13 +62,23 @@ impl HttpResponse { }; Self { - status_code: 400, + status_code: HTTP_BAD_REQUEST, headers: HashMap::from([("content-type".into(), "application/json".into())]), body, upgrade: None, } } + /// Returns a new `HttpResponse` intended to be used for not found + pub fn not_found() -> Self { + Self { + status_code: HTTP_NOT_FOUND, + headers: HashMap::from([("content-type".into(), "application/json".into())]), + body: ByteBuf::from("Not Found".as_bytes()), + upgrade: None, + } + } + /// Returns an OK response with the given body. pub fn ok(body: S) -> Self where @@ -73,7 +89,7 @@ impl HttpResponse { Err(e) => return HttpResponse::internal_error(e.to_string()), }; Self::new( - 200, + HTTP_OK, HashMap::from([("content-type".into(), "application/json".into())]), ByteBuf::from(body.as_bytes()), None, @@ -82,7 +98,12 @@ impl HttpResponse { /// Upgrade response to update call. pub fn upgrade_response() -> Self { - Self::new(204, HashMap::default(), ByteBuf::default(), Some(true)) + Self::new( + HTTP_UPGRADE, + HashMap::default(), + ByteBuf::default(), + Some(true), + ) } }