Merge lp:~canonical-platform-qa/uoa-integration-tests/python-testability into lp:uoa-integration-tests

Proposed by Leo Arias
Status: Merged
Merged at revision: 15
Proposed branch: lp:~canonical-platform-qa/uoa-integration-tests/python-testability
Merge into: lp:uoa-integration-tests
Diff against target: 365 lines (+346/-0)
3 files modified
python/uoa_integration_tests/evernote.py (+41/-0)
python/uoa_integration_tests/onlineaccounts.py (+233/-0)
python/uoa_integration_tests/tests/test_evernote_online_accounts.py (+72/-0)
To merge this branch: bzr merge lp:~canonical-platform-qa/uoa-integration-tests/python-testability
Reviewer Review Type Date Requested Status
Online Accounts Pending
Review via email: mp+241815@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'python'
=== added directory 'python/uoa_integration_tests'
=== added file 'python/uoa_integration_tests/__init__.py'
=== added file 'python/uoa_integration_tests/evernote.py'
--- python/uoa_integration_tests/evernote.py 1970-01-01 00:00:00 +0000
+++ python/uoa_integration_tests/evernote.py 2014-11-14 14:59:44 +0000
@@ -0,0 +1,41 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright (C) 2014 Canonical Ltd.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import logging
18
19from uoa_integration_tests import onlineaccounts
20
21
22logger = logging.getLogger(__name__)
23
24
25class EvernoteOnlineAccounts():
26
27 @classmethod
28 def add_evernote_sandbox_account_with_oauth_token(
29 cls, user_name, password, oauth_token):
30 """Add an Evernote Sandbox account .
31
32 :param user_name: The user name of the account.
33 :param password: The password of the account.
34 :param oauth_token: The oauth token of the account.
35
36 """
37 accounts_manager = onlineaccounts.AccountsManager()
38 provider_id = 'com.ubuntu.reminders_evernote-account-plugin-sandbox'
39 service_id = 'com.ubuntu.reminders_reminders-sandbox'
40 return accounts_manager.add_account_with_oauth_token(
41 provider_id, service_id, user_name, password, oauth_token)
042
=== added file 'python/uoa_integration_tests/onlineaccounts.py'
--- python/uoa_integration_tests/onlineaccounts.py 1970-01-01 00:00:00 +0000
+++ python/uoa_integration_tests/onlineaccounts.py 2014-11-14 14:59:44 +0000
@@ -0,0 +1,233 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright (C) 2014 Canonical Ltd.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import logging
18import time
19import threading
20
21from gi.repository import Accounts, GLib, Signon
22
23
24logger = logging.getLogger(__name__)
25
26
27class CredentialsException(Exception):
28
29 """Exception for credentials problems."""
30
31
32class AccountsManager(object):
33
34 """Manager for online accounts."""
35
36 def __init__(self):
37 self._manager = Accounts.Manager.new()
38
39 def _start_main_loop(self):
40 self.error = None
41 self._main_loop = GLib.MainLoop()
42 self._main_loop_thread = threading.Thread(
43 target=self._main_loop.run)
44 self._main_loop_thread.start()
45
46 def _join_main_loop(self):
47 self._main_loop_thread.join()
48 if self.error is not None:
49 raise CredentialsException(self.error)
50
51 def add_account_with_oauth_token(
52 self, provider_id, service_id, user_name, password, oauth_token):
53 """Add an account with an oauth token.
54
55 :param provider_id: The identifier of the account provider.
56 :param servide_id: The identifier of the service that will use the
57 account.
58 :param user_name: The user name of the account.
59 :param password: The password of the account.
60 :param oauth_token: The oauth token of the account.
61
62 """
63 logger.info('Add an account for provider {} and service {}.'.format(
64 provider_id, service_id))
65 logger.info('user name: {}, password: {}, oauth_token: {}.'.format(
66 user_name, password, oauth_token))
67 self._start_main_loop()
68
69 account = self._create_account(provider_id)
70 logger.debug('account %s' % account.get_settings_dict())
71
72 if not account.get_settings_dict():
73 self._delete_account_on_error(account)
74 self._quit_main_loop_on_error('account is blank', 'add account')
75
76 info = self._get_identity_info(user_name, password)
77
78 identity = Signon.Identity.new()
79 identity.store_credentials_with_info(
80 info, self._set_credentials_id_to_account,
81 {'account': account, 'oauth_token': oauth_token})
82 logger.debug('identity %s' % identity.list_properties())
83
84 logger.debug('Joining loop')
85
86 self._join_main_loop()
87
88 # XXX Sometimes, the account fails to be enabled. This sleep seems to
89 # fix it but we haven't yet found the reason. --elopio - 2014-06-25
90 time.sleep(10)
91 self._enable_service(account, service_id)
92
93 logger.info('Created the account with id: {}.'.format(account.id))
94 self._log_accounts_info()
95 return account
96
97 def _create_account(self, provider_id):
98 logger.debug('Creating the Evernote account.')
99 account = self._manager.create_account(provider_id)
100 account.set_enabled(True)
101 account.store(self._on_account_created, None)
102 return account
103
104 def _on_account_created(self, account, error, _):
105 if error:
106 self._quit_main_loop_on_error(error, 'storing account')
107
108 def _delete_account_on_error(self, account):
109 # attempt to clean up after ourselves, since normal
110 # addCleanups will not run in this case
111 try:
112 logger.debug('Cleaning up account %s' % account.id)
113 account.delete()
114 account.store(self._on_account_deleted, None)
115 except:
116 logger.warn('Failed to cleanup account')
117
118 def _quit_main_loop_on_error(self, error, step):
119 logger.error('Error {}.'.format(step))
120 self.error = error
121 self._main_loop.quit()
122 raise CredentialsException(error)
123
124 def _get_identity_info(self, user_name, password):
125 info = Signon.IdentityInfo.new()
126 info.set_username(user_name)
127 info.set_caption(user_name)
128 info.set_secret(password, True)
129 return info
130
131 def _set_credentials_id_to_account(
132 self, identity, id_, error, account_dict):
133 if error:
134 self._quit_main_loop_on_error(
135 error, 'storing credentials with info')
136
137 logger.debug('Setting credentials to account.')
138 account = account_dict.get('account')
139 oauth_token = account_dict.get('oauth_token')
140 account.set_variant('CredentialsId', GLib.Variant('u', id_))
141 account.store(self._process_session, oauth_token)
142 logger.debug('Account stored')
143
144 def _process_session(self, account, error, oauth_token):
145 if error:
146 self._quit_main_loop_on_error(
147 error, 'setting credentials id to account')
148
149 logger.debug('Processing session.')
150 account_service = Accounts.AccountService.new(account, None)
151 logger.debug('account_service %s' % account_service.list_properties())
152 auth_data = account_service.get_auth_data()
153 logger.debug('auth_data %s' % auth_data.get_parameters())
154 identity = auth_data.get_credentials_id()
155 method = auth_data.get_method()
156 if method is None:
157 self._delete_account_on_error(account)
158 self._quit_main_loop_on_error('Method is none',
159 'processing auth data')
160 mechanism = auth_data.get_mechanism()
161 session_data = auth_data.get_parameters()
162 session_data['ProvidedTokens'] = GLib.Variant('a{sv}', {
163 'TokenSecret': GLib.Variant('s', 'dummy'),
164 'AccessToken': GLib.Variant('s', oauth_token),
165 })
166 logger.debug('session_data %s' % session_data)
167 logger.debug('Authenticating session %s, %s' % (identity, method))
168 session = Signon.AuthSession.new(identity, method)
169 logger.debug('Send session %s' % session)
170 session.process(
171 session_data, mechanism, self._on_login_processed, None)
172 logger.debug('Session processed')
173
174 def _on_login_processed(self, session, reply, error, userdata):
175 if error:
176 self._quit_main_loop_on_error(error, 'processing session')
177
178 else:
179 self._main_loop.quit()
180
181 def _enable_service(self, account, service_id):
182 logger.debug('Enabling evernote service.')
183 service = self._manager.get_service(service_id)
184 account.select_service(service)
185 account.set_enabled(True)
186 account.store(self._on_service_enabled, None)
187
188 def _on_service_enabled(self, account, error, _):
189 if error:
190 self._quit_main_loop_on_error(error, 'enabling service')
191
192 def _log_accounts_info(self):
193 account_ids = self._manager.list()
194 logger.debug('Existing accounts: {}.'.format(account_ids))
195 for id_ in account_ids:
196 account = self._manager.get_account(id_)
197 self._log_account_info(account)
198
199 def _log_account_info(self, account):
200 logger.debug('Account info:')
201 logger.debug('id: {}'.format(account.id))
202 logger.debug('provider: {}'.format(account.get_provider_name()))
203 logger.debug('enabled: {}'.format(account.get_enabled()))
204 logger.debug('Account services:')
205 for service in account.list_services():
206 logger.debug('name: {}'.format(service.get_name()))
207 account_service = Accounts.AccountService.new(account, service)
208 logger.debug('enabled: {}'.format(account_service.get_enabled()))
209
210 def get_accounts_list(self):
211 return self._manager.list()
212
213 def delete_account(self, account):
214 """Delete an account.
215
216 :param account: The account to delete.
217
218 """
219 logger.info('Deleting the account with id {}.'.format(account.id))
220 self._start_main_loop()
221 # XXX There seems to be a problem when we try to delete the account too
222 # soon after starting the main loop.
223 # Reported as bug http://pad.lv/1363604. --elopio - 2014-09-01
224 time.sleep(10)
225 account.delete()
226 account.store(self._on_account_deleted, None)
227 self._join_main_loop()
228
229 def _on_account_deleted(self, account, error, _):
230 if error:
231 self._quit_main_loop_on_error(error, 'deleting account')
232 else:
233 self._main_loop.quit()
0234
=== added directory 'python/uoa_integration_tests/tests'
=== added file 'python/uoa_integration_tests/tests/__init__.py'
=== added file 'python/uoa_integration_tests/tests/test_evernote_online_accounts.py'
--- python/uoa_integration_tests/tests/test_evernote_online_accounts.py 1970-01-01 00:00:00 +0000
+++ python/uoa_integration_tests/tests/test_evernote_online_accounts.py 2014-11-14 14:59:44 +0000
@@ -0,0 +1,72 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright (C) 2014 Canonical Ltd
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 3 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import logging
18
19import testtools
20from gi.repository import Accounts
21from testtools.matchers import HasLength
22
23from uoa_integration_tests import onlineaccounts, evernote
24
25
26logger = logging.getLogger(__name__)
27
28
29class EvernoteCredentialsTestCase(testtools.TestCase):
30
31 def setUp(self):
32 super(EvernoteCredentialsTestCase, self).setUp()
33 self.accounts_manager = onlineaccounts.AccountsManager()
34
35 def add_evernote_sandbox_account(self):
36 accounts = evernote.EvernoteOnlineAccounts
37 add_account = accounts.add_evernote_sandbox_account_with_oauth_token
38 account = add_account('dummy', 'dummy', 'dummy')
39 self.addCleanup(self.delete_account, account)
40 return account
41
42 def delete_account(self, account):
43 if account.id in self.account_manager.get_accounts_list():
44 self.accounts_manager.delete_account(account)
45
46 def test_add_evernote_sandbox_account_must_enable_it(self):
47 account = self.add_evernote_sandbox_account()
48
49 self.assertTrue(account.get_enabled())
50
51 def test_add_evernote_sandbox_account_must_set_provider(self):
52 account = self.add_evernote_sandbox_account()
53
54 provider_id = 'com.ubuntu.reminders_evernote-account-plugin-sandbox'
55 self.assertEqual(account.get_provider_name(), provider_id)
56
57 def test_add_evernote_sandbox_account_must_enable_evernote_service(self):
58 account = self.add_evernote_sandbox_account()
59 services = account.list_services()
60
61 self.assertThat(services, HasLength(1))
62 service_id = 'com.ubuntu.reminders_reminders-sandbox'
63 self.assertEqual(services[0].get_name(), service_id)
64 service = Accounts.AccountService.new(account, services[0])
65 self.assertTrue(service.get_enabled())
66
67 def test_delete_evernote_sandbox_account_must_remove_it(self):
68 account = self.add_evernote_sandbox_account()
69 self.assertThat(self.account_manager._manager.list(), HasLength(1))
70
71 self.account_manager.delete_account(account)
72 self.assertThat(self.account_manager._manager.list(), HasLength(0))

Subscribers

People subscribed via source and target branches