Add tests for XEP-0013
This commit is contained in:
parent
02a519a11e
commit
d6323a7b5e
|
@ -110,7 +110,7 @@ edoc:
|
||||||
|
|
||||||
spec:
|
spec:
|
||||||
$(ERL) -noinput +B -pa ebin -pa deps/*/ebin -eval \
|
$(ERL) -noinput +B -pa ebin -pa deps/*/ebin -eval \
|
||||||
'case xml_gen:compile("tools/xmpp_codec.spec") of ok -> halt(0); _ -> halt(1) end.'
|
'case fxml_gen:compile("tools/xmpp_codec.spec") of ok -> halt(0); _ -> halt(1) end.'
|
||||||
|
|
||||||
JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wordlist 2,1000,$(1))),$(1))
|
JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wordlist 2,1000,$(1))),$(1))
|
||||||
|
|
||||||
|
|
|
@ -214,6 +214,8 @@ db_tests(riak) ->
|
||||||
{test_roster_subscribe, [parallel],
|
{test_roster_subscribe, [parallel],
|
||||||
[roster_subscribe_master,
|
[roster_subscribe_master,
|
||||||
roster_subscribe_slave]},
|
roster_subscribe_slave]},
|
||||||
|
{test_flex_offline, [sequence],
|
||||||
|
[flex_offline_master, flex_offline_slave]},
|
||||||
{test_offline, [sequence],
|
{test_offline, [sequence],
|
||||||
[offline_master, offline_slave]},
|
[offline_master, offline_slave]},
|
||||||
{test_muc, [parallel],
|
{test_muc, [parallel],
|
||||||
|
@ -245,6 +247,8 @@ db_tests(mnesia) ->
|
||||||
{test_roster_subscribe, [parallel],
|
{test_roster_subscribe, [parallel],
|
||||||
[roster_subscribe_master,
|
[roster_subscribe_master,
|
||||||
roster_subscribe_slave]},
|
roster_subscribe_slave]},
|
||||||
|
{test_flex_offline, [sequence],
|
||||||
|
[flex_offline_master, flex_offline_slave]},
|
||||||
{test_offline, [sequence],
|
{test_offline, [sequence],
|
||||||
[offline_master, offline_slave]},
|
[offline_master, offline_slave]},
|
||||||
{test_old_mam, [parallel],
|
{test_old_mam, [parallel],
|
||||||
|
@ -285,6 +289,8 @@ db_tests(_) ->
|
||||||
{test_roster_subscribe, [parallel],
|
{test_roster_subscribe, [parallel],
|
||||||
[roster_subscribe_master,
|
[roster_subscribe_master,
|
||||||
roster_subscribe_slave]},
|
roster_subscribe_slave]},
|
||||||
|
{test_flex_offline, [sequence],
|
||||||
|
[flex_offline_master, flex_offline_slave]},
|
||||||
{test_offline, [sequence],
|
{test_offline, [sequence],
|
||||||
[offline_master, offline_slave]},
|
[offline_master, offline_slave]},
|
||||||
{test_old_mam, [parallel],
|
{test_old_mam, [parallel],
|
||||||
|
@ -1433,6 +1439,131 @@ announce_slave(Config) ->
|
||||||
send(Config, #message{to = MotdDelJID}),
|
send(Config, #message{to = MotdDelJID}),
|
||||||
disconnect(Config).
|
disconnect(Config).
|
||||||
|
|
||||||
|
flex_offline_master(Config) ->
|
||||||
|
Peer = ?config(slave, Config),
|
||||||
|
LPeer = jlib:jid_remove_resource(Peer),
|
||||||
|
lists:foreach(
|
||||||
|
fun(I) ->
|
||||||
|
Body = jlib:integer_to_binary(I),
|
||||||
|
send(Config, #message{to = LPeer,
|
||||||
|
body = [#text{data = Body}],
|
||||||
|
subject = [#text{data = <<"subject">>}]})
|
||||||
|
end, lists:seq(1, 5)),
|
||||||
|
disconnect(Config).
|
||||||
|
|
||||||
|
flex_offline_slave(Config) ->
|
||||||
|
MyJID = my_jid(Config),
|
||||||
|
MyBareJID = jid:remove_resource(MyJID),
|
||||||
|
Peer = ?config(master, Config),
|
||||||
|
Peer_s = jid:to_string(Peer),
|
||||||
|
true = is_feature_advertised(Config, ?NS_FLEX_OFFLINE),
|
||||||
|
%% Request disco#info
|
||||||
|
#iq{type = result,
|
||||||
|
sub_els = [#disco_info{
|
||||||
|
node = ?NS_FLEX_OFFLINE,
|
||||||
|
identities = Ids,
|
||||||
|
features = Fts,
|
||||||
|
xdata = [X]}]} =
|
||||||
|
send_recv(Config, #iq{type = get,
|
||||||
|
sub_els = [#disco_info{
|
||||||
|
node = ?NS_FLEX_OFFLINE}]}),
|
||||||
|
%% Check if we have correct identities
|
||||||
|
true = lists:any(
|
||||||
|
fun(#identity{category = <<"automation">>,
|
||||||
|
type = <<"message-list">>}) -> true;
|
||||||
|
(_) -> false
|
||||||
|
end, Ids),
|
||||||
|
%% Check if we have needed feature
|
||||||
|
true = lists:member(?NS_FLEX_OFFLINE, Fts),
|
||||||
|
%% Check xdata, the 'number_of_messages' should be 5
|
||||||
|
#xdata{type = result,
|
||||||
|
fields = [#xdata_field{type = hidden,
|
||||||
|
var = <<"FORM_TYPE">>},
|
||||||
|
#xdata_field{var = <<"number_of_messages">>,
|
||||||
|
values = [<<"5">>]}]} = X,
|
||||||
|
%% Fetch headers,
|
||||||
|
#iq{type = result,
|
||||||
|
sub_els = [#disco_items{
|
||||||
|
node = ?NS_FLEX_OFFLINE,
|
||||||
|
items = DiscoItems}]} =
|
||||||
|
send_recv(Config, #iq{type = get,
|
||||||
|
sub_els = [#disco_items{
|
||||||
|
node = ?NS_FLEX_OFFLINE}]}),
|
||||||
|
%% Check if headers are correct
|
||||||
|
Nodes = lists:sort(
|
||||||
|
lists:map(
|
||||||
|
fun(#disco_item{jid = J, name = P, node = N})
|
||||||
|
when (J == MyBareJID) and (P == Peer_s) ->
|
||||||
|
N
|
||||||
|
end, DiscoItems)),
|
||||||
|
%% Check full fetch
|
||||||
|
I0 = send(Config, #iq{type = get, sub_els = [#offline{fetch = true}]}),
|
||||||
|
lists:foreach(
|
||||||
|
fun({I, N}) ->
|
||||||
|
Text = jlib:integer_to_binary(I),
|
||||||
|
?recv1(#message{body = Body, sub_els = SubEls}),
|
||||||
|
[#text{data = Text}] = Body,
|
||||||
|
#offline{items = [#offline_item{node = N}]} =
|
||||||
|
lists:keyfind(offline, 1, SubEls),
|
||||||
|
#delay{} = lists:keyfind(delay, 1, SubEls)
|
||||||
|
end, lists:zip(lists:seq(1, 5), Nodes)),
|
||||||
|
?recv1(#iq{type = result, id = I0, sub_els = []}),
|
||||||
|
%% Fetch 2nd and 4th message
|
||||||
|
I1 = send(Config,
|
||||||
|
#iq{type = get,
|
||||||
|
sub_els = [#offline{
|
||||||
|
items = [#offline_item{
|
||||||
|
action = view,
|
||||||
|
node = lists:nth(2, Nodes)},
|
||||||
|
#offline_item{
|
||||||
|
action = view,
|
||||||
|
node = lists:nth(4, Nodes)}]}]}),
|
||||||
|
lists:foreach(
|
||||||
|
fun({I, N}) ->
|
||||||
|
Text = jlib:integer_to_binary(I),
|
||||||
|
?recv1(#message{body = [#text{data = Text}], sub_els = SubEls}),
|
||||||
|
#offline{items = [#offline_item{node = N}]} =
|
||||||
|
lists:keyfind(offline, 1, SubEls)
|
||||||
|
end, lists:zip([2, 4], [lists:nth(2, Nodes), lists:nth(4, Nodes)])),
|
||||||
|
?recv1(#iq{type = result, id = I1, sub_els = []}),
|
||||||
|
%% Delete 2nd and 4th message
|
||||||
|
#iq{type = result, sub_els = []} =
|
||||||
|
send_recv(
|
||||||
|
Config,
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els = [#offline{
|
||||||
|
items = [#offline_item{
|
||||||
|
action = remove,
|
||||||
|
node = lists:nth(2, Nodes)},
|
||||||
|
#offline_item{
|
||||||
|
action = remove,
|
||||||
|
node = lists:nth(4, Nodes)}]}]}),
|
||||||
|
%% Check if messages were deleted
|
||||||
|
#iq{type = result,
|
||||||
|
sub_els = [#disco_items{
|
||||||
|
node = ?NS_FLEX_OFFLINE,
|
||||||
|
items = RemainedItems}]} =
|
||||||
|
send_recv(Config, #iq{type = get,
|
||||||
|
sub_els = [#disco_items{
|
||||||
|
node = ?NS_FLEX_OFFLINE}]}),
|
||||||
|
RemainedNodes = [lists:nth(1, Nodes),
|
||||||
|
lists:nth(3, Nodes),
|
||||||
|
lists:nth(5, Nodes)],
|
||||||
|
RemainedNodes = lists:sort(
|
||||||
|
lists:map(
|
||||||
|
fun(#disco_item{node = N}) -> N end,
|
||||||
|
RemainedItems)),
|
||||||
|
%% Purge everything left
|
||||||
|
#iq{type = result, sub_els = []} =
|
||||||
|
send_recv(Config, #iq{type = set, sub_els = [#offline{purge = true}]}),
|
||||||
|
%% Check if there is no offline messages
|
||||||
|
#iq{type = result,
|
||||||
|
sub_els = [#disco_items{node = ?NS_FLEX_OFFLINE, items = []}]} =
|
||||||
|
send_recv(Config, #iq{type = get,
|
||||||
|
sub_els = [#disco_items{
|
||||||
|
node = ?NS_FLEX_OFFLINE}]}),
|
||||||
|
disconnect(Config).
|
||||||
|
|
||||||
offline_master(Config) ->
|
offline_master(Config) ->
|
||||||
Peer = ?config(slave, Config),
|
Peer = ?config(slave, Config),
|
||||||
LPeer = jlib:jid_remove_resource(Peer),
|
LPeer = jlib:jid_remove_resource(Peer),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%% Created automatically by XML generator (xml_gen.erl)
|
%% Created automatically by XML generator (fxml_gen.erl)
|
||||||
%% Source: xmpp_codec.spec
|
%% Source: xmpp_codec.spec
|
||||||
|
|
||||||
-module(xmpp_codec).
|
-module(xmpp_codec).
|
||||||
|
@ -15,6 +15,22 @@ decode(_el) -> decode(_el, []).
|
||||||
decode({xmlel, _name, _attrs, _} = _el, Opts) ->
|
decode({xmlel, _name, _attrs, _} = _el, Opts) ->
|
||||||
IgnoreEls = proplists:get_bool(ignore_els, Opts),
|
IgnoreEls = proplists:get_bool(ignore_els, Opts),
|
||||||
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
||||||
|
{<<"offline">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
decode_offline(<<"http://jabber.org/protocol/offline">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"item">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
decode_offline_item(<<"http://jabber.org/protocol/offline">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"fetch">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
decode_offline_fetch(<<"http://jabber.org/protocol/offline">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"purge">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
decode_offline_purge(<<"http://jabber.org/protocol/offline">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
{<<"failed">>, <<"urn:xmpp:sm:2">>} ->
|
{<<"failed">>, <<"urn:xmpp:sm:2">>} ->
|
||||||
decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el);
|
decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el);
|
||||||
{<<"failed">>, <<"urn:xmpp:sm:3">>} ->
|
{<<"failed">>, <<"urn:xmpp:sm:3">>} ->
|
||||||
|
@ -1072,6 +1088,18 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) ->
|
||||||
|
|
||||||
is_known_tag({xmlel, _name, _attrs, _} = _el) ->
|
is_known_tag({xmlel, _name, _attrs, _} = _el) ->
|
||||||
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
||||||
|
{<<"offline">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
true;
|
||||||
|
{<<"item">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
true;
|
||||||
|
{<<"fetch">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
true;
|
||||||
|
{<<"purge">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>} ->
|
||||||
|
true;
|
||||||
{<<"failed">>, <<"urn:xmpp:sm:2">>} -> true;
|
{<<"failed">>, <<"urn:xmpp:sm:2">>} -> true;
|
||||||
{<<"failed">>, <<"urn:xmpp:sm:3">>} -> true;
|
{<<"failed">>, <<"urn:xmpp:sm:3">>} -> true;
|
||||||
{<<"a">>, <<"urn:xmpp:sm:2">>} -> true;
|
{<<"a">>, <<"urn:xmpp:sm:2">>} -> true;
|
||||||
|
@ -2124,7 +2152,15 @@ encode({sm_resumed, _, _, _} = Resumed) ->
|
||||||
encode({sm_r, _} = R) -> encode_sm_r(R, []);
|
encode({sm_r, _} = R) -> encode_sm_r(R, []);
|
||||||
encode({sm_a, _, _} = A) -> encode_sm_a(A, []);
|
encode({sm_a, _, _} = A) -> encode_sm_a(A, []);
|
||||||
encode({sm_failed, _, _} = Failed) ->
|
encode({sm_failed, _, _} = Failed) ->
|
||||||
encode_sm_failed(Failed, []).
|
encode_sm_failed(Failed, []);
|
||||||
|
encode({offline_item, _, _} = Item) ->
|
||||||
|
encode_offline_item(Item,
|
||||||
|
[{<<"xmlns">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>}]);
|
||||||
|
encode({offline, _, _, _} = Offline) ->
|
||||||
|
encode_offline(Offline,
|
||||||
|
[{<<"xmlns">>,
|
||||||
|
<<"http://jabber.org/protocol/offline">>}]).
|
||||||
|
|
||||||
get_ns({last, _, _}) -> <<"jabber:iq:last">>;
|
get_ns({last, _, _}) -> <<"jabber:iq:last">>;
|
||||||
get_ns({version, _, _, _}) -> <<"jabber:iq:version">>;
|
get_ns({version, _, _, _}) -> <<"jabber:iq:version">>;
|
||||||
|
@ -2319,6 +2355,10 @@ get_ns({carbons_sent, _}) -> <<"urn:xmpp:carbons:2">>;
|
||||||
get_ns({feature_csi, _}) -> <<"urn:xmpp:csi:0">>;
|
get_ns({feature_csi, _}) -> <<"urn:xmpp:csi:0">>;
|
||||||
get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>;
|
get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>;
|
||||||
get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>;
|
get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>;
|
||||||
|
get_ns({offline_item, _, _}) ->
|
||||||
|
<<"http://jabber.org/protocol/offline">>;
|
||||||
|
get_ns({offline, _, _, _}) ->
|
||||||
|
<<"http://jabber.org/protocol/offline">>;
|
||||||
get_ns(_) -> <<>>.
|
get_ns(_) -> <<>>.
|
||||||
|
|
||||||
dec_int(Val) -> dec_int(Val, infinity, infinity).
|
dec_int(Val) -> dec_int(Val, infinity, infinity).
|
||||||
|
@ -2522,6 +2562,8 @@ pp(sm_resumed, 3) -> [h, previd, xmlns];
|
||||||
pp(sm_r, 1) -> [xmlns];
|
pp(sm_r, 1) -> [xmlns];
|
||||||
pp(sm_a, 2) -> [h, xmlns];
|
pp(sm_a, 2) -> [h, xmlns];
|
||||||
pp(sm_failed, 2) -> [reason, xmlns];
|
pp(sm_failed, 2) -> [reason, xmlns];
|
||||||
|
pp(offline_item, 2) -> [node, action];
|
||||||
|
pp(offline, 3) -> [items, purge, fetch];
|
||||||
pp(_, _) -> no.
|
pp(_, _) -> no.
|
||||||
|
|
||||||
enc_bool(false) -> <<"false">>;
|
enc_bool(false) -> <<"false">>;
|
||||||
|
@ -2564,6 +2606,156 @@ dec_tzo(Val) ->
|
||||||
M = jlib:binary_to_integer(M1),
|
M = jlib:binary_to_integer(M1),
|
||||||
if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end.
|
if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end.
|
||||||
|
|
||||||
|
decode_offline(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"offline">>, _attrs, _els}) ->
|
||||||
|
{Items, Purge, Fetch} = decode_offline_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, [], false,
|
||||||
|
false),
|
||||||
|
{offline, Items, Purge, Fetch}.
|
||||||
|
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, [], Items,
|
||||||
|
Purge, Fetch) ->
|
||||||
|
{lists:reverse(Items), Purge, Fetch};
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlel, <<"purge">>, _attrs, _} = _el | _els], Items,
|
||||||
|
Purge, Fetch) ->
|
||||||
|
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||||
|
if _xmlns == <<>>; _xmlns == __TopXMLNS ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items,
|
||||||
|
decode_offline_purge(__TopXMLNS, __IgnoreEls,
|
||||||
|
_el),
|
||||||
|
Fetch);
|
||||||
|
true ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items,
|
||||||
|
Purge, Fetch)
|
||||||
|
end;
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlel, <<"fetch">>, _attrs, _} = _el | _els], Items,
|
||||||
|
Purge, Fetch) ->
|
||||||
|
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||||
|
if _xmlns == <<>>; _xmlns == __TopXMLNS ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items,
|
||||||
|
Purge,
|
||||||
|
decode_offline_fetch(__TopXMLNS, __IgnoreEls,
|
||||||
|
_el));
|
||||||
|
true ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items,
|
||||||
|
Purge, Fetch)
|
||||||
|
end;
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlel, <<"item">>, _attrs, _} = _el | _els], Items,
|
||||||
|
Purge, Fetch) ->
|
||||||
|
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||||
|
if _xmlns == <<>>; _xmlns == __TopXMLNS ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
[decode_offline_item(__TopXMLNS, __IgnoreEls, _el)
|
||||||
|
| Items],
|
||||||
|
Purge, Fetch);
|
||||||
|
true ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items,
|
||||||
|
Purge, Fetch)
|
||||||
|
end;
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, [_ | _els],
|
||||||
|
Items, Purge, Fetch) ->
|
||||||
|
decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items,
|
||||||
|
Purge, Fetch).
|
||||||
|
|
||||||
|
encode_offline({offline, Items, Purge, Fetch},
|
||||||
|
_xmlns_attrs) ->
|
||||||
|
_els = lists:reverse('encode_offline_$items'(Items,
|
||||||
|
'encode_offline_$purge'(Purge,
|
||||||
|
'encode_offline_$fetch'(Fetch,
|
||||||
|
[])))),
|
||||||
|
_attrs = _xmlns_attrs,
|
||||||
|
{xmlel, <<"offline">>, _attrs, _els}.
|
||||||
|
|
||||||
|
'encode_offline_$items'([], _acc) -> _acc;
|
||||||
|
'encode_offline_$items'([Items | _els], _acc) ->
|
||||||
|
'encode_offline_$items'(_els,
|
||||||
|
[encode_offline_item(Items, []) | _acc]).
|
||||||
|
|
||||||
|
'encode_offline_$purge'(false, _acc) -> _acc;
|
||||||
|
'encode_offline_$purge'(Purge, _acc) ->
|
||||||
|
[encode_offline_purge(Purge, []) | _acc].
|
||||||
|
|
||||||
|
'encode_offline_$fetch'(false, _acc) -> _acc;
|
||||||
|
'encode_offline_$fetch'(Fetch, _acc) ->
|
||||||
|
[encode_offline_fetch(Fetch, []) | _acc].
|
||||||
|
|
||||||
|
decode_offline_item(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"item">>, _attrs, _els}) ->
|
||||||
|
{Node, Action} = decode_offline_item_attrs(__TopXMLNS,
|
||||||
|
_attrs, undefined, undefined),
|
||||||
|
{offline_item, Node, Action}.
|
||||||
|
|
||||||
|
decode_offline_item_attrs(__TopXMLNS,
|
||||||
|
[{<<"node">>, _val} | _attrs], _Node, Action) ->
|
||||||
|
decode_offline_item_attrs(__TopXMLNS, _attrs, _val,
|
||||||
|
Action);
|
||||||
|
decode_offline_item_attrs(__TopXMLNS,
|
||||||
|
[{<<"action">>, _val} | _attrs], Node, _Action) ->
|
||||||
|
decode_offline_item_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
_val);
|
||||||
|
decode_offline_item_attrs(__TopXMLNS, [_ | _attrs],
|
||||||
|
Node, Action) ->
|
||||||
|
decode_offline_item_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
Action);
|
||||||
|
decode_offline_item_attrs(__TopXMLNS, [], Node,
|
||||||
|
Action) ->
|
||||||
|
{decode_offline_item_attr_node(__TopXMLNS, Node),
|
||||||
|
decode_offline_item_attr_action(__TopXMLNS, Action)}.
|
||||||
|
|
||||||
|
encode_offline_item({offline_item, Node, Action},
|
||||||
|
_xmlns_attrs) ->
|
||||||
|
_els = [],
|
||||||
|
_attrs = encode_offline_item_attr_action(Action,
|
||||||
|
encode_offline_item_attr_node(Node,
|
||||||
|
_xmlns_attrs)),
|
||||||
|
{xmlel, <<"item">>, _attrs, _els}.
|
||||||
|
|
||||||
|
decode_offline_item_attr_node(__TopXMLNS, undefined) ->
|
||||||
|
undefined;
|
||||||
|
decode_offline_item_attr_node(__TopXMLNS, _val) -> _val.
|
||||||
|
|
||||||
|
encode_offline_item_attr_node(undefined, _acc) -> _acc;
|
||||||
|
encode_offline_item_attr_node(_val, _acc) ->
|
||||||
|
[{<<"node">>, _val} | _acc].
|
||||||
|
|
||||||
|
decode_offline_item_attr_action(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
undefined;
|
||||||
|
decode_offline_item_attr_action(__TopXMLNS, _val) ->
|
||||||
|
case catch dec_enum(_val, [view, remove]) of
|
||||||
|
{'EXIT', _} ->
|
||||||
|
erlang:error({xmpp_codec,
|
||||||
|
{bad_attr_value, <<"action">>, <<"item">>,
|
||||||
|
__TopXMLNS}});
|
||||||
|
_res -> _res
|
||||||
|
end.
|
||||||
|
|
||||||
|
encode_offline_item_attr_action(undefined, _acc) ->
|
||||||
|
_acc;
|
||||||
|
encode_offline_item_attr_action(_val, _acc) ->
|
||||||
|
[{<<"action">>, enc_enum(_val)} | _acc].
|
||||||
|
|
||||||
|
decode_offline_fetch(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"fetch">>, _attrs, _els}) ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
encode_offline_fetch(true, _xmlns_attrs) ->
|
||||||
|
_els = [],
|
||||||
|
_attrs = _xmlns_attrs,
|
||||||
|
{xmlel, <<"fetch">>, _attrs, _els}.
|
||||||
|
|
||||||
|
decode_offline_purge(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"purge">>, _attrs, _els}) ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
encode_offline_purge(true, _xmlns_attrs) ->
|
||||||
|
_els = [],
|
||||||
|
_attrs = _xmlns_attrs,
|
||||||
|
{xmlel, <<"purge">>, _attrs, _els}.
|
||||||
|
|
||||||
decode_sm_failed(__TopXMLNS, __IgnoreEls,
|
decode_sm_failed(__TopXMLNS, __IgnoreEls,
|
||||||
{xmlel, <<"failed">>, _attrs, _els}) ->
|
{xmlel, <<"failed">>, _attrs, _els}) ->
|
||||||
Reason = decode_sm_failed_els(__TopXMLNS, __IgnoreEls,
|
Reason = decode_sm_failed_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%% Created automatically by XML generator (xml_gen.erl)
|
%% Created automatically by XML generator (fxml_gen.erl)
|
||||||
%% Source: xmpp_codec.spec
|
%% Source: xmpp_codec.spec
|
||||||
|
|
||||||
-record(chatstate, {type :: active | composing | gone | inactive | paused}).
|
-record(chatstate, {type :: active | composing | gone | inactive | paused}).
|
||||||
|
@ -424,6 +424,13 @@
|
||||||
features = [] :: [binary()],
|
features = [] :: [binary()],
|
||||||
xdata = [] :: [#xdata{}]}).
|
xdata = [] :: [#xdata{}]}).
|
||||||
|
|
||||||
|
-record(offline_item, {node :: binary(),
|
||||||
|
action :: 'remove' | 'view'}).
|
||||||
|
|
||||||
|
-record(offline, {items = [] :: [#offline_item{}],
|
||||||
|
purge = false :: boolean(),
|
||||||
|
fetch = false :: boolean()}).
|
||||||
|
|
||||||
-record(sasl_mechanisms, {list = [] :: [binary()]}).
|
-record(sasl_mechanisms, {list = [] :: [binary()]}).
|
||||||
|
|
||||||
-record(sm_failed, {reason :: atom() | #gone{} | #redirect{},
|
-record(sm_failed, {reason :: atom() | #gone{} | #redirect{},
|
||||||
|
|
|
@ -2398,6 +2398,35 @@
|
||||||
#ref{name = error_unexpected_request,
|
#ref{name = error_unexpected_request,
|
||||||
min = 0, max = 1, label = '$reason'}]}).
|
min = 0, max = 1, label = '$reason'}]}).
|
||||||
|
|
||||||
|
-xml(offline_purge,
|
||||||
|
#elem{name = <<"purge">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/offline">>,
|
||||||
|
result = true}).
|
||||||
|
|
||||||
|
-xml(offline_fetch,
|
||||||
|
#elem{name = <<"fetch">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/offline">>,
|
||||||
|
result = true}).
|
||||||
|
|
||||||
|
-xml(offline_item,
|
||||||
|
#elem{name = <<"item">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/offline">>,
|
||||||
|
result = {offline_item, '$node', '$action'},
|
||||||
|
attrs = [#attr{name = <<"node">>},
|
||||||
|
#attr{name = <<"action">>,
|
||||||
|
dec = {dec_enum, [[view, remove]]},
|
||||||
|
enc = {enc_enum, []}}]}).
|
||||||
|
|
||||||
|
-xml(offline,
|
||||||
|
#elem{name = <<"offline">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/offline">>,
|
||||||
|
result = {offline, '$items', '$purge', '$fetch'},
|
||||||
|
refs = [#ref{name = offline_purge, min = 0, max = 1,
|
||||||
|
label = '$purge', default = false},
|
||||||
|
#ref{name = offline_fetch, min = 0, max = 1,
|
||||||
|
label = '$fetch', default = false},
|
||||||
|
#ref{name = offline_item, min = 0, label = '$items'}]}).
|
||||||
|
|
||||||
dec_tzo(Val) ->
|
dec_tzo(Val) ->
|
||||||
[H1, M1] = str:tokens(Val, <<":">>),
|
[H1, M1] = str:tokens(Val, <<":">>),
|
||||||
H = jlib:binary_to_integer(H1),
|
H = jlib:binary_to_integer(H1),
|
||||||
|
|
Loading…
Reference in New Issue