Skip to content

Commit

Permalink
test: add basic canister http test (#2683)
Browse files Browse the repository at this point in the history
The original intent was to run a webserver during CI for this test, but that turned out not to be possible:
- the canister http service requires the https scheme
- the canister http service rejects requests to a local https server using a key/cert generated by openssl, with:
   "Failed to connect: error trying to connect: The certificate was not trusted."

Instead, this test reads https://smartcontracts.org and looks for some terms that should always show up there

Fixes https://dfinity.atlassian.net/browse/SDK-453
  • Loading branch information
ericswanson-dfinity committed Oct 17, 2022
1 parent b7cc028 commit 5c5a8c4
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
45 changes: 45 additions & 0 deletions e2e/assets/canister_http/main.mo
@@ -0,0 +1,45 @@
import Types "types";
import Cycles "mo:base/ExperimentalCycles";
import Nat64 "mo:base/Nat64";
import Text "mo:base/Text";
import Blob "mo:base/Blob";
import Nat "mo:base/Nat";

shared actor class HttpQuery() = this {
let MAX_RESPONSE_BYTES : Nat64 = 12000;
let CYCLES_TO_PAY : Nat = 2_000_000_000;

public func get_url(host : Text, url : Text) : async Text {
let request_headers = [
{ name = "Host"; value = host },
{ name = "User-Agent"; value = "sdk-e2e-test" },
];

let request : Types.CanisterHttpRequestArgs = {
url = url;
max_response_bytes = ?MAX_RESPONSE_BYTES;
headers = request_headers;
body = null;
method = #get;
transform = ?(#function(transform));
};

Cycles.add(CYCLES_TO_PAY);
let ic : Types.IC = actor ("aaaaa-aa");
let response : Types.CanisterHttpResponsePayload = await ic.http_request(request);
let result : Text = switch (Text.decodeUtf8(Blob.fromArray(response.body))) {
case null "";
case (?decoded) decoded;
};
result
};

public query func transform(raw : Types.CanisterHttpResponsePayload) : async Types.CanisterHttpResponsePayload {
let transformed : Types.CanisterHttpResponsePayload = {
status = raw.status;
body = raw.body;
headers = [];
};
transformed;
};
};
1 change: 1 addition & 0 deletions e2e/assets/canister_http/patch.bash
@@ -0,0 +1 @@
jq '.canisters.e2e_project_backend.main="main.mo"' dfx.json | sponge dfx.json
53 changes: 53 additions & 0 deletions e2e/assets/canister_http/types.mo
@@ -0,0 +1,53 @@
import HashMap "mo:base/HashMap";
import Principal "mo:base/Principal";

module Types {
public type Timestamp = Nat64;
public type Rate = Text;

public type TimeRange = {
start : Timestamp;
end : Timestamp;
};

public type RatesWithInterval = {
interval : Nat64;
rates : [(Timestamp, Rate)];
};

public type HttpHeader = {
name : Text;
value : Text;
};

public type HttpMethod = {
#get;
#post;
#head;
};

public type TransformType = {
#function : shared CanisterHttpResponsePayload -> async CanisterHttpResponsePayload;
};

public type CanisterHttpRequestArgs = {
url : Text;
max_response_bytes : ?Nat64;
headers : [HttpHeader];
body : ?[Nat8];
method : HttpMethod;
transform : ?{
#function : shared query CanisterHttpResponsePayload -> async CanisterHttpResponsePayload;
};
};

public type CanisterHttpResponsePayload = {
status : Nat;
headers : [HttpHeader];
body : [Nat8];
};

public type IC = actor {
http_request : Types.CanisterHttpRequestArgs -> async Types.CanisterHttpResponsePayload;
};
};
14 changes: 14 additions & 0 deletions e2e/tests-dfx/canister_http.bash
Expand Up @@ -320,3 +320,17 @@ set_shared_local_network_canister_http_empty() {
assert_command dfx start --background --verbose
assert_match "log level: Critical"
}

@test "can query a website" {
dfx_start

dfx_new
install_asset canister_http

dfx deploy

assert_command dfx canister call e2e_project_backend get_url '("smartcontracts.org:443","https://smartcontracts.org:443")'
assert_contains "Internet Computer"
assert_contains "smart contracts"
assert_contains "dapps"
}

0 comments on commit 5c5a8c4

Please sign in to comment.