1# Copyright (C) 2009 Nokia Corporation 2# Copyright (C) 2009 Collabora Ltd. 3# 4# This library is free software; you can redistribute it and/or 5# modify it under the terms of the GNU Lesser General Public 6# License as published by the Free Software Foundation; either 7# version 2.1 of the License, or (at your option) any later version. 8# 9# This library is distributed in the hope that it will be useful, but 10# WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12# Lesser General Public License for more details. 13# 14# You should have received a copy of the GNU Lesser General Public 15# License along with this library; if not, write to the Free Software 16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17# 02110-1301 USA 18 19import dbus 20"""Feature test for accounts becoming valid. 21""" 22 23import os 24 25import dbus 26import dbus.service 27 28from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ 29 call_async, sync_dbus 30from mctest import exec_test, SimulatedConnection, create_fakecm_account, MC 31import constants as cs 32 33cm_name_ref = dbus.service.BusName( 34 cs.tp_name_prefix + '.ConnectionManager.fakecm', bus=dbus.SessionBus()) 35 36account1_id = 'fakecm/fakeprotocol/jc_2edenton_40unatco_2eint' 37account2_id = 'fakecm/fakeprotocol/jc_2edenton_40example_2ecom' 38 39def preseed(q, bus, fake_accounts_service): 40 41 accounts_dir = os.environ['MC_ACCOUNT_DIR'] 42 43 try: 44 os.mkdir(accounts_dir, 0o700) 45 except OSError: 46 pass 47 48 fake_accounts_service.update_attributes(account1_id, changed={ 49 'manager': 'fakecm', 50 'protocol': 'fakeprotocol', 51 'DisplayName': 'Work account', 52 'NormalizedName': 'jc.denton@unatco.int', 53 'Enabled': True, 54 'ConnectAutomatically': True, 55 'AutomaticPresenceType': dbus.UInt32(2), 56 'AutomaticPresenceStatus': 'available', 57 'AutomaticPresenceMessage': 'My vision is augmented', 58 'Nickname': 'JC', 59 'AvatarMime': 'image/jpeg', 60 }) 61 fake_accounts_service.update_attributes(account2_id, changed={ 62 'manager': 'fakecm', 63 'protocol': 'fakeprotocol', 64 'DisplayName': 'Personal account', 65 'NormalizedName': 'jc.denton@example.com', 66 'Enabled': True, 67 'ConnectAutomatically': False, 68 'AutomaticPresenceType': dbus.UInt32(2), 69 'AutomaticPresenceStatus': 'available', 70 'AutomaticPresenceMessage': 'My vision is augmented', 71 'Nickname': 'JC', 72 'AvatarMime': 'image/jpeg', 73 }) 74 75 # The passwords are missing, so the accounts can't connect yet. 76 fake_accounts_service.update_parameters(account1_id, changed={ 77 'account': 'jc.denton@unatco.int', 78 }) 79 fake_accounts_service.update_parameters(account2_id, changed={ 80 'account': 'jc.denton@example.com', 81 }) 82 83 os.makedirs(accounts_dir + '/' + account1_id) 84 avatar_bin = open(accounts_dir + '/' + account1_id + '/avatar.bin', 'w') 85 avatar_bin.write('Deus Ex') 86 avatar_bin.close() 87 88 os.makedirs(accounts_dir + '/' + account2_id) 89 avatar_bin = open(accounts_dir + '/' + account2_id + '/avatar.bin', 'w') 90 avatar_bin.write('Invisible War') 91 avatar_bin.close() 92 93 account_connections_file = open(accounts_dir + '/.mc_connections', 'w') 94 account_connections_file.write("") 95 account_connections_file.close() 96 97def test(q, bus, unused, **kwargs): 98 99 # make sure RequestConnection doesn't get called yet 100 events = [EventPattern('dbus-method-call', method='RequestConnection')] 101 q.forbid_events(events) 102 103 fake_accounts_service = kwargs['fake_accounts_service'] 104 preseed(q, bus, fake_accounts_service) 105 106 # Wait for MC to load 107 mc = MC(q, bus) 108 109 # Trying to make a channel on account 1 doesn't work, because it's 110 # not valid 111 112 account_path = (cs.tp_path_prefix + '/Account/' + account1_id) 113 114 cd = bus.get_object(cs.CD, cs.CD_PATH) 115 116 user_action_time = dbus.Int64(1238582606) 117 request = dbus.Dictionary({ 118 cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, 119 cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, 120 cs.CHANNEL + '.TargetID': 'juliet', 121 }, signature='sv') 122 call_async(q, cd, 'CreateChannel', 123 account_path, request, user_action_time, "", 124 dbus_interface=cs.CD) 125 ret = q.expect('dbus-return', method='CreateChannel') 126 request_path = ret.value[0] 127 128 cr = bus.get_object(cs.CD, request_path) 129 request_props = cr.GetAll(cs.CR, dbus_interface=cs.PROPERTIES_IFACE) 130 assert request_props['Account'] == account_path 131 assert request_props['Requests'] == [request] 132 assert request_props['UserActionTime'] == user_action_time 133 assert request_props['PreferredHandler'] == "" 134 assert request_props['Interfaces'] == [] 135 136 sync_dbus(bus, q, mc) 137 138 cr.Proceed(dbus_interface=cs.CR) 139 140 # FIXME: error isn't specified (NotAvailable perhaps?) 141 q.expect('dbus-signal', path=cr.object_path, 142 interface=cs.CR, signal='Failed') 143 144 # Make account 1 valid: it should connect automatically 145 146 account_path = (cs.tp_path_prefix + '/Account/' + account1_id) 147 account = bus.get_object(cs.MC, account_path) 148 149 sync_dbus(bus, q, mc) 150 q.unforbid_events(events) 151 152 call_async(q, account, 'UpdateParameters', {'password': 'nanotech'}, [], 153 dbus_interface=cs.ACCOUNT) 154 155 expected_params = {'password': 'nanotech', 156 'account': 'jc.denton@unatco.int'} 157 158 e = q.expect('dbus-method-call', method='RequestConnection', 159 args=['fakeprotocol', expected_params], 160 destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', 161 path=cs.tp_path_prefix + '/ConnectionManager/fakecm', 162 interface=cs.tp_name_prefix + '.ConnectionManager', 163 handled=False) 164 165 conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', 'account1', 166 'myself', has_presence=True) 167 168 q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') 169 170 q.expect('dbus-method-call', method='Connect', 171 path=conn.object_path, handled=True, interface=cs.CONN) 172 conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) 173 174 set_presence, e = q.expect_many( 175 EventPattern('dbus-method-call', path=conn.object_path, 176 interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', 177 handled=True), 178 EventPattern('dbus-signal', signal='AccountPropertyChanged', 179 path=account_path, interface=cs.ACCOUNT, 180 predicate=lambda e: 'CurrentPresence' in e.args[0] 181 and e.args[0]['CurrentPresence'][2] != ''), 182 ) 183 184 assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_AVAILABLE, 185 'available', 'My vision is augmented') 186 187 # Request an online presence on account 2, then make it valid 188 189 q.forbid_events(events) 190 191 account_path = (cs.tp_path_prefix + '/Account/' + account2_id) 192 account = bus.get_object(cs.MC, account_path) 193 194 requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 195 'busy', 'Talking to Illuminati')) 196 account.Set(cs.ACCOUNT, 'RequestedPresence', 197 dbus.Struct(requested_presence, variant_level=1), 198 dbus_interface=cs.PROPERTIES_IFACE) 199 200 sync_dbus(bus, q, mc) 201 q.unforbid_events(events) 202 203 # Make the account valid 204 call_async(q, account, 'UpdateParameters', {'password': 'nanotech'}, [], 205 dbus_interface=cs.ACCOUNT) 206 207 expected_params = {'password': 'nanotech', 208 'account': 'jc.denton@example.com'} 209 210 e = q.expect('dbus-method-call', method='RequestConnection', 211 args=['fakeprotocol', expected_params], 212 destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', 213 path=cs.tp_path_prefix + '/ConnectionManager/fakecm', 214 interface=cs.tp_name_prefix + '.ConnectionManager', 215 handled=False) 216 217 conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', 'account2', 218 'myself', has_presence=True) 219 220 q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') 221 222 q.expect('dbus-method-call', method='Connect', 223 path=conn.object_path, handled=True, interface=cs.CONN) 224 conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) 225 226 set_presence = q.expect('dbus-method-call', path=conn.object_path, 227 interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', 228 handled=True) 229 230 e = q.expect('dbus-signal', signal='AccountPropertyChanged', 231 path=account_path, interface=cs.ACCOUNT, 232 predicate=lambda e: 'CurrentPresence' in e.args[0] 233 and e.args[0]['CurrentPresence'][1] == 'busy') 234 235 assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_BUSY, 236 'busy', 'Talking to Illuminati') 237 238if __name__ == '__main__': 239 exec_test(test, {}, preload_mc=False, use_fake_accounts_service=True, 240 pass_kwargs=True) 241