1: %%============================================================================== 2: %% Copyright 2012 Erlang Solutions Ltd. 3: %% 4: %% Licensed under the Apache License, Version 2.0 (the "License"); 5: %% you may not use this file except in compliance with the License. 6: %% You may obtain a copy of the License at 7: %% 8: %% http://www.apache.org/licenses/LICENSE-2.0 9: %% 10: %% Unless required by applicable law or agreed to in writing, software 11: %% distributed under the License is distributed on an "AS IS" BASIS, 12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13: %% See the License for the specific language governing permissions and 14: %% limitations under the License. 15: %%============================================================================== 16: 17: -module(websockets_SUITE). 18: -compile([export_all, nowarn_export_all]). 19: 20: -include_lib("escalus/include/escalus.hrl"). 21: -include_lib("common_test/include/ct.hrl"). 22: 23: -import(distributed_helper, [mim/0]). 24: 25: %%-------------------------------------------------------------------- 26: %% Suite configuration 27: %%-------------------------------------------------------------------- 28: 29: -define(REGISTRATION_TIMEOUT, 2). %% seconds 30: -define(MAX_STANZA_SIZE, 200). 31: 32: all() -> 33: [metrics_test, 34: {group, ws_chat}, 35: {group, wss_chat}]. 36: 37: groups() -> 38: [{ws_chat, [sequence], test_cases()}, 39: {wss_chat, [sequence], test_cases()}]. 40: 41: test_cases() -> 42: [chat_msg, 43: escape_chat_msg, 44: escape_attrs, 45: too_big_stanza_is_rejected]. 46: 47: suite() -> 48: escalus:suite(). 49: 50: %%-------------------------------------------------------------------- 51: %% Init & teardown 52: %%-------------------------------------------------------------------- 53: 54: init_per_suite(Config) -> 55: Config1 = escalus:init_per_suite(Config), 56: Config2 = setup_listeners(Config1), 57: escalus:create_users(Config2, escalus:get_users([alice, geralt, geralt_s, carol])). 58: 59: end_per_suite(Config) -> 60: Listeners = ?config(original_listeners, Config), 61: [mongoose_helper:restart_listener(mim(), Listener) || Listener <- Listeners], 62: Config1 = escalus:delete_users(Config, escalus:get_users([alice, geralt, geralt_s, carol])), 63: escalus:end_per_suite(Config1). 64: 65: init_per_group(GroupName, Config) -> 66: case GroupName of 67: wss_chat -> 68: [{user, geralt_s} | Config]; 69: _ -> 70: [{user, geralt} | Config] 71: end. 72: 73: end_per_group(_GroupName, _Config) -> 74: ok. 75: 76: init_per_testcase(CaseName, Config) -> 77: escalus:init_per_testcase(CaseName, Config). 78: 79: end_per_testcase(CaseName, Config) -> 80: escalus:end_per_testcase(CaseName, Config). 81: 82: setup_listeners(Config) -> 83: Listeners = mongoose_helper:get_listeners(mim(), #{module => ejabberd_cowboy}), 84: [mongoose_helper:restart_listener(mim(), update_listener(Listener)) || Listener <- Listeners], 85: [{original_listeners, Listeners} | Config]. 86: 87: update_listener(Listener = #{handlers := Handlers}) -> 88: Listener#{handlers := lists:map(fun update_handler/1, Handlers)}. 89: 90: update_handler(Handler = #{module := mod_websockets}) -> 91: Handler#{max_stanza_size := ?MAX_STANZA_SIZE}; 92: update_handler(Handler) -> 93: Handler. 94: 95: %%-------------------------------------------------------------------- 96: %% Message tests 97: %%-------------------------------------------------------------------- 98: 99: metrics_test(Config) -> 100: MongooseMetrics = [{[global, data, xmpp, received, xml_stanza_size], changed}, 101: {[global, data, xmpp, sent, xml_stanza_size], changed}, 102: {[global, data, xmpp, received, c2s, websocket], changed}, 103: {[global, data, xmpp, sent, c2s, websocket], changed}, 104: {[global, data, xmpp, received, c2s, tcp], 0}, 105: {[global, data, xmpp, sent, c2s, tcp], 0}], 106: escalus:story([{mongoose_metrics, MongooseMetrics} | Config], 107: [{geralt, 1}, {geralt_s, 1}], 108: fun(Geralt, GeraltS) -> 109: 110: escalus_client:send(GeraltS, escalus_stanza:chat_to(Geralt, <<"Hi!">>)), 111: escalus:assert(is_chat_message, [<<"Hi!">>], escalus_client:wait_for_stanza(Geralt)), 112: 113: escalus_client:send(Geralt, escalus_stanza:chat_to(GeraltS, <<"Hello!">>)), 114: escalus:assert(is_chat_message, [<<"Hello!">>], escalus_client:wait_for_stanza(GeraltS)) 115: 116: end). 117: 118: too_big_stanza_is_rejected(Config) -> 119: escalus:story( 120: Config, [{alice, 1}, {?config(user, Config), 1}], 121: fun(Alice, Geralt) -> 122: BigBody = base16:encode(crypto:strong_rand_bytes(?MAX_STANZA_SIZE)), 123: escalus_client:send(Geralt, escalus_stanza:chat_to(Alice, BigBody)), 124: escalus:assert(is_stream_error, [<<"policy-violation">>, <<>>], escalus_client:wait_for_stanza(Geralt)), 125: escalus:assert(is_stream_end, escalus_client:wait_for_stanza(Geralt)), 126: true = escalus_connection:wait_for_close(Geralt, timer:seconds(1)), 127: escalus_assert:has_no_stanzas(Alice) 128: end). 129: 130: chat_msg(Config) -> 131: escalus:story(Config, [{alice, 1}, {?config(user, Config), 1}, {carol, 1}], 132: fun(Alice, Geralt, Carol) -> 133: 134: escalus_client:send(Alice, escalus_stanza:chat_to(Geralt, <<"Hi!">>)), 135: FromAlice = escalus_client:wait_for_stanza(Geralt), 136: escalus:assert(is_chat_message, [<<"Hi!">>], FromAlice), 137: escalus:assert(has_ns, [<<"jabber:client">>], FromAlice), 138: 139: escalus_client:send(Geralt, escalus_stanza:chat_to(Alice, <<"Hello!">>)), 140: escalus:assert(is_chat_message, [<<"Hello!">>], escalus_client:wait_for_stanza(Alice)), 141: 142: escalus_client:send(Geralt, escalus_stanza:chat_to(Carol, <<"Hey!">>)), 143: escalus_assert:is_chat_message(<<"Hey!">>, escalus_client:wait_for_stanza(Carol)) 144: 145: end). 146: 147: escape_chat_msg(Config) -> 148: escalus:story(Config, [{alice, 1}, {?config(user, Config), 1}, {carol, 1}], 149: fun(Alice, Geralt, Carol) -> 150: special_chars_helper:check_cdata_from_to(Alice, Geralt, <<"Hi! & < >">>), 151: special_chars_helper:check_cdata_from_to(Geralt, Alice, <<"Hello! & < >">>), 152: special_chars_helper:check_cdata_from_to(Geralt, Carol, <<"Hey! & < >">>) 153: 154: end). 155: 156: escape_attrs(Config) -> 157: escalus:story(Config, [{alice, 1}, {?config(user, Config), 1}, {carol, 1}], 158: fun(Alice, Geralt, Carol) -> 159: special_chars_helper:check_attr_from_to(Alice, Geralt), 160: special_chars_helper:check_attr_from_to(Geralt, Alice), 161: special_chars_helper:check_attr_from_to(Geralt, Carol) 162: 163: end).