PFC6VDDZ55HDVMZYGJJOBUA4PTKDYIOBV7GKHT2FCWUJGXHXAPCAC AQ2M4QZFKBNHMJF25P275ISB7QV7JWKMFV632PI7NWJJGFXE6Q5AC YA3ELS7AQZ2XCZZVNMZOM3TSVCWU7HSBVMDXFCIOFTXAYFZSRL2AC YWCRGWVDIMCPXBQFM23MKCYZCXJJSD733NJEPB6WUU4G4BSREILAC 755UGKECZ3PFYEA2TFFOUZTF27CRQTBZWO7UYFU6WQDJMZDBVPRAC CZG24QKIB45EL7PK4UA6XVG3VEVKI7OAQXN4YMFUKKI2MXLHRANQC WHYWDNSL67TTB2AGAUACXERJ6X54YMNYVC32KJQFEXFFRYA4K3HQC OJ6KWAG7XUCYNQ6T3FRJK2QOP7DBO26PZEWDVH3Q2MJKIBMNWRPQC IBA3VK7OHBGLEYASI7JNTXPYVTNVFT4L4RRWLNF2VGPPCONDAWMQC 55WLMLEEVBRSTAFRZ5RGF7TOGUF5OPVCPA2TMHAQK45OUO7PA3YQC chunk_messages_test() ->A = crypto:strong_rand_bytes(5),ALen = wire:encode_varint(byte_size(A)),B = crypto:strong_rand_bytes(10),BLen = wire:encode_varint(byte_size(B)),C = crypto:strong_rand_bytes(5),CLen = wire:encode_varint(byte_size(C)),Payload = <<ALen/bytes, A/bytes, BLen/bytes, B/bytes, CLen/bytes, C/bytes>>,{ok, [A, B, C]} = wire:split_messages(Payload).multiple_in_one_test() ->[{binary, Bin1}, _] = examples:hash_response(),[{binary, Bin2}, _] = examples:post_request(),{multiple, Msgs} = wire:decode(<<Bin1/binary, Bin2/binary>>),?assertEqual(2, length(Msgs)).%% full circleencode_channel_state_req_test() ->TH = make_test_header(),Msg = wire:encode_channel_state_request(TH, "Foo", true),{ok, [Header, Body]} = wire:decode(Msg),[{requestId, Req}, {circuitId, Circ}, _] = TH,?assertEqual(Req, proplists:get_value(requestId, Header)),?assertEqual(Circ, proplists:get_value(circuitId, Header)),?assertEqual(<<"Foo">>, proplists:get_value(channel, Body)),?assertEqual(1, proplists:get_value(future, Body)).
%% move these to seperate test filepost_text_test() ->[{binary, Bin}, {obj, TestObj}] = examples:post_text(),Decoded = posts:decode_post_text(Bin),[ {pubKey, _PubKey}, {links, _Links}, {postType, _PostType}, {timestamp, _TimeStamp}, {channel, Channel}, {text, Text}] = Decoded,?assertEqual("default", Channel),?assertEqual(<<"h€llo world"/utf8>>, Text),assert_post(Decoded, TestObj).post_delete_test() ->[{binary, Bin}, {obj, TestObj}] = examples:post_delete(),Decoded = posts:decode_post_delete(Bin),[ {pubKey, _PubKey}, {links, _Links}, {postType, _PostType}, {timestamp, _TimeStamp}, {hashes, Hashes}] = Decoded,% TODO: assert Hash values?assertEqual(length(maps:get(<<"hashes">>, TestObj)), length(Hashes)),assert_post(Decoded, TestObj).
post_info_test() ->[{binary, Bin}, {obj, TestObj}] = examples:post_info(),Decoded = posts:decode_post_info(Bin),[ {pubKey, _PubKey}, {links, _Links}, {postType, _PostType}, {timestamp, _TimeStamp}, {infos, Infos}] = Decoded,?assertEqual(#{"name" => "cabler"}, Infos),assert_post(Decoded, TestObj).
%% full circleencode_channel_state_req_test() ->TH = make_test_header(),Bin = wire:encode_channel_state_request(TH, "Foo", true),{ok, [Msg]} = wire:split_messages(Bin),{ok, [Header, Body]} = wire:decode(Msg),[{requestId, Req}, {circuitId, Circ}, _] = TH,?assertEqual(Req, proplists:get_value(requestId, Header)),?assertEqual(Circ, proplists:get_value(circuitId, Header)),?assertEqual(<<"Foo">>, proplists:get_value(channel, Body)),?assertEqual(1, proplists:get_value(future, Body)).
post_topic_test() ->[{binary, Bin}, {obj, TestObj}] = examples:post_topic(),Decoded = posts:decode_post_topic(Bin),[ {pubKey, _PubKey}, {links, _Links}, {postType, _PostType}, {timestamp, _TimeStamp}, {channel, Channel}, {topic, Topic}] = Decoded,?assertEqual(maps:get(<<"channel">>, TestObj), Channel),?assertEqual(maps:get(<<"topic">>, TestObj), Topic),assert_post(Decoded, TestObj).
% low-level helper
post_join_test() ->[{binary, Bin}, {obj, TestObj}] = examples:post_join(),Decoded = posts:decode_post_join(Bin),[ {pubKey, _PubKey}, {links, _Links}, {postType, _PostType}, {timestamp, _TimeStamp}, {channel, Channel}] = Decoded,?assertEqual(maps:get(<<"channel">>, TestObj), Channel),assert_post(Decoded, TestObj).
chunk_messages_test() ->A = crypto:strong_rand_bytes(5),ALen = wire:encode_varint(byte_size(A)),B = crypto:strong_rand_bytes(10),BLen = wire:encode_varint(byte_size(B)),C = crypto:strong_rand_bytes(5),CLen = wire:encode_varint(byte_size(C)),Payload = <<ALen/bytes, A/bytes, BLen/bytes, B/bytes, CLen/bytes, C/bytes>>,{ok, [A, B, C]} = wire:split_messages(Payload).
post_leave_test() ->[{binary, Bin}, {obj, TestObj}] = examples:post_leave(),Decoded = posts:decode_post_leave(Bin),[ {pubKey, _PubKey}, {links, _Links}, {postType, _PostType}, {timestamp, _TimeStamp}, {channel, Channel}] = Decoded,?assertEqual(maps:get(<<"channel">>, TestObj), Channel),assert_post(Decoded, TestObj).
assert_post(Post, TestObj) ->?assertEqual(maps:get(<<"postType">>, TestObj), proplists:get_value(postType, Post)),?assertEqual(maps:get(<<"timestamp">>, TestObj), proplists:get_value(timestamp, Post)),?assertEqual(length(maps:get(<<"links">>, TestObj)), length(proplists:get_value(links, Post))),PubKey = hex:hexstr_to_bin(binary_to_list(maps:get(<<"publicKey">>, TestObj))),?assertEqual(PubKey, proplists:get_value(pubKey, Post)).
make_test_header() ->[{requestId, crypto:strong_rand_bytes(4)},{circuitId, crypto:strong_rand_bytes(4)},{ttl, rand:uniform(20)}].
{MsgLen, Rest} = decode_varint(Data),case MsgLen =:= byte_size(Rest) oftrue ->{MsgType, Rest2} = decode_varint(Rest),<< CircuitId:4/binary, ReqId:4/binary, Rest3/binary >> = Rest2,Header = [ {msgLen, MsgLen}, {msgType, MsgType}, {circuitId, CircuitId}, {requestId, ReqId}],{ok, [Header, Rest3]};false ->% we currently assume the passed data is a full message% but a client _could_ send multiple in a single (tcp) writeerlang:error("TODO: implement proper message chunking")end.
{MsgType, Rest2} = decode_varint(Data),<< CircuitId:4/binary, ReqId:4/binary, Rest3/binary >> = Rest2,Header = [ {msgType, MsgType}, {circuitId, CircuitId}, {requestId, ReqId}],{ok, [Header, Rest3]}.
Result = wire:decode(Data),% not sure if it's good to produce this many messages but i'm fine with it for nowcase Result of{ok, Msg} ->Handler ! {incoming, Conn, Msg};{multiple, Msgs} -> lists:foreach(fun(Msg) ->Handler ! {incoming, conn, Msg} end, Msgs)end,decode_loop(State, Conn);
{ok, Msgs} = wire:split_messages(Data),lists:foreach(fun(Chunk) ->{ok, Msg} = wire:decode(Chunk),Handler ! {incoming, Conn, Msg}end, Msgs),decode_loop(State, Conn);