Merge lp:~jaboing/canonical-identity-provider/more_device_tests_refactored into lp:canonical-identity-provider/release

Proposed by Julien Funk
Status: Rejected
Rejected by: Natalia Bidart
Proposed branch: lp:~jaboing/canonical-identity-provider/more_device_tests_refactored
Merge into: lp:canonical-identity-provider/release
Diff against target: 722 lines (+298/-294)
10 files modified
acceptance/pages.py (+111/-3)
acceptance/tests/devices/add_device_google.py (+0/-54)
acceptance/tests/devices/add_device_paper.py (+0/-65)
acceptance/tests/devices/add_device_yubikey.py (+0/-57)
acceptance/tests/devices/test_add_device.py (+77/-9)
acceptance/tests/devices/test_backup_device_warning.py (+56/-34)
acceptance/tests/devices/test_delete_device.py (+6/-6)
acceptance/tests/devices/test_generate_paper_codes.py (+44/-62)
webui/templates/device/generate-codes.html (+2/-2)
webui/templates/device/print-codes.html (+2/-2)
To merge this branch: bzr merge lp:~jaboing/canonical-identity-provider/more_device_tests_refactored
Reviewer Review Type Date Requested Status
Leo Arias Pending
Review via email: mp+163262@code.launchpad.net

Description of the change

Refactored many of the devices tests, Google, Yubikey, Paper, Generate_Codes and Device Warning.

To post a comment you must log in.
851. By Julien Funk

Attempting to fix merge conflict

852. By Julien Funk

Merging my changes for proposal.

853. By Julien Funk

Removed conflicts from source.

Revision history for this message
Leo Arias (elopio) wrote :
Download full text (5.5 KiB)

<jfunk> elopio, there's a couple things in there we might need to go over - line 10,11 + 118-121
<elopio> jfunk: what's up with those lines?
<jfunk> elopio, well, they methods come from the old helpers, I changed the test a bit so it didn't need those methods, but they seem like they'd be useful for other tests
<jfunk> I didn't want them to get lost so I added them to the page object, but they're referencing the helpers, duno if that's approporiate or not
<elopio> jfunk: in my opinion, the right place for get_key_from_qrcode is inside AddGoogleDevice as a _private method
<elopio> but I'm not sure if it's still used somewhere else.
<jfunk> elopio, maybe it's not a good idea, but one option is to copy the helpers until we've migrated the entire acceptance test collection
<jfunk> then delete the old ones
<elopio> jfunk: that's fine, with a TODO comment saying that.
<elopio> after we finish all the devices tests refactors, we can get rid of the acceptance/devices/__init__.py
<jfunk> elopio, ok I'll make that change now
<jfunk> please look at the changes I made to the code generation test cases
<jfunk> elopio, I made large change to the process
<jfunk> namely I stopped using the paper code to log in, and only verified that we create a new set of codes
<jfunk> I figured that testing the succes of a 2F login belonged in a different test suite
<elopio> One second, I'm still reading.
<elopio> l 362. it's weird.
<elopio> I think it will look better doing
<elopio> start = super(TestAddDevice, self).navigate_to_page()
<elopio> return navigate_to_device_add_page(start)
<elopio> after reading some of your code, now I think that naviaget_to_page is not a good name.
<elopio> sometimes we will use it to navigate_to_page, prepare some preconditions, keep navigating.
<elopio> and some other times we will use it to get the start page.
<elopio> I think that the fixtures project might help to makes things clearer here.
<jfunk> elopio, we can do it that way, I thought it was nice since that function is called 4 or 5 times to have as few lines as possible
<elopio> jfunk: yes, but the function is not clear, and the way you call it makes it even less clear.
<elopio> it's my fault, but while we find a clearer way to handle the preconditions, I'd prefer it to be more verbose.
<jfunk> elopio, re: navigate_to_page - I prefer using this method over setUp because it's simpler
<jfunk> elopio, perhaps just a better name
<elopio> jfunk: I think the name is one problem, and the second is that it's a magic secondary effect of calling set up.
<elopio> that's where fixtures can come handy, make the magic more explicit.
<jfunk> yeah, I think I mentioned that in my first experience with it
<elopio> jfunk: yes, next week I'll try to change it.
<elopio> let me know if you have more ideas related to it.
<jfunk> elopio, not at the moment, but I'll let you know if anything pops up, can you tell me more about the fixtures project?
<elopio> jfunk: https://pypi.python.org/pypi/fixtures/0.3.8
<elopio> our preconditions are really complex, so we can model them in a fixture
<elopio> and currently we are sharing preconditions between tests using inheritance
<elopio> with this we can make fixtur...

Read more...

Revision history for this message
Simon Davy (bloodearnest) wrote :

Minor quibble - l346-348 seem to be over indented, pep8-wise.

Other than that, looks good to me.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Setting MP as Rejected to reduce numbers of landing candidates in @reviewlist. Change status again if this MP is still current.

Unmerged revisions

853. By Julien Funk

Removed conflicts from source.

852. By Julien Funk

Merging my changes for proposal.

851. By Julien Funk

Attempting to fix merge conflict

850. By Julien Funk

Refactored backup device warning tests

849. By Julien Funk

refactored generate paper codes, removed uncessary steps and made into TestCase format

848. By Julien Funk

Refactored the Google, Yubikey and Paper device add tests into the class format and moved to test_add_devices.py

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'acceptance/pages.py'
2--- acceptance/pages.py 2013-05-10 00:45:35 +0000
3+++ acceptance/pages.py 2013-05-10 13:57:27 +0000
4@@ -7,6 +7,12 @@
5 import sst.actions
6 import u1testutils.sso.sst.pages
7
8+from acceptance.devices import (
9+ get_key_from_qrcode,
10+ store_paper_device,
11+ update_paper_device
12+)
13+
14 from u1testutils.sst import log_action
15
16
17@@ -188,12 +194,20 @@
18 return AddNewAuthenticationDevice()
19
20 @log_action(logging.info)
21- def delete_authentication_device(self):
22- delete_link = sst.actions.get_element_by_css(
23+ def delete_authentication_device(self, index=0):
24+ delete_link = sst.actions.get_elements_by_css(
25 'a[data-qa-id="delete-device"]')
26- sst.actions.click_link(delete_link)
27+ sst.actions.click_link(delete_link[index])
28 return DeleteAuthenticationDevice()
29
30+ def is_warning_displayed(self):
31+ try:
32+ warning_message = sst.actions.get_element_by_css(
33+ '#missing_backup_device')
34+ return warning_message.is_displayed()
35+ except AssertionError:
36+ return False
37+
38
39 class DeleteAuthenticationDevice(PageWithUsernameInTitle):
40
41@@ -250,6 +264,21 @@
42 self._add_device('type_generic')
43 return AddGenericDevice()
44
45+ @log_action(logging.info)
46+ def add_google_device(self):
47+ self._add_device('type_google')
48+ return AddGoogleDevice()
49+
50+ @log_action(logging.info)
51+ def add_yubikey_device(self):
52+ self._add_device('type_yubi')
53+ return AddYubikeyDevice()
54+
55+ @log_action(logging.info)
56+ def add_paper_device(self):
57+ self._add_device('type_paper')
58+ return PaperDevice()
59+
60 def _add_device(self, device_radio_identifier):
61 sst.actions.set_radio_value(device_radio_identifier)
62 add_button = sst.actions.get_element(
63@@ -322,3 +351,82 @@
64
65 def get_key(self):
66 return sst.actions.get_element(name='hex_key').get_attribute('value')
67+
68+
69+class AddGoogleDevice(AddDevice):
70+
71+ def get_key(self, email):
72+ return get_key_from_qrcode(email)
73+
74+
75+class AddYubikeyDevice(AddDevice):
76+
77+ def get_key(self):
78+ return sst.actions.get_element(name='hex_key').get_attribute('value')
79+
80+ def assert_warning(self):
81+ # Check that the YubiKey warning is showing
82+ warning = ('Warning: The YubiKey is shipped with a credential in the '
83+ 'short-press slot')
84+ sst.actions.assert_element(css_class='warning', text_regex=warning)
85+
86+
87+class PaperDevice(PageWithUsernameInTitle):
88+
89+ title = "{0}'s devices"
90+ url_path = '/device-print/.*'
91+ is_url_path_regex = True
92+ headings1 = ['Ubuntu Single Sign On','Printable backup codes']
93+
94+ def assert_codes_present(self):
95+ # ol.codelist has list of N codes
96+ sst.actions.assert_element(tag='ol', css_class='codelist')
97+
98+ def assert_print_button_visible(self):
99+ sst.actions.assert_element(tag='a', id='printbtn', css_class='btn')
100+
101+ @log_action(logging.info)
102+ def go_back_to_device_list(self):
103+ device_list_link = sst.actions.get_element_by_css(
104+ 'a[data-qa-id="go_back"]')
105+ sst.actions.click_link(device_list_link)
106+ return YourAuthenticationDevices()
107+
108+ @log_action(logging.info)
109+ def generate_new_codes(self):
110+ generate_link = sst.actions.get_element_by_css(
111+ 'a[data-qa-id="generate_codes"]')
112+ sst.actions.click_link(generate_link)
113+ return GenerateNewPaperCodes()
114+
115+ def get_first_code(self):
116+ return sst.actions.get_elements_by_css('ol.codelist li')[0].text
117+
118+ def store_paper_device(self, name='Printable Backup Codes'):
119+ acceptance.devices.store_paper_device(name)
120+
121+ def update_paper_device(self, name='Printable Backup Codes'):
122+ acceptance.devices.update_paper_device(name)
123+
124+
125+class GenerateNewPaperCodes(PageWithUsernameInTitle):
126+
127+ title = "{0}'s devices"
128+ url_path = '/device-generate/.*'
129+ is_url_path_regex = True
130+ headings1 = ['Ubuntu Single Sign On','Generate new codes']
131+
132+ @log_action(logging.info)
133+ def confirm_new_codes(self):
134+ confirm_button = sst.actions.get_element_by_css(
135+ 'button[data-qa-id="confirm-codes"]')
136+ sst.actions.click_button(confirm_button)
137+ return PaperDevice()
138+
139+ @log_action(logging.info)
140+ def cancel(self):
141+ cancel_link = sst.actions.get_element_by_css('a[data-qa-id="cancel"]')
142+ sst.actions.click_link(cancel_link)
143+ return PaperDevice()
144+
145+
146
147=== removed file 'acceptance/tests/devices/add_device_google.py'
148--- acceptance/tests/devices/add_device_google.py 2013-05-02 17:20:14 +0000
149+++ acceptance/tests/devices/add_device_google.py 1970-01-01 00:00:00 +0000
150@@ -1,54 +0,0 @@
151-# Test google device addition
152-from oath import hotp
153-from sst.actions import (
154- assert_table_has_rows,
155- assert_table_row_contains_text,
156- click_link,
157- get_element,
158- set_radio_value,
159- write_textfield,
160-)
161-from u1testutils.sst import config
162-
163-from acceptance import helpers
164-from acceptance.devices import (
165- click_add_device_button,
166- click_add_new_device_link,
167- get_key_from_qrcode,
168- store_device,
169-)
170-
171-
172-config.set_base_url_from_env()
173-
174-email = helpers.login_or_register_account(device_cleanup=True)
175-
176-# Go to the authentication devices page
177-click_link('devices-link')
178-
179-# Click on "Add a new authentication device" link
180-click_add_new_device_link()
181-
182-# Choose "Google device" and click add device
183-set_radio_value('type_google')
184-click_add_device_button()
185-
186-# get/check the image
187-aes_key = get_key_from_qrcode(email)
188-
189-# set device name
190-name = get_element(tag='input', name='name')
191-write_textfield(name, 'add_device_google')
192-
193-# Add correctly generated OTP
194-valid_otp = hotp.hotp(aes_key, 0)
195-write_textfield(get_element(tag='input', name='otp'), valid_otp)
196-
197-# Click "Add device"
198-click_add_device_button()
199-store_device('add_device_google', aes_key)
200-
201-# Check our new device is now in the table, with the correct name
202-assert_table_has_rows('device-list', 1)
203-assert_table_row_contains_text('device-list', 0,
204- ['add_device_google', 'Delete'], regex=True)
205
206=== removed file 'acceptance/tests/devices/add_device_paper.py'
207--- acceptance/tests/devices/add_device_paper.py 2013-05-02 17:20:14 +0000
208+++ acceptance/tests/devices/add_device_paper.py 1970-01-01 00:00:00 +0000
209@@ -1,65 +0,0 @@
210-# Test google device addition
211-from sst.actions import (
212- assert_element,
213- assert_table_has_rows,
214- assert_table_row_contains_text,
215- assert_url_contains,
216- check_flags,
217- click_link,
218- get_element,
219- go_to,
220- set_radio_value,
221-)
222-from u1testutils.sst import config
223-
224-from acceptance import helpers
225-from acceptance.devices import (
226- click_add_device_button,
227- click_add_new_device_link,
228- store_paper_device,
229-)
230-
231-check_flags('paper_device')
232-
233-config.set_base_url_from_env()
234-
235-email = helpers.login_or_register_account(device_cleanup=True)
236-
237-# Go to the authentication devices page
238-click_link('devices-link')
239-
240-# Click on "Add a new authentication device" link
241-click_add_new_device_link()
242-
243-# Choose "paper" device and click add device
244-set_radio_value('type_paper')
245-click_add_device_button()
246-
247-# check the page is correct
248-assert_url_contains('/device-print/')
249-assert_element(tag='h1', text='Printable backup codes')
250-
251-# ol.codelist has list of N codes
252-assert_element(tag='ol', css_class='codelist')
253-# make sure print button is visible
254-assert_element(tag='a', id='printbtn', css_class='btn')
255-
256-# Go to the device-list page
257-go_to('/device-list')
258-
259-# Check our new device is now in the table, with the correct name
260-assert_table_has_rows('device-list', 1)
261-texts = ['Printable Backup Codes', 'Rename Delete View Codes']
262-assert_table_row_contains_text('device-list', 0, texts, regex=True)
263-
264-# Save the device for cleanup
265-store_paper_device(name='Printable Backup Codes')
266-
267-# Go to the print view
268-click_link(get_element(tag='a', text='View Codes'))
269-assert_url_contains('/device-print/')
270-
271-# ol.codelist has list of N codes
272-assert_element(tag='ol', css_class='codelist')
273-# make sure print button is visible
274-assert_element(tag='a', id='printbtn')
275
276=== removed file 'acceptance/tests/devices/add_device_yubikey.py'
277--- acceptance/tests/devices/add_device_yubikey.py 2013-05-02 17:20:14 +0000
278+++ acceptance/tests/devices/add_device_yubikey.py 1970-01-01 00:00:00 +0000
279@@ -1,57 +0,0 @@
280-# Test YubiKey device addition
281-from oath import hotp
282-from sst.actions import (
283- assert_element,
284- assert_table_has_rows,
285- assert_table_row_contains_text,
286- click_link,
287- get_element,
288- set_radio_value,
289- write_textfield,
290-)
291-from u1testutils.sst import config
292-
293-from acceptance import helpers
294-from acceptance.devices import (
295- click_add_device_button,
296- click_add_new_device_link,
297- store_device,
298-)
299-
300-
301-config.set_base_url_from_env()
302-
303-email = helpers.login_or_register_account(device_cleanup=True)
304-
305-# Go to the authentication devices page
306-click_link('devices-link')
307-
308-# Click on "Add a new authentication device" link
309-click_add_new_device_link()
310-
311-# Choose YubiKey and click add device
312-set_radio_value('type_yubi')
313-click_add_device_button()
314-
315-# Check that the YubiKey warning is showing
316-warning = ('Warning: The YubiKey is shipped with a credential in the '
317- 'short-press slot')
318-assert_element(css_class='warning', text_regex=warning)
319-
320-# set device name
321-name = get_element(tag='input', name='name')
322-write_textfield(name, 'add_device_yubikey')
323-
324-# Add correctly generated OTP
325-aes_key = get_element(name='hex_key').get_attribute('value')
326-valid_otp = hotp.hotp(aes_key, 0)
327-write_textfield(get_element(tag='input', name='otp'), valid_otp)
328-
329-# Click "Add device"
330-click_add_device_button()
331-store_device('add_device_yubikey', aes_key)
332-
333-# Check our new device is now in the table, with the correct name
334-assert_table_has_rows('device-list', 1)
335-assert_table_row_contains_text('device-list', 0,
336- ['add_device_yubikey', 'Delete'], regex=True)
337
338=== modified file 'acceptance/tests/devices/test_add_device.py'
339--- acceptance/tests/devices/test_add_device.py 2013-05-02 17:20:14 +0000
340+++ acceptance/tests/devices/test_add_device.py 2013-05-10 13:57:27 +0000
341@@ -11,6 +11,12 @@
342 from acceptance import base
343
344
345+def navigate_to_device_add_page(start):
346+ # 'start' is the base YourAccount page object.
347+ authentication_devices = start.subheader.go_to_authentication_devices()
348+ return authentication_devices.add_new_authentication_device()
349+
350+
351 class TestAddDevice(base.SSTTestCaseWithLogIn):
352
353 def navigate_to_page(self):
354@@ -19,10 +25,8 @@
355 It will be accessible for the tests from the page attribute.
356
357 """
358- # Start from where the base test case leaves us, the YourAccount page.
359- start = super(TestAddDevice, self).navigate_to_page()
360- authentication_devices = start.subheader.go_to_authentication_devices()
361- return authentication_devices.add_new_authentication_device()
362+ return navigate_to_device_add_page(
363+ super(TestAddDevice, self).navigate_to_page())
364
365 def test_cancel_device_addition(self):
366 your_authentication_devices = self.page.cancel()
367@@ -54,11 +58,9 @@
368 It will be accessible for the tests from the page attribute.
369
370 """
371- # Start from where the base test case leaves us, the YourAccount page.
372- start = super(TestAddGenericDevice, self).navigate_to_page()
373- authentication_devices = start.subheader.go_to_authentication_devices()
374- add_device = authentication_devices.add_new_authentication_device()
375- return add_device.add_generic_device()
376+ add_device_page = navigate_to_device_add_page(
377+ super(TestAddGenericDevice, self).navigate_to_page())
378+ return add_device_page.add_generic_device()
379
380 def test_open_add_generic_device_page(self):
381 name, one_time_password = self.page.get_form_values()
382@@ -105,3 +107,69 @@
383 'Test generic device', one_time_password)
384 self.assertEqual(
385 your_authentication_devices.get_devices(), ['Test generic device'])
386+
387+
388+class TestAddGoogleDevice(base.SSTTestCaseWithLogIn):
389+
390+ def navigate_to_page(self):
391+ """Go to the AddGoogleDevice page.
392+
393+ It will be accessible for the tests from the page attribute.
394+
395+ """
396+ add_device_page = navigate_to_device_add_page(
397+ super(TestAddGoogleDevice, self).navigate_to_page())
398+ return add_device_page.add_google_device()
399+
400+ def test_add_google_device(self):
401+ aes_key = self.page.get_key(self.user.email)
402+ one_time_password = hotp.hotp(aes_key, 0)
403+ your_authentication_devices = self.page.add_device(
404+ 'Test Google device', one_time_password)
405+ self.assertEqual(
406+ your_authentication_devices.get_devices(), ['Test Google device'])
407+
408+
409+class TestAddYubikeyDevice(base.SSTTestCaseWithLogIn):
410+
411+ def navigate_to_page(self):
412+ """Go to the AddYubikeyDevice page.
413+
414+ It will be accessible for the tests from the page attribute.
415+
416+ """
417+ add_device_page = navigate_to_device_add_page(
418+ super(TestAddYubikeyDevice, self).navigate_to_page())
419+ return add_device_page.add_yubikey_device()
420+
421+ def test_add_yubikey_device(self):
422+ self.page.assert_warning()
423+ aes_key = self.page.get_key()
424+ one_time_password = hotp.hotp(aes_key, 0)
425+ your_authentication_devices = self.page.add_device(
426+ 'Test Yubikey device', one_time_password)
427+ self.assertEqual(
428+ your_authentication_devices.get_devices(), ['Test Yubikey device'])
429+
430+
431+@unittest.skipIf('paper_device' not in sst.config.flags,
432+ 'Paper device is not enabled.')
433+class TestAddPaperDevice(base.SSTTestCaseWithLogIn):
434+
435+ def navigate_to_page(self):
436+ """Go to the PaperDevice page.
437+
438+ It will be accessible for the tests from the page attribute.
439+
440+ """
441+ add_device_page = navigate_to_device_add_page(
442+ super(TestAddPaperDevice, self).navigate_to_page())
443+ return add_device_page.add_paper_device()
444+
445+ def test_add_paper_device(self):
446+ self.page.assert_codes_present()
447+ self.page.assert_print_button_visible()
448+ your_authentication_devices = self.page.go_back_to_device_list()
449+ self.assertEqual(
450+ your_authentication_devices.get_devices(), ['Printable Backup Codes'])
451+
452
453=== renamed file 'acceptance/tests/devices/warn_about_backup_device.py' => 'acceptance/tests/devices/test_backup_device_warning.py'
454--- acceptance/tests/devices/warn_about_backup_device.py 2013-05-02 17:20:14 +0000
455+++ acceptance/tests/devices/test_backup_device_warning.py 2013-05-10 13:57:27 +0000
456@@ -1,34 +1,56 @@
457-# Test enabling/disabling the warn_about_backup_device preference
458-
459-from sst.actions import (
460- fails,
461- go_to,
462-)
463-from u1testutils.sst import config
464-
465-from acceptance.devices import (
466- add_device,
467- delete_device,
468-)
469-from acceptance import helpers, urls
470-
471-
472-# setup
473-config.set_base_url_from_env()
474-helpers.login_or_register_account(device_cleanup=True)
475-
476-# the test: no warnings if no device
477-go_to(urls.DEVICES)
478-fails(helpers.get_backup_device_warning_div)
479-add_device('the single device')
480-
481-# the test: show warning if missing backup device
482-helpers.assert_backup_device_warning()
483-
484-# add a second device, ensure that the warning is no longer shown
485-add_device('the backup device')
486-fails(helpers.get_backup_device_warning_div)
487-
488-# delete one device and ensure the warning is back
489-delete_device()
490-helpers.assert_backup_device_warning()
491+# Copyright 2012, 2013 Canonical Ltd.
492+# This software is licensed under the GNU Affero General Public License
493+# version 3 (see the file LICENSE).
494+
495+import unittest
496+
497+import sst
498+
499+from oath import hotp
500+
501+from acceptance import base
502+
503+
504+class TestBackupDeviceWarning(base.SSTTestCaseWithLogIn):
505+
506+ def navigate_to_page(self):
507+ """Go to the YourAuthenticationDevices page.
508+
509+ It will be accessible for the tests from the page attribute.
510+
511+ """
512+ # 'start' is the base YourAccount page object.
513+ start = super(TestBackupDeviceWarning, self).navigate_to_page()
514+ return start.subheader.go_to_authentication_devices()
515+
516+ def test_no_warning_before_adding_device(self):
517+ self.assertFalse(self.page.is_warning_displayed())
518+
519+ def test_warning_displayed_for_single_device(self):
520+ your_auth_devices_page = self.add_device(
521+ self.page, 'Test device warning')
522+ self.assertTrue(your_auth_devices_page.is_warning_displayed())
523+
524+ def test_warning_removed_after_second_device_added(self):
525+ your_auth_devices_page = self.add_device(
526+ self.page, 'Test device warning 1')
527+ your_auth_devices_page = self.add_device(
528+ your_auth_devices_page, 'Test device warning 2')
529+ self.assertFalse(your_auth_devices_page.is_warning_displayed())
530+
531+ def test_warning_returns_after_second_device_deleted(self):
532+ your_auth_devices_page = self.add_device(
533+ self.page, 'Test device warning 1')
534+ your_auth_devices_page = self.add_device(
535+ your_auth_devices_page, 'Test device warning 2')
536+ rm_device_page = your_auth_devices_page.delete_authentication_device()
537+ your_auth_devices_page = rm_device_page.confirm_delete_device()
538+ self.assertTrue(your_auth_devices_page.is_warning_displayed())
539+
540+ def add_device(self, auth_devices_page, device_name):
541+ add_new_device_page = auth_devices_page.add_new_authentication_device()
542+ add_generic_device_page = add_new_device_page.add_generic_device()
543+ aes_key = add_generic_device_page.get_key()
544+ one_time_password = hotp.hotp(aes_key, 0)
545+ return add_generic_device_page.add_device(
546+ device_name, one_time_password)
547
548=== modified file 'acceptance/tests/devices/test_delete_device.py'
549--- acceptance/tests/devices/test_delete_device.py 2013-05-10 00:45:35 +0000
550+++ acceptance/tests/devices/test_delete_device.py 2013-05-10 13:57:27 +0000
551@@ -13,8 +13,8 @@
552 """Navigate to DeleteAuthenticationDevices with a device added."""
553 # Start from where the base test case leaves us, the YourAccount page.
554 start = super(TestDeleteDevice, self).navigate_to_page()
555- auth_devices = start.subheader.go_to_authentication_devices()
556- return self.add_device(auth_devices)
557+ auth_devices_page = start.subheader.go_to_authentication_devices()
558+ return self.add_device(auth_devices_page)
559
560 def test_device_deletion(self):
561 your_auth_devices = self.page.confirm_delete_device()
562@@ -26,11 +26,11 @@
563 self.assertEqual(
564 your_auth_devices.get_devices(), ['Test device delete'])
565
566- def add_device(self, auth_devices):
567- test_device_page = auth_devices.add_new_authentication_device()
568+ def add_device(self, auth_devices_page):
569+ test_device_page = auth_devices_page.add_new_authentication_device()
570 add_device_page = test_device_page.add_generic_device()
571 aes_key = add_device_page.get_key()
572 one_time_password = hotp.hotp(aes_key, 0)
573- auth_devices = add_device_page.add_device(
574+ auth_devices_page = add_device_page.add_device(
575 'Test device delete', one_time_password)
576- return auth_devices.delete_authentication_device()
577+ return auth_devices_page.delete_authentication_device()
578
579=== renamed file 'acceptance/tests/devices/generate_paper_codes.py' => 'acceptance/tests/devices/test_generate_paper_codes.py'
580--- acceptance/tests/devices/generate_paper_codes.py 2013-05-02 17:20:14 +0000
581+++ acceptance/tests/devices/test_generate_paper_codes.py 2013-05-10 13:57:27 +0000
582@@ -1,62 +1,44 @@
583-# Test google device addition
584-from sst.actions import *
585-from u1testutils.sst import config
586-
587-from acceptance import helpers
588-from acceptance.devices import (
589- click_add_device_button,
590- click_add_new_device_link,
591- enter_otp,
592- store_paper_device,
593- update_paper_device,
594-)
595-
596-check_flags('paper_device')
597-
598-config.set_base_url_from_env()
599-
600-email = helpers.login_or_register_account(device_cleanup=True)
601-
602-# Go to the authentication devices page
603-click_link('devices-link')
604-
605-# Click on "Add a new authentication device" link
606-click_add_new_device_link()
607-
608-# Add the paper device
609-set_radio_value('type_paper')
610-click_add_device_button()
611-
612-# Get the first code which we will invalidate
613-old_code = get_elements_by_css('ol.codelist li')[0].text
614-
615-# Save the device
616-store_paper_device('Printable backup codes')
617-
618-# Generate new codes
619-click_link(get_element(tag='a', text='Generate new codes'))
620-
621-# Fetch a new codes
622-new_code = get_elements_by_css('ol.codelist li')[0].text
623-
624-# Confirm the new codes
625-click_button(get_element(tag='button', text='Confirm new codes'))
626-
627-# Update our stored codes for device removal
628-update_paper_device('Printable backup codes', counter=1)
629-
630-# Set "twofactor required" in account preferences
631-helpers.set_twofactor_to_always_required()
632-add_cleanup(helpers.set_twofactor_to_required_as_needed)
633-
634-# Logout and back in again
635-helpers.logout_and_in()
636-go_to('/')
637-
638-# Check the first (invalidated) code fails
639-enter_otp(old_code)
640-assert_displayed('id_oath_token')
641-
642-# Check the new code works
643-enter_otp(new_code)
644-assert_url('/')
645+# Copyright 2012, 2013 Canonical Ltd.
646+# This software is licensed under the GNU Affero General Public License
647+# version 3 (see the file LICENSE).
648+
649+import unittest
650+
651+import sst
652+
653+from oath import hotp
654+
655+from acceptance import base
656+
657+
658+@unittest.skipIf('paper_device' not in sst.config.flags,
659+ 'Paper device is not enabled.')
660+class TestGeneratePaperCodes(base.SSTTestCaseWithLogIn):
661+
662+ def navigate_to_page(self):
663+ """Go to the PaperDevice page.
664+
665+ It will be accessible for the tests from the page attribute.
666+
667+ """
668+ # 'start' is the base YourAccount page object.
669+ start = super(TestGeneratePaperCodes, self).navigate_to_page()
670+ authentication_devices = start.subheader.go_to_authentication_devices()
671+ add_device_page = authentication_devices.add_new_authentication_device()
672+ return add_device_page.add_paper_device()
673+
674+ def test_generate_paper_codes(self):
675+ # Get the first code which we will invalidate
676+ old_code = self.page.get_first_code()
677+ new_codes_page = self.page.generate_new_codes()
678+ paper_device_page = new_codes_page.confirm_new_codes()
679+ new_code = paper_device_page.get_first_code()
680+ self.assertNotEqual(old_code, new_code)
681+
682+ def test_cancel_generating_paper_codes(self):
683+ # Get the first code which should remain after cancel
684+ the_code = self.page.get_first_code()
685+ new_codes_page = self.page.generate_new_codes()
686+ paper_device_page = new_codes_page.cancel()
687+ the_same_code = paper_device_page.get_first_code()
688+ self.assertEqual(the_code, the_same_code)
689
690=== modified file 'webui/templates/device/generate-codes.html'
691--- webui/templates/device/generate-codes.html 2012-10-25 21:22:30 +0000
692+++ webui/templates/device/generate-codes.html 2013-05-10 13:57:27 +0000
693@@ -28,10 +28,10 @@
694 <form method="post">
695 {% csrf_token %}
696 <p>
697- <button class="btn" type="submit">
698+ <button class="btn" type="submit" data-qa-id="confirm-codes">
699 <span><span>{% trans "Confirm new codes" %}</span></span>
700 </button>
701- {% trans "or" %} <a href="{% url device-print device_id %}">{% trans "cancel" %}</a>
702+ {% trans "or" %} <a href="{% url device-print device_id %}" data-qa-id="cancel">{% trans "cancel" %}</a>
703 </p>
704 </form>
705 {% endblock %}
706
707=== modified file 'webui/templates/device/print-codes.html'
708--- webui/templates/device/print-codes.html 2012-10-25 21:22:30 +0000
709+++ webui/templates/device/print-codes.html 2013-05-10 13:57:27 +0000
710@@ -25,10 +25,10 @@
711 <a class="btn" id="printbtn" onclick="window.print()"><span><span>{% trans "Print Codes" %}</span></span>
712 </a>
713 {% if generation_enabled %}
714- <a class="btn" href="{% url device-generate device_id %}">
715+ <a class="btn" href="{% url device-generate device_id %}" data-qa-id="generate_codes">
716 <span><span>{% trans "Generate new codes" %}</span></span>
717 </a>
718 {% endif %}
719- {% trans "or" %} <a href="{% url device-list %}">{% trans "go back to device list" %}</a>
720+ {% trans "or" %} <a href="{% url device-list %}" data-qa-id="go_back">{% trans "go back to device list" %}</a>
721 </p>
722 {% endblock %}