Skip to content

Commit

Permalink
fix: return 404 if token info or contract is not found
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso committed Feb 18, 2024
1 parent 9dfce51 commit e2cf513
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 94 deletions.
17 changes: 12 additions & 5 deletions integration-tests/src/client/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>, Cow<'static, str>> = Default::default();
headers.insert(
Cow::Borrowed("content-type"),
Expand All @@ -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()
}
}
49 changes: 10 additions & 39 deletions integration-tests/tests/http/deferred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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<Contract> = 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<Contract> = 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<TokenInfo> =
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<TokenInfo> =
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);

Expand Down
25 changes: 10 additions & 15 deletions src/deferred/src/http.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -38,34 +37,30 @@ 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 {
let params = match req.decode_body::<GetContractRequest>() {
Ok(request) => request,
Err(response) => return response,
};
let response = GetContractResponse::from(Deferred::get_contract(&params.id));

HttpResponse::ok(response)
Deferred::get_contract(&params.id)
.map(HttpResponse::ok)
.unwrap_or_else(HttpResponse::not_found)
}

fn get_token(req: HttpRequest) -> HttpResponse {
let params = match req.decode_body::<GetTokenRequest>() {
Ok(request) => request,
Err(response) => return response,
};
let response = GetTokenResponse::from(Deferred::get_token(&params.id));

HttpResponse::ok(response)
Deferred::get_token(&params.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())
}
}
3 changes: 0 additions & 3 deletions src/deferred/src/http/get_agencies.rs

This file was deleted.

16 changes: 1 addition & 15 deletions src/deferred/src/http/get_contract.rs
Original file line number Diff line number Diff line change
@@ -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<Contract>,
}

impl From<Option<Contract>> for GetContractResponse {
fn from(contract: Option<Contract>) -> Self {
Self { contract }
}
}

pub type GetContractsResponse = Vec<ID>;
15 changes: 2 additions & 13 deletions src/deferred/src/http/get_token.rs
Original file line number Diff line number Diff line change
@@ -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<TokenInfo>,
}

impl From<Option<TokenInfo>> for GetTokenResponse {
fn from(token: Option<TokenInfo>) -> Self {
Self { token }
}
}
29 changes: 25 additions & 4 deletions src/did/src/common/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -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<S>(body: S) -> Self
where
Expand All @@ -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,
Expand All @@ -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),
)
}
}

Expand Down

0 comments on commit e2cf513

Please sign in to comment.