Skip to content

Commit

Permalink
Merge pull request #3236 from imcyee/patch-3
Browse files Browse the repository at this point in the history
Add thread and thread parent to client api messages
  • Loading branch information
vkatsuba authored Aug 30, 2021
2 parents 6cf4127 + 6c3decc commit 61018c1
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 11 deletions.
118 changes: 117 additions & 1 deletion big_tests/tests/rest_client_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ all() ->

groups() ->
G = [{messages_with_props, [parallel], message_with_props_test_cases()},
{messages_with_thread, [parallel], message_with_thread_test_cases()},
{messages, [parallel], message_test_cases()},
{muc, [pararell], muc_test_cases()},
{muc_config, [], muc_config_cases()},
Expand Down Expand Up @@ -107,6 +108,14 @@ message_with_props_test_cases() ->
msg_with_malformed_props_is_sent_and_delivered_over_xmpp
].

message_with_thread_test_cases() ->
[msg_with_thread_is_sent_and_delivered_over_xmpp,
msg_with_thread_can_be_parsed,
msg_with_thread_and_parent_is_sent_and_delivered_over_xmpp,
msg_with_thread_and_parent_can_be_parse,
msg_without_thread_can_be_parsed,
msg_without_thread_is_sent_and_delivered_over_xmpp].

security_test_cases() ->
[
default_http_server_name_is_returned_if_not_changed,
Expand Down Expand Up @@ -161,7 +170,13 @@ init_per_testcase(TC, Config) ->
msg_with_props_is_sent_and_delivered_over_xmpp,
msg_with_props_can_be_parsed,
msg_with_malformed_props_can_be_parsed,
msg_with_malformed_props_is_sent_and_delivered_over_xmpp
msg_with_malformed_props_is_sent_and_delivered_over_xmpp,
msg_with_thread_is_sent_and_delivered_over_xmpp,
msg_with_thread_can_be_parse,
msg_with_thread_and_parent_is_sent_and_delivered_over_xmpp,
msg_with_thread_and_parent_can_be_parse,
msg_without_thread_can_be_parsed,
msg_without_thread_is_sent_and_delivered_over_xmpp
],
rest_helper:maybe_skip_mam_test_cases(TC, MAMTestCases, Config).

Expand Down Expand Up @@ -652,6 +667,107 @@ msg_with_malformed_props_can_be_parsed(Config) ->

end).

msg_with_thread_is_sent_and_delivered_over_xmpp(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun (Alice, Bob) ->
BobJID = user_jid(Bob),
MsgID = base16:encode(crypto:strong_rand_bytes(5)),
ThreadID = base16:encode(crypto:strong_rand_bytes(5)),
M1 = rest_helper:make_msg_stanza_with_thread(BobJID, MsgID, ThreadID),
escalus:send(Alice, M1),
M2 = escalus:wait_for_stanza(Bob),
escalus:assert(is_message, M2)
end).

msg_with_thread_can_be_parsed(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun (Alice, Bob) ->
AliceJID = escalus_utils:jid_to_lower(escalus_client:short_jid(Alice)),
BobJID = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)),
MsgID = base16:encode(crypto:strong_rand_bytes(5)),
ThreadID = base16:encode(crypto:strong_rand_bytes(5)),
M1 = rest_helper:make_msg_stanza_with_thread(BobJID, MsgID, ThreadID),
escalus:send(Alice, M1),
escalus:wait_for_stanza(Bob),
mam_helper:wait_for_archive_size(Bob, 1),
mam_helper:wait_for_archive_size(Alice, 1),
AliceCreds = {AliceJID, user_password(alice)},
% recent msgs with a limit
M2 = get_messages_with_props(AliceCreds, BobJID, 1),
[{MsgWithProps} | _] = M2,
Data = maps:from_list(MsgWithProps),
#{<<"thread">> := ReceivedThreadID,
<<"id">> := ReceivedMsgID} = Data,
%we are expecting thread and parent thread for this test message
%test message defined in rest_helper:make_msg_stanza_with_thread
ReceivedThreadID = ThreadID,
ReceivedMsgID = MsgID
end).

msg_with_thread_and_parent_is_sent_and_delivered_over_xmpp(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun (Alice, Bob) ->
BobJID = user_jid(Bob),
MsgID = base16:encode(crypto:strong_rand_bytes(5)),
ThreadID = base16:encode(crypto:strong_rand_bytes(5)),
ThreadParentID = base16:encode(crypto:strong_rand_bytes(5)),
M1 = rest_helper:make_msg_stanza_with_thread_and_parent(BobJID, MsgID, ThreadID, ThreadParentID),
escalus:send(Alice, M1),
M2 = escalus:wait_for_stanza(Bob),
escalus:assert(is_message, M2)
end).

msg_with_thread_and_parent_can_be_parsed(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun (Alice, Bob) ->
AliceJID = escalus_utils:jid_to_lower(escalus_client:short_jid(Alice)),
BobJID = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)),
MsgID = base16:encode(crypto:strong_rand_bytes(5)),
ThreadID = base16:encode(crypto:strong_rand_bytes(5)),
ThreadParentID = base16:encode(crypto:strong_rand_bytes(5)),
M1 = rest_helper:make_msg_stanza_with_thread_and_parent(BobJID, MsgID, ThreadID, ThreadParentID),
escalus:send(Alice, M1),
escalus:wait_for_stanza(Bob),
mam_helper:wait_for_archive_size(Bob, 1),
mam_helper:wait_for_archive_size(Alice, 1),
AliceCreds = {AliceJID, user_password(alice)},
% recent msgs with a limit
M2 = get_messages_with_props(AliceCreds, BobJID, 1),
[{MsgWithProps} | _] = M2,
Data = maps:from_list(MsgWithProps),
#{<<"thread">> := ReceivedThreadID,
<<"parent">> := ReceivedThreadParentID,
<<"id">> := ReceivedMsgID} = Data,
%we are expecting thread and parent thread for this test message
%test message defined in rest_helper:make_msg_stanza_with_thread
ReceivedThreadID = ThreadID,
ReceivedThreadParentID = ThreadParentID,
ReceivedMsgID = MsgID
end).

msg_without_thread_is_sent_and_delivered_over_xmpp(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun (Alice, Bob) ->
BobJID = user_jid(Bob),
MsgID = base16:encode(crypto:strong_rand_bytes(5)),
M1 = rest_helper:make_msg_stanza_without_thread(BobJID, MsgID),
escalus:send(Alice, M1),
M2 = escalus:wait_for_stanza(Bob),
escalus:assert(is_message, M2)
end).

msg_without_thread_can_be_parsed(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun (Alice, Bob) ->
AliceJID = escalus_utils:jid_to_lower(escalus_client:short_jid(Alice)),
AliceCreds = {AliceJID, user_password(alice)},
BobJID = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)),
MsgID = base16:encode(crypto:strong_rand_bytes(5)),
M1 = rest_helper:make_msg_stanza_without_thread(BobJID, MsgID),
escalus:send(Alice, M1),
escalus:wait_for_stanza(Bob),
mam_helper:wait_for_archive_size(Bob, 1),
mam_helper:wait_for_archive_size(Alice, 1),
% recent msgs with a limit
M2 = get_messages_with_props(AliceCreds, BobJID, 1),
Recv = [_Msg] = rest_helper:decode_maplist(M2),
MsgID = maps:get(id, _Msg)
end).

assert_room_messages(RecvMsg, {_ID, _GenFrom, GenMsg}) ->
escalus:assert(is_chat_message, [maps:get(body, RecvMsg)], GenMsg),
ok.
Expand Down
26 changes: 25 additions & 1 deletion big_tests/tests/rest_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
make_timestamp/2,
change_admin_creds/1,
make_msg_stanza_with_props/2,
make_malformed_msg_stanza_with_props/2
make_malformed_msg_stanza_with_props/2,
make_msg_stanza_with_thread_and_parent/4,
make_msg_stanza_with_thread/3,
make_msg_stanza_without_thread/2
]).

-import(distributed_helper, [mim/0,
Expand Down Expand Up @@ -501,6 +504,27 @@ make_malformed_msg_stanza_with_props(ToJID,MsgID) ->
</properties>
</message>">>).

make_msg_stanza_without_thread(ToJID, MsgID) ->
escalus_stanza:from_xml(
<<"<message xml:lang='en' to='",ToJID/binary,"' id='",MsgID/binary,"' type='chat'>
<body xml:lang='en_US'>Test message without thread</body>
</message>">>).

make_msg_stanza_with_thread(ToJID, MsgID, ThreadID) ->
escalus_stanza:from_xml(
<<"<message xml:lang='en' to='",ToJID/binary,"' id='",MsgID/binary,"' type='chat'>
<body xml:lang='en_US'>Test message with thread</body>
<thread>",ThreadID/binary,"</thread>
</message>">>).

make_msg_stanza_with_thread_and_parent(ToJID, MsgID, ThreadID, ThreadParentID) ->
escalus_stanza:from_xml(
<<"<message xml:lang='en' to='",ToJID/binary,"' id='",MsgID/binary,"' type='chat'>
<body xml:lang='en_US'>Test message with thread</body>
<thread parent='",ThreadParentID/binary,"'>",ThreadID/binary,"</thread>
</message>">>).


simple_request(Method, Path) when is_binary(Method)->
simple_request(Method, Path, <<>>).
simple_request(Method, Path, Port) when is_binary(Method) and is_integer(Port) ->
Expand Down
7 changes: 6 additions & 1 deletion doc/rest-api/Client-frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ For example if we have properties in the stanza like:
```xml
<message xml:lang='en' to='alice@localhost' id='123' type='chat'>
<body xml:lang='en_US'>Hi!</body>
<properties xmlns="http://www.jivesoftware.com/xmlns/xmpp/properties"
<thread parent='7edac73ab41e45c4aafa7b2d7b749080'>
e0ffe42b28561960c6b12b944a092794b9683a38
</thread>
<properties xmlns="http://www.jivesoftware.com/xmlns/xmpp/properties">
<property>
<name>some_number</name>
<value type='integer'>123</value>
Expand All @@ -71,6 +74,8 @@ then in the final json message these properties will be converted to json map wi
"id": "123",
"from": "bob@localhost",
"body": "Hi!",
"thread": "e0ffe42b28561960c6b12b944a092794b9683a38",
"parent": "7edac73ab41e45c4aafa7b2d7b749080",
"properties":{
"some_number":"123",
"some_string":"abc"
Expand Down
8 changes: 8 additions & 0 deletions doc/rest-api/Client-frontend_swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,14 @@ definitions:
type: string
description: Message content.
example: "Hello Alice!"
thread:
type: string
description: Message thread ID.
example: "e0ffe42b28561960c6b12b944a092794b9683a38"
parent:
type: string
description: Message thread parent ID.
example: "7edac73ab41e45c4aafa7b2d7b749080"
CreateRoomBody:
properties:
subject:
Expand Down
22 changes: 14 additions & 8 deletions src/mongoose_client_api/mongoose_client_api_messages.erl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ encode(Msg, Timestamp) ->
<<"http://www.jivesoftware.com/xmlns/xmpp/properties">>),

BodyTag = exml_query:path(Msg, [{element, <<"body">>}]),

ExtensionList =
case RawMsgProps of
#xmlel{children = Children} ->
Expand All @@ -137,14 +136,21 @@ encode(Msg, Timestamp) ->
_ ->
[]
end,

Thread = exml_query:path(Msg, [{element, <<"thread">>}, cdata]),
ThreadParent = exml_query:path(Msg, [{element, <<"thread">>}, {attr, <<"parent">>}]),
ThreadAndThreadParentList = case {Thread, ThreadParent} of
{undefined, undefined} ->
[];
{Thread, undefined} ->
[{<<"thread">>, Thread}];
{Thread, ThreadParent} ->
[{<<"thread">>, Thread}, {<<"parent">>, ThreadParent}]
end,
L = [{<<"from">>, exml_query:attr(Msg, <<"from">>)},
{<<"to">>, exml_query:attr(Msg, <<"to">>)},
{<<"id">>, exml_query:attr(Msg, <<"id">>)},
{<<"body">>, exml_query:cdata(BodyTag)},
{<<"timestamp">>, Timestamp} | ExtensionList],


{<<"to">>, exml_query:attr(Msg, <<"to">>)},
{<<"id">>, exml_query:attr(Msg, <<"id">>)},
{<<"body">>, exml_query:cdata(BodyTag)},
{<<"timestamp">>, Timestamp} | ExtensionList] ++ ThreadAndThreadParentList,
maps:from_list(L).

convert_prop_child(Child)->
Expand Down
10 changes: 10 additions & 0 deletions src/swagger_docs/mongoose_client_api_messages_doc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ trails() ->
type => <<"string">>,
description => <<"Message content">>,
default => <<"Hello Alice!">>
},
<<"thread">> => #{
type => <<"string">>,
description => <<"ID of thread">>,
default => <<"e0ffe42b28561960c6b12b944a092794b9683a38">>
},
<<"parent">> => #{
type => <<"string">>,
description => <<"ID of thread parent">>,
default => <<"7edac73ab41e45c4aafa7b2d7b749080">>
}
},

Expand Down

0 comments on commit 61018c1

Please sign in to comment.