1: -module(inbox_SUITE). 2: -compile([export_all, nowarn_export_all]). 3: 4: -include_lib("common_test/include/ct.hrl"). 5: -include_lib("eunit/include/eunit.hrl"). 6: -include_lib("escalus/include/escalus_xmlns.hrl"). 7: -include_lib("exml/include/exml.hrl"). 8: -include_lib("jid/include/jid.hrl"). 9: -include_lib("inbox.hrl"). 10: 11: %% tests 12: -import(muc_light_helper, [room_bin_jid/1]). 13: -import(inbox_helper, [ 14: inbox_modules/0, 15: muclight_modules/0, 16: inbox_opts/0, 17: muc_domain/0, 18: parse_form_iq/1, 19: check_inbox/2, check_inbox/3, 20: check_inbox/4, 21: clear_inbox_all/0, 22: given_conversations_between/2, 23: assert_invalid_inbox_form_value_error/3, 24: assert_invalid_reset_inbox/4, 25: extract_user_specs/1 26: ]). 27: 28: -define(ROOM3, <<"testroom3">>). 29: -define(ROOM4, <<"testroom4">>). 30: 31: %%-------------------------------------------------------------------- 32: %% Suite configuration 33: %%-------------------------------------------------------------------- 34: 35: all() -> 36: inbox_helper:skip_or_run_inbox_tests(tests()). 37: 38: tests() -> 39: [ 40: {group, regular}, 41: {group, async_pools} 42: ]. 43: 44: groups() -> 45: Gs = [ 46: {generic, [], 47: [ 48: disco_service, 49: returns_valid_form, 50: returns_error_when_first_bad_form_field_encountered, 51: returns_error_when_bad_form_field_start_sent, 52: returns_error_when_bad_form_field_end_sent, 53: returns_error_when_bad_form_field_order_sent, 54: returns_error_when_bad_form_field_hidden_read_sent, 55: returns_error_when_bad_reset_field_jid, 56: returns_error_when_no_reset_field_jid, 57: returns_error_when_unknown_field_sent 58: ]}, 59: {one_to_one, [], 60: [ 61: user_has_empty_inbox, 62: msg_sent_stored_in_inbox, 63: msg_sent_stored_in_inbox_iq_id_as_queryid_fallback, 64: msg_sent_stored_in_inbox_queryid, 65: msg_with_no_store_is_not_stored_in_inbox, 66: msg_with_store_hint_is_always_stored, 67: carbons_are_not_stored, 68: user_has_two_conversations, 69: msg_sent_to_offline_user, 70: msg_sent_to_not_existing_user, 71: user_has_two_unread_messages, 72: other_resources_do_not_interfere, 73: reset_unread_counter_with_reset_chat_marker, 74: reset_unread_counter_with_reset_stanza, 75: try_to_reset_unread_counter_with_bad_marker, 76: non_reset_marker_should_not_affect_inbox, 77: user_has_only_unread_messages_or_only_read, 78: reset_unread_counter_and_show_only_unread, 79: check_total_unread_count_and_active_conv_count, 80: check_total_unread_count_when_there_are_no_active_conversations, 81: total_unread_count_and_active_convs_are_zero_at_no_activity 82: ]}, 83: {muclight, [], 84: [ 85: simple_groupchat_stored_in_all_inbox, 86: advanced_groupchat_stored_in_all_inbox, 87: groupchat_markers_one_reset, 88: non_reset_marker_should_not_affect_muclight_inbox, 89: groupchat_reset_stanza_resets_inbox, 90: create_groupchat, 91: leave_and_remove_conversation, 92: groupchat_markers_one_reset_room_created, 93: groupchat_markers_all_reset_room_created, 94: inbox_does_not_trigger_does_user_exist 95: ]}, 96: {muclight_config, [sequence], 97: [ 98: create_groupchat_no_affiliation_stored, 99: leave_and_store_conversation, 100: no_aff_stored_and_remove_on_kicked, 101: no_stored_and_remain_after_kicked, 102: system_message_is_correctly_avoided 103: ]}, 104: {muc, [], 105: [ 106: simple_groupchat_stored_in_all_inbox_muc, 107: simple_groupchat_stored_in_offline_users_inbox_muc, 108: unread_count_is_the_same_after_going_online_again, 109: unread_count_is_reset_after_sending_chatmarker, 110: non_reset_marker_should_not_affect_muc_inbox, 111: unread_count_is_reset_after_sending_reset_stanza, 112: private_messages_are_handled_as_one2one 113: ]}, 114: {timestamps, [], 115: [ 116: timestamp_is_updated_on_new_message, 117: order_by_timestamp_ascending, 118: get_by_timestamp_range, 119: get_with_start_timestamp, 120: get_with_end_timestamp 121: ]}, 122: {bin, [], 123: [ 124: timeout_cleaner_flush_all, 125: rest_api_bin_flush_all, 126: rest_api_bin_flush_user, 127: xmpp_bin_flush, 128: bin_is_not_included_by_default 129: ]}, 130: {regular, [], test_groups()}, 131: {async_pools, [], [{group, bin} | test_groups()]} 132: ], 133: inbox_helper:maybe_run_in_parallel(Gs). 134: 135: test_groups() -> 136: [ 137: {group, generic}, 138: {group, one_to_one}, 139: {group, muclight}, 140: {group, muclight_config}, 141: {group, muc}, 142: {group, timestamps} 143: ]. 144: 145: suite() -> 146: escalus:suite(). 147: 148: %%-------------------------------------------------------------------- 149: %% Init & teardown 150: %%-------------------------------------------------------------------- 151: 152: init_per_suite(Config) -> 153: mongoose_helper:inject_module(?MODULE), 154: escalus:init_per_suite(Config). 155: 156: end_per_suite(Config) -> 157: escalus:end_per_suite(Config). 158: 159: init_per_group(GroupName, Config) when GroupName =:= regular; GroupName =:= async_pools -> 160: HostType = domain_helper:host_type(), 161: SecHostType = domain_helper:secondary_host_type(), 162: Config1 = dynamic_modules:save_modules(HostType, Config), 163: Config2 = dynamic_modules:save_modules(SecHostType, Config1), 164: InboxOptions = inbox_helper:inbox_opts(GroupName), 165: ok = dynamic_modules:ensure_modules(HostType, 166: inbox_helper:inbox_modules(GroupName) 167: ++ inbox_helper:muclight_modules() 168: ++ [{mod_offline, config_parser_helper:default_mod_config(mod_offline)}]), 169: ok = dynamic_modules:ensure_modules(SecHostType, 170: [{mod_inbox, InboxOptions#{aff_changes := false}}]), 171: [{inbox_opts, InboxOptions} | Config2]; 172: 173: init_per_group(muclight, Config) -> 174: ok = dynamic_modules:ensure_modules(domain_helper:host_type(), muclight_modules()), 175: inbox_helper:reload_inbox_option(Config, groupchat, [muclight]); 176: init_per_group(muclight_config, Config) -> 177: ok = dynamic_modules:ensure_modules(domain_helper:host_type(), muclight_modules()), 178: Config1 = inbox_helper:reload_inbox_option(Config, groupchat, [muclight]), 179: escalus:create_users(Config1, escalus:get_users([alice, alice_bis, bob, kate, mike])); 180: init_per_group(muc, Config) -> 181: muc_helper:load_muc(), 182: inbox_helper:reload_inbox_option(Config, groupchat, [muc]); 183: init_per_group(_GroupName, Config) -> 184: Config. 185: 186: end_per_group(GroupName, Config) when GroupName =:= regular; GroupName =:= async_pools -> 187: muc_light_helper:clear_db(domain_helper:host_type()), 188: escalus_fresh:clean(), 189: dynamic_modules:restore_modules(Config); 190: end_per_group(muclight_config, Config) -> 191: escalus:delete_users(Config, escalus:get_users([alice, alice_bis, bob, kate, mike])); 192: end_per_group(muc, Config) -> 193: inbox_helper:restore_inbox_option(Config), 194: muc_helper:unload_muc(); 195: end_per_group(_GroupName, Config) -> 196: Config. 197: 198: init_per_testcase(timeout_cleaner_flush_all, Config) -> 199: clear_inbox_all(), 200: inbox_helper:reload_inbox_option(Config, [{bin_ttl, 0}, {bin_clean_after, 10}]), 201: escalus:init_per_testcase(timeout_cleaner_flush_all, Config); 202: init_per_testcase(TS, Config) 203: when TS =:= create_groupchat_no_affiliation_stored; 204: TS =:= system_message_is_correctly_avoided -> 205: clear_inbox_all(), 206: inbox_helper:reload_inbox_option(Config, aff_changes, false), 207: escalus:init_per_testcase(TS, Config); 208: init_per_testcase(leave_and_store_conversation, Config) -> 209: clear_inbox_all(), 210: inbox_helper:reload_inbox_option(Config, remove_on_kicked, false), 211: escalus:init_per_testcase(leave_and_store_conversation, Config); 212: init_per_testcase(no_aff_stored_and_remove_on_kicked, Config) -> 213: clear_inbox_all(), 214: muc_light_helper:create_room(?ROOM3, muc_light_helper:muc_host(), alice, [bob, kate], 215: Config, muc_light_helper:ver(1)), 216: inbox_helper:reload_inbox_option(Config, [{remove_on_kicked, true}, {aff_changes, false}]), 217: escalus:init_per_testcase(no_aff_stored_and_remove_on_kicked, Config); 218: init_per_testcase(no_stored_and_remain_after_kicked, Config) -> 219: clear_inbox_all(), 220: muc_light_helper:create_room(?ROOM4, muc_light_helper:muc_host(), alice, [bob, kate], 221: Config, muc_light_helper:ver(1)), 222: inbox_helper:reload_inbox_option(Config, [{remove_on_kicked, false}, {aff_changes, true}]), 223: escalus:init_per_testcase(no_stored_and_remain_after_kicked, Config); 224: init_per_testcase(CaseName, Config) -> 225: escalus:init_per_testcase(CaseName, Config). 226: 227: end_per_testcase(timeout_cleaner_flush_all, Config) -> 228: inbox_helper:restore_inbox_option(Config), 229: escalus:end_per_testcase(timeout_cleaner_flush_all, Config); 230: end_per_testcase(TS, Config) 231: when TS =:= create_groupchat_no_affiliation_stored; 232: TS =:= system_message_is_correctly_avoided -> 233: clear_inbox_all(), 234: inbox_helper:restore_inbox_option(Config), 235: escalus:end_per_testcase(TS, Config); 236: end_per_testcase(leave_and_store_conversation, Config) -> 237: clear_inbox_all(), 238: inbox_helper:restore_inbox_option(Config), 239: escalus:end_per_testcase(leave_and_store_conversation, Config); 240: end_per_testcase(no_aff_stored_and_remove_on_kicked, Config) -> 241: clear_inbox_all(), 242: inbox_helper:restore_inbox_option(Config), 243: escalus:end_per_testcase(no_aff_stored_and_remove_on_kicked, Config); 244: end_per_testcase(no_stored_and_remain_after_kicked, Config) -> 245: clear_inbox_all(), 246: inbox_helper:restore_inbox_option(Config), 247: escalus:end_per_testcase(no_stored_and_remain_after_kicked, Config); 248: end_per_testcase(msg_sent_to_not_existing_user, Config) -> 249: HostType = domain_helper:host_type(), 250: escalus_ejabberd:rpc(mod_inbox_utils, clear_inbox, [HostType, <<"not_existing_user">>,<<"localhost">>]), 251: escalus:end_per_testcase(msg_sent_to_not_existing_user, Config); 252: end_per_testcase(CaseName, Config) -> 253: escalus:end_per_testcase(CaseName, Config). 254: 255: 256: %%-------------------------------------------------------------------- 257: %% Generic Inbox tests 258: %%-------------------------------------------------------------------- 259: 260: disco_service(Config) -> 261: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 262: Server = escalus_client:server(Alice), 263: escalus:send( 264: Alice, escalus_stanza:to(escalus_stanza:iq_get(?NS_DISCO_INFO, []), Server)), 265: Stanza = escalus:wait_for_stanza(Alice), 266: Features = exml_query:paths(Stanza, [{element, <<"query">>}, 267: {element, <<"feature">>}, 268: {attr, <<"var">>}]), 269: ?assertEqual(true, lists:member(inbox_helper:inbox_ns(), Features)) 270: end). 271: 272: returns_valid_form(Config) -> 273: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 274: escalus:send(Alice, inbox_helper:get_inbox_form_stanza()), 275: ResIQ = escalus:wait_for_stanza(Alice), 276: InboxNS = inbox_helper:inbox_ns(), 277: #{ field_count := 7 } = Form = parse_form_iq(ResIQ), 278: #{ <<"FORM_TYPE">> := #{ type := <<"hidden">>, 279: value := InboxNS } } = Form, 280: #{ <<"start">> := #{ type := <<"text-single">> } } = Form, 281: #{ <<"end">> := #{ type := <<"text-single">> } } = Form, 282: #{ <<"archive">> := #{ type := <<"boolean">>, 283: value := <<"false">> } } = Form, 284: #{ <<"box">> := #{ type := <<"list-single">>, 285: value := <<"all">>, 286: options := BoxOptions } } = Form, 287: #{ <<"order">> := #{ type := <<"list-single">>, 288: value := <<"desc">>, 289: options := OrderOptions } } = Form, 290: [<<"asc">>, <<"desc">>] = lists:sort(OrderOptions), 291: [<<"all">>, <<"archive">>, <<"bin">>, <<"inbox">>, <<"other">>] = lists:sort(BoxOptions), 292: #{ <<"hidden_read">> := #{ type := <<"text-single">> } } = Form 293: end). 294: 295: returns_error_when_bad_form_field_order_sent(Config) -> 296: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 297: assert_invalid_inbox_form_value_error(Alice, <<"order">>, <<"invalid">>) 298: end). 299: 300: returns_error_when_bad_form_field_start_sent(Config) -> 301: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 302: assert_invalid_inbox_form_value_error(Alice, <<"start">>, <<"invalid">>) 303: end). 304: 305: returns_error_when_bad_form_field_end_sent(Config) -> 306: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 307: assert_invalid_inbox_form_value_error(Alice, <<"end">>, <<"invalid">>) 308: end). 309: 310: returns_error_when_bad_form_field_hidden_read_sent(Config) -> 311: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 312: assert_invalid_inbox_form_value_error(Alice, <<"hidden_read">>, <<"invalid">>) 313: end). 314: 315: returns_error_when_bad_reset_field_jid(Config) -> 316: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 317: assert_invalid_reset_inbox( 318: Alice, <<"$@/">>, <<"jid">>, <<"invalid-jid">>) 319: end). 320: 321: returns_error_when_no_reset_field_jid(Config) -> 322: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 323: assert_invalid_reset_inbox( 324: Alice, undefined, <<"jid">>, <<"jid-required">>) 325: end). 326: 327: 328: returns_error_when_first_bad_form_field_encountered(Config) -> 329: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 330: Stanza = inbox_helper:make_inbox_stanza(#{<<"start">> => <<"invalid">>, 331: <<"end">> => <<"invalid">>}, false), 332: escalus:send(Alice, Stanza), 333: [ResIQ] = escalus:wait_for_stanzas(Alice, 1), 334: escalus_pred:is_iq_error(ResIQ), 335: ErrorMsg = inbox_helper:get_error_message(ResIQ), 336: inbox_helper:assert_message_content(ErrorMsg, <<"field=end">>, <<"value=invalid">>) 337: end). 338: 339: returns_error_when_unknown_field_sent(Config) -> 340: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 341: Stanza = inbox_helper:make_inbox_stanza(#{<<"unknown_field">> => <<"unknown_field_value">>}, false), 342: escalus:send(Alice, Stanza), 343: [ResIQ] = escalus:wait_for_stanzas(Alice, 1), 344: escalus_pred:is_iq_error(ResIQ), 345: ErrorMsg = inbox_helper:get_error_message(ResIQ), 346: inbox_helper:assert_message_content(ErrorMsg, <<"field=unknown_field">>, <<"value=unknown_field_value">>) 347: end). 348: 349: 350: %%-------------------------------------------------------------------- 351: %% Inbox tests one-to-one 352: %%-------------------------------------------------------------------- 353: 354: user_has_empty_inbox(Config) -> 355: escalus:fresh_story(Config, [{kate, 1}], fun(Kate) -> 356: Stanza = inbox_helper:make_inbox_stanza(), 357: %% Kate logs in for first time and ask for inbox 358: escalus:send(Kate, Stanza), 359: [ResIQ] = escalus:wait_for_stanzas(Kate, 1), 360: true = escalus_pred:is_iq_result(ResIQ), 361: %% Inbox is empty 362: TotalCount = inbox_helper:get_result_el(ResIQ, <<"count">>), 363: 0 = TotalCount 364: end). 365: 366: msg_sent_stored_in_inbox(Config) -> 367: test_msg_stored_in_inbox(Config, undefined). 368: 369: msg_sent_stored_in_inbox_iq_id_as_queryid_fallback(Config) -> 370: test_msg_stored_in_inbox(Config, iq_id). 371: 372: msg_sent_stored_in_inbox_queryid(Config) -> 373: test_msg_stored_in_inbox(Config, queryid). 374: 375: test_msg_stored_in_inbox(Config, QueryId) -> 376: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 377: #{ Alice := AliceConvs, Bob := BobConvs } = given_conversations_between(Alice, [Bob]), 378: %% Both check inbox 379: check_inbox(Alice, AliceConvs, inbox_helper:maybe_make_queryid(QueryId)), 380: check_inbox(Bob, BobConvs, inbox_helper:maybe_make_queryid(QueryId)) 381: end). 382: 383: msg_with_no_store_is_not_stored_in_inbox(Config) -> 384: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 385: %% Alice sends a message to Bob with a no-store hint 386: Body = <<"test">>, 387: Msg1 = escalus_stanza:chat_to(Bob, Body), 388: Msg2 = escalus_stanza:set_id(Msg1, escalus_stanza:id()), 389: Msg3 = mam_helper:add_nostore_hint(Msg2), 390: escalus:send(Alice, Msg3), 391: MsgSent = escalus:wait_for_stanza(Bob), 392: escalus:assert(is_chat_message, MsgSent), 393: %% Bob has no unread messages in conversation with Alice 394: check_inbox(Bob, []), 395: %% Alice has no conv in her inbox either 396: check_inbox(Alice, []) 397: end). 398: 399: msg_with_store_hint_is_always_stored(Config) -> 400: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 401: %% Alice sends a message to Bob with a store hint, that would otherwise be ignored 402: Msg1 = escalus_stanza:to(#xmlel{name = <<"message">>}, Bob), 403: Msg2 = escalus_stanza:set_id(Msg1, escalus_stanza:id()), 404: Msg3 = mam_helper:add_store_hint(Msg2), 405: escalus:send(Alice, Msg3), 406: escalus:wait_for_stanza(Bob), 407: %% Alice and Bob has a body-less message in their inbox 408: check_inbox(Bob, [#conv{unread = 1, from = Alice, to = Bob, content = <<>>}]), 409: check_inbox(Alice, [#conv{unread = 0, from = Alice, to = Bob, content = <<>>}]) 410: end). 411: 412: carbons_are_not_stored(Config) -> 413: escalus:fresh_story(Config, [{alice, 2}, {bob, 2}], fun(Alice1, Alice2, Bob1, Bob2) -> 414: mongoose_helper:enable_carbons([Alice1, Alice2, Bob1, Bob2]), 415: #{ Alice1 := AliceConvs, Bob1 := BobConvs } = given_conversations_between(Alice1, [Bob1]), 416: %% Both check inbox and carbons aren't there 417: check_inbox(Alice1, AliceConvs), 418: check_inbox(Bob1, BobConvs) 419: end). 420: 421: user_has_two_conversations(Config) -> 422: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 423: #{ Alice := AliceConvs, Bob := BobConvs, Kate := KateConvs } = 424: given_conversations_between(Alice, [Bob, Kate]), 425: 426: %% Alice has two conversations in her inbox (no unread messages) 427: check_inbox(Alice, AliceConvs), 428: 429: %% Kate has one conversation with one unread 430: check_inbox(Kate, KateConvs), 431: 432: %% Bob has one conversation with one unread 433: check_inbox(Bob, BobConvs) 434: end). 435: 436: user_has_only_unread_messages_or_only_read(Config) -> 437: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 438: given_conversations_between(Alice, [Bob, Kate]), 439: % Alice has no unread messages, but requests all conversations 440: inbox_helper:get_inbox(Alice, #{ hidden_read => false }, #{count => 2}), 441: 442: % Requests only conversations with unread messages 443: inbox_helper:get_inbox(Alice, #{ hidden_read => true }, #{count => 0}), 444: % Bob has only one, unread message 445: inbox_helper:get_inbox(Bob, #{ hidden_read => true }, #{count => 1}) 446: end). 447: 448: msg_sent_to_offline_user(Config) -> 449: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 450: %% Bob goes offline 451: mongoose_helper:logout_user(Config, Bob), 452: 453: %% Alice sends a message to Bob 454: Msg1 = escalus_stanza:chat_to(Bob, <<"test">>), 455: escalus:send(Alice, Msg1), 456: 457: %% Bob goes online again 458: {_, BobSpecs} = extract_user_specs(Bob), 459: {ok, NewBob} = escalus_client:start(Config, BobSpecs, <<"new-session">>), 460: escalus:send(NewBob, escalus_stanza:presence(<<"available">>)), 461: Stanzas = escalus:wait_for_stanzas(NewBob, 2), 462: 463: escalus_new_assert:mix_match 464: ([is_presence, fun(Stanza) -> escalus_pred:is_chat_message(<<"test">>, Stanza) end], 465: Stanzas), 466: 467: %% Alice has conversation 468: check_inbox(Alice, [#conv{unread = 0, from = Alice, to = Bob, content = <<"test">>}]), 469: 470: %% Both check inbox and has a conversation 471: check_inbox(NewBob, [#conv{unread = 1, from = Alice, to = Bob, content = <<"test">>}]) 472: end). 473: 474: msg_sent_to_not_existing_user(Config) -> 475: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 476: %% Alice sends message to user that doesnt exist 477: Msg1 = escalus_stanza:chat_to(<<"not_existing_user@localhost">>, <<"test2">>), 478: escalus:send(Alice, Msg1), 479: 480: %% Alice receives error 481: ServiceUnavailable = escalus:wait_for_stanza(Alice), 482: escalus_pred:is_error(<<"cancel">>,<<"service-unavailable">>, ServiceUnavailable), 483: 484: %% Alice has this conversation in inbox. 485: check_inbox(Alice,[#conv{unread = 0, 486: from = Alice, 487: to = <<"not_existing_user@localhost">>, 488: content = <<"test2">>}]) 489: end). 490: 491: user_has_two_unread_messages(Config) -> 492: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}], fun(Kate, Mike) -> 493: inbox_helper:send_msg(Kate, Mike, "Hello"), 494: inbox_helper:send_msg(Kate, Mike, "How are you"), 495: %% Mike has two unread messages in conversation with Kate 496: check_inbox(Mike, [#conv{unread = 2, from = Kate, to = Mike, content = <<"How are you">>}]), 497: %% Kate has one conv in her inbox (no unread messages) 498: check_inbox(Kate, [#conv{unread = 0, from = Kate, to = Mike, content = <<"How are you">>}]) 499: end). 500: 501: other_resources_do_not_interfere(Config) -> 502: %% regression test 503: escalus:fresh_story(Config, [{kate, 2}, {mike, 1}], fun(Kate, Kate2, Mike) -> 504: Prio = #xmlel{name = <<"priority">>, children = [#xmlcdata{content = <<"100">>}]}, 505: escalus_client:send(Kate2, escalus_stanza:presence(<<"available">>, [Prio])), 506: escalus_client:wait_for_stanza(Kate), 507: inbox_helper:send_msg(Kate, Mike, "Hello"), 508: inbox_helper:send_msg(Kate, Mike, "How are you"), 509: %% Mike has two unread messages in conversation with Kate 510: check_inbox(Mike, [#conv{unread = 2, from = Kate, to = Mike, content = <<"How are you">>}]), 511: %% Kate has one conv in her inbox (no unread messages) 512: check_inbox(Kate, [#conv{unread = 0, from = Kate, to = Mike, content = <<"How are you">>}]) 513: end). 514: 515: reset_unread_counter_with_reset_chat_marker(Config) -> 516: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}], fun(Kate, Mike) -> 517: Msg = inbox_helper:send_msg(Kate, Mike, <<"Hi mike">>), 518: MsgId = exml_query:attr(Msg, <<"id">>), 519: 520: %% Mike has one unread message 521: check_inbox(Mike, [#conv{unread = 1, from = Kate, to = Mike, content = <<"Hi mike">>}]), 522: ChatMarker = escalus_stanza:chat_marker(Kate, <<"displayed">>, MsgId), 523: %% Mike sends "displayed" chat marker to Kate 524: escalus:send(Mike, ChatMarker), 525: %% Now Mike asks for inbox second time. He has 0 unread messages now 526: check_inbox(Mike, [#conv{unread = 0, from = Kate, to = Mike, content = <<"Hi mike">>}]) 527: end). 528: 529: reset_unread_counter_with_reset_stanza(Config) -> 530: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}], fun(Kate, Mike) -> 531: _Msg = inbox_helper:send_msg(Kate, Mike, <<"Hi mike">>), 532: 533: %% Mike has one unread message 534: check_inbox(Mike, [#conv{unread = 1, from = Kate, to = Mike, content = <<"Hi mike">>}]), 535: %% Mike sends "reset" stanza 536: inbox_helper:reset_inbox(Mike, Kate), 537: %% Now Mike asks for inbox second time. He has 0 unread messages now 538: check_inbox(Mike, [#conv{unread = 0, from = Kate, to = Mike, content = <<"Hi mike">>}]), 539: %% Kate should not be receiving this stanza 540: inbox_helper:assert_has_no_stanzas(Kate) 541: end). 542: 543: reset_unread_counter_and_show_only_unread(Config) -> 544: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}, {alice, 1}], fun(Kate, Mike, Alice) -> 545: Msg = inbox_helper:send_msg(Kate, Mike), 546: MsgId = exml_query:attr(Msg, <<"id">>), 547: inbox_helper:get_inbox(Mike, #{ hidden_read => true }, #{count => 1}), 548: 549: ChatMarker = escalus_stanza:chat_marker(Kate, <<"displayed">>, MsgId), 550: escalus:send(Mike, ChatMarker), 551: 552: inbox_helper:get_inbox(Mike, #{ hidden_read => true }, #{count => 0}), 553: 554: inbox_helper:send_msg(Alice, Mike), 555: % Mike has two conversations, one with unread messages 556: inbox_helper:get_inbox(Mike, #{ hidden_read => true }, #{count => 1}), 557: inbox_helper:get_inbox(Mike, #{ hidden_read => false }, #{count => 2}) 558: end). 559: 560: check_total_unread_count_and_active_conv_count(Config) -> 561: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}, {alice, 1}], fun(Kate, Mike, Alice) -> 562: inbox_helper:send_and_mark_msg(Kate, Mike), 563: inbox_helper:send_msg(Alice, Mike), 564: inbox_helper:send_msg(Alice, Mike), 565: inbox_helper:send_msg(Kate, Mike), 566: inbox_helper:get_inbox(Mike, #{count => 2, unread_messages => 3, active_conversations => 2}) 567: end). 568: 569: check_total_unread_count_when_there_are_no_active_conversations(Config) -> 570: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}], fun(Kate, Mike) -> 571: inbox_helper:send_and_mark_msg(Kate, Mike), 572: inbox_helper:get_inbox(Mike, #{count => 1, unread_messages => 0, active_conversations => 0}) 573: end). 574: 575: total_unread_count_and_active_convs_are_zero_at_no_activity(Config) -> 576: escalus:fresh_story(Config, [{kate, 1}], fun(Kate) -> 577: inbox_helper:get_inbox(Kate, #{count => 0, unread_messages => 0, active_conversations => 0}) 578: end). 579: 580: try_to_reset_unread_counter_with_bad_marker(Config) -> 581: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}], fun(Kate, Mike) -> 582: Msg1 = escalus_stanza:set_id(escalus_stanza:chat_to(Mike, <<"okey dockey">>), <<"111">>), 583: %% Kate sends message to Mike 584: escalus:send(Kate, Msg1), 585: M1 = escalus:wait_for_stanza(Mike), 586: escalus:assert(is_chat_message, M1), 587: %% Mike has one unread message 588: check_inbox(Mike, [#conv{unread = 1, from = Kate, to = Mike, content = <<"okey dockey">>}]), 589: MsgId = <<"badId">>, 590: ChatMarker = escalus_stanza:chat_marker(Kate, <<"displayed">>, MsgId), 591: %% Mike sends "displayed" chat marker but 'id' field is wrong 592: escalus:send(Mike, ChatMarker), 593: %% Now Mike asks for inbox second time. Unread count should be still the same 594: check_inbox(Mike, [#conv{unread = 1, from = Kate, to = Mike, content = <<"okey dockey">>}]) 595: end). 596: 597: non_reset_marker_should_not_affect_inbox(Config) -> 598: escalus:fresh_story(Config, [{kate, 1}, {mike, 1}], fun(Kate, Mike) -> 599: MsgId = <<"kate_to_mike">>, 600: MsgBody = <<"okey dockey">>, 601: Msg = escalus_stanza:set_id(escalus_stanza:chat_to(Mike, MsgBody), MsgId), 602: %% Kate sends message to Mike 603: escalus:send(Kate, Msg), 604: M1 = escalus:wait_for_stanza(Mike), 605: escalus:assert(is_chat_message, M1), 606: %% Mike has one unread message 607: check_inbox(Mike, [#conv{unread = 1, from = Kate, to = Mike, content = MsgBody}]), 608: ChatMarker = escalus_stanza:chat_marker(Kate, <<"received">>, MsgId), 609: %% Mike sends "received" chat marker, which is not a reset_marker 610: escalus:send(Mike, ChatMarker), 611: CM = escalus:wait_for_stanza(Kate), 612: escalus:assert(is_message, CM), 613: %% Now Mike asks for inbox second time. Unread count should be still the same 614: check_inbox(Mike, [#conv{unread = 1, from = Kate, to = Mike, content = MsgBody}]), 615: check_inbox(Kate, [], #{hidden_read => true}, #{}) 616: end). 617: 618: %%-------------------------------------------------------------------- 619: %% Inbox tests muclight 620: %%-------------------------------------------------------------------- 621: 622: simple_groupchat_stored_in_all_inbox(Config) -> 623: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 624: Msg = <<"Hi Room!">>, 625: Id = <<"MyID">>, 626: Users = [Alice, Bob, Kate], 627: Room = inbox_helper:create_room(Alice, [Bob, Kate]), 628: AliceJid = inbox_helper:to_bare_lower(Alice), 629: KateJid = inbox_helper:to_bare_lower(Kate), 630: BobJid = inbox_helper:to_bare_lower(Bob), 631: RoomJid = room_bin_jid(Room), 632: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 633: Stanza = escalus_stanza:set_id( 634: escalus_stanza:groupchat_to(RoomJid, Msg), Id), 635: %% Alice sends message to a room 636: escalus:send(Alice, Stanza), 637: inbox_helper:wait_for_groupchat_msg(Users), 638: %% Alice has 0 unread messages 639: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 640: %% Bob and Kate have one conv with 1 unread message 641: check_inbox(Bob, [#conv{unread = 1, from = AliceRoomJid, to = BobJid, content = Msg}]), 642: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]) 643: end). 644: 645: advanced_groupchat_stored_in_all_inbox(Config) -> 646: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 647: Msg1 = <<"Hi Room!">>, 648: Msg2 = <<"How are you?">>, 649: Id1 = <<"id-1">>, 650: Id2 = <<"id-2">>, 651: Users = [Alice, Bob, Kate], 652: Room = pubsub_tools:pubsub_node_name(), 653: inbox_helper:create_room_and_check_inbox(Alice, [Bob, Kate], Room), 654: BobJid = inbox_helper:to_bare_lower(Bob), 655: AliceJid = inbox_helper:to_bare_lower(Alice), 656: KateJid = inbox_helper:to_bare_lower(Kate), 657: RoomJid = room_bin_jid(Room), 658: BobRoomJid = <<RoomJid/binary, "/", BobJid/binary>>, 659: Stanza1 = escalus_stanza:set_id( 660: escalus_stanza:groupchat_to(RoomJid, Msg1), Id1), 661: %% Alice sends msg to room 662: escalus:send(Alice, Stanza1), 663: inbox_helper:wait_for_groupchat_msg(Users), 664: %% Bob sends second message 665: Stanza2 = escalus_stanza:set_id( 666: escalus_stanza:groupchat_to(RoomJid, Msg2), Id2), 667: escalus:send(Bob, Stanza2), 668: inbox_helper:wait_for_groupchat_msg(Users), 669: %% Alice have one unread message (from Bob) 670: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg2}]), 671: %% Bob has 0 unread messages because he sent the last message 672: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg2}]), 673: %% Kate has 2 unread messages (from Alice and Bob) 674: check_inbox(Kate, [#conv{unread = 2, from = BobRoomJid, to = KateJid, content = Msg2}]) 675: end). 676: 677: groupchat_markers_one_reset(Config) -> 678: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 679: AliceJid = inbox_helper:to_bare_lower(Alice), 680: BobJid = inbox_helper:to_bare_lower(Bob), 681: KateJid = inbox_helper:to_bare_lower(Kate), 682: Room = inbox_helper:create_room(Alice, [Bob, Kate]), 683: RoomJid = room_bin_jid(Room), 684: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 685: Id = <<"markerId">>, 686: Users = [Alice, Bob, Kate], 687: Stanza1 = escalus_stanza:set_id( 688: escalus_stanza:groupchat_to(RoomJid, <<"marker time!">>), Id), 689: escalus:send(Alice, Stanza1), 690: inbox_helper:wait_for_groupchat_msg(Users), 691: ChatMarkerWOType = escalus_stanza:chat_marker(RoomJid,<<"displayed">>, Id), 692: ChatMarker = escalus_stanza:setattr(ChatMarkerWOType, <<"type">>, <<"groupchat">>), 693: %% User marks last message 694: escalus:send(Bob, ChatMarker), 695: %% participants receive marker 696: muc_helper:foreach_recipient([Alice, Bob, Kate], fun(Marker) -> 697: true = escalus_pred:is_chat_marker(<<"displayed">>, Id, Marker) end), 698: %% Bob has 0 unread messages because he reset his counter 699: check_inbox(Bob, [#conv{unread = 0, from = AliceRoomJid, 700: to = BobJid, content = <<"marker time!">>}]), 701: %% Alice has 0 unread messages because she was the sender 702: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, 703: to = AliceJid, content = <<"marker time!">>}]), 704: %% Kate still has unread message 705: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, 706: to = KateJid, content = <<"marker time!">>}]) 707: end). 708: 709: non_reset_marker_should_not_affect_muclight_inbox(Config) -> 710: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 711: % %% GIVEN 712: AliceJid = inbox_helper:to_bare_lower(Alice), 713: BobJid = inbox_helper:to_bare_lower(Bob), 714: KateJid = inbox_helper:to_bare_lower(Kate), 715: % %% WHEN DONE 716: Id = <<"some_ID">>, 717: Msg = <<"marker time!">>, 718: RoomName = pubsub_tools:pubsub_node_name(), 719: RoomJid = inbox_helper:create_room_send_msg_check_inbox(Alice, [Bob, Kate], RoomName, Msg, Id), 720: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 721: % %% AND MARKED WRONG 722: inbox_helper:mark_last_muclight_message(Bob, [Alice, Bob, Kate], <<"received">>), 723: inbox_helper:mark_last_muclight_message(Kate, [Alice, Bob, Kate], <<"acknowledged">>), 724: % %% THEN 725: %% Alice has 0 unread messages because she was the sender 726: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, 727: to = AliceJid, content = Msg}]), 728: %% Bob still has unread message 729: check_inbox(Bob, [#conv{unread = 1, from = AliceRoomJid, 730: to = BobJid, content = Msg}]), 731: %% Kate still has unread message 732: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, 733: to = KateJid, content = Msg}]) 734: end). 735: 736: groupchat_reset_stanza_resets_inbox(Config) -> 737: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 738: % %% WITH 739: Id = <<"some_ID">>, 740: Msg = <<"marker time!">>, 741: RoomName = pubsub_tools:pubsub_node_name(), 742: AliceJid = inbox_helper:to_bare_lower(Alice), 743: BobJid = inbox_helper:to_bare_lower(Bob), 744: KateJid = inbox_helper:to_bare_lower(Kate), 745: % %% WHEN A MESSAGE IS SENT 746: RoomJid = inbox_helper:create_room_send_msg_check_inbox(Alice, [Bob, Kate], RoomName, Msg, Id), 747: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 748: % %% AND WHEN SEND RESET FOR ROOM 749: inbox_helper:reset_inbox(Bob, RoomJid), 750: % %% THEN INBOX IS RESET FOR BOB, WITHOUT FORWARDING 751: %% Bob has 0 unread messages because he reset his counter 752: check_inbox(Bob, [#conv{unread = 0, from = AliceRoomJid, 753: to = BobJid, content = <<"marker time!">>}]), 754: %% Alice has 0 unread messages because she was the sender 755: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, 756: to = AliceJid, content = <<"marker time!">>}]), 757: %% Kate still has unread message 758: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, 759: to = KateJid, content = <<"marker time!">>}]), 760: %% And nobody received any other stanza 761: inbox_helper:assert_has_no_stanzas([Alice, Bob, Kate]) 762: end). 763: 764: %% this test combines options: 765: %% ... 766: %%{aff_changes, true}, 767: %%{remove_on_kicked, true}, 768: create_groupchat(Config) -> 769: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 770: RoomName = pubsub_tools:pubsub_node_name(), 771: inbox_helper:create_room_and_check_inbox(Bob, [Alice, Kate], RoomName) 772: end). 773: 774: %% this test combines options: 775: %% ... 776: %%{aff_changes, false}, 777: %%{remove_on_kicked, true}, 778: create_groupchat_no_affiliation_stored(Config) -> 779: escalus:story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 780: InitOccupants = [{Alice, member}, {Kate, member}], 781: FinalOccupants = [{Bob, owner} | InitOccupants], 782: Msg = <<"Hi all!">>, 783: Users = [Alice, Bob, Kate], 784: InitConfig = [{<<"roomname">>, <<"Bob's room2">>}], 785: RoomNode = <<"bobroom2">>, 786: RoomJid = room_bin_jid(RoomNode), 787: AliceJid = inbox_helper:to_bare_lower(Alice), 788: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 789: BobJid = inbox_helper:to_bare_lower(Bob), 790: KateJid = inbox_helper:to_bare_lower(Kate), 791: %% Bob creates room 792: escalus:send(Bob, muc_light_helper:stanza_create_room(RoomNode, InitConfig, InitOccupants)), 793: muc_light_helper:verify_aff_bcast(FinalOccupants, FinalOccupants), 794: escalus:assert(is_iq_result, escalus:wait_for_stanza(Bob)), 795: %% affiliation change messages are not stored in inbox 796: [ check_inbox(User, []) || User <- Users ], 797: Stanza = escalus_stanza:set_id( 798: escalus_stanza:groupchat_to(RoomJid, Msg), <<"123">>), 799: %% Alice sends a message 800: escalus:send(Alice, Stanza), 801: inbox_helper:wait_for_groupchat_msg(Users), 802: %% Alice has 0 unread because she sent the last message 803: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 804: %% Bob and Kate have one unread message 805: check_inbox(Bob, [#conv{unread = 1, from = AliceRoomJid, to = BobJid, content = Msg}]), 806: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]) 807: end). 808: 809: %% this test combines options: 810: %% ... 811: %%{aff_changes, true}, 812: %%{remove_on_kicked, true}, 813: leave_and_remove_conversation(Config) -> 814: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 815: RoomName = pubsub_tools:pubsub_node_name(), 816: AliceJid = inbox_helper:to_bare_lower(Alice), 817: BobJid = inbox_helper:to_bare_lower(Bob), 818: KateJid = inbox_helper:to_bare_lower(Kate), 819: %% Alice creates a room and send msg 820: Msg = <<"Hi all">>, 821: Id = <<"leave-id">>, 822: RoomJid = inbox_helper:create_room_send_msg_check_inbox(Alice, [Bob, Kate], RoomName, Msg, Id), 823: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 824: %% Bob leaves the room 825: muc_light_helper:user_leave(RoomName, Bob, [{Alice, owner}, {Kate, member}]), 826: %% Alice and Kate have one message 827: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 828: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]), 829: %% Bob doesn't have conversation in his inbox 830: check_inbox(Bob, [], #{box => inbox}), 831: if_async_check_bin(Config, Bob, [#conv{unread = 2, from = RoomJid, to = BobJid, 832: verify = fun inbox_helper:verify_is_none_aff_change/2}]) 833: end). 834: 835: %% this test combines options: 836: %% ... 837: %%{aff_changes, true}, 838: %%{remove_on_kicked, false}, 839: leave_and_store_conversation(Config) -> 840: escalus:story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 841: RoomName = pubsub_tools:pubsub_node_name(), 842: AliceJid = inbox_helper:to_bare_lower(Alice), 843: BobJid = inbox_helper:to_bare_lower(Bob), 844: KateJid = inbox_helper:to_bare_lower(Kate), 845: %% Alice creates a room and send msg 846: Msg = <<"Hi all">>, 847: Id = <<"leave-id">>, 848: RoomJid = inbox_helper:create_room_send_msg_check_inbox(Alice, [Bob, Kate], RoomName, Msg, Id), 849: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 850: %% Bob leaves room 851: muc_light_helper:user_leave(RoomName, Bob, [{Alice, owner}, {Kate, member}]), 852: %% Alice and Kate have conversation 853: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 854: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]), 855: %% Bob still has a conversation in inbox. Two unread - first is invitation, 856: %% the second is the leaving affiliation 857: check_inbox(Bob, [#conv{unread = 2, from = RoomJid, to = BobJid, 858: verify = fun inbox_helper:verify_is_none_aff_change/2}]) 859: end). 860: 861: %% this test combines options: 862: %% ... 863: %%{aff_changes, false}, 864: %%{remove_on_kicked, true}, 865: no_aff_stored_and_remove_on_kicked(Config) -> 866: escalus:story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 867: AliceJid = inbox_helper:to_bare_lower(Alice), 868: BobJid = inbox_helper:to_bare_lower(Bob), 869: KateJid = inbox_helper:to_bare_lower(Kate), 870: RoomJid = room_bin_jid(?ROOM3), 871: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 872: Msg = <<"Hi all">>, 873: Users = [Alice, Bob, Kate], 874: Stanza = escalus_stanza:set_id( 875: escalus_stanza:groupchat_to(RoomJid, Msg), <<"33">>), 876: %% Alice sends a message 877: escalus:send(Alice, Stanza), 878: inbox_helper:wait_for_groupchat_msg(Users), 879: %% Bob leaves the room 880: muc_light_helper:user_leave(?ROOM3, Bob, [{Alice, owner}, {Kate, member}]), 881: %% Alice and Kate have message in groupchats 882: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 883: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]), 884: %% Bob doesnt have a conversation in inbox 885: check_inbox(Bob, [], #{box => inbox}), 886: if_async_check_bin(Config, Bob, [#conv{unread = 1, from = AliceRoomJid, to = BobJid, content = Msg}]) 887: end). 888: 889: %% this test combines options: 890: %% ... 891: %%{aff_changes, true}, 892: %%{remove_on_kicked, false}, 893: no_stored_and_remain_after_kicked(Config) -> 894: escalus:story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 895: AliceJid = inbox_helper:to_bare_lower(Alice), 896: KateJid = inbox_helper:to_bare_lower(Kate), 897: BobJid = inbox_helper:to_bare_lower(Bob), 898: RoomJid = room_bin_jid(?ROOM4), 899: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 900: Msg = <<"Hi all">>, 901: Users = [Alice, Bob, Kate], 902: Stanza = escalus_stanza:set_id( 903: escalus_stanza:groupchat_to(RoomJid, Msg), <<"33">>), 904: %% Alice sends a message 905: escalus:send(Alice, Stanza), 906: inbox_helper:wait_for_groupchat_msg(Users), 907: %% Bob leaves the room 908: muc_light_helper:user_leave(?ROOM4, Bob, [{Alice, owner}, {Kate, member}]), 909: %% Alice and Kate have message in groupchats 910: check_inbox(Alice, [#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 911: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]), 912: %% Bob have a conversation in inbox. First unread is message from Alice, the second the affiliation change 913: check_inbox(Bob, [#conv{unread = 2, from = RoomJid, to = BobJid, 914: verify = fun inbox_helper:verify_is_none_aff_change/2}]) 915: end). 916: 917: groupchat_markers_one_reset_room_created(Config) -> 918: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 919: Id = <<"random-id">>, 920: Msg = <<"Welcome guys">>, 921: RoomName = pubsub_tools:pubsub_node_name(), 922: AliceJid = inbox_helper:to_bare_lower(Alice), 923: BobJid = inbox_helper:to_bare_lower(Bob), 924: KateJid = inbox_helper:to_bare_lower(Kate), 925: RoomJid = inbox_helper:create_room_send_msg_check_inbox(Alice, [Bob, Kate], RoomName, Msg, Id), 926: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 927: %% Now Bob sends marker 928: inbox_helper:mark_last_muclight_message(Bob, [Alice, Bob, Kate]), 929: %% The crew ask for inbox second time. Only Kate has unread messages 930: check_inbox(Alice,[#conv{unread = 0, from = AliceRoomJid, to = AliceJid, content = Msg}]), 931: check_inbox(Kate, [#conv{unread = 1, from = AliceRoomJid, to = KateJid, content = Msg}]), 932: check_inbox(Bob, [#conv{unread = 0, from = AliceRoomJid, to = BobJid, content = Msg}]) 933: end). 934: 935: groupchat_markers_all_reset_room_created(Config) -> 936: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 937: Id = <<"random-id">>, 938: Msg = <<"Mark me!">>, 939: RoomName = pubsub_tools:pubsub_node_name(), 940: AliceJid = inbox_helper:to_bare_lower(Alice), 941: RoomJid = inbox_helper:create_room_send_msg_check_inbox(Alice, [Bob, Kate], RoomName, Msg, Id), 942: AliceRoomJid = <<RoomJid/binary, "/", AliceJid/binary>>, 943: [inbox_helper:mark_last_muclight_message(U, [Alice, Bob, Kate]) || U <- [Bob, Kate]], 944: inbox_helper:foreach_check_inbox([Bob, Kate, Alice], 0, AliceRoomJid, Msg) 945: end). 946: 947: inbox_does_not_trigger_does_user_exist(Config) -> 948: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 949: Msg = <<"Mark me!">>, 950: RoomName = inbox_helper:create_room(Alice, [Bob, Kate]), 951: RoomJid = room_bin_jid(RoomName), 952: HookHandlerExtra = start_hook_listener(), 953: Stanza = escalus_stanza:groupchat_to(RoomJid, Msg), 954: %% Alice sends message to a room 955: escalus:send(Alice, Stanza), 956: [escalus:wait_for_stanza(User) || User <- [Alice, Bob, Kate]], 957: stop_hook_listener(HookHandlerExtra), 958: verify_hook_listener(RoomName) 959: end). 960: 961: system_message_is_correctly_avoided(Config) -> 962: escalus:story(Config, [{alice, 1}, {alice_bis, 1}, {bob, 1}], fun(Alice, AliceBis, Bob) -> 963: %% Variables 964: Id1 = <<"id-1">>, 965: Id2 = <<"id-2">>, 966: Msg1 = <<"Hi Room!">>, 967: Msg2 = <<"How are you?">>, 968: Users = [Alice, AliceBis, Bob], 969: InitOccupants = [{M, member} || M <- [AliceBis, Bob]], 970: Room = atom_to_binary(?FUNCTION_NAME, utf8), 971: BobJid = inbox_helper:to_bare_lower(Bob), 972: AliceJid = inbox_helper:to_bare_lower(Alice), 973: AliceBisJid = inbox_helper:to_bare_lower(AliceBis), 974: RoomJid = room_bin_jid(Room), 975: %% Given a room 976: muc_light_helper:given_muc_light_room(Room, Alice, InitOccupants), 977: BobRoomJid = <<RoomJid/binary, "/", BobJid/binary>>, 978: Stanza1 = escalus_stanza:set_id(escalus_stanza:groupchat_to(RoomJid, Msg1), Id1), 979: %% Alice sends msg to room 980: escalus:send(Alice, Stanza1), 981: inbox_helper:wait_for_groupchat_msg(Users), 982: %% Bob sends second message 983: Stanza2 = escalus_stanza:set_id(escalus_stanza:groupchat_to(RoomJid, Msg2), Id2), 984: escalus:send(Bob, Stanza2), 985: inbox_helper:wait_for_groupchat_msg(Users), 986: %% Alice has one unread message (from Bob) 987: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg2}]), 988: %% Bob has 0 unread messages because he sent the last message 989: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg2}]), 990: %% AliceBis has 2 unread messages (from Alice and Bob) and does not have the affiliation 991: check_inbox(AliceBis, [#conv{unread = 2, from = BobRoomJid, to = AliceBisJid, content = Msg2}]) 992: end). 993: 994: %%-------------------------------------------------------------------- 995: %% Classic MUC tests 996: %%-------------------------------------------------------------------- 997: 998: simple_groupchat_stored_in_all_inbox_muc(Config) -> 999: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1000: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1001: Users = [Alice, Bob, Kate], 1002: Msg = <<"Hi Room!">>, 1003: Id = <<"MyID">>, 1004: Room = ?config(room, RoomConfig), 1005: RoomAddr = muc_helper:room_address(Room), 1006: 1007: inbox_helper:enter_room(Room, Users), 1008: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1009: Stanza = escalus_stanza:set_id( 1010: escalus_stanza:groupchat_to(RoomAddr, Msg), Id), 1011: escalus:send(Bob, Stanza), 1012: inbox_helper:wait_for_groupchat_msg(Users), 1013: [AliceJid, BobJid, KateJid] = lists:map(fun inbox_helper:to_bare_lower/1, Users), 1014: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1015: %% Bob has 0 unread messages 1016: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg}], 1017: #{}, #{case_sensitive => true}), 1018: %% Alice and Kate have one conv with 1 unread message 1019: check_inbox(Alice,[#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg}], 1020: #{}, #{case_sensitive => true}), 1021: check_inbox(Kate, [#conv{unread = 1, from = BobRoomJid, to = KateJid, content = Msg}], 1022: #{}, #{case_sensitive => true}) 1023: end). 1024: 1025: simple_groupchat_stored_in_offline_users_inbox_muc(Config) -> 1026: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1027: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1028: Users = [Alice, Bob, Kate], 1029: Msg = <<"Hi Room!">>, 1030: Id = <<"MyID">>, 1031: Room = ?config(room, RoomConfig), 1032: RoomAddr = muc_helper:room_address(Room), 1033: 1034: inbox_helper:enter_room(Room, Users), 1035: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1036: inbox_helper:leave_room(Kate, Room, Users), 1037: Stanza = escalus_stanza:set_id( 1038: escalus_stanza:groupchat_to(RoomAddr, Msg), Id), 1039: escalus:send(Bob, Stanza), 1040: inbox_helper:wait_for_groupchat_msg(Users -- [Kate]), 1041: 1042: [AliceJid, BobJid, KateJid] = lists:map(fun inbox_helper:to_bare_lower/1, Users), 1043: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1044: %% Bob has 0 unread messages 1045: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg}], 1046: #{}, #{case_sensitive => true}), 1047: %% Alice and Kate have one conv with 1 unread message 1048: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg}], 1049: #{}, #{case_sensitive => true}), 1050: check_inbox(Kate, [#conv{unread = 1, from = BobRoomJid, to = KateJid, content = Msg}], 1051: #{}, #{case_sensitive => true}) 1052: end). 1053: 1054: 1055: unread_count_is_the_same_after_going_online_again(Config) -> 1056: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1057: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1058: Users = [Alice, Bob, Kate], 1059: Msg = <<"Hi Room!">>, 1060: Id = <<"MyID">>, 1061: Room = ?config(room, RoomConfig), 1062: RoomAddr = muc_helper:room_address(Room), 1063: 1064: inbox_helper:enter_room(Room, Users), 1065: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1066: inbox_helper:leave_room(Kate, Room, Users), 1067: Stanza = escalus_stanza:set_id( 1068: escalus_stanza:groupchat_to(RoomAddr, Msg), Id), 1069: escalus:send(Bob, Stanza), 1070: inbox_helper:wait_for_groupchat_msg(Users -- [Kate]), 1071: inbox_helper:enter_room(Room, Kate, Users -- [Kate], 1), 1072: [AliceJid, BobJid, KateJid] = lists:map(fun inbox_helper:to_bare_lower/1, Users), 1073: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1074: %% Bob has 0 unread messages 1075: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg}], 1076: #{}, #{case_sensitive => true}), 1077: %% Alice and Kate have one conv with 1 unread message 1078: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg}], 1079: #{}, #{case_sensitive => true}), 1080: check_inbox(Kate, [#conv{unread = 1, from = BobRoomJid, to = KateJid, content = Msg}], 1081: #{}, #{case_sensitive => true}) 1082: end). 1083: 1084: unread_count_is_reset_after_sending_chatmarker(Config) -> 1085: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1086: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1087: Users = [Alice, Bob, Kate], 1088: Msg = <<"Hi Room!">>, 1089: Id = <<"MyID">>, 1090: Room = ?config(room, RoomConfig), 1091: RoomAddr = muc_helper:room_address(Room), 1092: 1093: inbox_helper:enter_room(Room, Users), 1094: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1095: Stanza = escalus_stanza:set_id( 1096: escalus_stanza:groupchat_to(RoomAddr, Msg), Id), 1097: escalus:send(Bob, Stanza), 1098: inbox_helper:wait_for_groupchat_msg(Users), 1099: ChatMarkerWOType = escalus_stanza:chat_marker(RoomAddr, <<"displayed">>, Id), 1100: ChatMarker = escalus_stanza:setattr(ChatMarkerWOType, <<"type">>, <<"groupchat">>), 1101: %% User marks last message 1102: escalus:send(Kate, ChatMarker), 1103: inbox_helper:wait_for_groupchat_msg(Users), 1104: 1105: [AliceJid, BobJid, KateJid] = lists:map(fun inbox_helper:to_bare_lower/1, Users), 1106: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1107: %% Bob has 0 unread messages 1108: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg}], 1109: #{}, #{case_sensitive => true}), 1110: %% Alice have one conv with 1 unread message 1111: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg}], 1112: #{}, #{case_sensitive => true}), 1113: %% Kate has 0 unread messages 1114: check_inbox(Kate, [#conv{unread = 0, from = BobRoomJid, to = KateJid, content = Msg}], 1115: #{}, #{case_sensitive => true}) 1116: end). 1117: 1118: non_reset_marker_should_not_affect_muc_inbox(Config) -> 1119: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1120: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1121: % %% GIVEN 1122: Users = [Alice, Bob, Kate], 1123: Msg = <<"Hi Room!">>, 1124: Id = <<"MyID">>, 1125: Room = ?config(room, RoomConfig), 1126: RoomAddr = muc_helper:room_address(Room), 1127: 1128: % %% WHEN 1129: inbox_helper:enter_room(Room, Users), 1130: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1131: Stanza = escalus_stanza:set_id(escalus_stanza:groupchat_to(RoomAddr, Msg), Id), 1132: escalus:send(Bob, Stanza), 1133: inbox_helper:wait_for_groupchat_msg(Users), 1134: % %% AND MARKED WRONG 1135: KateChatMarkerWOType = escalus_stanza:chat_marker(RoomAddr,<<"acknowledged">>, Id), 1136: KateChatMarker = escalus_stanza:setattr(KateChatMarkerWOType, <<"type">>, <<"groupchat">>), 1137: escalus:send(Kate, KateChatMarker), 1138: inbox_helper:wait_for_groupchat_msg(Users), 1139: 1140: [AliceJid, BobJid, KateJid] = lists:map(fun inbox_helper:to_bare_lower/1, Users), 1141: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1142: % %% THEN 1143: %% Bob has 0 unread messages 1144: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg}], 1145: #{}, #{case_sensitive => true}), 1146: %% Alice have one conv with 1 unread message 1147: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg}], 1148: #{}, #{case_sensitive => true}), 1149: %% Kate has 1 unread messages 1150: check_inbox(Kate, [#conv{unread = 1, from = BobRoomJid, to = KateJid, content = Msg}], 1151: #{}, #{case_sensitive => true}) 1152: end). 1153: 1154: unread_count_is_reset_after_sending_reset_stanza(Config) -> 1155: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1156: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1157: % %% WITH 1158: Users = [Alice, Bob, Kate], 1159: Msg = <<"Hi Room!">>, 1160: Id = <<"MyID">>, 1161: Room = ?config(room, RoomConfig), 1162: RoomAddr = muc_helper:room_address(Room), 1163: % %% PROVIDED 1164: inbox_helper:enter_room(Room, Users), 1165: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1166: % %% WHEN A MESSAGE IS SENT 1167: Stanza = escalus_stanza:set_id( 1168: escalus_stanza:groupchat_to(RoomAddr, Msg), Id), 1169: escalus:send(Bob, Stanza), 1170: inbox_helper:wait_for_groupchat_msg(Users), 1171: [AliceJid, BobJid, KateJid] = lists:map(fun inbox_helper:to_bare_lower/1, Users), 1172: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1173: %% Make sure Kate gets her inbox updated 1174: check_inbox(Kate, [#conv{unread = 1, from = BobRoomJid, to = KateJid, content = Msg}], 1175: #{}, #{case_sensitive => true}), 1176: % %% AND WHEN SEND RESET FOR ROOM 1177: inbox_helper:reset_inbox(Kate, RoomAddr), 1178: 1179: %% Bob has 0 unread messages 1180: check_inbox(Bob, [#conv{unread = 0, from = BobRoomJid, to = BobJid, content = Msg}], 1181: #{}, #{case_sensitive => true}), 1182: %% Alice have one conv with 1 unread message 1183: check_inbox(Alice, [#conv{unread = 1, from = BobRoomJid, to = AliceJid, content = Msg}], 1184: #{}, #{case_sensitive => true}), 1185: %% Kate has 0 unread messages 1186: check_inbox(Kate, [#conv{unread = 0, from = BobRoomJid, to = KateJid, content = Msg}], 1187: #{}, #{case_sensitive => true}), 1188: inbox_helper:assert_has_no_stanzas([Alice, Bob, Kate]) 1189: end). 1190: 1191: private_messages_are_handled_as_one2one(Config) -> 1192: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1193: RoomConfig = muc_helper:start_room(Config, extract_user_specs(Alice), muc_helper:fresh_room_name(), <<"some_friendly_name">>, default), 1194: Users = [Alice, Bob, Kate], 1195: Msg = <<"Hi Room!">>, 1196: Id = <<"MyID">>, 1197: Room = ?config(room, RoomConfig), 1198: BobRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Bob)), 1199: KateRoomJid = muc_helper:room_address(Room, inbox_helper:nick(Kate)), 1200: 1201: inbox_helper:enter_room(Room, Users), 1202: inbox_helper:make_members(Room, Alice, Users -- [Alice]), 1203: Stanza = escalus_stanza:set_id( 1204: escalus_stanza:chat_to(BobRoomJid, Msg), Id), 1205: escalus:send(Kate, Stanza), 1206: _BobsPrivMsg = escalus:wait_for_stanza(Bob), 1207: 1208: KateJid = inbox_helper:to_bare_lower(Kate), 1209: %% Bob has 1 unread message 1210: check_inbox(Bob, [#conv{unread = 1, from = KateRoomJid, to = BobRoomJid, content = Msg}], 1211: #{}, #{case_sensitive => true}), 1212: %% Alice gets nothing 1213: check_inbox(Alice, []), 1214: %% Kate has 1 conv with 0 unread messages 1215: check_inbox(Kate, [#conv{unread = 0, from = KateJid, to = BobRoomJid, content = Msg}], 1216: #{}, #{case_sensitive => true, check_resource => false}) 1217: end). 1218: 1219: %%-------------------------------------------------------------------- 1220: %% Timestamp-related tests 1221: %%-------------------------------------------------------------------- 1222: 1223: timestamp_is_updated_on_new_message(Config) -> 1224: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 1225: Body1 = <<"Hello Bob">>, 1226: Body2 = <<"Are you there?">>, 1227: %% We capture the timestamp after the first message 1228: escalus:send(Alice, escalus_stanza:chat_to(Bob, Body1)), 1229: _M1 = escalus:wait_for_stanza(Bob), 1230: [Item1] = check_inbox(Bob, [#conv{unread = 1, from = Alice, to = Bob, content = Body1}]), 1231: TStamp1 = inbox_helper:timestamp_from_item(Item1), 1232: %% We capture the timestamp after the second message 1233: escalus:send(Alice, escalus_stanza:chat_to(Bob, Body2)), 1234: _M2 = escalus:wait_for_stanza(Bob), 1235: [Item2] = check_inbox(Bob, [#conv{unread = 2, from = Alice, to = Bob, content = Body2}]), 1236: TStamp2 = inbox_helper:timestamp_from_item(Item2), 1237: %% Timestamp after second message must be higher 1238: case TStamp2 > TStamp1 of 1239: true -> ok; 1240: false -> error(#{ type => timestamp_is_not_greater, 1241: item1 => Item1, 1242: item2 => Item2, 1243: tstamp1 => TStamp1, 1244: tstamp2 => TStamp2 }) 1245: end 1246: end). 1247: 1248: order_by_timestamp_ascending(Config) -> 1249: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1250: #{ Alice := AliceConvs, Bob := BobConvs, Kate := KateConvs } = 1251: given_conversations_between(Alice, [Bob, Kate]), 1252: 1253: %% Alice has two conversations in her inbox (no unread messages) 1254: %% check_inbox will reverse conversation list automatically 1255: check_inbox(Alice, AliceConvs, #{ order => asc }, #{}), 1256: 1257: %% Kate has one conversation with one unread 1258: check_inbox(Kate, KateConvs), 1259: 1260: %% Bob has one conversation with one unread 1261: check_inbox(Bob, BobConvs) 1262: end). 1263: 1264: get_by_timestamp_range(Config) -> 1265: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1266: #{ Alice := AliceConvs, time_before := TimeBefore } = 1267: given_conversations_between(Alice, [Bob, Kate]), 1268: 1269: ConvWithBob = lists:keyfind(Bob, #conv.to, AliceConvs), 1270: TimeAfterBob = ConvWithBob#conv.time_after, 1271: 1272: %% Between given timestamps we have only one conversation: with Bob 1273: check_inbox(Alice, [ConvWithBob], #{ start => TimeBefore, 'end' => TimeAfterBob }, #{}) 1274: end). 1275: 1276: get_with_start_timestamp(Config) -> 1277: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1278: #{ Alice := AliceConvs } = 1279: given_conversations_between(Alice, [Bob, Kate]), 1280: 1281: ConvWithBob = lists:keyfind(Bob, #conv.to, AliceConvs), 1282: TimeAfterBob = ConvWithBob#conv.time_after, 1283: ConvWithKate = lists:keyfind(Kate, #conv.to, AliceConvs), 1284: 1285: %% After given timestamp we have only one conversation: with Kate 1286: check_inbox(Alice, [ConvWithKate], #{ start => TimeAfterBob }, #{}) 1287: end). 1288: 1289: get_with_end_timestamp(Config) -> 1290: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1291: #{ Alice := AliceConvs } = 1292: given_conversations_between(Alice, [Bob, Kate]), 1293: 1294: ConvWithBob = lists:keyfind(Bob, #conv.to, AliceConvs), 1295: TimeAfterBob = ConvWithBob#conv.time_after, 1296: %% Before given timestamp we have only one conversation: with Bob 1297: %% TODO: Improve this test to store 3+ conversations in Alice's inbox 1298: check_inbox(Alice, [ConvWithBob], #{ 'end' => TimeAfterBob }, #{}) 1299: end). 1300: 1301: 1302: %% Bin flushes tests 1303: bin_is_not_included_by_default(Config) -> 1304: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1305: RoomName = create_room_and_make_users_leave(Alice, Bob, Kate), 1306: RoomJid = room_bin_jid(RoomName), 1307: BobJid = inbox_helper:to_bare_lower(Bob), 1308: Convs = [#conv{unread = 1, from = RoomJid, to = BobJid, 1309: verify = fun inbox_helper:verify_is_none_aff_change/2}], 1310: %% Fetching all does include it 1311: check_inbox(Bob, Convs, #{box => all}), 1312: %% Fetching without explicit box name skips the bin 1313: check_inbox(Bob, [], #{}) 1314: end). 1315: 1316: rest_api_bin_flush_user(Config) -> 1317: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1318: create_room_and_make_users_leave(Alice, Bob, Kate), 1319: %% It is not in his bin anymore after triggering a bin flush 1320: BobName = escalus_utils:get_username(Bob), 1321: BobDomain = escalus_utils:get_server(Bob), 1322: Path = <<"/inbox", "/", (BobDomain)/binary, "/", (BobName)/binary, "/0/bin">>, 1323: {{<<"200">>, <<"OK">>}, NumOfRows} = rest_helper:delete(admin, Path), 1324: ?assertEqual(1, NumOfRows), 1325: check_inbox(Bob, [], #{box => bin}) 1326: end). 1327: 1328: rest_api_bin_flush_all(Config) -> 1329: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1330: create_room_and_make_users_leave(Alice, Bob, Kate), 1331: %% It is not in any bin anymore after triggering a bin flush 1332: HostTypePath = uri_string:normalize(#{path => domain_helper:host_type()}), 1333: Path = <<"/inbox/", HostTypePath/binary, "/0/bin">>, 1334: {{<<"200">>, <<"OK">>}, NumOfRows} = rest_helper:delete(admin, Path), 1335: ?assertEqual(2, NumOfRows), 1336: check_inbox(Bob, [], #{box => bin}), 1337: check_inbox(Kate, [], #{box => bin}) 1338: end). 1339: 1340: timeout_cleaner_flush_all(Config) -> 1341: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1342: create_room_and_make_users_leave(Alice, Bob, Kate), 1343: %% It is eventually not in any bin thanks to the periodic cleanouts 1344: check_inbox(Bob, [], #{box => bin}), 1345: check_inbox(Kate, [], #{box => bin}) 1346: end). 1347: 1348: xmpp_bin_flush(Config) -> 1349: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}], fun(Alice, Bob, Kate) -> 1350: create_room_and_make_users_leave(Alice, Bob, Kate), 1351: %% It is eventually not in any bin thanks to the periodic cleanouts 1352: %% Bob requests flush through xmpp 1353: Iq = escalus_stanza:iq(<<"set">>, 1354: [#xmlel{name = <<"empty-bin">>, 1355: attrs = [{<<"xmlns">>, inbox_helper:inbox_ns()}], 1356: children = []}]), 1357: escalus:send(Bob, Iq), 1358: escalus:assert(is_iq_result, [Iq], escalus:wait_for_stanza(Bob)), 1359: check_inbox(Bob, [], #{box => bin}) 1360: end). 1361: 1362: 1363: %% helpers 1364: create_room_and_make_users_leave(Alice, Bob, Kate) -> 1365: RoomName = pubsub_tools:pubsub_node_name(), 1366: inbox_helper:create_room_and_check_inbox(Alice, [Bob, Kate], RoomName), 1367: %% Bob leaves the room 1368: muc_light_helper:user_leave(RoomName, Bob, [{Alice, owner}, {Kate, member}]), 1369: muc_light_helper:user_leave(RoomName, Kate, [{Alice, owner}]), 1370: %% Bob doesn't have conversation in his inbox, nor Kate 1371: check_inbox(Bob, [], #{box => inbox}), 1372: check_inbox(Kate, [], #{box => inbox}), 1373: RoomName. 1374: 1375: if_async_check_bin(Config, Bob, Convs) -> 1376: case maps:get(backend, ?config(inbox_opts, Config), rdbms) of 1377: rdbms -> ok; 1378: rdbms_async -> 1379: check_inbox(Bob, Convs, #{box => bin}) 1380: end. 1381: 1382: start_hook_listener() -> 1383: TestCasePid = self(), 1384: distributed_helper:rpc(distributed_helper:mim(), ?MODULE, rpc_start_hook_handler, [TestCasePid, domain_helper:host_type()]). 1385: 1386: stop_hook_listener(HookExtra) -> 1387: distributed_helper:rpc(distributed_helper:mim(), ?MODULE, rpc_stop_hook_handler, [HookExtra, domain_helper:host_type()]). 1388: 1389: rpc_start_hook_handler(TestCasePid, HostType) -> 1390: Extra = #{test_case_pid => TestCasePid}, 1391: gen_hook:add_handler(does_user_exist, HostType, fun ?MODULE:hook_handler_fn/3, Extra, 1), 1392: Extra. 1393: 1394: rpc_stop_hook_handler(HookExtra, HostType) -> 1395: gen_hook:delete_handler(does_user_exist, HostType, fun ?MODULE:hook_handler_fn/3, HookExtra, 1). 1396: 1397: hook_handler_fn(Acc, 1398: #{args := [_HostType, User, _Stored]} = _Params, 1399: #{test_case_pid := Pid} = _Extra) -> 1400: Pid ! {input, User#jid.user}, 1401: {ok, Acc}. 1402: 1403: verify_hook_listener(RoomName) -> 1404: receive 1405: {input, RoomName} -> 1406: ct:fail("does_user_exist was called with a room jid"); 1407: {input, _} -> 1408: verify_hook_listener(RoomName) 1409: after 100 -> 1410: ct:pal("OK") 1411: end.