1: %%============================================================================== 2: %% Copyright 2011 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: -module(private_SUITE). 17: -compile([export_all, nowarn_export_all]). 18: 19: -include_lib("exml/include/exml.hrl"). 20: -include_lib("escalus/include/escalus.hrl"). 21: -include_lib("common_test/include/ct.hrl"). 22: 23: -import(config_parser_helper, [mod_config_with_auto_backend/2]). 24: 25: %%-------------------------------------------------------------------- 26: %% Suite configuration 27: %%-------------------------------------------------------------------- 28: all() -> 29: [{group, private_positive}, 30: {group, private_negative}]. 31: 32: groups() -> 33: G = [{private_positive, [sequence], positive_test_cases()}, 34: {private_negative, [sequence], negative_test_cases()}], 35: ct_helper:repeat_all_until_all_ok(G). 36: %% FIXME: broken exmpp prevents us from sending 37: %% out elements without NS set missing_ns]}]. 38: 39: positive_test_cases() -> 40: [store_retrieve]. 41: 42: negative_test_cases() -> 43: [get_other_user, 44: set_other_user]. 45: 46: suite() -> 47: escalus:suite(). 48: 49: init_per_suite(Config0) -> 50: HostType = domain_helper:host_type(), 51: Config1 = dynamic_modules:save_modules(HostType, Config0), 52: dynamic_modules:ensure_modules(HostType, create_config()), 53: escalus:init_per_suite(Config1). 54: 55: create_config() -> 56: [{mod_private, 57: mod_config_with_auto_backend(mod_private, #{iqdisc => one_queue})}]. 58: 59: end_per_suite(Config) -> 60: dynamic_modules:restore_modules(Config), 61: escalus:end_per_suite(Config). 62: 63: init_per_group(_GroupName, Config) -> 64: escalus:create_users(Config, escalus:get_users([alice, bob])). 65: 66: end_per_group(_GroupName, Config) -> 67: escalus:delete_users(Config, escalus:get_users([alice, bob])). 68: 69: init_per_testcase(CaseName, Config) -> 70: escalus:init_per_testcase(CaseName, Config). 71: 72: end_per_testcase(CaseName, Config) -> 73: escalus:end_per_testcase(CaseName, Config). 74: 75: %%-------------------------------------------------------------------- 76: %% Private storage tests 77: %%-------------------------------------------------------------------- 78: store_retrieve(Config) -> 79: escalus:story(Config, [{alice, 1}], 80: fun(Alice) -> 81: NS = <<"alice:private:ns">>, 82: 83: %% Alice stores some data in her private storage 84: PrivateStanza = escalus_stanza:private_set(my_banana(NS)), 85: escalus_client:send(Alice, PrivateStanza), 86: 87: %% Alice receives store confirmation 88: escalus:assert( 89: is_iq_result, 90: [PrivateStanza], 91: escalus_client:wait_for_stanza(Alice)), 92: 93: %% Alice asks for the data 94: escalus_client:send(Alice, escalus_stanza:private_get(NS, <<"my_element">>)), 95: 96: %% Alice ensures data has not been changed 97: Stanza = escalus_client:wait_for_stanza(Alice), 98: escalus:assert(is_private_result, Stanza), 99: check_body(Stanza, [<<"my_element">>, <<"banana">>]), 100: 101: %% Alice asks for non-existing data 102: escalus_client:send(Alice, escalus_stanza:private_get(<<"non_existing_ns">>, 103: <<"my_element">>)), 104: 105: %% Alice receives an empty response 106: Stanza2 = escalus_client:wait_for_stanza(Alice), 107: escalus:assert(is_private_result, Stanza2), 108: check_body(Stanza, [<<"my_element">>]) 109: end). 110: 111: get_other_user(Config) -> 112: escalus:story(Config, [{alice, 1}, {bob, 1}], 113: fun(Alice, _Bob) -> 114: NS = <<"bob:private:ns">>, 115: 116: %% Alice asks for Bob's private data 117: GetIQ = escalus_stanza:private_get(NS, <<"my_element">>), 118: IQ = escalus_stanza:to(GetIQ, escalus_users:get_jid(Config, bob)), 119: escalus_client:send(Alice, IQ), 120: 121: %% Alice gets an error 122: Stanza = escalus_client:wait_for_stanza(Alice), 123: escalus:assert(is_private_error, Stanza), 124: escalus_pred:is_error(<<"cancel">>, forbidden, Stanza) 125: end). 126: 127: set_other_user(Config) -> 128: escalus:story(Config, [{alice, 1}, {bob, 1}], 129: fun(Alice, _Bob) -> 130: NS = <<"bob:private:ns">>, 131: 132: %% Alice asks for Bob's private data 133: IQ = escalus_stanza:to(escalus_stanza:private_set(my_banana(NS)), 134: escalus_users:get_jid(Config, bob)), 135: escalus_client:send(Alice, IQ), 136: 137: %% Alice gets a forbidden error 138: Stanza = escalus_client:wait_for_stanza(Alice), 139: escalus:assert(is_private_error, Stanza), 140: escalus_pred:is_error(<<"cancel">>, forbidden, Stanza) 141: end). 142: 143: missing_ns(Config) -> 144: escalus:story(Config, [{alice, 1}], 145: fun(Alice) -> 146: %% Alice asks for her own private storage, without 147: %% providing a namespace for a child 148: MyBanana = #xmlel{name = <<"my_element">>, 149: children = [#xmlel{name = <<"banana">>}]}, 150: IQ = escalus_stanza:private_get(MyBanana), 151: escalus_client:send(Alice, IQ), 152: 153: %% Alice gets a bad-format error 154: Stanza = escalus_client:wait_for_stanza(Alice), 155: escalus:assert(is_private_error, Stanza), 156: escalus_pred:is_error(<<"modify">>, 'bad-format', Stanza) 157: end). 158: 159: %%----------------------------------------------------------------- 160: %% Helpers 161: %%----------------------------------------------------------------- 162: 163: my_banana(NS) -> 164: #xmlel{ 165: name = <<"my_element">>, 166: attrs = [{<<"xmlns">>, NS}], 167: children = [#xmlel{name = <<"banana">>}]}. 168: 169: check_body(Stanza, Names) -> 170: Query = exml_query:subelement(Stanza, <<"query">>), 171: check_body_rec(Query, Names). 172: 173: check_body_rec(_, []) -> 174: ok; 175: check_body_rec(Element, [Name | Names]) -> 176: [Child] = Element#xmlel.children, 177: Name = Child#xmlel.name, 178: check_body_rec(Child, Names).