diff --git a/big_tests/tests/inbox_extensions_SUITE.erl b/big_tests/tests/inbox_extensions_SUITE.erl index af4c63f72e6..e372d964bd0 100644 --- a/big_tests/tests/inbox_extensions_SUITE.erl +++ b/big_tests/tests/inbox_extensions_SUITE.erl @@ -103,7 +103,7 @@ groups() -> {group, pagination} ]}, {pagination, [parallel], [ - bad_id_throws_error, + pagination_error_conditions, pagination_overrides_form, can_paginate_forwards, can_paginate_backwards, @@ -673,15 +673,16 @@ properties_many_can_be_set(Config, QueryId) -> end}], #{box => archive}) end). -bad_id_throws_error(Config) -> +pagination_error_conditions(Config) -> escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> % We set start and end to return Convs with Mike, but using RSM we override that TS = erlang:system_time(millisecond), AliceJid = escalus_utils:get_short_jid(Alice), IdNotDividing = <<(integer_to_binary(TS))/binary, (base64:encode(AliceJid))/binary>>, - verify_returns_error(Alice, #{box => inbox, 'after' => IdNotDividing}), + verify_returns_error(Alice, #{box => inbox, 'after' => IdNotDividing}, <<"bad-request">>), BadInt = <<(integer_to_binary(-10))/binary, "/", (base64:encode(AliceJid))/binary>>, - verify_returns_error(Alice, #{box => inbox, 'after' => BadInt}) + verify_returns_error(Alice, #{box => inbox, 'after' => BadInt}, <<"bad-request">>), + verify_returns_error(Alice, #{box => inbox, index => 10}, <<"feature-not-implemented">>) end). pagination_overrides_form(Config) -> @@ -971,6 +972,10 @@ muted_status(MutedOrUnmuted, Outer) -> ?assert(Now + Diff < GivenMutedUntil) end. -verify_returns_error(User, Params) -> +verify_returns_error(User, Params, Error) -> Stanza = inbox_helper:make_inbox_stanza(Params), - assert_invalid_request(User, Stanza, <<"bad-request">>). + escalus:send(User, Stanza), + [ResIQ] = escalus:wait_for_stanzas(User, 1), + escalus:assert(is_iq_error, [Stanza], ResIQ), + Type = exml_query:path(ResIQ, [{element, <<"error">>}, {element, Error}]), + ?assertNotEqual(undefined, Type). diff --git a/big_tests/tests/inbox_helper.erl b/big_tests/tests/inbox_helper.erl index ae351df5c6f..02e9d87119a 100644 --- a/big_tests/tests/inbox_helper.erl +++ b/big_tests/tests/inbox_helper.erl @@ -400,9 +400,13 @@ rsm(Params) -> Max = maps:get(limit, Params, undefined), Before = maps:get(before, Params, undefined), After = maps:get('after', Params, undefined), + Index = maps:get(index, Params, undefined), Elems = [#xmlel{name = <<"max">>, children = [#xmlcdata{content = to_bin(Max)}]} || _ <- [Max], undefined =/= Max ] ++ + [#xmlel{name = <<"index">>, + children = [#xmlcdata{content = to_bin(Index)}]} + || _ <- [Index], undefined =/= Index ] ++ [#xmlel{name = <<"before">>, children = [#xmlcdata{content = to_bin(Before)}]} || _ <- [Before], undefined =/= Before ] ++ diff --git a/doc/open-extensions/inbox.md b/doc/open-extensions/inbox.md index 3ba855ecdfb..f27fec28e97 100644 --- a/doc/open-extensions/inbox.md +++ b/doc/open-extensions/inbox.md @@ -148,7 +148,7 @@ It can happen that the amount of inbox entries is too big for a given user, even ``` where `Max` is a non-negative integer. -Inbox also has partial support for pagination as described in [XEP-0059](https://xmpp.org/extensions/xep-0059.html). If specifying `before` or `after`, the `start` and `end` form fields will be overridden. +Inbox also has partial support for pagination as described in [XEP-0059](https://xmpp.org/extensions/xep-0059.html). If specifying `before` or `after`, the `start` and `end` form fields will be overridden. However, inbox pagination does not support total count nor indexes as described in [XEP-0059: #2.6 Retrieving a Page Out of Order](https://xmpp.org/extensions/xep-0059.html#jump). ## Properties of an entry Given an entry, certain properties are defined for such an entry: diff --git a/src/inbox/mod_inbox.erl b/src/inbox/mod_inbox.erl index b3f4dc09237..094d2fdc7bb 100644 --- a/src/inbox/mod_inbox.erl +++ b/src/inbox/mod_inbox.erl @@ -200,8 +200,8 @@ process_iq(Acc, From, _To, #iq{type = set, sub_el = QueryEl} = IQ, _Extra) -> LUser = From#jid.luser, LServer = From#jid.lserver, case query_to_params(HostType, QueryEl) of - {error, bad_request, Msg} -> - {Acc, IQ#iq{type = error, sub_el = [mongoose_xmpp_errors:bad_request(<<"en">>, Msg)]}}; + {error, Error, Msg} -> + {Acc, IQ#iq{type = error, sub_el = [mongoose_xmpp_errors:Error(<<"en">>, Msg)]}}; Params -> List0 = mod_inbox_backend:get_inbox(HostType, LUser, LServer, Params), List = with_rsm(List0, Params), @@ -464,18 +464,20 @@ text_single_form_field(Var, DefaultValue) -> %%%%%%%%%%%%%%%%%%% %% iq-set -spec query_to_params(mongooseim:host_type(), QueryEl :: exml:element()) -> - get_inbox_params() | {error, bad_request, binary()}. + get_inbox_params() | {error, atom(), binary()}. query_to_params(HostType, QueryEl) -> Form = form_to_params(HostType, exml_query:subelement_with_ns(QueryEl, ?NS_XDATA)), Rsm = jlib:rsm_decode(QueryEl), build_params(Form, Rsm). --spec build_params(get_inbox_params() | {error, bad_request, binary()}, none | jlib:rsm_in()) -> - get_inbox_params() | {error, bad_request, binary()}. -build_params({error, bad_request, Msg}, _) -> - {error, bad_request, Msg}; +-spec build_params(get_inbox_params() | {error, atom(), binary()}, none | jlib:rsm_in()) -> + get_inbox_params() | {error, atom(), binary()}. +build_params({error, Error, Msg}, _) -> + {error, Error, Msg}; build_params(_, #rsm_in{max = Max, index = Index}) when Max =:= error; Index =:= error -> {error, bad_request, <<"bad-request">>}; +build_params(_, #rsm_in{index = Index}) when Index =/= undefined -> + {error, feature_not_implemented, <<"Inbox does not expose a total count and indexes">>}; build_params(Params, none) -> Params; build_params(Params, #rsm_in{max = Max, id = undefined}) when Max =/= undefined ->