Merge lp:~nataliabidart/ubuntuone-control-panel/disconnect-flow into lp:ubuntuone-control-panel

Proposed by Natalia Bidart on 2011-08-26
Status: Merged
Approved by: Natalia Bidart on 2011-08-29
Approved revision: 215
Merged at revision: 207
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/disconnect-flow
Merge into: lp:ubuntuone-control-panel
Diff against target: 1217 lines (+664/-230)
20 files modified
data/qt/controlpanel.ui (+218/-191)
data/qt/signin.ui (+197/-0)
data/qt/ubuntuone.qss (+11/-0)
ubuntuone/controlpanel/__init__.py (+2/-1)
ubuntuone/controlpanel/gui/__init__.py (+1/-0)
ubuntuone/controlpanel/gui/qt/account.py (+1/-0)
ubuntuone/controlpanel/gui/qt/controlpanel.py (+23/-22)
ubuntuone/controlpanel/gui/qt/devices.py (+8/-2)
ubuntuone/controlpanel/gui/qt/folders.py (+1/-0)
ubuntuone/controlpanel/gui/qt/gotoweb.py (+1/-0)
ubuntuone/controlpanel/gui/qt/gui.py (+5/-0)
ubuntuone/controlpanel/gui/qt/loadingoverlay.py (+1/-2)
ubuntuone/controlpanel/gui/qt/signin.py (+50/-0)
ubuntuone/controlpanel/gui/qt/tests/__init__.py (+7/-2)
ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py (+63/-9)
ubuntuone/controlpanel/gui/qt/tests/test_devices.py (+10/-0)
ubuntuone/controlpanel/gui/qt/tests/test_gotoweb.py (+5/-0)
ubuntuone/controlpanel/gui/qt/tests/test_gui.py (+7/-0)
ubuntuone/controlpanel/gui/qt/tests/test_signin.py (+52/-0)
ubuntuone/controlpanel/gui/qt/ubuntuonebin.py (+1/-1)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/disconnect-flow
Reviewer Review Type Date Requested Status
Diego Sarmentero (community) Approve on 2011-08-29
Roberto Alsina (community) 2011-08-26 Approve on 2011-08-26
Review via email: mp+73084@code.launchpad.net

Commit Message

- Check for credentials at startup, if they are not present, show the signin screen (LP: #800444).
  - After local device removal, show the sign in page (LP: #813073).

Description of the Change

Handle the absence of credentials, either because they are not present at startup, or because the local device is removed.

This branch implements everything needed to solve the bugs attached except the actual login using email and password, which depends on lp:~nataliabidart/ubuntuone-client/login-email-password-for-everyone being merged. I decided to propose for merge this branch so it does not grow in size too much, while waiting for the dependency to land.

To test:

* Scenario 1: Open the QT control panel having valid credentials, go to the Devices tab and remove the local one. You should be redirected to the new sign in panel. In there, you can check that:
 - Clicking "Cancel" will close the app.
 - Clicking "Forgot password" should redirect to SSO web site to reset password.
 - Clicking "Sign in" will do nothing but show the "Loading" overlay, for now (see bug #834900 for pending logic implementation).

* Scenario 2: open the QT control panel with no credentials in the system, you should get the sign in screen with the same reduced functionality as described before.

NOTE: the change in the WEBSERVICE_BASE_URL will be reverted when proposing the fix for bug #834900, otherwise you won't be able to test device removal without hitting our egde rest api service.

To post a comment you must log in.
215. By Natalia Bidart on 2011-08-26

Removed commentted code.

Roberto Alsina (ralsina) wrote :

+1

review: Approve
Diego Sarmentero (diegosarmentero) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/qt/controlpanel.ui'
2--- data/qt/controlpanel.ui 2011-08-23 16:13:09 +0000
3+++ data/qt/controlpanel.ui 2011-08-26 18:04:35 +0000
4@@ -6,8 +6,8 @@
5 <rect>
6 <x>0</x>
7 <y>0</y>
8- <width>367</width>
9- <height>142</height>
10+ <width>387</width>
11+ <height>168</height>
12 </rect>
13 </property>
14 <property name="sizePolicy">
15@@ -20,215 +20,237 @@
16 <string notr="true">Form</string>
17 </property>
18 <layout class="QVBoxLayout" name="verticalLayout">
19- <property name="spacing">
20- <number>3</number>
21- </property>
22 <property name="margin">
23 <number>0</number>
24 </property>
25 <item>
26- <widget class="QFrame" name="frame_header">
27- <layout class="QHBoxLayout" name="horizontalLayout_2">
28- <property name="spacing">
29- <number>5</number>
30- </property>
31- <property name="margin">
32- <number>0</number>
33- </property>
34- <item>
35- <widget class="QFrame" name="frame_greeting">
36- <layout class="QVBoxLayout" name="verticalLayout_4">
37- <property name="margin">
38- <number>0</number>
39- </property>
40- <item>
41- <widget class="QLabel" name="greeting_label">
42- <property name="alignment">
43- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
44- </property>
45- </widget>
46- </item>
47- </layout>
48- </widget>
49- </item>
50- <item>
51- <spacer name="horizontalSpacer">
52- <property name="orientation">
53- <enum>Qt::Horizontal</enum>
54- </property>
55- <property name="sizeType">
56- <enum>QSizePolicy::Fixed</enum>
57- </property>
58- <property name="sizeHint" stdset="0">
59- <size>
60- <width>15</width>
61- <height>20</height>
62- </size>
63- </property>
64- </spacer>
65- </item>
66- <item>
67- <widget class="QFrame" name="frame_storage">
68- <property name="sizePolicy">
69- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
70- <horstretch>0</horstretch>
71- <verstretch>0</verstretch>
72- </sizepolicy>
73- </property>
74- <property name="minimumSize">
75- <size>
76- <width>165</width>
77- <height>0</height>
78- </size>
79- </property>
80- <property name="maximumSize">
81- <size>
82- <width>165</width>
83- <height>16777215</height>
84- </size>
85- </property>
86- <layout class="QVBoxLayout" name="vLayoutStorage">
87- <property name="spacing">
88- <number>6</number>
89- </property>
90- <property name="sizeConstraint">
91- <enum>QLayout::SetDefaultConstraint</enum>
92- </property>
93- <property name="margin">
94- <number>0</number>
95- </property>
96- <item>
97- <widget class="QFrame" name="frame_quota">
98- <layout class="QVBoxLayout" name="verticalLayout_3">
99+ <widget class="QStackedWidget" name="switcher">
100+ <property name="currentIndex">
101+ <number>1</number>
102+ </property>
103+ <widget class="QWidget" name="management">
104+ <property name="sizePolicy">
105+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
106+ <horstretch>0</horstretch>
107+ <verstretch>0</verstretch>
108+ </sizepolicy>
109+ </property>
110+ <layout class="QVBoxLayout" name="verticalLayout_5">
111+ <property name="margin">
112+ <number>0</number>
113+ </property>
114+ <item>
115+ <layout class="QVBoxLayout" name="verticalLayout_2">
116+ <item>
117+ <widget class="QFrame" name="frame_header">
118+ <layout class="QHBoxLayout" name="horizontalLayout_2">
119 <property name="spacing">
120- <number>2</number>
121+ <number>5</number>
122 </property>
123 <property name="margin">
124 <number>0</number>
125 </property>
126 <item>
127- <widget class="QLabel" name="percentage_usage_label">
128- <property name="sizePolicy">
129- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
130- <horstretch>0</horstretch>
131- <verstretch>0</verstretch>
132- </sizepolicy>
133- </property>
134- <property name="text">
135- <string notr="true"/>
136- </property>
137- </widget>
138- </item>
139- <item>
140- <widget class="QLabel" name="quota_usage_label">
141- <property name="font">
142- <font>
143- <pointsize>8</pointsize>
144- </font>
145- </property>
146- <property name="text">
147- <string/>
148- </property>
149+ <widget class="QFrame" name="frame_greeting">
150+ <layout class="QVBoxLayout" name="verticalLayout_4">
151+ <property name="margin">
152+ <number>0</number>
153+ </property>
154+ <item>
155+ <widget class="QLabel" name="greeting_label">
156+ <property name="alignment">
157+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
158+ </property>
159+ </widget>
160+ </item>
161+ </layout>
162+ </widget>
163+ </item>
164+ <item>
165+ <spacer name="horizontalSpacer">
166+ <property name="orientation">
167+ <enum>Qt::Horizontal</enum>
168+ </property>
169+ <property name="sizeType">
170+ <enum>QSizePolicy::Fixed</enum>
171+ </property>
172+ <property name="sizeHint" stdset="0">
173+ <size>
174+ <width>15</width>
175+ <height>20</height>
176+ </size>
177+ </property>
178+ </spacer>
179+ </item>
180+ <item>
181+ <widget class="QFrame" name="frame_storage">
182+ <property name="sizePolicy">
183+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
184+ <horstretch>0</horstretch>
185+ <verstretch>0</verstretch>
186+ </sizepolicy>
187+ </property>
188+ <property name="minimumSize">
189+ <size>
190+ <width>165</width>
191+ <height>0</height>
192+ </size>
193+ </property>
194+ <property name="maximumSize">
195+ <size>
196+ <width>165</width>
197+ <height>16777215</height>
198+ </size>
199+ </property>
200+ <layout class="QVBoxLayout" name="vLayoutStorage">
201+ <property name="spacing">
202+ <number>6</number>
203+ </property>
204+ <property name="sizeConstraint">
205+ <enum>QLayout::SetDefaultConstraint</enum>
206+ </property>
207+ <property name="margin">
208+ <number>0</number>
209+ </property>
210+ <item>
211+ <widget class="QFrame" name="frame_quota">
212+ <layout class="QVBoxLayout" name="verticalLayout_3">
213+ <property name="spacing">
214+ <number>2</number>
215+ </property>
216+ <property name="margin">
217+ <number>0</number>
218+ </property>
219+ <item>
220+ <widget class="QLabel" name="percentage_usage_label">
221+ <property name="sizePolicy">
222+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
223+ <horstretch>0</horstretch>
224+ <verstretch>0</verstretch>
225+ </sizepolicy>
226+ </property>
227+ <property name="text">
228+ <string notr="true"/>
229+ </property>
230+ </widget>
231+ </item>
232+ <item>
233+ <widget class="QLabel" name="quota_usage_label">
234+ <property name="font">
235+ <font>
236+ <pointsize>8</pointsize>
237+ </font>
238+ </property>
239+ <property name="text">
240+ <string/>
241+ </property>
242+ </widget>
243+ </item>
244+ </layout>
245+ <zorder>quota_usage_label</zorder>
246+ <zorder>percentage_usage_label</zorder>
247+ </widget>
248+ </item>
249+ <item>
250+ <widget class="GoToWebButton" name="get_more_space_button">
251+ <property name="text">
252+ <string>Get more storage</string>
253+ </property>
254+ </widget>
255+ </item>
256+ </layout>
257+ </widget>
258+ </item>
259+ <item>
260+ <widget class="QFrame" name="frame_status">
261+ <property name="sizePolicy">
262+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
263+ <horstretch>0</horstretch>
264+ <verstretch>0</verstretch>
265+ </sizepolicy>
266+ </property>
267+ <property name="minimumSize">
268+ <size>
269+ <width>165</width>
270+ <height>0</height>
271+ </size>
272+ </property>
273+ <property name="maximumSize">
274+ <size>
275+ <width>165</width>
276+ <height>16777215</height>
277+ </size>
278+ </property>
279+ <layout class="QHBoxLayout" name="horizontalLayout_8">
280+ <property name="margin">
281+ <number>0</number>
282+ </property>
283+ <item>
284+ <widget class="FileSyncStatus" name="file_sync_status" native="true">
285+ <property name="sizePolicy">
286+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
287+ <horstretch>0</horstretch>
288+ <verstretch>0</verstretch>
289+ </sizepolicy>
290+ </property>
291+ <property name="minimumSize">
292+ <size>
293+ <width>0</width>
294+ <height>0</height>
295+ </size>
296+ </property>
297+ <property name="maximumSize">
298+ <size>
299+ <width>165</width>
300+ <height>16777215</height>
301+ </size>
302+ </property>
303+ </widget>
304+ </item>
305+ </layout>
306 </widget>
307 </item>
308 </layout>
309- <zorder>quota_usage_label</zorder>
310- <zorder>percentage_usage_label</zorder>
311- </widget>
312- </item>
313- <item>
314- <widget class="GoToWebButton" name="get_more_space_button">
315- <property name="text">
316- <string>Get more storage</string>
317- </property>
318- </widget>
319- </item>
320- </layout>
321- </widget>
322- </item>
323- <item>
324- <widget class="QFrame" name="frame_status">
325- <property name="sizePolicy">
326- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
327- <horstretch>0</horstretch>
328- <verstretch>0</verstretch>
329- </sizepolicy>
330- </property>
331- <property name="minimumSize">
332- <size>
333- <width>165</width>
334- <height>0</height>
335- </size>
336- </property>
337- <property name="maximumSize">
338- <size>
339- <width>165</width>
340- <height>16777215</height>
341- </size>
342- </property>
343- <layout class="QHBoxLayout" name="horizontalLayout_8">
344- <property name="margin">
345- <number>0</number>
346- </property>
347- <item>
348- <widget class="FileSyncStatus" name="file_sync_status" native="true">
349+ </widget>
350+ </item>
351+ <item>
352+ <widget class="QTabWidget" name="tab_widget">
353 <property name="sizePolicy">
354- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
355+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
356 <horstretch>0</horstretch>
357 <verstretch>0</verstretch>
358 </sizepolicy>
359 </property>
360- <property name="minimumSize">
361- <size>
362- <width>0</width>
363- <height>0</height>
364- </size>
365- </property>
366- <property name="maximumSize">
367- <size>
368- <width>165</width>
369- <height>16777215</height>
370- </size>
371- </property>
372+ <property name="currentIndex">
373+ <number>0</number>
374+ </property>
375+ <widget class="FoldersPanel" name="folders_tab">
376+ <attribute name="title">
377+ <string>Folders</string>
378+ </attribute>
379+ </widget>
380+ <widget class="DevicesPanel" name="devices_tab">
381+ <attribute name="title">
382+ <string>Devices</string>
383+ </attribute>
384+ </widget>
385+ <widget class="PreferencesPanel" name="preferences_tab">
386+ <attribute name="title">
387+ <string>Settings</string>
388+ </attribute>
389+ </widget>
390+ <widget class="AccountPanel" name="account_tab">
391+ <attribute name="title">
392+ <string>Account information</string>
393+ </attribute>
394+ </widget>
395 </widget>
396 </item>
397 </layout>
398- </widget>
399- </item>
400- </layout>
401- </widget>
402- </item>
403- <item>
404- <widget class="QTabWidget" name="tab_widget">
405- <property name="sizePolicy">
406- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
407- <horstretch>0</horstretch>
408- <verstretch>0</verstretch>
409- </sizepolicy>
410- </property>
411- <property name="currentIndex">
412- <number>0</number>
413- </property>
414- <widget class="FoldersPanel" name="folders_tab">
415- <attribute name="title">
416- <string>Folders</string>
417- </attribute>
418- </widget>
419- <widget class="DevicesPanel" name="devices_tab">
420- <attribute name="title">
421- <string>Devices</string>
422- </attribute>
423- </widget>
424- <widget class="PreferencesPanel" name="preferences_tab">
425- <attribute name="title">
426- <string>Settings</string>
427- </attribute>
428- </widget>
429- <widget class="AccountPanel" name="account_tab">
430- <attribute name="title">
431- <string>Account information</string>
432- </attribute>
433- </widget>
434+ </item>
435+ </layout>
436+ </widget>
437+ <widget class="SignInPanel" name="signin"/>
438 </widget>
439 </item>
440 <item>
441@@ -371,9 +393,14 @@
442 <header>ubuntuone.controlpanel.gui.qt.account</header>
443 <container>1</container>
444 </customwidget>
445+ <customwidget>
446+ <class>SignInPanel</class>
447+ <extends>QWidget</extends>
448+ <header>ubuntuone.controlpanel.gui.qt.signin</header>
449+ <container>1</container>
450+ </customwidget>
451 </customwidgets>
452 <tabstops>
453- <tabstop>tab_widget</tabstop>
454 <tabstop>help_button</tabstop>
455 <tabstop>twitter_button</tabstop>
456 <tabstop>facebook_button</tabstop>
457
458=== added file 'data/qt/signin.ui'
459--- data/qt/signin.ui 1970-01-01 00:00:00 +0000
460+++ data/qt/signin.ui 2011-08-26 18:04:35 +0000
461@@ -0,0 +1,197 @@
462+<?xml version="1.0" encoding="UTF-8"?>
463+<ui version="4.0">
464+ <class>Form</class>
465+ <widget class="QWidget" name="Form">
466+ <property name="geometry">
467+ <rect>
468+ <x>0</x>
469+ <y>0</y>
470+ <width>344</width>
471+ <height>312</height>
472+ </rect>
473+ </property>
474+ <property name="windowTitle">
475+ <string>Form</string>
476+ </property>
477+ <layout class="QHBoxLayout" name="horizontalLayout_3">
478+ <property name="margin">
479+ <number>0</number>
480+ </property>
481+ <item>
482+ <widget class="QFrame" name="signin">
483+ <layout class="QVBoxLayout" name="sign_in">
484+ <property name="spacing">
485+ <number>15</number>
486+ </property>
487+ <property name="margin">
488+ <number>3</number>
489+ </property>
490+ <item>
491+ <widget class="QLabel" name="sign_in_label">
492+ <property name="text">
493+ <string>Sign in to Ubuntu One</string>
494+ </property>
495+ </widget>
496+ </item>
497+ <item>
498+ <widget class="QLabel" name="description_label">
499+ <property name="text">
500+ <string>Sign in with yur existing Ubuntu One username and password.</string>
501+ </property>
502+ </widget>
503+ </item>
504+ <item>
505+ <layout class="QHBoxLayout" name="horizontalLayout">
506+ <item>
507+ <layout class="QVBoxLayout" name="verticalLayout_2">
508+ <property name="spacing">
509+ <number>15</number>
510+ </property>
511+ <item>
512+ <layout class="QVBoxLayout" name="verticalLayout_4">
513+ <property name="spacing">
514+ <number>0</number>
515+ </property>
516+ <item>
517+ <widget class="QLabel" name="email_label">
518+ <property name="text">
519+ <string>Email address</string>
520+ </property>
521+ </widget>
522+ </item>
523+ <item>
524+ <widget class="QLineEdit" name="email_entry">
525+ <property name="text">
526+ <string/>
527+ </property>
528+ </widget>
529+ </item>
530+ </layout>
531+ </item>
532+ <item>
533+ <layout class="QVBoxLayout" name="verticalLayout_3">
534+ <property name="spacing">
535+ <number>0</number>
536+ </property>
537+ <item>
538+ <widget class="QLabel" name="password_label">
539+ <property name="text">
540+ <string>Password</string>
541+ </property>
542+ </widget>
543+ </item>
544+ <item>
545+ <widget class="QLineEdit" name="password_entry">
546+ <property name="echoMode">
547+ <enum>QLineEdit::Password</enum>
548+ </property>
549+ </widget>
550+ </item>
551+ </layout>
552+ </item>
553+ <item>
554+ <layout class="QHBoxLayout" name="horizontalLayout_2">
555+ <item>
556+ <widget class="QPushButton" name="signin_button">
557+ <property name="text">
558+ <string>Sign in</string>
559+ </property>
560+ </widget>
561+ </item>
562+ <item>
563+ <widget class="QPushButton" name="cancel_button">
564+ <property name="text">
565+ <string>Cancel</string>
566+ </property>
567+ </widget>
568+ </item>
569+ <item>
570+ <spacer name="horizontalSpacer">
571+ <property name="orientation">
572+ <enum>Qt::Horizontal</enum>
573+ </property>
574+ <property name="sizeHint" stdset="0">
575+ <size>
576+ <width>40</width>
577+ <height>20</height>
578+ </size>
579+ </property>
580+ </spacer>
581+ </item>
582+ </layout>
583+ </item>
584+ <item>
585+ <layout class="QHBoxLayout" name="horizontalLayout_4">
586+ <item>
587+ <widget class="GoToWebButton" name="forgot_password_button">
588+ <property name="sizePolicy">
589+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
590+ <horstretch>0</horstretch>
591+ <verstretch>0</verstretch>
592+ </sizepolicy>
593+ </property>
594+ <property name="text">
595+ <string>Forgot your password?</string>
596+ </property>
597+ </widget>
598+ </item>
599+ <item>
600+ <spacer name="horizontalSpacer_3">
601+ <property name="orientation">
602+ <enum>Qt::Horizontal</enum>
603+ </property>
604+ <property name="sizeHint" stdset="0">
605+ <size>
606+ <width>40</width>
607+ <height>20</height>
608+ </size>
609+ </property>
610+ </spacer>
611+ </item>
612+ </layout>
613+ </item>
614+ </layout>
615+ </item>
616+ <item>
617+ <spacer name="horizontalSpacer_2">
618+ <property name="orientation">
619+ <enum>Qt::Horizontal</enum>
620+ </property>
621+ <property name="sizeHint" stdset="0">
622+ <size>
623+ <width>40</width>
624+ <height>20</height>
625+ </size>
626+ </property>
627+ </spacer>
628+ </item>
629+ </layout>
630+ </item>
631+ <item>
632+ <spacer name="verticalSpacer">
633+ <property name="orientation">
634+ <enum>Qt::Vertical</enum>
635+ </property>
636+ <property name="sizeHint" stdset="0">
637+ <size>
638+ <width>20</width>
639+ <height>40</height>
640+ </size>
641+ </property>
642+ </spacer>
643+ </item>
644+ </layout>
645+ </widget>
646+ </item>
647+ </layout>
648+ </widget>
649+ <customwidgets>
650+ <customwidget>
651+ <class>GoToWebButton</class>
652+ <extends>QPushButton</extends>
653+ <header>ubuntuone.controlpanel.gui.qt.gotoweb</header>
654+ </customwidget>
655+ </customwidgets>
656+ <resources/>
657+ <connections/>
658+</ui>
659
660=== modified file 'data/qt/ubuntuone.qss'
661--- data/qt/ubuntuone.qss 2011-08-23 15:35:07 +0000
662+++ data/qt/ubuntuone.qss 2011-08-26 18:04:35 +0000
663@@ -12,6 +12,7 @@
664 border: none;
665 }
666
667+QFrame#signin,
668 QFrame#frame_header {
669 background: #ffffff;
670 border-radius: 5px;
671@@ -137,6 +138,7 @@
672 border: none;
673 }
674
675+GoToWebButton#forgot_password_button,
676 GoToWebButton#share_publish_button {
677 background: transparent;
678 border: none;
679@@ -249,6 +251,15 @@
680 color: white;
681 }
682
683+QLabel#sign_in_label {
684+ font: 16px;
685+}
686+
687+QLabel#email_label,
688+QLabel#password_label {
689+ font-size: 10px;
690+}
691+
692 QAbstractItemView {
693 border-style: solid;
694 border-color: #898989;
695
696=== modified file 'ubuntuone/controlpanel/__init__.py'
697--- ubuntuone/controlpanel/__init__.py 2011-05-23 21:24:08 +0000
698+++ ubuntuone/controlpanel/__init__.py 2011-08-26 18:04:35 +0000
699@@ -29,5 +29,6 @@
700 DBUS_PREFERENCES_PATH = "/preferences"
701 DBUS_PREFERENCES_IFACE = "com.ubuntuone.controlpanel.Preferences"
702
703-WEBSERVICE_BASE_URL = u"https://one.ubuntu.com/api/"
704+# XXX: use edge only when testing new stuff
705+WEBSERVICE_BASE_URL = u"https://edge.one.ubuntu.com/api/"
706 TRANSLATION_DOMAIN = 'ubuntuone-control-panel'
707
708=== modified file 'ubuntuone/controlpanel/gui/__init__.py'
709--- ubuntuone/controlpanel/gui/__init__.py 2011-08-12 15:07:23 +0000
710+++ ubuntuone/controlpanel/gui/__init__.py 2011-08-26 18:04:35 +0000
711@@ -67,6 +67,7 @@
712 GET_SUPPORT_LINK = UBUNTUONE_LINK + 'support/'
713 LEARN_MORE_LINK = UBUNTUONE_LINK
714 MANAGE_FILES_LINK = UBUNTUONE_LINK + 'files/'
715+RESET_PASSWORD_LINK = EDIT_PROFILE_LINK + '+forgot_password'
716 TWITTER_LINK = 'http://twitter.com/ubuntuone/'
717
718 ALWAYS_SUBSCRIBED = _('Always in sync')
719
720=== modified file 'ubuntuone/controlpanel/gui/qt/account.py'
721--- ubuntuone/controlpanel/gui/qt/account.py 2011-07-20 21:04:28 +0000
722+++ ubuntuone/controlpanel/gui/qt/account.py 2011-08-26 18:04:35 +0000
723@@ -40,6 +40,7 @@
724
725 def _setup(self):
726 """Do some extra setupping for the UI."""
727+ super(AccountPanel, self)._setup()
728 self.ui.edit_profile_button.uri = EDIT_PROFILE_LINK
729 self.ui.edit_services_button.uri = EDIT_ACCOUNT_LINK
730
731
732=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
733--- ubuntuone/controlpanel/gui/qt/controlpanel.py 2011-08-05 15:19:12 +0000
734+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2011-08-26 18:04:35 +0000
735@@ -21,10 +21,9 @@
736
737 from __future__ import division
738
739-from PyQt4 import QtGui, QtCore
740+from PyQt4 import QtCore
741 from twisted.internet import defer
742
743-from ubuntuone.controlpanel import backend
744 from ubuntuone.controlpanel.logger import setup_logging, log_call
745 from ubuntuone.controlpanel.gui import (
746 humanize,
747@@ -37,6 +36,7 @@
748 USAGE_LABEL,
749 )
750 from ubuntuone.controlpanel.gui.qt import uri_hook
751+from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin
752 from ubuntuone.controlpanel.gui.qt.ui import controlpanel_ui
753
754
755@@ -46,37 +46,38 @@
756 PERCENTAGE_STYLE = '<span style=" font-size:16pt;">%.0f%%</span>'
757
758
759-class ControlPanel(QtGui.QWidget):
760+class ControlPanel(UbuntuOneBin):
761 """The Control Panel widget"""
762
763- def __init__(self, parent=None):
764- """Initialize the UI of the widget."""
765- QtGui.QWidget.__init__(self, parent)
766- self.ui = controlpanel_ui.Ui_Form()
767- self.ui.setupUi(self)
768-
769- self.backend = backend.ControlBackend()
770- self._setup()
771- logger.debug('%s: started.', self.__class__.__name__)
772+ ui_class = controlpanel_ui
773
774 def _setup(self):
775 """Do some extra setupping for the UI."""
776 self.ui.get_more_space_button.uri = EDIT_ACCOUNT_LINK
777 self.ui.help_button.uri = GET_SUPPORT_LINK
778-
779- # Invalid name "showEvent"
780- # pylint: disable=C0103
781-
782- def showEvent(self, event):
783- """Load info."""
784- self.load()
785- event.accept()
786+ self.ui.devices_tab.localDeviceRemoved.connect(
787+ self.on_credentials_not_found)
788+
789+ def on_credentials_not_found(self):
790+ """Credentials are not found or were removed."""
791+ self.ui.switcher.setCurrentWidget(self.ui.signin)
792+
793+ def on_credentials_found(self):
794+ """Credentials are not found or were removed."""
795+ self.ui.switcher.setCurrentWidget(self.ui.management)
796
797 @defer.inlineCallbacks
798 def load(self):
799 """Load info."""
800- info = yield self.backend.account_info()
801- self.process_info(info)
802+ self.is_processing = True
803+ credentials = yield self.backend.get_credentials()
804+ if credentials == {}:
805+ self.on_credentials_not_found()
806+ else:
807+ self.on_credentials_found()
808+ info = yield self.backend.account_info()
809+ self.process_info(info)
810+ self.is_processing = False
811
812 @log_call(logger.debug)
813 def process_info(self, info):
814
815=== modified file 'ubuntuone/controlpanel/gui/qt/devices.py'
816--- ubuntuone/controlpanel/gui/qt/devices.py 2011-07-21 13:21:00 +0000
817+++ ubuntuone/controlpanel/gui/qt/devices.py 2011-08-26 18:04:35 +0000
818@@ -41,9 +41,11 @@
819
820 title = _('This device')
821 ui_class = devices_ui
822+ localDeviceRemoved = QtCore.pyqtSignal()
823
824 def _setup(self):
825 """Do some extra setupping for the UI."""
826+ super(DevicesPanel, self)._setup()
827 self.ui.manage_devices_button.uri = EDIT_DEVICES_LINK
828
829 @defer.inlineCallbacks
830@@ -64,6 +66,11 @@
831
832 self.is_processing = False
833
834+ def on_local_device_removed(self):
835+ """When the local device is removed, clear the box and emit signal."""
836+ self.clear_device_info(self.ui.local_device_box)
837+ self.localDeviceRemoved.emit()
838+
839 def clear_device_info(self, box):
840 """Clear all the device info."""
841 children = box.count()
842@@ -87,8 +94,7 @@
843 device_widget = device.DeviceWidget(backend=self.backend,
844 device_id=device_info['device_id'])
845 device_widget.update_device_info(device_info)
846- f = lambda: self.clear_device_info(self.ui.local_device_box)
847- device_widget.removed.connect(f)
848+ device_widget.removed.connect(self.on_local_device_removed)
849
850 self.ui.local_device_box.addWidget(device_widget)
851
852
853=== modified file 'ubuntuone/controlpanel/gui/qt/folders.py'
854--- ubuntuone/controlpanel/gui/qt/folders.py 2011-08-05 15:19:12 +0000
855+++ ubuntuone/controlpanel/gui/qt/folders.py 2011-08-26 18:04:35 +0000
856@@ -68,6 +68,7 @@
857
858 def _setup(self):
859 """Do some extra setupping for the UI."""
860+ super(FoldersPanel, self)._setup()
861 load_info = lambda *a, **kw: self.load()
862 self.ui.add_folder_button.folderCreated.connect(load_info)
863
864
865=== modified file 'ubuntuone/controlpanel/gui/qt/gotoweb.py'
866--- ubuntuone/controlpanel/gui/qt/gotoweb.py 2011-07-20 16:31:52 +0000
867+++ ubuntuone/controlpanel/gui/qt/gotoweb.py 2011-08-26 18:04:35 +0000
868@@ -33,6 +33,7 @@
869 self.setIcon(qt.icon_from_name('external_icon_white'))
870 self.setLayoutDirection(QtCore.Qt.RightToLeft)
871 self.clicked.connect(self.on_clicked)
872+ self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
873
874 @QtCore.pyqtSlot()
875 def on_clicked(self):
876
877=== modified file 'ubuntuone/controlpanel/gui/qt/gui.py'
878--- ubuntuone/controlpanel/gui/qt/gui.py 2011-06-14 11:41:11 +0000
879+++ ubuntuone/controlpanel/gui/qt/gui.py 2011-08-26 18:04:35 +0000
880@@ -37,6 +37,11 @@
881 self.ui = mainwindow_ui.Ui_MainWindow()
882 self.ui.setupUi(self)
883 self.close_callback = close_callback
884+ self._setup()
885+
886+ def _setup(self):
887+ """Do some extra setupping for the UI."""
888+ self.ui.control_panel.ui.signin.signinCanceled.connect(self.close)
889
890 # Invalid name "closeEvent"
891 # pylint: disable=C0103
892
893=== modified file 'ubuntuone/controlpanel/gui/qt/loadingoverlay.py'
894--- ubuntuone/controlpanel/gui/qt/loadingoverlay.py 2011-07-28 13:17:49 +0000
895+++ ubuntuone/controlpanel/gui/qt/loadingoverlay.py 2011-08-26 18:04:35 +0000
896@@ -18,8 +18,7 @@
897
898 """Loading animation over a widget."""
899
900-from PyQt4 import QtGui
901-from PyQt4 import QtCore
902+from PyQt4 import QtGui, QtCore
903
904 from ubuntuone.controlpanel.gui.qt.ui import loadingoverlay_ui
905
906
907=== added file 'ubuntuone/controlpanel/gui/qt/signin.py'
908--- ubuntuone/controlpanel/gui/qt/signin.py 1970-01-01 00:00:00 +0000
909+++ ubuntuone/controlpanel/gui/qt/signin.py 2011-08-26 18:04:35 +0000
910@@ -0,0 +1,50 @@
911+# -*- coding: utf-8 -*-
912+
913+# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
914+#
915+# Copyright 2011 Canonical Ltd.
916+#
917+# This program is free software: you can redistribute it and/or modify it
918+# under the terms of the GNU General Public License version 3, as published
919+# by the Free Software Foundation.
920+#
921+# This program is distributed in the hope that it will be useful, but
922+# WITHOUT ANY WARRANTY; without even the implied warranties of
923+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
924+# PURPOSE. See the GNU General Public License for more details.
925+#
926+# You should have received a copy of the GNU General Public License along
927+# with this program. If not, see <http://www.gnu.org/licenses/>.
928+
929+"""The signin page."""
930+
931+from PyQt4 import QtCore
932+
933+from ubuntuone.controlpanel.gui import RESET_PASSWORD_LINK
934+from ubuntuone.controlpanel.gui.qt import icon_from_name
935+from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin
936+from ubuntuone.controlpanel.gui.qt.ui import signin_ui
937+
938+
939+class SignInPanel(UbuntuOneBin):
940+ """The widget for signing in."""
941+
942+ ui_class = signin_ui
943+ signinCanceled = QtCore.pyqtSignal()
944+
945+ def _setup(self):
946+ """Do some extra setupping for the UI."""
947+ super(SignInPanel, self)._setup()
948+ self.ui.forgot_password_button.uri = RESET_PASSWORD_LINK
949+ icon = icon_from_name('external_icon_orange')
950+ self.ui.forgot_password_button.setIcon(icon)
951+
952+ @QtCore.pyqtSlot()
953+ def on_signin_button_clicked(self):
954+ """The 'Sign in' button was clicked."""
955+ self.is_processing = True
956+
957+ @QtCore.pyqtSlot()
958+ def on_cancel_button_clicked(self):
959+ """The 'Cancel' button was clicked."""
960+ self.signinCanceled.emit()
961
962=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
963--- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-07-21 13:21:00 +0000
964+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-08-26 18:04:35 +0000
965@@ -23,7 +23,7 @@
966 from PyQt4 import QtCore
967
968 from ubuntuone.controlpanel import backend
969-from ubuntuone.controlpanel.tests import TestCase, EXPECTED_ACCOUNT_INFO
970+from ubuntuone.controlpanel.tests import TestCase, EXPECTED_ACCOUNT_INFO, TOKEN
971 from ubuntuone.controlpanel.gui.tests import FakedObject, USER_HOME
972
973 # Attribute 'yyy' defined outside __init__, access to a protected member
974@@ -114,7 +114,7 @@
975 backend.UPLOAD_KEY: -1, # no limit
976 }
977
978- next_result = object()
979+ next_result = []
980 exposed_methods = [
981 'account_info', # account
982 'devices_info', 'device_names_info', # devices
983@@ -131,6 +131,11 @@
984 'shutdown',
985 ]
986
987+ def get_credentials(self):
988+ """Fake credentials retrieval."""
989+ self._called['get_credentials'] = ((), {})
990+ return TOKEN
991+
992
993 class FakedConfirmDialog(object):
994 """Fake a confirmation dialog."""
995
996=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
997--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2011-07-20 16:31:52 +0000
998+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2011-08-26 18:04:35 +0000
999@@ -25,11 +25,14 @@
1000 from ubuntuone.controlpanel.gui import qt
1001 from ubuntuone.controlpanel.gui.qt import controlpanel as gui
1002 from ubuntuone.controlpanel.gui.qt.tests import (
1003- BaseTestCase, SAMPLE_ACCOUNT_INFO, SAMPLE_NAME,
1004-)
1005-
1006-
1007-class ControlPanelTestCase(BaseTestCase):
1008+ SAMPLE_ACCOUNT_INFO, SAMPLE_NAME,
1009+)
1010+from ubuntuone.controlpanel.gui.qt.tests.test_ubuntuonebin import (
1011+ UbuntuOneBinTestCase,
1012+)
1013+
1014+
1015+class ControlPanelTestCase(UbuntuOneBinTestCase):
1016 """Test the qt control panel."""
1017
1018 innerclass_ui = gui.controlpanel_ui
1019@@ -41,16 +44,62 @@
1020 yield super(ControlPanelTestCase, self).setUp()
1021 self.ui.backend.next_result = SAMPLE_ACCOUNT_INFO
1022
1023- def test_backend(self):
1024- """Backend is created."""
1025- self.assertIsInstance(self.ui.backend,
1026- gui.backend.ControlBackend)
1027+ @defer.inlineCallbacks
1028+ def test_is_processing_while_asking_info(self):
1029+ """The ui is processing while the contents are loaded."""
1030+ def check():
1031+ """The ui must be is_processing."""
1032+ self.assertTrue(self.ui.is_processing, 'ui must be processing')
1033+ return {}
1034+
1035+ self.patch(self.ui.backend, 'get_credentials', check)
1036+
1037+ yield self.ui.load() # trigger the info request
1038+ self.assertFalse(self.ui.is_processing, 'ui must not be processing')
1039+
1040+ @defer.inlineCallbacks
1041+ def test_credentials_are_requested_on_load(self):
1042+ """The info is requested to the backend."""
1043+ yield self.ui.load()
1044+ self.assert_backend_called('get_credentials')
1045+
1046+ @defer.inlineCallbacks
1047+ def test_on_credentials_not_found_called(self):
1048+ """If no credentials, on_credentials_not_found is called."""
1049+ self.patch(self.ui, 'on_credentials_not_found', self._set_called)
1050+ self.patch(self.ui.backend, 'get_credentials', lambda: {})
1051+ yield self.ui.load()
1052+
1053+ self.assertEqual(self._called, ((), {}))
1054+
1055+ def test_on_credentials_not_found(self):
1056+ """The signin panel is shown."""
1057+ self.ui.on_credentials_found()
1058+ self.ui.on_credentials_not_found()
1059+ self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.signin)
1060+
1061+ @defer.inlineCallbacks
1062+ def test_on_credentials_found_called(self):
1063+ """If credentials, on_credentials_not_found is called."""
1064+ self.patch(self.ui, 'on_credentials_found', self._set_called)
1065+ yield self.ui.load()
1066+
1067+ self.assertEqual(self._called, ((), {}))
1068+
1069+ def test_on_credentials_found(self):
1070+ """The management panel is shown."""
1071+ self.ui.on_credentials_not_found()
1072+ self.ui.on_credentials_found()
1073+ self.assertIs(self.ui.ui.switcher.currentWidget(),
1074+ self.ui.ui.management)
1075
1076 @defer.inlineCallbacks
1077 def test_info_is_requested_on_load(self):
1078 """The info is requested to the backend."""
1079+ self.patch(self.ui, 'process_info', self._set_called)
1080 yield self.ui.load()
1081 self.assert_backend_called('account_info')
1082+ self.assertEqual(self._called, ((SAMPLE_ACCOUNT_INFO,), {}))
1083
1084 def test_process_info(self):
1085 """The info is processed when ready."""
1086@@ -72,6 +121,11 @@
1087 msg = gui.PERCENTAGE_LABEL % percentage_usage
1088 self.assertEqual(self.ui.ui.percentage_usage_label.text(), msg)
1089
1090+ def test_on_local_device_removed(self):
1091+ """On DeviesPanel's localDeviceRemoved, emit credentialsNotFound."""
1092+ self.ui.ui.devices_tab.localDeviceRemoved.emit()
1093+ self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.signin)
1094+
1095
1096 class ExternalLinkButtonsTestCase(ControlPanelTestCase):
1097 """The link in the go-to-web buttons are correct."""
1098
1099=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_devices.py'
1100--- ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2011-07-21 13:21:00 +0000
1101+++ ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2011-08-26 18:04:35 +0000
1102@@ -110,3 +110,13 @@
1103 local_device.removed.emit()
1104
1105 self.assertTrue(self.ui.ui.local_device_box.itemAt(0) is None)
1106+
1107+ def test_local_device_removed_signal(self):
1108+ """When the local device is removed, emit localDeviceRemoved signal."""
1109+ self.ui.localDeviceRemoved.connect(self._set_called)
1110+ self.ui.process_info(SAMPLE_DEVICES_INFO)
1111+
1112+ local_device = self.ui.ui.local_device_box.itemAt(0).widget()
1113+ local_device.removed.emit()
1114+
1115+ self.assertEqual(self._called, ((), {}))
1116
1117=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gotoweb.py'
1118--- ubuntuone/controlpanel/gui/qt/tests/test_gotoweb.py 2011-07-20 16:31:52 +0000
1119+++ ubuntuone/controlpanel/gui/qt/tests/test_gotoweb.py 2011-08-26 18:04:35 +0000
1120@@ -47,6 +47,11 @@
1121 """The layout direction is RightToLeft."""
1122 self.assertEqual(self.ui.layoutDirection(), gui.QtCore.Qt.RightToLeft)
1123
1124+ def test_cursor_pointer(self):
1125+ """The cursor is PointingHandCursor."""
1126+ self.assertEqual(self.ui.cursor().shape(),
1127+ gui.QtCore.Qt.PointingHandCursor)
1128+
1129 def test_open_uri_when_clicked(self):
1130 """When clicking the button, the uri is opened."""
1131 self.ui.uri = 'yadda-yadda-yoo'
1132
1133=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gui.py'
1134--- ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2011-07-11 11:19:09 +0000
1135+++ ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2011-08-26 18:04:35 +0000
1136@@ -41,3 +41,10 @@
1137 self.ui.close_callback = None
1138 self.ui.closeEvent(event=gui.QtGui.QCloseEvent())
1139 # world did not explode
1140+
1141+ def test_on_signin_canceled(self):
1142+ """On SigninPanel's signinCanceled, close."""
1143+ self.patch(self.ui, 'closeEvent', self._set_called)
1144+ self.ui.ui.control_panel.ui.signin.signinCanceled.emit()
1145+ self.assertEqual(len(self._called[0]), 1)
1146+ self.assertIsInstance(self._called[0][0], gui.QtGui.QCloseEvent)
1147
1148=== added file 'ubuntuone/controlpanel/gui/qt/tests/test_signin.py'
1149--- ubuntuone/controlpanel/gui/qt/tests/test_signin.py 1970-01-01 00:00:00 +0000
1150+++ ubuntuone/controlpanel/gui/qt/tests/test_signin.py 2011-08-26 18:04:35 +0000
1151@@ -0,0 +1,52 @@
1152+# -*- coding: utf-8 -*-
1153+
1154+# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
1155+#
1156+# Copyright 2011 Canonical Ltd.
1157+#
1158+# This program is free software: you can redistribute it and/or modify it
1159+# under the terms of the GNU General Public License version 3, as published
1160+# by the Free Software Foundation.
1161+#
1162+# This program is distributed in the hope that it will be useful, but
1163+# WITHOUT ANY WARRANTY; without even the implied warranties of
1164+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1165+# PURPOSE. See the GNU General Public License for more details.
1166+#
1167+# You should have received a copy of the GNU General Public License along
1168+# with this program. If not, see <http://www.gnu.org/licenses/>.
1169+
1170+"""Tests for the Sign In Panel."""
1171+
1172+from ubuntuone.controlpanel.gui import qt
1173+from ubuntuone.controlpanel.gui.qt import signin as gui
1174+from ubuntuone.controlpanel.gui.qt.tests.test_ubuntuonebin import (
1175+ UbuntuOneBinTestCase,
1176+)
1177+
1178+
1179+class SignInPanelTestCase(UbuntuOneBinTestCase):
1180+ """Test the qt cloud preferences tab."""
1181+
1182+ innerclass_ui = gui.signin_ui
1183+ innerclass_name = "Ui_Form"
1184+ class_ui = gui.SignInPanel
1185+
1186+ def test_signin_button(self):
1187+ """Show a loading overlay when the signin button is clicked."""
1188+ self.assertFalse(self.ui.is_processing)
1189+ self.ui.ui.signin_button.click()
1190+ self.assertTrue(self.ui.is_processing)
1191+
1192+ def test_cancel_button(self):
1193+ """Send a signal when the cancel button is clicked."""
1194+ self.ui.signinCanceled.connect(self._set_called)
1195+ self.ui.ui.cancel_button.click()
1196+ self.assertEqual(self._called, ((), {}))
1197+
1198+ def test_forgot_password_button(self):
1199+ """When clicking the forgot passsword btn, the proper url is opened."""
1200+ self.patch(qt, 'uri_hook', self._set_called)
1201+ self.ui.ui.forgot_password_button.click()
1202+
1203+ self.assertEqual(self._called, ((gui.RESET_PASSWORD_LINK,), {}))
1204
1205=== modified file 'ubuntuone/controlpanel/gui/qt/ubuntuonebin.py'
1206--- ubuntuone/controlpanel/gui/qt/ubuntuonebin.py 2011-07-20 21:04:28 +0000
1207+++ ubuntuone/controlpanel/gui/qt/ubuntuonebin.py 2011-08-26 18:04:35 +0000
1208@@ -45,8 +45,8 @@
1209 self._is_processing = None
1210 self.is_processing = False
1211
1212+ self.backend = backend.ControlBackend()
1213 self._setup()
1214- self.backend = backend.ControlBackend()
1215
1216 def _get_is_processing(self):
1217 """Get the value of is_processing."""

Subscribers

People subscribed via source and target branches