1# Copyright (C) 2009 Nokia Corporation
2# Copyright (C) 2009-2012 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
20import dbus
21import dbus.service
22
23from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \
24        call_async, assertEquals, assertContains
25from mctest import exec_test, create_fakecm_account, AccountManager
26import constants as cs
27
28def test(q, bus, mc):
29    account_manager = AccountManager(bus)
30
31    # Check AccountManager has D-Bus property interface
32    call_async(q, account_manager.Properties, 'GetAll', cs.AM)
33    properties, = q.expect('dbus-return', method='GetAll').value
34    assert properties is not None
35    assert properties.get('ValidAccounts') == [], \
36        properties.get('ValidAccounts')
37    assert properties.get('InvalidAccounts') == [], \
38        properties.get('InvalidAccounts')
39    interfaces = properties.get('Interfaces')
40    supported = properties.get('SupportedAccountProperties')
41
42    assert (cs.ACCOUNT + '.AutomaticPresence') in supported
43    assert (cs.ACCOUNT + '.Enabled') in supported
44    assert (cs.ACCOUNT + '.Icon') in supported
45    assert (cs.ACCOUNT + '.Nickname') in supported
46    assert (cs.ACCOUNT + '.ConnectAutomatically') in supported
47    assert (cs.ACCOUNT_IFACE_AVATAR + '.Avatar') in supported
48    assert (cs.ACCOUNT_IFACE_NOKIA_CONDITIONS + '.Condition') in supported
49
50    assert (cs.ACCOUNT + '.RequestedPresence') in supported
51    assert (cs.ACCOUNT + '.Supersedes') in supported
52    assertContains(cs.ACCOUNT + '.Service', supported)
53
54    params = dbus.Dictionary({"account": "anarki@example.com",
55        "password": "secrecy"}, signature='sv')
56
57    cm_name_ref = dbus.service.BusName(cs.tp_name_prefix +
58            '.ConnectionManager.fakecm', bus=bus)
59
60    creation_properties = dbus.Dictionary({
61        cs.ACCOUNT + '.Enabled': True,
62        cs.ACCOUNT + '.AutomaticPresence': dbus.Struct((
63            dbus.UInt32(cs.PRESENCE_TYPE_BUSY),
64            'busy', 'Exploding'), signature='uss'),
65        cs.ACCOUNT + '.RequestedPresence': dbus.Struct((
66            dbus.UInt32(cs.PRESENCE_TYPE_AWAY),
67            'away', 'Respawning'), signature='uss'),
68        cs.ACCOUNT + '.Icon': 'quake3arena',
69        cs.ACCOUNT + '.Nickname': 'AnArKi',
70        cs.ACCOUNT + '.ConnectAutomatically': True,
71        cs.ACCOUNT_IFACE_AVATAR + '.Avatar': (dbus.ByteArray(b'foo'),
72            'image/jpeg'),
73        cs.ACCOUNT_IFACE_NOKIA_CONDITIONS + '.Condition':
74            dbus.Dictionary({ 'has-quad-damage': ':y' }, signature='ss'),
75        cs.ACCOUNT + '.Supersedes': dbus.Array([
76            cs.ACCOUNT_PATH_PREFIX + 'q1/q1/Ranger',
77            cs.ACCOUNT_PATH_PREFIX + 'q2/q2/Grunt',
78            ], signature='o'),
79        cs.ACCOUNT + '.Service': 'arena',
80        }, signature='sv')
81
82    call_async(q, account_manager, 'CreateAccount',
83            'fakecm',
84            'fakeprotocol',
85            'fakeaccount',
86            params,
87            creation_properties)
88
89    # The spec has no order guarantee here.
90    # FIXME: MC ought to also introspect the CM and find out that the params
91    # are in fact sufficient
92
93    am_signal, ret, rc = q.expect_many(
94            EventPattern('dbus-signal', path=cs.AM_PATH,
95                signal='AccountValidityChanged', interface=cs.AM),
96            EventPattern('dbus-return', method='CreateAccount'),
97            EventPattern('dbus-method-call', method='RequestConnection'),
98            )
99    account_path = ret.value[0]
100    assert am_signal.args == [account_path, True], am_signal.args
101
102    assert account_path is not None
103
104    account = bus.get_object(
105        cs.tp_name_prefix + '.AccountManager',
106        account_path)
107    account_props = dbus.Interface(account, cs.PROPERTIES_IFACE)
108
109    properties = account_props.GetAll(cs.ACCOUNT)
110    assert properties.get('AutomaticPresence') == (cs.PRESENCE_TYPE_BUSY,
111            'busy', 'Exploding'), \
112        properties.get('AutomaticPresence')
113    assert properties.get('RequestedPresence') == (cs.PRESENCE_TYPE_AWAY,
114            'away', 'Respawning'), \
115        properties.get('RequestedPresence')
116    assert properties.get('ConnectAutomatically') == True, \
117        properties.get('ConnectAutomatically')
118    assert properties.get('Enabled') == True, \
119        properties.get('Enabled')
120    assert properties.get('Valid') == True, \
121        properties.get('Valid')
122    assert properties.get('Icon') == 'quake3arena', \
123        properties.get('Icon')
124    assert properties.get('Nickname') == 'AnArKi', \
125        properties.get('Nickname')
126    assertEquals(
127            dbus.Array([
128                cs.ACCOUNT_PATH_PREFIX + 'q1/q1/Ranger',
129                cs.ACCOUNT_PATH_PREFIX + 'q2/q2/Grunt',
130                ], signature='o'),
131        properties.get('Supersedes'))
132    assertEquals('arena', properties.get('Service'))
133
134    properties = account_props.GetAll(cs.ACCOUNT_IFACE_AVATAR)
135    assert properties.get('Avatar') == ([ord('f'), ord('o'), ord('o')],
136            'image/jpeg')
137
138    properties = account_props.GetAll(cs.ACCOUNT_IFACE_NOKIA_CONDITIONS)
139    assert properties.get('Condition') == {
140            'has-quad-damage': ':y',
141            }
142
143    # tests for errors when creating an account
144
145    creation_properties2 = creation_properties.copy()
146    creation_properties2[cs.ACCOUNT + '.NonExistent'] = 'foo'
147    call_async(q, account_manager, 'CreateAccount',
148            'fakecm',
149            'fakeprotocol',
150            'fakeaccount',
151            params,
152            creation_properties2)
153    q.expect('dbus-error', method='CreateAccount')
154
155    params2 = params.copy()
156    params2['fake_param'] = 'foo'
157    call_async(q, account_manager, 'CreateAccount',
158            'fakecm',
159            'fakeprotocol',
160            'fakeaccount',
161            params2,
162            creation_properties)
163    q.expect('dbus-error', method='CreateAccount')
164
165if __name__ == '__main__':
166    exec_test(test, {})
167