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