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_riak(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(riak) -> 56: [{mod_private, #{backend => riak, 57: iqdisc => one_queue, 58: riak => #{bucket_type => <<"private">>}}}]; 59: create_config(Backend) -> 60: [{mod_private, #{backend => Backend, iqdisc => one_queue}}]. 61: 62: end_per_suite(Config) -> 63: dynamic_modules:restore_modules(Config), 64: escalus:end_per_suite(Config). 65: 66: init_per_group(_GroupName, Config) -> 67: escalus:create_users(Config, escalus:get_users([alice, bob])). 68: 69: end_per_group(_GroupName, Config) -> 70: escalus:delete_users(Config, escalus:get_users([alice, bob])). 71: 72: init_per_testcase(CaseName, Config) -> 73: escalus:init_per_testcase(CaseName, Config). 74: 75: end_per_testcase(CaseName, Config) -> 76: escalus:end_per_testcase(CaseName, Config). 77: 78: %%-------------------------------------------------------------------- 79: %% Private storage tests 80: %%-------------------------------------------------------------------- 81: store_retrieve(Config) -> 82: escalus:story(Config, [{alice, 1}], 83: fun(Alice) -> 84: NS = <<"alice:private:ns">>, 85: 86: %% Alice stores some data in her private storage 87: PrivateStanza = escalus_stanza:private_set(my_banana(NS)), 88: escalus_client:send(Alice, PrivateStanza), 89: 90: %% Alice receives store confirmation 91: escalus:assert( 92: is_iq_result, 93: [PrivateStanza], 94: escalus_client:wait_for_stanza(Alice)), 95: 96: %% Alice asks for the data 97: escalus_client:send(Alice, escalus_stanza:private_get(NS, <<"my_element">>)), 98: 99: %% Alice ensures data has not been changed 100: Stanza = escalus_client:wait_for_stanza(Alice), 101: escalus:assert(is_private_result, Stanza), 102: check_body(Stanza, [<<"my_element">>, <<"banana">>]), 103: 104: %% Alice asks for non-existing data 105: escalus_client:send(Alice, escalus_stanza:private_get(<<"non_existing_ns">>, 106: <<"my_element">>)), 107: 108: %% Alice receives an empty response 109: Stanza2 = escalus_client:wait_for_stanza(Alice), 110: escalus:assert(is_private_result, Stanza2), 111: check_body(Stanza, [<<"my_element">>]) 112: end). 113: 114: get_other_user(Config) -> 115: escalus:story(Config, [{alice, 1}, {bob, 1}], 116: fun(Alice, _Bob) -> 117: NS = <<"bob:private:ns">>, 118: 119: %% Alice asks for Bob's private data 120: GetIQ = escalus_stanza:private_get(NS, <<"my_element">>), 121: IQ = escalus_stanza:to(GetIQ, escalus_users:get_jid(Config, bob)), 122: escalus_client:send(Alice, IQ), 123: 124: %% Alice gets an error 125: Stanza = escalus_client:wait_for_stanza(Alice), 126: escalus:assert(is_private_error, Stanza), 127: escalus_pred:is_error(<<"cancel">>, forbidden, Stanza) 128: end). 129: 130: set_other_user(Config) -> 131: escalus:story(Config, [{alice, 1}, {bob, 1}], 132: fun(Alice, _Bob) -> 133: NS = <<"bob:private:ns">>, 134: 135: %% Alice asks for Bob's private data 136: IQ = escalus_stanza:to(escalus_stanza:private_set(my_banana(NS)), 137: escalus_users:get_jid(Config, bob)), 138: escalus_client:send(Alice, IQ), 139: 140: %% Alice gets a forbidden error 141: Stanza = escalus_client:wait_for_stanza(Alice), 142: escalus:assert(is_private_error, Stanza), 143: escalus_pred:is_error(<<"cancel">>, forbidden, Stanza) 144: end). 145: 146: missing_ns(Config) -> 147: escalus:story(Config, [{alice, 1}], 148: fun(Alice) -> 149: %% Alice asks for her own private storage, without 150: %% providing a namespace for a child 151: MyBanana = #xmlel{name = <<"my_element">>, 152: children = [#xmlel{name = <<"banana">>}]}, 153: IQ = escalus_stanza:private_get(MyBanana), 154: escalus_client:send(Alice, IQ), 155: 156: %% Alice gets a bad-format error 157: Stanza = escalus_client:wait_for_stanza(Alice), 158: escalus:assert(is_private_error, Stanza), 159: escalus_pred:is_error(<<"modify">>, 'bad-format', Stanza) 160: end). 161: 162: %%----------------------------------------------------------------- 163: %% Helpers 164: %%----------------------------------------------------------------- 165: 166: my_banana(NS) -> 167: #xmlel{ 168: name = <<"my_element">>, 169: attrs = [{<<"xmlns">>, NS}], 170: children = [#xmlel{name = <<"banana">>}]}. 171: 172: check_body(Stanza, Names) -> 173: Query = exml_query:subelement(Stanza, <<"query">>), 174: check_body_rec(Query, Names). 175: 176: check_body_rec(_, []) -> 177: ok; 178: check_body_rec(Element, [Name | Names]) -> 179: [Child] = Element#xmlel.children, 180: Name = Child#xmlel.name, 181: check_body_rec(Child, Names). 182: 183: required_modules(Backend) -> 184: [{mod_private, [{backend, Backend}]}].