diff --git a/src/test/contracts/id.ligo b/src/test/contracts/id.ligo new file mode 100644 index 000000000..ec4d3c1ca --- /dev/null +++ b/src/test/contracts/id.ligo @@ -0,0 +1,178 @@ +type id is int + +type id_details is + record [ + owner: address; + controller: address; + profile: bytes; + ] + +type buy is + record [ + profile: bytes; + initial_controller: option(address); + ] + +type update_owner is + record [ + id: id; + new_owner: address; + ] + +type update_details is + record [ + id: id; + new_profile: option(bytes); + new_controller: option(address); + ] + +type action is + | Buy of buy + | Update_owner of update_owner + | Update_details of update_details + | Skip of unit + +(* The prices kept in storage can be changed by bakers, though they should only be + adjusted down over time, not up. *) +type storage is + record [ + identities: big_map (id, id_details); + next_id: int; + name_price: tez; + skip_price: tez; + ] + +(** Preliminary thoughts on ids: + +I very much like the simplicity of http://gurno.com/adam/mne/. +5 three letter words means you have a 15 character identity, not actually more +annoying than an IP address and a lot more memorable than the raw digits. This +can be stored as a single integer which is then translated into the corresponding +series of 5 words. + +I in general like the idea of having a 'skip' mechanism, but it does need to cost +something so people don't eat up the address space. 256 ^ 5 means you have a lot +of address space, but if people troll by skipping a lot that could be eaten up. +Should probably do some napkin calculations for how expensive skipping needs to +be to deter people from doing it just to chew up address space. +*) + +function buy (const parameter : buy; const storage : storage) : list(operation) * storage is + begin + if amount = storage.name_price + then skip + else failwith("Incorrect amount paid."); + const profile : bytes = parameter.profile; + const initial_controller : option(address) = parameter.initial_controller; + var identities : big_map (id, id_details) := storage.identities; + const new_id : int = storage.next_id; + const controller : address = + case initial_controller of + Some(addr) -> addr + | None -> sender + end; + const new_id_details: id_details = + record [ + owner = sender ; + controller = controller ; + profile = profile ; + ]; + identities[new_id] := Some(new_id_details); + end with ((nil : list(operation)), record [ + identities = updated_identities; + next_id = new_id + 1; + name_price = storage.name_price; + skip_price = storage.skip_price; + ]) + +function update_owner (const parameter : update_owner; const storage : storage) : + list(operation) * storage is + begin + if (amount =/= 0mutez) + then + begin + failwith("Updating owner doesn't cost anything."); + end + else skip; + const id : int = parameter[id]; + const new_owner : address = parameter[new_owner]; + var identities : big_map (id, id_details) := storage[identities]; + const id_details : id_details = + case identities[id] of + Some(id_details) -> id_details + | None -> (failwith("This ID does not exist."): id_details) + end; + var is_allowed : bool := false; + if sender = id_details[owner] + then is_allowed := true + else failwith("You are not the owner of this ID."); + id_details[owner] := new_owner; + identities[id] := Some(id_details); + end with ((nil: list(operation)), record [ + identities = updated_identities; + next_id = storage.next_id; + name_price = storage.name_price; + skip_price = storage.skip_price; + ]) + +function update_details (const parameter : update_details; const storage : storage ) : + list(operation) * storage is + begin + if (amount =/= 0mutez) + then failwith("Updating details doesn't cost anything.") + else skip; + const id : int = parameter[id]; + const new_profile : option(bytes) = parameter[new_profile]; + const new_controller : option(address) = parameter[new_controller]; + const identities : big_map (id, id_details) = storage[identities]; + const id_details: id_details = + case identities[id] of + Some(id_details) -> id_details + | None -> (failwith("This ID does not exist."): id_details) + end; + var is_allowed : bool := false; + if (sender = current_id_details[controller]) or (sender = current_id_details[owner]) + then is_allowed := true + else failwith("You are not the owner or controller of this ID."); + const owner: address = id_details[owner]; + const profile: bytes = + case new_profile of + None -> (* Default *) id_details[profile] + | Some(new_profile) -> new_profile + end; + const controller: address = + case new_controller of + None -> (* Default *) current_id_details[controller] + | Some(new_controller) -> new_controller + end; + id_details[owner] := owner; + id_details[controller] := controller; + id_details[profile] := profile; + identities[id] := Some(id_details); + end with ((nil: list(operation)), record [ + identities = identities; + next_id = storage[next_id]; + name_price = storage[name_price]; + skip_price = storage[skip_price]; + ]) + +(* Let someone skip the next identity so nobody has to take one that's undesirable *) +function skip_ (const p: unit; const storage: storage) : list(operation) * storage is + begin + if amount = storage[skip_price] + then skip + else failwith("Incorrect amount paid."); + end with ((nil: list(operation)), record [ + identities = storage[identities]; + next_id = storage[next_id] + 1; + name_price = storage[name_price]; + skip_price = storage[skip_price]; + ]) + +function main (const action : action; const storage : storage) : list(operation) * storage is + case action of + | Buy(b) -> buy (b, storage) + | Update_owner(uo) -> update_owner (uo, storage) + | Update_details(ud) -> update_details (ud, storage) + | Skip(s) -> skip_ (unit, storage) + end; diff --git a/src/test/id_tests_p.ml b/src/test/id_tests_p.ml new file mode 100644 index 000000000..ab98a8c95 --- /dev/null +++ b/src/test/id_tests_p.ml @@ -0,0 +1,527 @@ +open Trace +open Test_helpers +open Ast_simplified + + +let mtype_file f = + let%bind simplified = Ligo.Compile.Of_source.compile f (Syntax_name "pascaligo") 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.ligo" in + s := Some program ; + ok program + ) + +let compile_main () = + let%bind simplified = Ligo.Compile.Of_source.compile "./contracts/id.ligo" (Syntax_name "pascaligo") 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_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ; + ("next_id", e_int 1) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_addr = first_owner in + let options = Proto_alpha_utils.Memory_proto_alpha.make_options + ~sender: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_record_ez [("profile", owner_website) ; + ("initial_controller", (e_some (e_address new_addr))) ; + ] in + let new_storage = e_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", 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_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ; + ("next_id", e_int 1) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_addr = first_owner in + let options = Proto_alpha_utils.Memory_proto_alpha.make_options + ~sender: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_record_ez [("profile", owner_website) ; + ("initial_controller", (e_typed_none t_address))] in + let new_storage = e_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", 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_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ; + ("next_id", e_int 1) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_addr = first_owner in + let options = Proto_alpha_utils.Memory_proto_alpha.make_options + ~sender:first_contract + ~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) () + in + let param = e_record_ez [("profile", owner_website) ; + ("initial_controller", (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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_storage = e_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2_diff)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let details = e_bytes_string "ligolang.org" in + let param = e_record_ez [("id", e_int 1) ; + ("new_profile", e_some details) ; + ("new_controller", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_storage = e_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2_diff)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let details = e_bytes_string "ligolang.org" in + let param = e_record_ez [("id", e_int 1) ; + ("new_profile", e_some details) ; + ("new_controller", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let details = e_bytes_string "ligolang.org" in + let param = e_record_ez [("id", e_int 2) ; + ("new_profile", e_some details) ; + ("new_controller", 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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let details = e_bytes_string "ligolang.org" in + let param = e_record_ez [("id", e_int 0) ; + ("new_profile", e_some details) ; + ("new_controller", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let param = e_record_ez [("id", e_int 1) ; + ("new_profile", e_typed_none t_bytes) ; + ("new_controller", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_storage = e_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2_diff)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let param = e_record_ez [("id", e_int 1) ; + ("new_owner", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let param = e_record_ez [("id", e_int 2); + ("new_owner", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let param = e_record_ez [("id", e_int 0); + ("new_owner", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", e_mutez 1000000) ; ] + in + let new_storage = e_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 3) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", 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 + ~sender: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_record_ez [("identities", (e_big_map + [(e_int 0, id_details_1) ; + (e_int 1, id_details_2)])) ; + ("next_id", e_int 2) ; + ("name_price", e_mutez 1000000) ; + ("skip_price", 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 ; +] diff --git a/src/test/test.ml b/src/test/test.ml index 01d8a78f6..04eb54428 100644 --- a/src/test/test.ml +++ b/src/test/test.ml @@ -11,6 +11,7 @@ let () = Coase_tests.main ; Vote_tests.main ; Id_tests.main ; + Id_tests_p.main ; Multisig_tests.main ; Multisig_v2_tests.main ; Replaceable_id_tests.main ;