Merge lp:~nataliabidart/ubuntuone-control-panel/fix-933576 into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 284
Merged at revision: 274
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/fix-933576
Merge into: lp:ubuntuone-control-panel
Diff against target: 1910 lines (+940/-456)
24 files modified
data/qt/controlpanel.ui (+4/-4)
data/qt/images.qrc (+7/-0)
data/qt/side_widget.ui (+214/-0)
data/qt/signin.ui (+115/-152)
data/qt/ubuntuone.qss (+15/-2)
ubuntuone/controlpanel/backend.py (+17/-4)
ubuntuone/controlpanel/gui/__init__.py (+5/-9)
ubuntuone/controlpanel/gui/qt/controlpanel.py (+16/-5)
ubuntuone/controlpanel/gui/qt/gui.py (+1/-1)
ubuntuone/controlpanel/gui/qt/side_widget.py (+81/-0)
ubuntuone/controlpanel/gui/qt/signin.py (+7/-72)
ubuntuone/controlpanel/gui/qt/tests/__init__.py (+24/-4)
ubuntuone/controlpanel/gui/qt/tests/test_account.py (+0/-5)
ubuntuone/controlpanel/gui/qt/tests/test_addfolder.py (+0/-2)
ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py (+19/-20)
ubuntuone/controlpanel/gui/qt/tests/test_devices.py (+0/-5)
ubuntuone/controlpanel/gui/qt/tests/test_folders.py (+2/-1)
ubuntuone/controlpanel/gui/qt/tests/test_gui.py (+1/-1)
ubuntuone/controlpanel/gui/qt/tests/test_preferences.py (+2/-16)
ubuntuone/controlpanel/gui/qt/tests/test_side_widget.py (+90/-0)
ubuntuone/controlpanel/gui/qt/tests/test_signin.py (+39/-147)
ubuntuone/controlpanel/gui/qt/tests/test_wizard.py (+158/-0)
ubuntuone/controlpanel/gui/qt/wizard.py (+110/-0)
ubuntuone/controlpanel/gui/tests/__init__.py (+13/-6)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/fix-933576
Reviewer Review Type Date Requested Status
Eric Casteleijn (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+95627@code.launchpad.net

Commit message

- Changed the initial signin page so both login and register options are shown,
  and when clicked, the user is presented with either the Qt login dialog,
  or the Qt registration dialog (LP: #933576).

Description of the change

To test IRL, please have all our U1 nightlies installed and updated.

Inside this branch, run:

./setup.py clean build; U1_DEBUG=True PYTHONPATH=. bin/ubuntuone-control-panel-qt

Remove your current device and you should be taken to the 'choose sign in' page where you can either register or login.

To post a comment you must log in.
282. By Natalia Bidart

Removed unnecessary styles.

283. By Natalia Bidart

- No more 2 default buttons in the device remove confirmation dialog
  (LP: #933577).

284. By Natalia Bidart

Merged trunk in.

Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Code looks good, and even better, it works! ;)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/banner.png'
2Binary files data/banner.png 1970-01-01 00:00:00 +0000 and data/banner.png 2012-03-02 19:56:20 +0000 differ
3=== added file 'data/logo.png'
4Binary files data/logo.png 1970-01-01 00:00:00 +0000 and data/logo.png 2012-03-02 19:56:20 +0000 differ
5=== added file 'data/progress_arrow_grey.png'
6Binary files data/progress_arrow_grey.png 1970-01-01 00:00:00 +0000 and data/progress_arrow_grey.png 2012-03-02 19:56:20 +0000 differ
7=== added file 'data/progress_arrow_orange.png'
8Binary files data/progress_arrow_orange.png 1970-01-01 00:00:00 +0000 and data/progress_arrow_orange.png 2012-03-02 19:56:20 +0000 differ
9=== added file 'data/progress_finish_grey.png'
10Binary files data/progress_finish_grey.png 1970-01-01 00:00:00 +0000 and data/progress_finish_grey.png 2012-03-02 19:56:20 +0000 differ
11=== added file 'data/progress_finish_orange.png'
12Binary files data/progress_finish_orange.png 1970-01-01 00:00:00 +0000 and data/progress_finish_orange.png 2012-03-02 19:56:20 +0000 differ
13=== added file 'data/progress_tick.png'
14Binary files data/progress_tick.png 1970-01-01 00:00:00 +0000 and data/progress_tick.png 2012-03-02 19:56:20 +0000 differ
15=== modified file 'data/qt/controlpanel.ui'
16--- data/qt/controlpanel.ui 2012-03-02 13:37:00 +0000
17+++ data/qt/controlpanel.ui 2012-03-02 19:56:20 +0000
18@@ -263,7 +263,7 @@
19 </layout>
20 </widget>
21 <widget class="QWidget" name="empty"/>
22- <widget class="SignInPanel" name="signin"/>
23+ <widget class="UbuntuOneWizard" name="wizard"/>
24 </widget>
25 </item>
26 <item>
27@@ -407,9 +407,9 @@
28 <container>1</container>
29 </customwidget>
30 <customwidget>
31- <class>SignInPanel</class>
32- <extends>QWidget</extends>
33- <header>ubuntuone.controlpanel.gui.qt.signin</header>
34+ <class>UbuntuOneWizard</class>
35+ <extends>QWizard</extends>
36+ <header>ubuntuone.controlpanel.gui.qt.wizard</header>
37 <container>1</container>
38 </customwidget>
39 </customwidgets>
40
41=== modified file 'data/qt/images.qrc'
42--- data/qt/images.qrc 2012-03-02 13:37:00 +0000
43+++ data/qt/images.qrc 2012-03-02 19:56:20 +0000
44@@ -1,11 +1,18 @@
45 <RCC>
46 <qresource prefix="/">
47+ <file>../banner.png</file>
48 <file>../computer.png</file>
49 <file>../external_icon_orange.png</file>
50 <file>../external_icon_white.png</file>
51 <file>../icon.png</file>
52 <file>../folder.png</file>
53+ <file>../logo.png</file>
54 <file>../phone.png</file>
55+ <file>../progress_arrow_grey.png</file>
56+ <file>../progress_arrow_orange.png</file>
57+ <file>../progress_finish_grey.png</file>
58+ <file>../progress_finish_orange.png</file>
59+ <file>../progress_tick.png</file>
60 <file>../sync_status_alert.png</file>
61 <file>../sync_status_disconnected.png</file>
62 <file>../sync_status_loading.png</file>
63
64=== added file 'data/qt/side_widget.ui'
65--- data/qt/side_widget.ui 1970-01-01 00:00:00 +0000
66+++ data/qt/side_widget.ui 2012-03-02 19:56:20 +0000
67@@ -0,0 +1,214 @@
68+<?xml version="1.0" encoding="UTF-8"?>
69+<ui version="4.0">
70+ <class>SideWidget</class>
71+ <widget class="QFrame" name="SideWidget">
72+ <property name="geometry">
73+ <rect>
74+ <x>0</x>
75+ <y>0</y>
76+ <width>170</width>
77+ <height>466</height>
78+ </rect>
79+ </property>
80+ <property name="sizePolicy">
81+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
82+ <horstretch>0</horstretch>
83+ <verstretch>0</verstretch>
84+ </sizepolicy>
85+ </property>
86+ <property name="minimumSize">
87+ <size>
88+ <width>170</width>
89+ <height>466</height>
90+ </size>
91+ </property>
92+ <layout class="QVBoxLayout" name="verticalLayout">
93+ <property name="spacing">
94+ <number>40</number>
95+ </property>
96+ <property name="margin">
97+ <number>0</number>
98+ </property>
99+ <item>
100+ <widget class="QLabel" name="ubuntu_one_logo_label">
101+ <property name="sizePolicy">
102+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
103+ <horstretch>0</horstretch>
104+ <verstretch>0</verstretch>
105+ </sizepolicy>
106+ </property>
107+ <property name="pixmap">
108+ <pixmap resource="images.qrc">:/logo.png</pixmap>
109+ </property>
110+ </widget>
111+ </item>
112+ <item>
113+ <widget class="QFrame" name="states_frame">
114+ <property name="sizePolicy">
115+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
116+ <horstretch>0</horstretch>
117+ <verstretch>0</verstretch>
118+ </sizepolicy>
119+ </property>
120+ <layout class="QVBoxLayout" name="verticalLayout_2">
121+ <property name="spacing">
122+ <number>20</number>
123+ </property>
124+ <property name="margin">
125+ <number>0</number>
126+ </property>
127+ <item>
128+ <layout class="QHBoxLayout" name="horizontalLayout">
129+ <property name="spacing">
130+ <number>7</number>
131+ </property>
132+ <item>
133+ <widget class="QLabel" name="install_icon">
134+ <property name="sizePolicy">
135+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
136+ <horstretch>0</horstretch>
137+ <verstretch>0</verstretch>
138+ </sizepolicy>
139+ </property>
140+ <property name="pixmap">
141+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
142+ </property>
143+ </widget>
144+ </item>
145+ <item>
146+ <widget class="QLabel" name="install_label">
147+ <property name="enabled">
148+ <bool>true</bool>
149+ </property>
150+ <property name="text">
151+ <string notr="true">Install</string>
152+ </property>
153+ </widget>
154+ </item>
155+ </layout>
156+ </item>
157+ <item>
158+ <layout class="QHBoxLayout" name="horizontalLayout_2">
159+ <property name="spacing">
160+ <number>7</number>
161+ </property>
162+ <property name="sizeConstraint">
163+ <enum>QLayout::SetDefaultConstraint</enum>
164+ </property>
165+ <item>
166+ <widget class="QLabel" name="signin_icon">
167+ <property name="sizePolicy">
168+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
169+ <horstretch>0</horstretch>
170+ <verstretch>0</verstretch>
171+ </sizepolicy>
172+ </property>
173+ <property name="text">
174+ <string/>
175+ </property>
176+ <property name="pixmap">
177+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
178+ </property>
179+ </widget>
180+ </item>
181+ <item>
182+ <widget class="QLabel" name="signin_label">
183+ <property name="enabled">
184+ <bool>true</bool>
185+ </property>
186+ <property name="text">
187+ <string notr="true">Sign In</string>
188+ </property>
189+ </widget>
190+ </item>
191+ </layout>
192+ </item>
193+ <item>
194+ <layout class="QHBoxLayout" name="horizontalLayout_4">
195+ <property name="spacing">
196+ <number>7</number>
197+ </property>
198+ <item>
199+ <widget class="QLabel" name="folders_icon">
200+ <property name="sizePolicy">
201+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
202+ <horstretch>0</horstretch>
203+ <verstretch>0</verstretch>
204+ </sizepolicy>
205+ </property>
206+ <property name="text">
207+ <string/>
208+ </property>
209+ <property name="pixmap">
210+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
211+ </property>
212+ </widget>
213+ </item>
214+ <item>
215+ <widget class="QLabel" name="folders_label">
216+ <property name="enabled">
217+ <bool>true</bool>
218+ </property>
219+ <property name="text">
220+ <string notr="true">Select sync folders</string>
221+ </property>
222+ </widget>
223+ </item>
224+ </layout>
225+ </item>
226+ <item>
227+ <layout class="QHBoxLayout" name="horizontalLayout_5">
228+ <property name="spacing">
229+ <number>7</number>
230+ </property>
231+ <item>
232+ <widget class="QLabel" name="sync_icon">
233+ <property name="sizePolicy">
234+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
235+ <horstretch>0</horstretch>
236+ <verstretch>0</verstretch>
237+ </sizepolicy>
238+ </property>
239+ <property name="text">
240+ <string/>
241+ </property>
242+ <property name="pixmap">
243+ <pixmap resource="images.qrc">:/progress_finish_grey.png</pixmap>
244+ </property>
245+ </widget>
246+ </item>
247+ <item>
248+ <widget class="QLabel" name="sync_label">
249+ <property name="enabled">
250+ <bool>true</bool>
251+ </property>
252+ <property name="text">
253+ <string notr="true">Sync, stream, share!</string>
254+ </property>
255+ </widget>
256+ </item>
257+ </layout>
258+ </item>
259+ </layout>
260+ </widget>
261+ </item>
262+ <item>
263+ <spacer name="verticalSpacer">
264+ <property name="orientation">
265+ <enum>Qt::Vertical</enum>
266+ </property>
267+ <property name="sizeHint" stdset="0">
268+ <size>
269+ <width>20</width>
270+ <height>40</height>
271+ </size>
272+ </property>
273+ </spacer>
274+ </item>
275+ </layout>
276+ </widget>
277+ <resources>
278+ <include location="images.qrc"/>
279+ </resources>
280+ <connections/>
281+</ui>
282
283=== modified file 'data/qt/signin.ui'
284--- data/qt/signin.ui 2012-02-22 15:41:33 +0000
285+++ data/qt/signin.ui 2012-03-02 19:56:20 +0000
286@@ -6,152 +6,133 @@
287 <rect>
288 <x>0</x>
289 <y>0</y>
290- <width>344</width>
291- <height>312</height>
292+ <width>370</width>
293+ <height>447</height>
294 </rect>
295 </property>
296- <layout class="QHBoxLayout" name="horizontalLayout_3">
297+ <layout class="QVBoxLayout" name="verticalLayout_2">
298 <property name="margin">
299 <number>0</number>
300 </property>
301 <item>
302 <widget class="QFrame" name="signin">
303 <layout class="QVBoxLayout" name="sign_in">
304- <property name="spacing">
305- <number>15</number>
306- </property>
307 <property name="margin">
308- <number>3</number>
309+ <number>0</number>
310 </property>
311 <item>
312- <widget class="QLabel" name="sign_in_label">
313- <property name="text">
314- <string notr="true">Sign in to Ubuntu One</string>
315- </property>
316- </widget>
317- </item>
318- <item>
319- <widget class="QLabel" name="description_label">
320- <property name="text">
321- <string notr="true">Sign in with your existing Ubuntu One username and password.</string>
322- </property>
323- </widget>
324+ <widget class="QFrame" name="frame">
325+ <layout class="QHBoxLayout" name="horizontalLayout_3">
326+ <property name="leftMargin">
327+ <number>0</number>
328+ </property>
329+ <property name="topMargin">
330+ <number>22</number>
331+ </property>
332+ <property name="rightMargin">
333+ <number>0</number>
334+ </property>
335+ <property name="bottomMargin">
336+ <number>0</number>
337+ </property>
338+ <item>
339+ <widget class="QLabel" name="banner">
340+ <property name="text">
341+ <string/>
342+ </property>
343+ <property name="textFormat">
344+ <enum>Qt::PlainText</enum>
345+ </property>
346+ <property name="pixmap">
347+ <pixmap resource="images.qrc">:/banner.png</pixmap>
348+ </property>
349+ <property name="alignment">
350+ <set>Qt::AlignCenter</set>
351+ </property>
352+ <property name="wordWrap">
353+ <bool>true</bool>
354+ </property>
355+ </widget>
356+ </item>
357+ </layout>
358+ </widget>
359+ </item>
360+ <item>
361+ <spacer name="verticalSpacer_2">
362+ <property name="orientation">
363+ <enum>Qt::Vertical</enum>
364+ </property>
365+ <property name="sizeHint" stdset="0">
366+ <size>
367+ <width>20</width>
368+ <height>40</height>
369+ </size>
370+ </property>
371+ </spacer>
372+ </item>
373+ <item>
374+ <widget class="QLabel" name="welcome_label">
375+ <property name="font">
376+ <font>
377+ <pointsize>11</pointsize>
378+ <weight>50</weight>
379+ <bold>false</bold>
380+ </font>
381+ </property>
382+ <property name="text">
383+ <string notr="true">Welcome to Ubuntu One</string>
384+ </property>
385+ <property name="alignment">
386+ <set>Qt::AlignCenter|Qt::AlignHCenter|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
387+ </property>
388+ </widget>
389+ </item>
390+ <item>
391+ <spacer name="verticalSpacer">
392+ <property name="orientation">
393+ <enum>Qt::Vertical</enum>
394+ </property>
395+ <property name="sizeHint" stdset="0">
396+ <size>
397+ <width>20</width>
398+ <height>40</height>
399+ </size>
400+ </property>
401+ </spacer>
402 </item>
403 <item>
404 <layout class="QHBoxLayout" name="horizontalLayout">
405 <item>
406- <layout class="QVBoxLayout" name="verticalLayout_2">
407- <property name="spacing">
408- <number>15</number>
409- </property>
410- <item>
411- <layout class="QVBoxLayout" name="verticalLayout_4">
412- <property name="spacing">
413- <number>0</number>
414- </property>
415- <item>
416- <widget class="QLabel" name="email_label">
417- <property name="text">
418- <string notr="true">Email address</string>
419- </property>
420- </widget>
421- </item>
422- <item>
423- <widget class="QLineEdit" name="email_entry">
424- <property name="text">
425- <string/>
426- </property>
427- </widget>
428- </item>
429- </layout>
430- </item>
431- <item>
432- <layout class="QVBoxLayout" name="verticalLayout_3">
433- <property name="spacing">
434- <number>0</number>
435- </property>
436- <item>
437- <widget class="QLabel" name="password_label">
438- <property name="text">
439- <string notr="true">Password</string>
440- </property>
441- </widget>
442- </item>
443- <item>
444- <widget class="QLineEdit" name="password_entry">
445- <property name="echoMode">
446- <enum>QLineEdit::Password</enum>
447- </property>
448- </widget>
449- </item>
450- </layout>
451- </item>
452- <item>
453- <layout class="QHBoxLayout" name="horizontalLayout_2">
454- <item>
455- <widget class="QPushButton" name="signin_button">
456- <property name="text">
457- <string notr="true">Sign in</string>
458- </property>
459- <property name="default">
460- <bool>true</bool>
461- </property>
462- </widget>
463- </item>
464- <item>
465- <widget class="QPushButton" name="cancel_button">
466- <property name="text">
467- <string notr="true">Cancel</string>
468- </property>
469- <property name="secondary" stdset="0">
470- <bool>true</bool>
471- </property>
472- </widget>
473- </item>
474- <item>
475- <spacer name="horizontalSpacer">
476- <property name="orientation">
477- <enum>Qt::Horizontal</enum>
478- </property>
479- <property name="sizeHint" stdset="0">
480- <size>
481- <width>40</width>
482- <height>20</height>
483- </size>
484- </property>
485- </spacer>
486- </item>
487- </layout>
488- </item>
489- <item>
490- <layout class="QHBoxLayout" name="horizontalLayout_4">
491- <item>
492- <widget class="GoToWebButton" name="forgot_password_button">
493- <property name="sizePolicy">
494- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
495- <horstretch>0</horstretch>
496- <verstretch>0</verstretch>
497- </sizepolicy>
498- </property>
499- <property name="text">
500- <string notr="true">Forgot your password?</string>
501- </property>
502- </widget>
503- </item>
504- <item>
505- <spacer name="horizontalSpacer_3">
506- <property name="orientation">
507- <enum>Qt::Horizontal</enum>
508- </property>
509- <property name="sizeHint" stdset="0">
510- <size>
511- <width>40</width>
512- <height>20</height>
513- </size>
514- </property>
515- </spacer>
516- </item>
517- </layout>
518+ <spacer name="horizontalSpacer">
519+ <property name="orientation">
520+ <enum>Qt::Horizontal</enum>
521+ </property>
522+ <property name="sizeHint" stdset="0">
523+ <size>
524+ <width>40</width>
525+ <height>20</height>
526+ </size>
527+ </property>
528+ </spacer>
529+ </item>
530+ <item>
531+ <layout class="QVBoxLayout" name="verticalLayout">
532+ <item>
533+ <widget class="QPushButton" name="login_button">
534+ <property name="text">
535+ <string notr="true">Existing account</string>
536+ </property>
537+ <property name="default">
538+ <bool>true</bool>
539+ </property>
540+ </widget>
541+ </item>
542+ <item>
543+ <widget class="QPushButton" name="register_button">
544+ <property name="text">
545+ <string notr="true">Setup new account</string>
546+ </property>
547+ </widget>
548 </item>
549 </layout>
550 </item>
551@@ -170,31 +151,13 @@
552 </item>
553 </layout>
554 </item>
555- <item>
556- <spacer name="verticalSpacer">
557- <property name="orientation">
558- <enum>Qt::Vertical</enum>
559- </property>
560- <property name="sizeHint" stdset="0">
561- <size>
562- <width>20</width>
563- <height>40</height>
564- </size>
565- </property>
566- </spacer>
567- </item>
568 </layout>
569 </widget>
570 </item>
571 </layout>
572 </widget>
573- <customwidgets>
574- <customwidget>
575- <class>GoToWebButton</class>
576- <extends>QPushButton</extends>
577- <header>ubuntuone.controlpanel.gui.qt.gotoweb</header>
578- </customwidget>
579- </customwidgets>
580- <resources/>
581+ <resources>
582+ <include location="images.qrc"/>
583+ </resources>
584 <connections/>
585 </ui>
586
587=== modified file 'data/qt/ubuntuone.qss'
588--- data/qt/ubuntuone.qss 2012-03-02 13:37:00 +0000
589+++ data/qt/ubuntuone.qss 2012-03-02 19:56:20 +0000
590@@ -12,9 +12,9 @@
591 border: none;
592 }
593
594-QFrame#signin,
595+UbuntuOneWizard,
596 QFrame#frame_header {
597- background: #ffffff;
598+ background: white;
599 border-radius: 5px;
600 border-style: solid;
601 border-color: #939389;
602@@ -59,6 +59,15 @@
603 font-size: 24px;
604 }
605
606+SideWidget {
607+ background-color: white;
608+ border-style: dotted;
609+ border-color: #939389;
610+ border-right-width: 1px;
611+ color: white;
612+ min-height: 100px;
613+}
614+
615 QPushButton {
616 border-radius: 5px;
617 border-style: solid;
618@@ -280,6 +289,10 @@
619 color: #df2d1f;
620 }
621
622+QLabel#welcome_label {
623+ font-size: 20px;
624+}
625+
626 QAbstractItemView {
627 border-style: solid;
628 border-color: #898989;
629
630=== modified file 'ubuntuone/controlpanel/backend.py'
631--- ubuntuone/controlpanel/backend.py 2012-02-06 15:23:27 +0000
632+++ ubuntuone/controlpanel/backend.py 2012-03-02 19:56:20 +0000
633@@ -343,10 +343,23 @@
634
635 @log_call(logger.debug, with_args=False)
636 @inlineCallbacks
637- def login(self, email, password):
638- """Login using 'email' and 'password'."""
639- result = yield self.login_client.login_email_password(
640- email=email, password=password)
641+ def login(self, email=None, password=None):
642+ """Login using 'email' and 'password' if not None, else prompt user."""
643+ result = None
644+ if email is not None and password is not None:
645+ result = yield self.login_client.login_email_password(
646+ email=email, password=password)
647+ else:
648+ result = yield self.login_client.login()
649+ # cache credentils
650+ self._credentials = result
651+ returnValue(result)
652+
653+ @log_call(logger.debug)
654+ @inlineCallbacks
655+ def register(self):
656+ """Register a new user."""
657+ result = yield self.login_client.register()
658 # cache credentils
659 self._credentials = result
660 returnValue(result)
661
662=== modified file 'ubuntuone/controlpanel/gui/__init__.py'
663--- ubuntuone/controlpanel/gui/__init__.py 2012-02-22 16:31:41 +0000
664+++ ubuntuone/controlpanel/gui/__init__.py 2012-03-02 19:56:20 +0000
665@@ -83,7 +83,7 @@
666 CREDENTIALS_ERROR = _('There was a problem while retrieving the credentials.')
667 DASHBOARD_BUTTON_TOOLTIP = _('View your personal details and service '
668 'summary')
669-DASHBOARD_TITLE = _('Welcome to Ubuntu One!')
670+DASHBOARD_TITLE = WELCOME_LABEL = _('Welcome to Ubuntu One!')
671 DASHBOARD_VALUE_ERROR = _('The information could not be retrieved. '
672 'Maybe your internet connection is down?')
673 DESKTOPCOUCH_PKG = 'desktopcouch-ubuntuone'
674@@ -154,6 +154,7 @@
675 GET_HELP_ONLINE = _('Get help online')
676 GET_MORE_STORAGE = _('Get more storage')
677 GREETING = _('Hi %(user_display_name)s')
678+INSTALL = _('Install')
679 INSTALL_PACKAGE = _('You need to install the package <i>%(package_name)s'
680 '</i> in order to enable more sync services.')
681 INSTALL_PLUGIN = _('Install the %(plugin_name)s for the sync service: '
682@@ -181,6 +182,7 @@
683 QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).0f%%)')
684 REMOVE_BUTTON = _('Remove')
685 RESTORE_LABEL = _('Restore')
686+SELECT_FOLDERS = _('Select sync folders')
687 SERVICES_BUTTON_TOOLTIP = _('Manage the sync services')
688 SERVICES_TITLE = _('Enable the sync services for this computer.')
689 SETTINGS_ALLOW_NOTIFICATIONS = _('Allow all notifications to this device')
690@@ -202,15 +204,9 @@
691 'to this computer')
692 SHARES_BUTTON_TOOLTIP = _('Manage the shares offered to others')
693 SHARES_TITLE = _('Manage permissions for shares made to other users.')
694-SIGNIN_BUTTON = _('Sign in')
695-SIGNIN_CANCEL = _('Cancel')
696-SIGNIN_DESCRIPTION = _('Sign in with your existing Ubuntu One '
697- 'username and password.')
698-SIGNIN_EMAIL = _('Email address')
699-SIGNIN_FORGOT_PASSWORD = _('Forgot your password?')
700-SIGNIN_PASSWORD = _('Password')
701-SIGNIN_TITLE = _('Sign in to Ubuntu One')
702+SIGN_IN = _('Sign in')
703 SUCCESS_INSTALL = _('<i>%(package_name)s</i> was successfully installed')
704+SYNC_STREAM_SHARE = _('Sync, stream, share')
705 TALK_TO_US = _('Talk to us')
706 VALUE_ERROR = _('Value could not be retrieved.')
707 UNKNOWN_ERROR = _('Unknown error')
708
709=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
710--- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-02-28 21:29:16 +0000
711+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-02 19:56:20 +0000
712@@ -58,6 +58,8 @@
713 ui_class = controlpanel_ui
714 logger = logger
715
716+ finished = QtCore.pyqtSignal()
717+
718 def _setup(self):
719 """Do some extra setupping for the UI."""
720 self.ui.get_more_space_button.setText(GET_MORE_STORAGE)
721@@ -70,7 +72,6 @@
722
723 self.ui.devices_tab.localDeviceRemoved.connect(
724 self.on_credentials_not_found)
725- self.ui.signin.credentialsFound.connect(lambda creds: self.load())
726
727 self.ui.tab_widget.setTabText(
728 self.ui.tab_widget.indexOf(self.ui.folders_tab), MAIN_FOLDERS_TAB)
729@@ -86,15 +87,16 @@
730 def connect_file_sync(self):
731 """Connect file sync service if the setting autoconnect is enabled."""
732 settings = yield self.backend.file_sync_settings_info()
733- if AUTOCONNECT_KEY in settings and settings[AUTOCONNECT_KEY]:
734+ if settings.get(AUTOCONNECT_KEY, False):
735 yield self.backend.connect_files()
736
737 @log_call(logger.debug)
738 def on_credentials_not_found(self):
739 """Credentials are not found or were removed."""
740- self.ui.switcher.setCurrentWidget(self.ui.signin)
741+ self.ui.switcher.setCurrentWidget(self.ui.wizard)
742 self.is_processing = False
743
744+ @defer.inlineCallbacks
745 @log_call(logger.debug)
746 def on_credentials_found(self):
747 """Credentials are not found or were removed."""
748@@ -102,6 +104,9 @@
749 self.connect_file_sync()
750 self.is_processing = False
751
752+ info = yield self.backend.account_info()
753+ self.process_info(info)
754+
755 # pylint: disable=E0202
756 @defer.inlineCallbacks
757 def load(self):
758@@ -112,8 +117,6 @@
759 self.on_credentials_not_found()
760 else:
761 self.on_credentials_found()
762- info = yield self.backend.account_info()
763- self.process_info(info)
764
765 @log_call(logger.debug)
766 def process_info(self, info):
767@@ -155,3 +158,11 @@
768 def on_facebook_button_clicked(self):
769 """The facebook button was clicked."""
770 qt.uri_hook(FACEBOOK_LINK)
771+
772+ def on_wizard_rejected(self):
773+ """Let clients know that we're done."""
774+ self.finished.emit()
775+
776+ def on_wizard_finished(self, status):
777+ """Move to controlpanel if wizar ended successfully."""
778+ self.on_credentials_found()
779
780=== modified file 'ubuntuone/controlpanel/gui/qt/gui.py'
781--- ubuntuone/controlpanel/gui/qt/gui.py 2012-02-28 20:26:13 +0000
782+++ ubuntuone/controlpanel/gui/qt/gui.py 2012-03-02 19:56:20 +0000
783@@ -39,7 +39,7 @@
784
785 def _setup(self):
786 """Do some extra setupping for the UI."""
787- self.ui.control_panel.ui.signin.signinCanceled.connect(self.close)
788+ self.ui.control_panel.finished.connect(self.close)
789
790 # Invalid name "closeEvent"
791 # pylint: disable=C0103
792
793=== added file 'ubuntuone/controlpanel/gui/qt/side_widget.py'
794--- ubuntuone/controlpanel/gui/qt/side_widget.py 1970-01-01 00:00:00 +0000
795+++ ubuntuone/controlpanel/gui/qt/side_widget.py 2012-03-02 19:56:20 +0000
796@@ -0,0 +1,81 @@
797+# -*- coding: utf-8 -*-
798+
799+# Authors: Roberto Alsina <roberto.alsina@canonical.com>
800+#
801+# Copyright 2011 Canonical Ltd.
802+#
803+# This program is free software: you can redistribute it and/or modify it
804+# under the terms of the GNU General Public License version 3, as published
805+# by the Free Software Foundation.
806+#
807+# This program is distributed in the hope that it will be useful, but
808+# WITHOUT ANY WARRANTY; without even the implied warranties of
809+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
810+# PURPOSE. See the GNU General Public License for more details.
811+#
812+# You should have received a copy of the GNU General Public License along
813+# with this program. If not, see <http://www.gnu.org/licenses/>.
814+
815+"""Wizard's side widget."""
816+
817+from PyQt4 import QtGui
818+
819+from ubuntuone.controlpanel.gui import (
820+ INSTALL,
821+ SIGN_IN,
822+ SELECT_FOLDERS,
823+ SYNC_STREAM_SHARE,
824+)
825+from ubuntuone.controlpanel.gui.qt.ui import side_widget_ui
826+
827+
828+class SideWidget(QtGui.QFrame):
829+
830+ """Wizard's side widget."""
831+
832+ install_stage = 0
833+ signin_stage = 1
834+ folders_stage = 2
835+ sync_stage = 3
836+
837+ def __init__(self, *args, **kwargs):
838+ super(SideWidget, self).__init__(*args, **kwargs)
839+ self.ui = side_widget_ui.Ui_SideWidget()
840+ self.ui.setupUi(self)
841+
842+ self.ui.install_label.setText(INSTALL)
843+ self.ui.signin_label.setText(SIGN_IN)
844+ self.ui.folders_label.setText(SELECT_FOLDERS)
845+ self.ui.sync_label.setText(SYNC_STREAM_SHARE)
846+
847+ self._stage = 0
848+
849+ def _get_stage(self):
850+ """Return the current stage."""
851+ return self._stage
852+
853+ def _set_stage(self, stage):
854+ """Switch to the desired stage."""
855+ self._stage = stage
856+
857+ self.set_stage_icon(self.ui.install_icon, self.install_stage)
858+ self.set_stage_icon(self.ui.signin_icon, self.signin_stage)
859+ self.set_stage_icon(self.ui.folders_icon, self.folders_stage)
860+ self.set_stage_icon(self.ui.sync_icon, self.sync_stage)
861+
862+ stage = property(fget=_get_stage, fset=_set_stage)
863+
864+ def set_stage_icon(self, icon, target_stage):
865+ """Set the icon depending on the proper state."""
866+ icon.setEnabled(self.stage >= target_stage)
867+
868+ if self.stage == target_stage and icon == self.ui.sync_icon:
869+ icon.setPixmap(QtGui.QPixmap(":/progress_finish_orange.png"))
870+ elif self.stage == target_stage:
871+ icon.setPixmap(QtGui.QPixmap(":/progress_arrow_orange.png"))
872+ elif self.stage > target_stage:
873+ icon.setPixmap(QtGui.QPixmap(":/progress_tick.png"))
874+ elif icon == self.ui.sync_icon:
875+ icon.setPixmap(QtGui.QPixmap(":/progress_finish_grey.png"))
876+ else:
877+ icon.setPixmap(QtGui.QPixmap(":/progress_arrow_grey.png"))
878
879=== modified file 'ubuntuone/controlpanel/gui/qt/signin.py'
880--- ubuntuone/controlpanel/gui/qt/signin.py 2012-02-22 14:58:25 +0000
881+++ ubuntuone/controlpanel/gui/qt/signin.py 2012-03-02 19:56:20 +0000
882@@ -16,88 +16,23 @@
883
884 """The signin page."""
885
886-from PyQt4 import QtCore
887-from twisted.internet import defer
888-
889-from ubuntuone.controlpanel.gui import (
890- RESET_PASSWORD_LINK,
891- SIGNIN_BUTTON,
892- SIGNIN_CANCEL,
893- SIGNIN_DESCRIPTION,
894- SIGNIN_EMAIL,
895- SIGNIN_FORGOT_PASSWORD,
896- SIGNIN_PASSWORD,
897- SIGNIN_TITLE,
898+from ubuntu_sso.utils.ui import (
899+ EXISTING_ACCOUNT_CHOICE_BUTTON,
900+ SET_UP_ACCOUNT_CHOICE_BUTTON,
901 )
902-from ubuntuone.controlpanel.gui.qt import icon_from_name, handle_errors
903+from ubuntuone.controlpanel.gui import WELCOME_LABEL
904 from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin
905 from ubuntuone.controlpanel.gui.qt.ui import signin_ui
906-from ubuntuone.controlpanel.logger import setup_logging, log_call
907-
908-
909-logger = setup_logging('qt.signin')
910
911
912 class SignInPanel(UbuntuOneBin):
913 """The widget for signing in."""
914
915 ui_class = signin_ui
916- logger = logger
917-
918- signinCanceled = QtCore.pyqtSignal()
919- credentialsFound = QtCore.pyqtSignal(dict)
920
921 def _setup(self):
922 """Do some extra setupping for the UI."""
923 super(SignInPanel, self)._setup()
924- self.ui.cancel_button.setText(SIGNIN_CANCEL)
925- self.ui.description_label.setText(SIGNIN_DESCRIPTION)
926- self.ui.email_label.setText(SIGNIN_EMAIL)
927- self.ui.sign_in_label.setText(SIGNIN_TITLE)
928- self.ui.password_label.setText(SIGNIN_PASSWORD)
929-
930- self.ui.forgot_password_button.setText(SIGNIN_FORGOT_PASSWORD)
931- self.ui.forgot_password_button.uri = RESET_PASSWORD_LINK
932- icon = icon_from_name('external_icon_orange')
933- self.ui.forgot_password_button.setIcon(icon)
934-
935- self.ui.signin_button.setText(SIGNIN_BUTTON)
936- self.ui.signin_button.setEnabled(False)
937- for entry in (self.ui.email_entry, self.ui.password_entry):
938- entry.textChanged.connect(self.validate)
939- entry.returnPressed.connect(self.ui.signin_button.click)
940-
941- def validate(self, *a, **kw):
942- """Enable sign in button only if email and password are non empty."""
943- email = unicode(self.ui.email_entry.text())
944- password = unicode(self.ui.password_entry.text())
945- self.ui.signin_button.setEnabled(bool(email and password))
946- self.ui.signin_button.style().unpolish(self.ui.signin_button)
947- self.ui.signin_button.style().polish(self.ui.signin_button)
948-
949- # pylint: disable=E0202
950- @defer.inlineCallbacks
951- def load(self):
952- """Load specific tab info."""
953- yield self.backend.get_credentials()
954-
955- @QtCore.pyqtSlot()
956- @handle_errors(logger=logger)
957- @log_call(logger.debug)
958- @defer.inlineCallbacks
959- def on_signin_button_clicked(self):
960- """The 'Sign in' button was clicked."""
961- email = unicode(self.ui.email_entry.text())
962- password = unicode(self.ui.password_entry.text())
963- self.is_processing = True
964- try:
965- result = yield self.backend.login(email=email, password=password)
966- logger.info('Emitting credentialsFound for email %r.', email)
967- self.credentialsFound.emit(result)
968- finally:
969- self.is_processing = False
970-
971- @QtCore.pyqtSlot()
972- def on_cancel_button_clicked(self):
973- """The 'Cancel' button was clicked."""
974- self.signinCanceled.emit()
975+ self.ui.welcome_label.setText(WELCOME_LABEL)
976+ self.ui.login_button.setText(EXISTING_ACCOUNT_CHOICE_BUTTON)
977+ self.ui.register_button.setText(SET_UP_ACCOUNT_CHOICE_BUTTON)
978
979=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
980--- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-02 13:40:05 +0000
981+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-02 19:56:20 +0000
982@@ -1,8 +1,6 @@
983 # -*- coding: utf-8 -*-
984-
985-# Authors: Alejandro J. Cura <alecu@canonical.com>
986 #
987-# Copyright 2011 Canonical Ltd.
988+# Copyright 2011-2012 Canonical Ltd.
989 #
990 # This program is free software: you can redistribute it and/or modify it
991 # under the terms of the GNU General Public License version 3, as published
992@@ -28,7 +26,11 @@
993 from ubuntuone.controlpanel import backend, cache
994 from ubuntuone.controlpanel.tests import TestCase, EXPECTED_ACCOUNT_INFO, TOKEN
995 from ubuntuone.controlpanel.gui import qt
996-from ubuntuone.controlpanel.gui.tests import FakedObject, USER_HOME
997+from ubuntuone.controlpanel.gui.tests import (
998+ FakedObject,
999+ FAKE_VOLUMES_INFO,
1000+ USER_HOME,
1001+)
1002
1003 # Attribute 'yyy' defined outside __init__, access to a protected member
1004 # pylint: disable=W0201, W0212
1005@@ -66,6 +68,16 @@
1006 SAMPLE_COMPUTER_INFO,
1007 SAMPLE_PHONE_INFO,
1008 ]
1009+
1010+SAMPLE_SETTINGS = {
1011+ backend.AUTOCONNECT_KEY: True,
1012+ backend.SHOW_ALL_NOTIFICATIONS_KEY: True,
1013+ backend.SHARE_AUTOSUBSCRIBE_KEY: True,
1014+ backend.UDF_AUTOSUBSCRIBE_KEY: True,
1015+ backend.DOWNLOAD_KEY: 20480,
1016+ backend.UPLOAD_KEY: 2048,
1017+}
1018+
1019 NO_OP = lambda *args: None
1020
1021
1022@@ -121,6 +133,7 @@
1023 'file_sync_settings_info',
1024 'file_sync_status',
1025 'login',
1026+ 'register',
1027 'remove_device',
1028 'replications_info',
1029 'restart_files',
1030@@ -131,6 +144,12 @@
1031 'validate_path_for_folder',
1032 'volumes_info',
1033 ]
1034+ exposed_results = {
1035+ 'account_info': SAMPLE_ACCOUNT_INFO,
1036+ 'devices_info': SAMPLE_DEVICES_INFO,
1037+ 'volumes_info': FAKE_VOLUMES_INFO,
1038+ 'file_sync_settings_info': SAMPLE_SETTINGS,
1039+ }
1040
1041 def get_credentials(self):
1042 """Fake credentials retrieval."""
1043@@ -254,6 +273,7 @@
1044 # pylint: disable=E1102
1045 self.ui = self.class_ui(**self.kwargs)
1046 # pylint: enable=E1102
1047+ self.ui.show()
1048 self.addCleanup(self.ui.destroy)
1049
1050 if getattr(self.ui, 'backend', None) is not None:
1051
1052=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_account.py'
1053--- ubuntuone/controlpanel/gui/qt/tests/test_account.py 2011-09-01 17:11:16 +0000
1054+++ ubuntuone/controlpanel/gui/qt/tests/test_account.py 2012-03-02 19:56:20 +0000
1055@@ -36,11 +36,6 @@
1056 innerclass_name = "Ui_Form"
1057 class_ui = gui.AccountPanel
1058
1059- @defer.inlineCallbacks
1060- def setUp(self):
1061- yield super(AccountPanelTestCase, self).setUp()
1062- self.ui.backend.next_result = SAMPLE_ACCOUNT_INFO
1063-
1064 def test_is_processing_while_asking_info(self):
1065 """The ui is processing while the contents are loaded."""
1066 def check():
1067
1068=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_addfolder.py'
1069--- ubuntuone/controlpanel/gui/qt/tests/test_addfolder.py 2012-01-18 19:52:25 +0000
1070+++ ubuntuone/controlpanel/gui/qt/tests/test_addfolder.py 2012-03-02 19:56:20 +0000
1071@@ -23,7 +23,6 @@
1072 from twisted.internet import defer
1073
1074 from ubuntuone.controlpanel.gui.tests import (
1075- FAKE_VOLUMES_INFO,
1076 USER_HOME,
1077 )
1078 from ubuntuone.controlpanel.gui.qt import addfolder as gui
1079@@ -51,7 +50,6 @@
1080 yield super(AddFolderButtonTestCase, self).setUp()
1081 self.patch(FakedFileDialog, 'response', gui.QtCore.QString(''))
1082 self.patch(self.ui.backend, 'validate_path_for_folder', lambda p: True)
1083- self.ui.backend.next_result = FAKE_VOLUMES_INFO
1084 old_home = os.environ['HOME']
1085 os.environ['HOME'] = USER_HOME
1086 self.addCleanup(lambda: os.environ.__setitem__('HOME', old_home))
1087
1088=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
1089--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-02-28 20:26:13 +0000
1090+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-02 19:56:20 +0000
1091@@ -24,12 +24,14 @@
1092
1093 from ubuntuone.controlpanel.gui.qt import controlpanel as gui
1094 from ubuntuone.controlpanel.gui.qt.tests import (
1095- SAMPLE_ACCOUNT_INFO, SAMPLE_NAME, TOKEN,
1096+ SAMPLE_ACCOUNT_INFO, SAMPLE_NAME,
1097 )
1098 from ubuntuone.controlpanel.gui.qt.tests.test_ubuntuonebin import (
1099 UbuntuOneBinTestCase,
1100 )
1101
1102+# pylint: disable=W0212
1103+
1104
1105 class ControlPanelTestCase(UbuntuOneBinTestCase):
1106 """Test the qt control panel."""
1107@@ -39,12 +41,6 @@
1108 class_ui = gui.ControlPanel
1109
1110 @defer.inlineCallbacks
1111- def setUp(self):
1112- yield super(ControlPanelTestCase, self).setUp()
1113- self.patch(self.ui.ui.folders_tab, 'process_info', lambda info: None)
1114- self.ui.backend.next_result = SAMPLE_ACCOUNT_INFO
1115-
1116- @defer.inlineCallbacks
1117 def test_is_processing_while_asking_info(self):
1118 """The ui is processing while the contents are loaded."""
1119 def check():
1120@@ -73,10 +69,10 @@
1121 self.assertEqual(self._called, ((), {}))
1122
1123 def test_on_credentials_not_found(self):
1124- """The signin panel is shown."""
1125+ """The wizard panel is shown."""
1126 self.ui.on_credentials_found()
1127 self.ui.on_credentials_not_found()
1128- self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.signin)
1129+ self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.wizard)
1130
1131 @defer.inlineCallbacks
1132 def test_on_credentials_found_called(self):
1133@@ -126,9 +122,7 @@
1134
1135 def test_update_over_quota(self):
1136 """Check the labels state when the user exceed the quota."""
1137- # pylint: disable=W0212
1138 self.ui._update_quota(True)
1139- # pylint: enable=W0212
1140
1141 self.assertTrue(
1142 self.ui.ui.percentage_usage_label.property("OverQuota").toBool())
1143@@ -137,9 +131,7 @@
1144
1145 def test_update_quota_in_range(self):
1146 """Check the labels state when the quota is under the threshold."""
1147- # pylint: disable=W0212
1148 self.ui._update_quota(False)
1149- # pylint: enable=W0212
1150
1151 self.assertFalse(
1152 self.ui.ui.percentage_usage_label.property("OverQuota").toBool())
1153@@ -149,12 +141,19 @@
1154 def test_on_local_device_removed(self):
1155 """On DeviesPanel's localDeviceRemoved, emit credentialsNotFound."""
1156 self.ui.ui.devices_tab.localDeviceRemoved.emit()
1157- self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.signin)
1158-
1159- def test_on_signin_credentials_found(self):
1160- """On SignInPanel's credentialsFound, the management panel is shown."""
1161- self.patch(self.ui, 'load', self._set_called)
1162- self.ui.ui.signin.credentialsFound.emit(TOKEN)
1163+ self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.wizard)
1164+
1165+ def test_on_wizard_finished(self):
1166+ """When the wizard is finished, the management panel is shown."""
1167+ self.patch(self.ui, 'on_credentials_found', self._set_called)
1168+ self.ui.ui.wizard.finished.emit(1)
1169+
1170+ self.assertEqual(self._called, ((), {}))
1171+
1172+ def test_on_wizard_rejected(self):
1173+ """When the wizard is cancelled, the finished signal is emitted."""
1174+ self.ui.finished.connect(self._set_called)
1175+ self.ui.ui.wizard.rejected.emit()
1176
1177 self.assertEqual(self._called, ((), {}))
1178
1179@@ -172,13 +171,13 @@
1180 @defer.inlineCallbacks
1181 def test_connect_file_sync_without_autoconnect(self):
1182 """Connect is called if autoconnect is disabled."""
1183+ self.ui.backend._called.clear()
1184 settings = {gui.AUTOCONNECT_KEY: False}
1185 self.patch(self.ui.backend, 'file_sync_settings_info',
1186 lambda: defer.succeed(settings))
1187
1188 yield self.ui.connect_file_sync()
1189
1190- # pylint: disable=W0212
1191 self.assertNotIn('connect_files', self.ui.backend._called)
1192
1193
1194
1195=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_devices.py'
1196--- ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2012-01-05 15:20:21 +0000
1197+++ ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2012-03-02 19:56:20 +0000
1198@@ -37,11 +37,6 @@
1199 class_ui = gui.DevicesPanel
1200 executed = False
1201
1202- @defer.inlineCallbacks
1203- def setUp(self):
1204- yield super(DevicesPanelTestCase, self).setUp()
1205- self.ui.backend.next_result = SAMPLE_DEVICES_INFO
1206-
1207 def test_is_processing_while_asking_info(self):
1208 """The ui is processing while the contents are loaded."""
1209 def check():
1210
1211=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
1212--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-02-28 17:48:23 +0000
1213+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-02 19:56:20 +0000
1214@@ -64,7 +64,8 @@
1215 @defer.inlineCallbacks
1216 def setUp(self):
1217 yield super(FoldersPanelTestCase, self).setUp()
1218- self.ui.backend.next_result = FAKE_VOLUMES_MINIMAL_INFO
1219+ self.patch(self.ui.backend, 'volumes_info',
1220+ lambda *a, **kw: defer.succeed(FAKE_VOLUMES_MINIMAL_INFO))
1221
1222 self.memento = MementoHandler()
1223 self.memento.setLevel(logging.DEBUG)
1224
1225=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gui.py'
1226--- ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-02-28 20:26:13 +0000
1227+++ ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-03-02 19:56:20 +0000
1228@@ -45,7 +45,7 @@
1229 def test_on_signin_canceled(self):
1230 """On SigninPanel's signinCanceled, close."""
1231 self.patch(self.ui, 'closeEvent', self._set_called)
1232- self.ui.ui.control_panel.ui.signin.signinCanceled.emit()
1233+ self.ui.ui.control_panel.finished.emit()
1234 self.assertEqual(len(self._called[0]), 1)
1235 self.assertIsInstance(self._called[0][0], gui.QtGui.QCloseEvent)
1236
1237
1238=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_preferences.py'
1239--- ubuntuone/controlpanel/gui/qt/tests/test_preferences.py 2011-07-18 17:53:32 +0000
1240+++ ubuntuone/controlpanel/gui/qt/tests/test_preferences.py 2012-03-02 19:56:20 +0000
1241@@ -23,6 +23,7 @@
1242 from twisted.internet import defer
1243
1244 from ubuntuone.controlpanel.gui.qt import preferences as gui
1245+from ubuntuone.controlpanel.gui.qt.tests import SAMPLE_SETTINGS
1246 from ubuntuone.controlpanel.gui.qt.tests.test_ubuntuonebin import (
1247 UbuntuOneBinTestCase,
1248 )
1249@@ -30,15 +31,6 @@
1250 # Access to a protected member
1251 # pylint: disable=W0212
1252
1253-SAMPLE_SETTINGS = {
1254- gui.backend.AUTOCONNECT_KEY: True,
1255- gui.backend.SHOW_ALL_NOTIFICATIONS_KEY: True,
1256- gui.backend.SHARE_AUTOSUBSCRIBE_KEY: True,
1257- gui.backend.UDF_AUTOSUBSCRIBE_KEY: True,
1258- gui.backend.DOWNLOAD_KEY: 20480,
1259- gui.backend.UPLOAD_KEY: 2048,
1260-}
1261-
1262
1263 class PreferencesPanelTestCase(UbuntuOneBinTestCase):
1264 """Test the qt cloud preferences tab."""
1265@@ -47,12 +39,6 @@
1266 innerclass_name = "Ui_Form"
1267 class_ui = gui.PreferencesPanel
1268
1269- @defer.inlineCallbacks
1270- def setUp(self):
1271- yield super(PreferencesPanelTestCase, self).setUp()
1272- self.ui.backend.next_result = SAMPLE_SETTINGS
1273- yield self.ui.load()
1274-
1275 def dict_from_ui_values(self):
1276 """Build the settings dict from the ui values."""
1277 autoconnect = self.ui.ui.autoconnect_checkbox.checkState()
1278@@ -275,7 +261,7 @@
1279 self._test_update_ui_from_settings_info(settings)
1280
1281 @defer.inlineCallbacks
1282- def test_is_processing_while_restoreing_changes(self):
1283+ def test_is_processing_while_restoring_changes(self):
1284 """The ui is processing while the changes are being applied."""
1285 def check():
1286 """The ui must be is_processing."""
1287
1288=== added file 'ubuntuone/controlpanel/gui/qt/tests/test_side_widget.py'
1289--- ubuntuone/controlpanel/gui/qt/tests/test_side_widget.py 1970-01-01 00:00:00 +0000
1290+++ ubuntuone/controlpanel/gui/qt/tests/test_side_widget.py 2012-03-02 19:56:20 +0000
1291@@ -0,0 +1,90 @@
1292+# -*- coding: utf-8 -*-
1293+#
1294+# Copyright 2011-2012 Canonical Ltd.
1295+#
1296+# This program is free software: you can redistribute it and/or modify it
1297+# under the terms of the GNU General Public License version 3, as published
1298+# by the Free Software Foundation.
1299+#
1300+# This program is distributed in the hope that it will be useful, but
1301+# WITHOUT ANY WARRANTY; without even the implied warranties of
1302+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1303+# PURPOSE. See the GNU General Public License for more details.
1304+#
1305+# You should have received a copy of the GNU General Public License along
1306+# with this program. If not, see <http://www.gnu.org/licenses/>.
1307+
1308+"""Tests for the Qt UI."""
1309+
1310+from PyQt4 import QtGui
1311+
1312+from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
1313+from ubuntuone.controlpanel.gui.qt.side_widget import SideWidget
1314+
1315+
1316+class SideWidgetTestCase(BaseTestCase):
1317+
1318+ """Test the qt main window."""
1319+
1320+ class_ui = SideWidget
1321+
1322+ def test_stage_0(self):
1323+ """Check that each stage in the widget enables the right labels."""
1324+ self.ui.stage = 0
1325+ self.assertTrue(self.ui.ui.install_icon.isEnabled())
1326+ self.assertFalse(self.ui.ui.signin_icon.isEnabled())
1327+ self.assertFalse(self.ui.ui.folders_icon.isEnabled())
1328+ self.assertFalse(self.ui.ui.sync_icon.isEnabled())
1329+ self.check_state_pixmap()
1330+
1331+ def test_stage_1(self):
1332+ """Check that each stage in the widget enables the right labels."""
1333+ self.ui.stage = 1
1334+ self.assertTrue(self.ui.ui.install_icon.isEnabled())
1335+ self.assertTrue(self.ui.ui.signin_icon.isEnabled())
1336+ self.assertFalse(self.ui.ui.folders_icon.isEnabled())
1337+ self.assertFalse(self.ui.ui.sync_icon.isEnabled())
1338+ self.check_state_pixmap()
1339+
1340+ def test_stage_2(self):
1341+ """Check that each stage in the widget enables the right labels."""
1342+ self.ui.stage = 2
1343+ self.assertTrue(self.ui.ui.install_icon.isEnabled())
1344+ self.assertTrue(self.ui.ui.signin_icon.isEnabled())
1345+ self.assertTrue(self.ui.ui.folders_icon.isEnabled())
1346+ self.assertFalse(self.ui.ui.sync_icon.isEnabled())
1347+ self.check_state_pixmap()
1348+
1349+ def test_stage_3(self):
1350+ """Check that each stage in the widget enables the right labels."""
1351+ self.ui.stage = 3
1352+ self.assertTrue(self.ui.ui.install_icon.isEnabled())
1353+ self.assertTrue(self.ui.ui.signin_icon.isEnabled())
1354+ self.assertTrue(self.ui.ui.folders_icon.isEnabled())
1355+ self.assertTrue(self.ui.ui.sync_icon.isEnabled())
1356+ self.check_state_pixmap()
1357+
1358+ def check_state_pixmap(self):
1359+ """Check if each label has the proper pixmap depending on the state."""
1360+ stage = self.ui.stage
1361+
1362+ active_pixmap = QtGui.QPixmap(":/progress_arrow_orange.png")
1363+ no_active_pixmap = QtGui.QPixmap(":/progress_arrow_grey.png")
1364+ complete_pixmap = QtGui.QPixmap(":/progress_tick.png")
1365+ sync_active_pixmap = QtGui.QPixmap(":/progress_finish_orange.png")
1366+ sync_no_active_pixmap = QtGui.QPixmap(":/progress_finish_grey.png")
1367+
1368+ labels = (self.ui.ui.install_icon, self.ui.ui.signin_icon,
1369+ self.ui.ui.folders_icon, self.ui.ui.sync_icon)
1370+ for item in labels[:stage]:
1371+ self.assertEqualPixmaps(complete_pixmap, item.pixmap())
1372+
1373+ if stage != 3:
1374+ self.assertEqualPixmaps(active_pixmap, labels[stage].pixmap())
1375+ else:
1376+ self.assertEqualPixmaps(sync_active_pixmap, labels[3].pixmap())
1377+
1378+ if stage < 3:
1379+ for item in labels[stage + 1:len(labels) - 1]:
1380+ self.assertEqualPixmaps(no_active_pixmap, item.pixmap())
1381+ self.assertEqualPixmaps(sync_no_active_pixmap, labels[3].pixmap())
1382
1383=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_signin.py'
1384--- ubuntuone/controlpanel/gui/qt/tests/test_signin.py 2012-02-06 15:23:27 +0000
1385+++ ubuntuone/controlpanel/gui/qt/tests/test_signin.py 2012-03-02 19:56:20 +0000
1386@@ -1,8 +1,6 @@
1387 # -*- coding: utf-8 -*-
1388-
1389-# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
1390 #
1391-# Copyright 2011 Canonical Ltd.
1392+# Copyright 2011-2012 Canonical Ltd.
1393 #
1394 # This program is free software: you can redistribute it and/or modify it
1395 # under the terms of the GNU General Public License version 3, as published
1396@@ -18,148 +16,42 @@
1397
1398 """Tests for the Sign In Panel."""
1399
1400-from twisted.internet import defer
1401-
1402+from ubuntuone.controlpanel.gui.qt import pixmap_from_name
1403 from ubuntuone.controlpanel.gui.qt import signin as gui
1404-from ubuntuone.controlpanel.gui.qt.tests import (
1405- CrashyBackend,
1406- CrashyBackendException,
1407-)
1408-from ubuntuone.controlpanel.gui.qt.tests.test_ubuntuonebin import (
1409- UbuntuOneBinTestCase,
1410-)
1411-
1412-EMAIL = 'foo@bar.com'
1413-PASSWORD = 'h3ll0World'
1414-TOKEN = {'yadda': 'doo'}
1415-
1416-MSG = {u'errtype': u'AuthenticationError',
1417- u'message': u'The authentication failed.'}
1418-
1419-
1420-def fail(*a, **kw):
1421- """Emit CredentialsError."""
1422- raise TypeError(MSG)
1423-
1424-
1425-class BaseSignInPanelTestCase(UbuntuOneBinTestCase):
1426- """Test the signin panel."""
1427-
1428- innerclass_ui = gui.signin_ui
1429- innerclass_name = "Ui_Form"
1430- class_ui = gui.SignInPanel
1431- logger = gui.logger
1432-
1433- @defer.inlineCallbacks
1434- def setUp(self):
1435- yield super(BaseSignInPanelTestCase, self).setUp()
1436- self.ui.backend.next_result = TOKEN
1437-
1438-
1439-class SignInPanelTestCase(BaseSignInPanelTestCase):
1440- """Test the signin panel."""
1441-
1442- innerclass_ui = gui.signin_ui
1443- innerclass_name = "Ui_Form"
1444- class_ui = gui.SignInPanel
1445-
1446- @defer.inlineCallbacks
1447- def setUp(self):
1448- yield super(SignInPanelTestCase, self).setUp()
1449- self.ui.backend.next_result = TOKEN
1450- self.ui.ui.email_entry.setText(gui.QtCore.QString(''))
1451- self.ui.ui.password_entry.setText(gui.QtCore.QString(''))
1452-
1453- @defer.inlineCallbacks
1454- def test_is_processing_while_asking_info(self):
1455- """The ui is processing while the contents are loaded."""
1456- def check(email, password):
1457- """The ui must be is_processing."""
1458- self.assertTrue(self.ui.is_processing, 'ui must be processing')
1459- return TOKEN
1460-
1461- self.patch(self.ui.backend, 'login', check)
1462-
1463- self.assertFalse(self.ui.is_processing)
1464- yield self.ui.ui.signin_button.click()
1465- self.assertFalse(self.ui.is_processing)
1466-
1467- def test_signin_disabled_at_startup(self):
1468- """The signin_button is disabled at startup."""
1469- self.assertFalse(self.ui.ui.signin_button.isEnabled())
1470-
1471- def test_signin_disabled_if_no_email_but_password(self):
1472- """Disable signin_button if no email."""
1473- self.ui.ui.password_entry.setText(gui.QtCore.QString('doo'))
1474- self.assertFalse(self.ui.ui.signin_button.isEnabled())
1475-
1476- def test_signin_disabled_if_no_password_but_email(self):
1477- """Disable signin_button if no password."""
1478- self.ui.ui.email_entry.setText(gui.QtCore.QString('duh'))
1479- self.assertFalse(self.ui.ui.signin_button.isEnabled())
1480-
1481- def test_cancel_button(self):
1482- """Send a signal when the cancel button is clicked."""
1483- self.ui.signinCanceled.connect(self._set_called)
1484- self.ui.ui.cancel_button.click()
1485- self.assertEqual(self._called, ((), {}))
1486-
1487- def test_forgot_password_button(self):
1488- """When clicking the forgot passsword btn, the proper url is opened."""
1489- self.assert_uri_hook_called(self.ui.ui.forgot_password_button,
1490- gui.RESET_PASSWORD_LINK)
1491-
1492-
1493-class SignInButtonPanelTestCase(BaseSignInPanelTestCase):
1494- """Test the signin_button widget."""
1495-
1496- @defer.inlineCallbacks
1497- def setUp(self):
1498- yield super(SignInButtonPanelTestCase, self).setUp()
1499- self.ui.ui.email_entry.setText(gui.QtCore.QString(EMAIL))
1500- self.ui.ui.password_entry.setText(gui.QtCore.QString(PASSWORD))
1501-
1502- @defer.inlineCallbacks
1503- def test_signin_button(self):
1504- """Call the backend when the signin button is clicked."""
1505- yield self.ui.ui.signin_button.click()
1506-
1507- self.assert_backend_called('login', email=EMAIL, password=PASSWORD)
1508- # pylint: disable=W0212
1509- for arg in self.ui.backend._called['login'][1].itervalues():
1510- self.assertIsInstance(arg, unicode) # make sure not send QString
1511-
1512- @defer.inlineCallbacks
1513- def test_signin_success(self):
1514- """Emit credentialsFound on signin success."""
1515- self.ui.credentialsFound.connect(self._set_called)
1516- yield self.ui.ui.signin_button.click()
1517-
1518- self.assertEqual(self._called, ((TOKEN,), {}))
1519- self.assertFalse(self.ui.is_processing)
1520-
1521- def test_signin_enabled_if_email_and_password(self):
1522- """Enable signin_button if email and password are non empty."""
1523- self.assertTrue(self.ui.ui.signin_button.isEnabled())
1524-
1525- def test_return_pressed(self):
1526- """On return pressed, click the signin_button."""
1527- self.patch(self.ui.ui.signin_button, 'click', self._set_called)
1528-
1529- for entry in (self.ui.ui.email_entry, self.ui.ui.password_entry):
1530- entry.returnPressed.emit()
1531-
1532- # This is failing, so we need to settle with counting recievers
1533- #self.assertEqual(self._called, ((), {}))
1534- receivers = entry.receivers(gui.QtCore.SIGNAL('returnPressed()'))
1535- self.assertEqual(1, receivers)
1536-
1537- self._called = False
1538-
1539- @defer.inlineCallbacks
1540- def test_backend_error_is_handled(self):
1541- """Any error from the backend is properly handled."""
1542- self.patch(self.ui, 'backend', CrashyBackend())
1543- yield self.ui.ui.signin_button.click()
1544-
1545- self.assertTrue(self.memento.check_exception(CrashyBackendException))
1546+from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
1547+
1548+
1549+class SignInPanelTestCase(BaseTestCase):
1550+
1551+ """Test the signin panel."""
1552+
1553+ innerclass_ui = gui.signin_ui
1554+ innerclass_name = "Ui_Form"
1555+ class_ui = gui.SignInPanel
1556+
1557+ def test_all_buttons_enabled(self):
1558+ """All the buttons are enabled at startup."""
1559+ self.assertTrue(self.ui.isEnabled())
1560+ self.assertTrue(self.ui.ui.login_button.isEnabled())
1561+ self.assertTrue(self.ui.ui.register_button.isEnabled())
1562+
1563+ def test_login_button_is_default(self):
1564+ """The login_button is the only default button."""
1565+ self.assertTrue(self.ui.ui.login_button.isDefault())
1566+ self.assertFalse(self.ui.ui.register_button.isDefault())
1567+
1568+ def test_banner_is_correct(self):
1569+ """The banner has the correct image."""
1570+ expected = pixmap_from_name('banner')
1571+ self.assertEqualPixmaps(self.ui.ui.banner.pixmap(), expected)
1572+
1573+ def test_label_is_correct(self):
1574+ """The welcome_label has the correct text."""
1575+ self.assertEqual(self.ui.ui.welcome_label.text(), gui.WELCOME_LABEL)
1576+
1577+ def test_buttos_are_correct(self):
1578+ """The buttos have the correct text."""
1579+ self.assertEqual(self.ui.ui.login_button.text(),
1580+ gui.EXISTING_ACCOUNT_CHOICE_BUTTON)
1581+ self.assertEqual(self.ui.ui.register_button.text(),
1582+ gui.SET_UP_ACCOUNT_CHOICE_BUTTON)
1583
1584=== added file 'ubuntuone/controlpanel/gui/qt/tests/test_wizard.py'
1585--- ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 1970-01-01 00:00:00 +0000
1586+++ ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-02 19:56:20 +0000
1587@@ -0,0 +1,158 @@
1588+# -*- coding: utf-8 -*-
1589+#
1590+# Copyright 2012 Canonical Ltd.
1591+#
1592+# This program is free software: you can redistribute it and/or modify it
1593+# under the terms of the GNU General Public License version 3, as published
1594+# by the Free Software Foundation.
1595+#
1596+# This program is distributed in the hope that it will be useful, but
1597+# WITHOUT ANY WARRANTY; without even the implied warranties of
1598+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1599+# PURPOSE. See the GNU General Public License for more details.
1600+#
1601+# You should have received a copy of the GNU General Public License along
1602+# with this program. If not, see <http://www.gnu.org/licenses/>.
1603+
1604+"""Tests for the First-time wizard."""
1605+
1606+from twisted.internet import defer
1607+
1608+from ubuntuone.controlpanel.gui.qt import wizard as gui
1609+from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase, TOKEN
1610+
1611+
1612+class UbuntuOneWizardTestCase(BaseTestCase):
1613+ """Test the UbuntuOneWizard."""
1614+
1615+ class_ui = gui.UbuntuOneWizard
1616+
1617+ def test_options(self):
1618+ """Tne wizard options are correct."""
1619+ options = [
1620+ (self.ui.NoBackButtonOnStartPage, True),
1621+ (self.ui.HaveFinishButtonOnEarlyPages, False),
1622+ ]
1623+ for option, expected in options:
1624+ self.assertEqual(expected, self.ui.testOption(option))
1625+
1626+ def test_style(self):
1627+ """Tne wizard style is Modern."""
1628+ self.assertEqual(self.ui.wizardStyle(), self.ui.ModernStyle)
1629+
1630+ def test_cancel_button(self):
1631+ """Send the rejected signal when the cancel button is clicked."""
1632+ button = self.ui.button(self.ui.CancelButton)
1633+ self.assertEqual(button.text(), gui.CLOSE_AND_SETUP_LATER)
1634+
1635+ self.ui.rejected.connect(self._set_called)
1636+ button.click()
1637+
1638+ self.assertEqual(self._called, ((), {}))
1639+
1640+ def test_button_layout(self):
1641+ """The button layout is correct."""
1642+ buttons = [
1643+ 'BackButton', 'CommitButton', 'CustomButton1', 'CustomButton2',
1644+ 'CustomButton3', 'FinishButton', 'HelpButton', 'NextButton',
1645+ ]
1646+ for button_name in buttons:
1647+ button = self.ui.button(getattr(self.ui, button_name))
1648+ self.assertFalse(button.isVisible(),
1649+ 'Button %s should not be visible.' % button_name)
1650+
1651+ button = self.ui.button(self.ui.CancelButton)
1652+ self.assertTrue(button.isVisible(),
1653+ 'Cancel button should not be visible.')
1654+
1655+ def test_first_page(self):
1656+ """The first page is the correct one."""
1657+ self.assertEqual(self.ui.startId(),
1658+ self.ui.pages[self.ui.signin_page])
1659+
1660+ def test_tab_order(self):
1661+ """The button tab order is correct."""
1662+ # can not be tested due to Qt API limitations
1663+
1664+
1665+class SideWidgetTestCase(UbuntuOneWizardTestCase):
1666+ """Test the side widget in the wizard."""
1667+
1668+ def test_is_there(self):
1669+ """The side widget is correct."""
1670+ self.assertIsInstance(self.ui.side_widget, gui.SideWidget)
1671+ self.assertIs(self.ui.sideWidget(), self.ui.side_widget)
1672+
1673+
1674+class SignInPageTestCase(UbuntuOneWizardTestCase):
1675+ """Test the SignInPage wizard page."""
1676+
1677+ page_name = 'signin'
1678+
1679+ @defer.inlineCallbacks
1680+ def setUp(self):
1681+ yield super(SignInPageTestCase, self).setUp()
1682+ self.page = getattr(self.ui, '%s_page' % self.page_name)
1683+
1684+ def test_was_added(self):
1685+ """The SignInPage is added correctly."""
1686+ page_id = self.ui.pages[self.page]
1687+ self.assertIs(self.ui.page(page_id), self.page)
1688+
1689+ def test_enabled_at_startup(self):
1690+ """The page is enabled at startup."""
1691+ self.assertTrue(self.page.isEnabled())
1692+
1693+
1694+class LoginTestCase(UbuntuOneWizardTestCase):
1695+ """Test the login through the wizard."""
1696+
1697+ method = 'login'
1698+
1699+ @defer.inlineCallbacks
1700+ def test_with_credentials(self):
1701+ """Wizard is done when credentials were retrieved."""
1702+ self.ui.finished.connect(self._set_called)
1703+ d = defer.succeed(TOKEN)
1704+
1705+ def check():
1706+ """Confirm the ui is disabled while processing."""
1707+ self.assertFalse(self.ui.signin_page.isEnabled())
1708+ return d
1709+
1710+ self.patch(self.ui.backend, self.method, check)
1711+ button = getattr(self.ui.signin_page.panel.ui,
1712+ '%s_button' % self.method)
1713+ button.click()
1714+
1715+ yield d
1716+
1717+ self.assertTrue(self.ui.signin_page.isEnabled())
1718+ self.assertEqual(self._called, ((1,), {}))
1719+
1720+ @defer.inlineCallbacks
1721+ def test_without_credentials(self):
1722+ """Wizard is done when credentials were retrieved."""
1723+ self.ui.finished.connect(self._set_called)
1724+ d = defer.succeed(None)
1725+
1726+ def check():
1727+ """Confirm the ui is disabled while processing."""
1728+ self.assertFalse(self.ui.signin_page.isEnabled())
1729+ return d
1730+
1731+ self.patch(self.ui.backend, self.method, check)
1732+ button = getattr(self.ui.signin_page.panel.ui,
1733+ '%s_button' % self.method)
1734+ button.click()
1735+
1736+ yield d
1737+
1738+ self.assertTrue(self.ui.signin_page.isEnabled())
1739+ self.assertFalse(self._called)
1740+
1741+
1742+class RegisterTestCase(LoginTestCase):
1743+ """Test the register through the wizard."""
1744+
1745+ method = 'register'
1746
1747=== added file 'ubuntuone/controlpanel/gui/qt/wizard.py'
1748--- ubuntuone/controlpanel/gui/qt/wizard.py 1970-01-01 00:00:00 +0000
1749+++ ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-02 19:56:20 +0000
1750@@ -0,0 +1,110 @@
1751+# -*- coding: utf-8 -*-
1752+#
1753+# Copyright 2011-2012 Canonical Ltd.
1754+#
1755+# This program is free software: you can redistribute it and/or modify it
1756+# under the terms of the GNU General Public License version 3, as published
1757+# by the Free Software Foundation.
1758+#
1759+# This program is distributed in the hope that it will be useful, but
1760+# WITHOUT ANY WARRANTY; without even the implied warranties of
1761+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1762+# PURPOSE. See the GNU General Public License for more details.
1763+#
1764+# You should have received a copy of the GNU General Public License along
1765+# with this program. If not, see <http://www.gnu.org/licenses/>.
1766+
1767+"""The base widget for the Control Panel tabs."""
1768+
1769+from PyQt4 import QtGui, QtCore
1770+
1771+from twisted.internet import defer
1772+from ubuntu_sso.utils.ui import CLOSE_AND_SETUP_LATER
1773+
1774+from ubuntuone.controlpanel import cache
1775+from ubuntuone.controlpanel.gui.qt.signin import SignInPanel
1776+from ubuntuone.controlpanel.gui.qt.side_widget import SideWidget
1777+
1778+
1779+class UbuntuOnePage(QtGui.QWizardPage):
1780+ """A generic page for the UbuntuOneWizard."""
1781+
1782+ panel_class = None
1783+
1784+ def __init__(self, *args, **kwargs):
1785+ super(UbuntuOnePage, self).__init__(*args, **kwargs)
1786+
1787+ self.layout = QtGui.QVBoxLayout(self)
1788+ self.panel = None
1789+ if self.panel_class is not None:
1790+ self.panel = SignInPanel()
1791+ self.layout.addWidget(self.panel)
1792+
1793+
1794+class SignInPage(UbuntuOnePage):
1795+ """The page to signin to Ubuntu One."""
1796+
1797+ panel_class = SignInPanel
1798+
1799+
1800+class UbuntuOneWizard(cache.Cache, QtGui.QWizard):
1801+ """The Ubuntu One wizard."""
1802+
1803+ def __init__(self, *args, **kwargs):
1804+ super(UbuntuOneWizard, self).__init__(*args, **kwargs)
1805+ self.pages = {}
1806+
1807+ self.setOption(self.NoBackButtonOnStartPage, True)
1808+ self.setOption(self.HaveFinishButtonOnEarlyPages, False)
1809+ self.setWizardStyle(self.ModernStyle)
1810+
1811+ self.setButtonText(self.CancelButton, CLOSE_AND_SETUP_LATER)
1812+ self.setButtonLayout([self.Stretch, self.CancelButton])
1813+
1814+ self.side_widget = SideWidget()
1815+ self.side_widget.stage = self.side_widget.signin_stage
1816+ self.setSideWidget(self.side_widget)
1817+
1818+ self.signin_page = SignInPage()
1819+ self.addPage(self.signin_page)
1820+
1821+ self.signin_page.panel.ui.login_button.clicked.connect(self.login)
1822+ self.signin_page.panel.ui.register_button.clicked.connect(
1823+ self.register)
1824+
1825+ self.setTabOrder(self.signin_page.panel.ui.login_button,
1826+ self.signin_page.panel.ui.register_button)
1827+ self.setTabOrder(self.signin_page.panel.ui.register_button,
1828+ self.button(self.CancelButton))
1829+
1830+ # pylint: disable=C0103
1831+
1832+ def addPage(self, page):
1833+ """Add 'page' to this wizard, and keep a reference of its ID."""
1834+ page_id = super(UbuntuOneWizard, self).addPage(page)
1835+ self.pages[page] = page_id
1836+
1837+ # pylint: enable=C0103
1838+
1839+ @QtCore.pyqtSlot()
1840+ @defer.inlineCallbacks
1841+ def login(self):
1842+ """Show the login dialog."""
1843+ self.setEnabled(False)
1844+ credentials = yield self.backend.login()
1845+ self._process_credentials(credentials)
1846+ self.setEnabled(True)
1847+
1848+ @QtCore.pyqtSlot()
1849+ @defer.inlineCallbacks
1850+ def register(self):
1851+ """Show the register dialog."""
1852+ self.setEnabled(False)
1853+ credentials = yield self.backend.register()
1854+ self._process_credentials(credentials)
1855+ self.setEnabled(True)
1856+
1857+ def _process_credentials(self, credentials=None):
1858+ """Confirm which is the next step after analyzing 'credentials'."""
1859+ if credentials:
1860+ self.accept()
1861
1862=== modified file 'ubuntuone/controlpanel/gui/tests/__init__.py'
1863--- ubuntuone/controlpanel/gui/tests/__init__.py 2011-09-09 15:05:22 +0000
1864+++ ubuntuone/controlpanel/gui/tests/__init__.py 2012-03-02 19:56:20 +0000
1865@@ -1,8 +1,6 @@
1866 # -*- coding: utf-8 -*-
1867-
1868-# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
1869 #
1870-# Copyright 2011 Canonical Ltd.
1871+# Copyright 2011-2012 Canonical Ltd.
1872 #
1873 # This program is free software: you can redistribute it and/or modify it
1874 # under the terms of the GNU General Public License version 3, as published
1875@@ -20,6 +18,8 @@
1876
1877 import os
1878
1879+from twisted.internet import defer
1880+
1881 from ubuntuone.controlpanel import gui
1882 from ubuntuone.controlpanel.backend import (
1883 ControlBackend,
1884@@ -133,6 +133,7 @@
1885
1886 next_result = None
1887 exposed_methods = []
1888+ exposed_results = {}
1889
1890 def __init__(self, *args, **kwargs):
1891 self._args = args
1892@@ -144,9 +145,15 @@
1893 def _record_call(self, func_name):
1894 """Store values when calling 'func_name'."""
1895
1896- def inner(*args, **kwargs):
1897+ def faked_call_in_faked_object(*args, **kwargs):
1898 """Fake 'func_name'."""
1899 self._called[func_name] = (args, kwargs)
1900- return self.next_result
1901+ no_func_result = object()
1902+ result = self.exposed_results.get(func_name, no_func_result)
1903+ if result is no_func_result:
1904+ result = self.next_result
1905+ else:
1906+ result = defer.succeed(result)
1907+ return result
1908
1909- return inner
1910+ return faked_call_in_faked_object

Subscribers

People subscribed via source and target branches