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