ligo/src/test/id_tests.ml
2020-02-09 00:31:30 +01:00

486 lines
21 KiB
OCaml

open Trace
open Test_helpers
open Ast_simplified
let mtype_file f =
let%bind simplified = Ligo.Compile.Of_source.compile f (Syntax_name "cameligo") in
let%bind typed,state = Ligo.Compile.Of_simplified.compile simplified in
ok (typed,state)
let get_program =
let s = ref None in
fun () -> match !s with
| Some s -> ok s
| None -> (
let%bind program = mtype_file "./contracts/id.mligo" in
s := Some program ;
ok program
)
let compile_main () =
let%bind simplified = Ligo.Compile.Of_source.compile "./contracts/id.mligo" (Syntax_name "cameligo") in
let%bind typed_prg,_ = Ligo.Compile.Of_simplified.compile simplified in
let%bind mini_c_prg = Ligo.Compile.Of_typed.compile typed_prg in
let%bind michelson_prg = Ligo.Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg "main" in
let%bind (_contract: Tezos_utils.Michelson.michelson) =
(* fails if the given entry point is not a valid contract *)
Ligo.Compile.Of_michelson.build_contract michelson_prg in
ok ()
let (first_owner , first_contract) =
let open Proto_alpha_utils.Memory_proto_alpha in
let id = List.nth dummy_environment.identities 0 in
let kt = id.implicit_contract in
Protocol.Alpha_context.Contract.to_b58check kt , kt
let buy_id () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1)]) ;
e_int 1;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let param = e_pair owner_website (e_some (e_address new_addr)) in
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let%bind () = expect_eq ~options program "buy"
(e_pair param storage)
(e_pair (e_list []) new_storage)
in ok ()
let buy_id_sender_addr () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1)]) ;
e_int 1;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let param = e_pair owner_website (e_typed_none t_address) in
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let%bind () = expect_eq ~options program "buy"
(e_pair param storage)
(e_pair (e_list []) new_storage)
in ok ()
(* Test that contract fails if we attempt to buy an ID for the wrong amount *)
let buy_id_wrong_amount () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1)]) ;
e_int 1;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
in
let param = e_pair owner_website (e_some (e_address new_addr)) in
let%bind () = expect_string_failwith ~options program "buy"
(e_pair param storage)
"Incorrect amount paid."
in ok ()
let update_details_owner () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address owner_addr) ;
("profile", new_website)]
in
let id_details_2_diff = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)] in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2_diff)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let details = e_bytes_string "ligolang.org" in
let param = e_tuple [e_int 1 ;
e_some details ;
e_some (e_address new_addr)] in
let%bind () = expect_eq ~options program "update_details"
(e_pair param storage)
(e_pair (e_list []) new_storage)
in ok ()
let update_details_controller () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", new_website)] in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2_diff)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let details = e_bytes_string "ligolang.org" in
let param = e_tuple [e_int 1 ;
e_some details ;
e_some (e_address owner_addr)] in
let%bind () = expect_eq ~options program "update_details"
(e_pair param storage)
(e_pair (e_list []) new_storage)
in ok ()
(* Test that contract fails when we attempt to update details of nonexistent ID *)
let update_details_nonexistent () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let details = e_bytes_string "ligolang.org" in
let param = e_tuple [e_int 2 ;
e_some details ;
e_some (e_address owner_addr)] in
let%bind () = expect_string_failwith ~options program "update_details"
(e_pair param storage)
"This ID does not exist."
in ok ()
(* Test that contract fails when we attempt to update details from wrong addr *)
let update_details_wrong_addr () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let details = e_bytes_string "ligolang.org" in
let param = e_tuple [e_int 0 ;
e_some details ;
e_some (e_address owner_addr)] in
let%bind () = expect_string_failwith ~options program "update_details"
(e_pair param storage)
"You are not the owner or controller of this ID."
in ok ()
(* Test that giving none on both profile and controller address is a no-op *)
let update_details_unchanged () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let param = e_tuple [e_int 1 ;
e_typed_none t_bytes ;
e_typed_none t_address] in
let%bind () = expect_eq ~options program "update_details"
(e_pair param storage)
(e_pair (e_list []) storage)
in ok ()
let update_owner () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)] in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2_diff)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let param = e_pair (e_int 1) (e_address owner_addr) in
let%bind () = expect_eq ~options program "update_owner"
(e_pair param storage)
(e_pair (e_list []) new_storage)
in ok ()
(* Test that contract fails when we attempt to update owner of nonexistent ID *)
let update_owner_nonexistent () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let param = e_pair (e_int 2) (e_address new_addr) in
let%bind () = expect_string_failwith ~options program "update_owner"
(e_pair param storage)
"This ID does not exist."
in ok ()
(* Test that contract fails when we attempt to update owner from non-owner addr *)
let update_owner_wrong_addr () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let param = e_pair (e_int 0) (e_address new_addr) in
let%bind () = expect_string_failwith ~options program "update_owner"
(e_pair param storage)
"You are not the owner of this ID."
in ok ()
let skip () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 3;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let%bind () = expect_eq ~options program "skip"
(e_pair (e_unit ()) storage)
(e_pair (e_list []) new_storage)
in ok ()
(* Test that contract fails if we try to skip without paying the right amount *)
let skip_wrong_amount () =
let%bind program, _ = get_program () in
let owner_addr = addr 5 in
let owner_website = e_bytes_string "ligolang.org" in
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
("controller", e_address owner_addr) ;
("profile", owner_website)]
in
let new_addr = first_owner in
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
~payer:first_contract
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
in
let new_website = e_bytes_string "ligolang.org" in
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
("controller", e_address new_addr) ;
("profile", new_website)]
in
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
(e_int 1, id_details_2)]) ;
e_int 2;
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
in
let%bind () = expect_string_failwith ~options program "skip"
(e_pair (e_unit ()) storage)
"Incorrect amount paid."
in ok ()
let main = test_suite "ID Layer" [
test "buy" buy_id ;
test "buy (sender addr)" buy_id_sender_addr ;
test "buy (wrong amount)" buy_id_wrong_amount ;
test "update_details (owner)" update_details_owner ;
test "update_details (controller)" update_details_controller ;
test "update_details_nonexistent" update_details_nonexistent ;
test "update_details_wrong_addr" update_details_wrong_addr ;
test "update_details_unchanged" update_details_unchanged ;
test "update_owner" update_owner ;
test "update_owner_nonexistent" update_owner_nonexistent ;
test "update_owner_wrong_addr" update_owner_wrong_addr ;
test "skip" skip ;
test "skip (wrong amount)" skip_wrong_amount ;
]