Merge lp:~elopio/reminders-app/test_with_account into lp:reminders-app
- test_with_account
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Nicholas Skaggs |
Approved revision: | 124 |
Merged at revision: | 135 |
Proposed branch: | lp:~elopio/reminders-app/test_with_account |
Merge into: | lp:reminders-app |
Diff against target: |
246 lines (+180/-6) 3 files modified
tests/autopilot/reminders/credentials.py (+145/-0) tests/autopilot/reminders/tests/__init__.py (+7/-4) tests/autopilot/reminders/tests/test_reminders.py (+28/-2) |
To merge this branch: | bzr merge lp:~elopio/reminders-app/test_with_account |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Nicholas Skaggs (community) | Approve | ||
Víctor R. Ruiz | Needs Fixing | ||
Richard Huddie | Pending | ||
Julia Palandri | Pending | ||
Allan LeSage | Pending | ||
Alberto Mardegan | Pending | ||
Review via email: mp+218688@code.launchpad.net |
This proposal supersedes a proposal from 2014-04-25.
Commit message
Added helpers to create an evernote account in autopilot tests.
Description of the change
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
Alberto Mardegan (mardy) wrote : Posted in a previous version of this proposal | # |
Looks good!
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
Successfully run on flo device!
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
My desktop seems to fail in a similar way as to jenkins?
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:122
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
It helps if you install the plugin. Works great locally here now.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:122
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:122
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nicholas Skaggs (nskaggs) wrote : | # |
Running with the generated debs above on my local box works properly..
Víctor R. Ruiz (vrruiz) wrote : | # |
Add docstrings, please :)
Nicholas Skaggs (nskaggs) wrote : | # |
We should also setup the environment properly. I'll try and propose a branch if I finish up some things before you get to it :-)
https:/
Leo Arias (elopio) wrote : | # |
> Add docstrings, please :)
I have added some more.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:122
http://
Executed test runs:
SUCCESS: http://
deb: http://
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:123
http://
Executed test runs:
SUCCESS: http://
deb: http://
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:124
http://
Executed test runs:
SUCCESS: http://
deb: http://
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nicholas Skaggs (nskaggs) wrote : | # |
Just confirming I'm happy with the merge, as soon as Jenkins is ;-)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:124
http://
Executed test runs:
SUCCESS: http://
deb: http://
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:124
http://
Executed test runs:
SUCCESS: http://
deb: http://
FAILURE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:124
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) : | # |
Preview Diff
1 | === added file 'tests/autopilot/reminders/credentials.py' | |||
2 | --- tests/autopilot/reminders/credentials.py 1970-01-01 00:00:00 +0000 | |||
3 | +++ tests/autopilot/reminders/credentials.py 2014-05-08 23:52:52 +0000 | |||
4 | @@ -0,0 +1,145 @@ | |||
5 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
6 | 2 | # | ||
7 | 3 | # Copyright (C) 2014 Canonical Ltd. | ||
8 | 4 | # | ||
9 | 5 | # This program is free software; you can redistribute it and/or modify | ||
10 | 6 | # it under the terms of the GNU General Public License version 3, as published | ||
11 | 7 | # by the Free Software Foundation. | ||
12 | 8 | # | ||
13 | 9 | # This program is distributed in the hope that it will be useful, | ||
14 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | 12 | # GNU General Public License for more details. | ||
17 | 13 | # | ||
18 | 14 | # You should have received a copy of the GNU General Public License | ||
19 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | 16 | |||
21 | 17 | |||
22 | 18 | import threading | ||
23 | 19 | |||
24 | 20 | from gi.repository import Accounts, GLib, Signon | ||
25 | 21 | |||
26 | 22 | |||
27 | 23 | class CredentialsException(Exception): | ||
28 | 24 | """Exception for credentials problems.""" | ||
29 | 25 | |||
30 | 26 | |||
31 | 27 | class AccountManager(object): | ||
32 | 28 | """Manager for online accounts.""" | ||
33 | 29 | |||
34 | 30 | def __init__(self): | ||
35 | 31 | self._manager = Accounts.Manager() | ||
36 | 32 | |||
37 | 33 | def _start_main_loop(self): | ||
38 | 34 | self.error = None | ||
39 | 35 | self._main_loop = GLib.MainLoop() | ||
40 | 36 | self._main_loop_thread = threading.Thread( | ||
41 | 37 | target=self._main_loop.run) | ||
42 | 38 | self._main_loop_thread.start() | ||
43 | 39 | |||
44 | 40 | def _join_main_loop(self): | ||
45 | 41 | self._main_loop_thread.join() | ||
46 | 42 | if self.error is not None: | ||
47 | 43 | raise CredentialsException(self.error.message) | ||
48 | 44 | |||
49 | 45 | def add_evernote_account(self, user_name, password, oauth_token): | ||
50 | 46 | """Add an evernote account. | ||
51 | 47 | |||
52 | 48 | :param user_name: The user name of the account. | ||
53 | 49 | :param password: The password of the account. | ||
54 | 50 | :param oauth_token: The oauth token of the account. | ||
55 | 51 | |||
56 | 52 | """ | ||
57 | 53 | self._start_main_loop() | ||
58 | 54 | |||
59 | 55 | account = self._create_account() | ||
60 | 56 | |||
61 | 57 | info = self._get_identity_info(user_name, password) | ||
62 | 58 | |||
63 | 59 | identity = Signon.Identity.new() | ||
64 | 60 | identity.store_credentials_with_info( | ||
65 | 61 | info, self._set_credentials_id_to_account, | ||
66 | 62 | {'account': account, 'oauth_token': oauth_token}) | ||
67 | 63 | |||
68 | 64 | self._join_main_loop() | ||
69 | 65 | |||
70 | 66 | self._enable_evernote_service(account) | ||
71 | 67 | |||
72 | 68 | return account | ||
73 | 69 | |||
74 | 70 | def _create_account(self): | ||
75 | 71 | account = self._manager.create_account('evernote') | ||
76 | 72 | account.set_enabled(True) | ||
77 | 73 | account.store(self._on_account_created, None) | ||
78 | 74 | return account | ||
79 | 75 | |||
80 | 76 | def _on_account_created(self, account, error, _): | ||
81 | 77 | if error: | ||
82 | 78 | self.error = error | ||
83 | 79 | self._main_loop.quit() | ||
84 | 80 | |||
85 | 81 | def _get_identity_info(self, user_name, password): | ||
86 | 82 | info = Signon.IdentityInfo.new() | ||
87 | 83 | info.set_username(user_name) | ||
88 | 84 | info.set_caption(user_name) | ||
89 | 85 | info.set_secret(password, True) | ||
90 | 86 | return info | ||
91 | 87 | |||
92 | 88 | def _set_credentials_id_to_account( | ||
93 | 89 | self, identity, id_, error, account_dict): | ||
94 | 90 | if error: | ||
95 | 91 | self.error = error | ||
96 | 92 | self._main_loop.quit() | ||
97 | 93 | |||
98 | 94 | account = account_dict.get('account') | ||
99 | 95 | oauth_token = account_dict.get('oauth_token') | ||
100 | 96 | account.set_variant('CredentialsId', GLib.Variant('u', id_)) | ||
101 | 97 | account.store(self._process_session, oauth_token) | ||
102 | 98 | |||
103 | 99 | def _process_session(self, account, error, oauth_token): | ||
104 | 100 | if error: | ||
105 | 101 | self.error = error | ||
106 | 102 | self._main_loop.quit() | ||
107 | 103 | |||
108 | 104 | account_service = Accounts.AccountService.new(account, None) | ||
109 | 105 | auth_data = account_service.get_auth_data() | ||
110 | 106 | identity = auth_data.get_credentials_id() | ||
111 | 107 | method = auth_data.get_method() | ||
112 | 108 | mechanism = auth_data.get_mechanism() | ||
113 | 109 | session_data = auth_data.get_parameters() | ||
114 | 110 | session_data['ProvidedTokens'] = GLib.Variant('a{sv}', { | ||
115 | 111 | 'TokenSecret': GLib.Variant('s', 'dummy'), | ||
116 | 112 | 'AccessToken': GLib.Variant('s', oauth_token), | ||
117 | 113 | }) | ||
118 | 114 | session = Signon.AuthSession.new(identity, method) | ||
119 | 115 | session.process( | ||
120 | 116 | session_data, mechanism, self._on_login_processed, None) | ||
121 | 117 | |||
122 | 118 | def _on_login_processed(self, session, reply, error, userdata): | ||
123 | 119 | if error: | ||
124 | 120 | self.error = error | ||
125 | 121 | |||
126 | 122 | self._main_loop.quit() | ||
127 | 123 | |||
128 | 124 | def _enable_evernote_service(self, account): | ||
129 | 125 | service = self._manager.get_service('evernote') | ||
130 | 126 | account.select_service(service) | ||
131 | 127 | account.set_enabled(True) | ||
132 | 128 | account.store(self._on_account_created, None) | ||
133 | 129 | |||
134 | 130 | def delete_account(self, account): | ||
135 | 131 | """Delete an account. | ||
136 | 132 | |||
137 | 133 | :param account: The account to delete. | ||
138 | 134 | |||
139 | 135 | """ | ||
140 | 136 | self._start_main_loop() | ||
141 | 137 | account.delete() | ||
142 | 138 | account.store(self._on_account_deleted, None) | ||
143 | 139 | self._join_main_loop() | ||
144 | 140 | |||
145 | 141 | def _on_account_deleted(self, account, error, userdata): | ||
146 | 142 | if error: | ||
147 | 143 | self.error = error | ||
148 | 144 | |||
149 | 145 | self._main_loop.quit() | ||
150 | 0 | 146 | ||
151 | === modified file 'tests/autopilot/reminders/tests/__init__.py' | |||
152 | --- tests/autopilot/reminders/tests/__init__.py 2014-05-08 21:09:52 +0000 | |||
153 | +++ tests/autopilot/reminders/tests/__init__.py 2014-05-08 23:52:52 +0000 | |||
154 | @@ -50,6 +50,8 @@ | |||
155 | 50 | installed_location_binary = '/usr/bin/reminders' | 50 | installed_location_binary = '/usr/bin/reminders' |
156 | 51 | installed_location_qml = '/usr/share/reminders/qml/reminders.qml' | 51 | installed_location_qml = '/usr/share/reminders/qml/reminders.qml' |
157 | 52 | 52 | ||
158 | 53 | home_dir = None | ||
159 | 54 | |||
160 | 53 | def get_launcher_and_type(self): | 55 | def get_launcher_and_type(self): |
161 | 54 | if os.path.exists(self.local_location_binary): | 56 | if os.path.exists(self.local_location_binary): |
162 | 55 | launcher = self.launch_test_local | 57 | launcher = self.launch_test_local |
163 | @@ -63,8 +65,9 @@ | |||
164 | 63 | return launcher, test_type | 65 | return launcher, test_type |
165 | 64 | 66 | ||
166 | 65 | def setUp(self): | 67 | def setUp(self): |
169 | 66 | launcher, self.test_type = self.get_launcher_and_type() | 68 | launcher, test_type = self.get_launcher_and_type() |
170 | 67 | self.home_dir = self._patch_home() | 69 | if self.home_dir is None: |
171 | 70 | self.home_dir = self._patch_home(test_type) | ||
172 | 68 | self.pointing_device = Pointer(self.input_device_class.create()) | 71 | self.pointing_device = Pointer(self.input_device_class.create()) |
173 | 69 | super(RemindersAppTestCase, self).setUp() | 72 | super(RemindersAppTestCase, self).setUp() |
174 | 70 | 73 | ||
175 | @@ -80,7 +83,7 @@ | |||
176 | 80 | os.path.expanduser(os.path.join('~', '.Xauthority')), | 83 | os.path.expanduser(os.path.join('~', '.Xauthority')), |
177 | 81 | os.path.join(directory, '.Xauthority')) | 84 | os.path.join(directory, '.Xauthority')) |
178 | 82 | 85 | ||
180 | 83 | def _patch_home(self): | 86 | def _patch_home(self, test_type): |
181 | 84 | """ mock /home for testing purposes to preserve user data | 87 | """ mock /home for testing purposes to preserve user data |
182 | 85 | """ | 88 | """ |
183 | 86 | temp_dir_fixture = fixtures.TempDir() | 89 | temp_dir_fixture = fixtures.TempDir() |
184 | @@ -95,7 +98,7 @@ | |||
185 | 95 | 98 | ||
186 | 96 | #click requires using initctl env (upstart), but the desktop can set | 99 | #click requires using initctl env (upstart), but the desktop can set |
187 | 97 | #an environment variable instead | 100 | #an environment variable instead |
189 | 98 | if self.test_type == 'click': | 101 | if test_type == 'click': |
190 | 99 | self.useFixture(toolkit_fixtures.InitctlEnvironmentVariable( | 102 | self.useFixture(toolkit_fixtures.InitctlEnvironmentVariable( |
191 | 100 | HOME=temp_dir)) | 103 | HOME=temp_dir)) |
192 | 101 | else: | 104 | else: |
193 | 102 | 105 | ||
194 | === modified file 'tests/autopilot/reminders/tests/test_reminders.py' | |||
195 | --- tests/autopilot/reminders/tests/test_reminders.py 2014-04-24 19:33:26 +0000 | |||
196 | +++ tests/autopilot/reminders/tests/test_reminders.py 2014-05-08 23:52:52 +0000 | |||
197 | @@ -23,9 +23,10 @@ | |||
198 | 23 | from autopilot import platform | 23 | from autopilot import platform |
199 | 24 | from autopilot.matchers import Eventually | 24 | from autopilot.matchers import Eventually |
200 | 25 | from testtools.matchers import Equals | 25 | from testtools.matchers import Equals |
201 | 26 | from testtools import ExpectedException | ||
202 | 26 | 27 | ||
203 | 27 | import reminders | 28 | import reminders |
205 | 28 | from reminders import fixture_setup, tests | 29 | from reminders import credentials, fixture_setup, tests |
206 | 29 | 30 | ||
207 | 30 | 31 | ||
208 | 31 | logger = logging.getLogger(__name__) | 32 | logger = logging.getLogger(__name__) |
209 | @@ -40,7 +41,7 @@ | |||
210 | 40 | def test_go_to_account_settings(self): | 41 | def test_go_to_account_settings(self): |
211 | 41 | """Test that the Go to account settings button calls url-dispatcher.""" | 42 | """Test that the Go to account settings button calls url-dispatcher.""" |
212 | 42 | if platform.model() == 'Desktop': | 43 | if platform.model() == 'Desktop': |
214 | 43 | self.skipTest("URL dispatcher doesn't work on the desktop.") | 44 | self.skipTest("URL dispatcher doesn't work on the desktop.") |
215 | 44 | url_dispatcher = fixture_setup.FakeURLDispatcher() | 45 | url_dispatcher = fixture_setup.FakeURLDispatcher() |
216 | 45 | self.useFixture(url_dispatcher) | 46 | self.useFixture(url_dispatcher) |
217 | 46 | 47 | ||
218 | @@ -56,3 +57,28 @@ | |||
219 | 56 | self.assertThat( | 57 | self.assertThat( |
220 | 57 | get_last_dispatch_url_call_parameter, | 58 | get_last_dispatch_url_call_parameter, |
221 | 58 | Eventually(Equals('settings:///system/online-accounts'))) | 59 | Eventually(Equals('settings:///system/online-accounts'))) |
222 | 60 | |||
223 | 61 | |||
224 | 62 | class RemindersTestCaseWithAccount(tests.RemindersAppTestCase): | ||
225 | 63 | |||
226 | 64 | def setUp(self): | ||
227 | 65 | # We need to change the home dir before adding the account, otherwise | ||
228 | 66 | # the account will not be found when the app is opened. | ||
229 | 67 | _, test_type = self.get_launcher_and_type() | ||
230 | 68 | self.home_dir = self._patch_home(test_type) | ||
231 | 69 | self.add_evernote_account() | ||
232 | 70 | super(RemindersTestCaseWithAccount, self).setUp() | ||
233 | 71 | |||
234 | 72 | def add_evernote_account(self): | ||
235 | 73 | account_manager = credentials.AccountManager() | ||
236 | 74 | oauth_token = ( | ||
237 | 75 | 'S=s1:U=8e6bf:E=14d08e375ff:C=145b1324a03:P=1cd:A=en-devtoken:' | ||
238 | 76 | 'V=2:H=79b946c32b4515ee52b387f7b68baa69') | ||
239 | 77 | account = account_manager.add_evernote_account( | ||
240 | 78 | 'dummy', 'dummy', oauth_token) | ||
241 | 79 | self.addCleanup(account_manager.delete_account, account) | ||
242 | 80 | |||
243 | 81 | def test_open_application_with_account(self): | ||
244 | 82 | """Test that the No account dialog is not visible.""" | ||
245 | 83 | with ExpectedException(reminders.RemindersAppException): | ||
246 | 84 | self.app.main_view.no_account_dialog |
FAILED: Continuous integration, rev:122 91.189. 93.70:8080/ job/reminders- app-ci/ 298/ 91.189. 93.70:8080/ job/generic- mediumtests- trusty/ 2477 91.189. 93.70:8080/ job/reminders- app-saucy- amd64-ci/ 298 91.189. 93.70:8080/ job/reminders- app-trusty- amd64-ci/ 298
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/reminders- app-ci/ 298/rebuild
http://