Merge lp:~mandel/ubuntu-sso-client/creds-dialog into lp:ubuntu-sso-client

Proposed by Manuel de la Peña
Status: Merged
Approved by: Alejandro J. Cura
Approved revision: 862
Merged at revision: 864
Proposed branch: lp:~mandel/ubuntu-sso-client/creds-dialog
Merge into: lp:ubuntu-sso-client
Diff against target: 589 lines (+564/-0)
4 files modified
data/qt/proxy_credentials_dialog.ui (+316/-0)
ubuntu_sso/qt/proxy_dialog.py (+79/-0)
ubuntu_sso/qt/tests/test_proxy_dialog.py (+158/-0)
ubuntu_sso/utils/ui.py (+11/-0)
To merge this branch: bzr merge lp:~mandel/ubuntu-sso-client/creds-dialog
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) resubmit Approve
Roberto Alsina (community) Approve
Review via email: mp+92769@code.launchpad.net

This proposal supersedes a proposal from 2012-02-10.

Commit message

Adds the credentials dialog with nearly no functionality to the project.

Description of the change

Adds the credentials dialog with nearly no functionality to the project.

To post a comment you must log in.
Revision history for this message
Alejandro J. Cura (alecu) wrote : Posted in a previous version of this proposal

Nicest branch ever!

review: Approve
Revision history for this message
Roberto Alsina (ralsina) wrote : Posted in a previous version of this proposal

+1

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote : Posted in a previous version of this proposal

The prerequisite lp:~mandel/ubuntu-sso-client/support-user-name-url has not yet been merged into lp:ubuntu-sso-client.

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote : Posted in a previous version of this proposal
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote : Posted in a previous version of this proposal
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
862. By Manuel de la Peña

Fixed merge issues and pep8.

Revision history for this message
Alejandro J. Cura (alecu) wrote :

Approving the resubmit of the branch.

review: Approve (resubmit)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/qt/proxy_credentials_dialog.ui'
2--- data/qt/proxy_credentials_dialog.ui 1970-01-01 00:00:00 +0000
3+++ data/qt/proxy_credentials_dialog.ui 2012-02-13 16:19:17 +0000
4@@ -0,0 +1,316 @@
5+<?xml version="1.0" encoding="UTF-8"?>
6+<ui version="4.0">
7+ <class>ProxyCredsDialog</class>
8+ <widget class="QDialog" name="ProxyCredsDialog">
9+ <property name="windowModality">
10+ <enum>Qt::NonModal</enum>
11+ </property>
12+ <property name="geometry">
13+ <rect>
14+ <x>0</x>
15+ <y>0</y>
16+ <width>550</width>
17+ <height>364</height>
18+ </rect>
19+ </property>
20+ <property name="sizePolicy">
21+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
22+ <horstretch>0</horstretch>
23+ <verstretch>0</verstretch>
24+ </sizepolicy>
25+ </property>
26+ <property name="minimumSize">
27+ <size>
28+ <width>502</width>
29+ <height>0</height>
30+ </size>
31+ </property>
32+ <property name="windowTitle">
33+ <string>Add proxy settings</string>
34+ </property>
35+ <property name="sizeGripEnabled">
36+ <bool>false</bool>
37+ </property>
38+ <layout class="QHBoxLayout" name="horizontalLayout">
39+ <property name="sizeConstraint">
40+ <enum>QLayout::SetFixedSize</enum>
41+ </property>
42+ <item>
43+ <layout class="QVBoxLayout" name="verticalLayout">
44+ <property name="spacing">
45+ <number>24</number>
46+ </property>
47+ <item>
48+ <layout class="QHBoxLayout" name="horizontalLayout_4">
49+ <property name="spacing">
50+ <number>12</number>
51+ </property>
52+ <item>
53+ <layout class="QVBoxLayout" name="verticalLayout_4">
54+ <property name="spacing">
55+ <number>0</number>
56+ </property>
57+ <property name="sizeConstraint">
58+ <enum>QLayout::SetDefaultConstraint</enum>
59+ </property>
60+ <item>
61+ <widget class="QLabel" name="logo_label">
62+ <property name="sizePolicy">
63+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
64+ <horstretch>0</horstretch>
65+ <verstretch>0</verstretch>
66+ </sizepolicy>
67+ </property>
68+ <property name="minimumSize">
69+ <size>
70+ <width>48</width>
71+ <height>48</height>
72+ </size>
73+ </property>
74+ <property name="maximumSize">
75+ <size>
76+ <width>48</width>
77+ <height>48</height>
78+ </size>
79+ </property>
80+ <property name="text">
81+ <string>TextLabel</string>
82+ </property>
83+ </widget>
84+ </item>
85+ <item>
86+ <spacer name="verticalSpacer_4">
87+ <property name="orientation">
88+ <enum>Qt::Vertical</enum>
89+ </property>
90+ <property name="sizeType">
91+ <enum>QSizePolicy::Expanding</enum>
92+ </property>
93+ <property name="sizeHint" stdset="0">
94+ <size>
95+ <width>0</width>
96+ <height>20</height>
97+ </size>
98+ </property>
99+ </spacer>
100+ </item>
101+ </layout>
102+ </item>
103+ <item>
104+ <layout class="QVBoxLayout" name="verticalLayout_3">
105+ <property name="spacing">
106+ <number>24</number>
107+ </property>
108+ <item>
109+ <layout class="QVBoxLayout" name="verticalLayout_2">
110+ <property name="spacing">
111+ <number>24</number>
112+ </property>
113+ <item>
114+ <widget class="QLabel" name="title_label">
115+ <property name="sizePolicy">
116+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
117+ <horstretch>0</horstretch>
118+ <verstretch>0</verstretch>
119+ </sizepolicy>
120+ </property>
121+ <property name="font">
122+ <font>
123+ <pointsize>14</pointsize>
124+ <weight>75</weight>
125+ <bold>true</bold>
126+ </font>
127+ </property>
128+ <property name="text">
129+ <string>You are connection through a proxy.</string>
130+ </property>
131+ <property name="wordWrap">
132+ <bool>true</bool>
133+ </property>
134+ </widget>
135+ </item>
136+ <item>
137+ <widget class="QLabel" name="explanation_label">
138+ <property name="text">
139+ <string>Please provide the login details below, or check your system settings</string>
140+ </property>
141+ <property name="wordWrap">
142+ <bool>true</bool>
143+ </property>
144+ </widget>
145+ </item>
146+ </layout>
147+ </item>
148+ <item>
149+ <widget class="QFrame" name="frame">
150+ <property name="frameShape">
151+ <enum>QFrame::NoFrame</enum>
152+ </property>
153+ <property name="frameShadow">
154+ <enum>QFrame::Plain</enum>
155+ </property>
156+ <layout class="QGridLayout" name="gridLayout_2">
157+ <property name="spacing">
158+ <number>12</number>
159+ </property>
160+ <item row="0" column="0">
161+ <widget class="QLabel" name="connection_label">
162+ <property name="sizePolicy">
163+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
164+ <horstretch>0</horstretch>
165+ <verstretch>0</verstretch>
166+ </sizepolicy>
167+ </property>
168+ <property name="text">
169+ <string>Connecting to:</string>
170+ </property>
171+ <property name="alignment">
172+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
173+ </property>
174+ </widget>
175+ </item>
176+ <item row="0" column="1">
177+ <widget class="QLabel" name="domain_label">
178+ <property name="text">
179+ <string/>
180+ </property>
181+ </widget>
182+ </item>
183+ <item row="4" column="0">
184+ <widget class="QLabel" name="username_label">
185+ <property name="text">
186+ <string>Proxy username:</string>
187+ </property>
188+ <property name="alignment">
189+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
190+ </property>
191+ </widget>
192+ </item>
193+ <item row="4" column="1">
194+ <widget class="QLineEdit" name="username_entry">
195+ <property name="text">
196+ <string/>
197+ </property>
198+ </widget>
199+ </item>
200+ <item row="5" column="0">
201+ <widget class="QLabel" name="password_label">
202+ <property name="text">
203+ <string>Proxy password:</string>
204+ </property>
205+ <property name="alignment">
206+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
207+ </property>
208+ </widget>
209+ </item>
210+ <item row="5" column="1">
211+ <widget class="QLineEdit" name="password_entry">
212+ <property name="echoMode">
213+ <enum>QLineEdit::Password</enum>
214+ </property>
215+ </widget>
216+ </item>
217+ <item row="1" column="0">
218+ <spacer name="verticalSpacer">
219+ <property name="orientation">
220+ <enum>Qt::Vertical</enum>
221+ </property>
222+ <property name="sizeType">
223+ <enum>QSizePolicy::Fixed</enum>
224+ </property>
225+ <property name="sizeHint" stdset="0">
226+ <size>
227+ <width>24</width>
228+ <height>12</height>
229+ </size>
230+ </property>
231+ </spacer>
232+ </item>
233+ <item row="2" column="0" colspan="2">
234+ <widget class="QLabel" name="error_label">
235+ <property name="text">
236+ <string>TextLabel</string>
237+ </property>
238+ <property name="wordWrap">
239+ <bool>false</bool>
240+ </property>
241+ </widget>
242+ </item>
243+ <item row="3" column="0">
244+ <spacer name="verticalSpacer_2">
245+ <property name="orientation">
246+ <enum>Qt::Vertical</enum>
247+ </property>
248+ <property name="sizeType">
249+ <enum>QSizePolicy::Fixed</enum>
250+ </property>
251+ <property name="sizeHint" stdset="0">
252+ <size>
253+ <width>24</width>
254+ <height>12</height>
255+ </size>
256+ </property>
257+ </spacer>
258+ </item>
259+ </layout>
260+ </widget>
261+ </item>
262+ </layout>
263+ </item>
264+ </layout>
265+ </item>
266+ <item>
267+ <layout class="QHBoxLayout" name="horizontalLayout_5">
268+ <item>
269+ <widget class="QPushButton" name="help_button">
270+ <property name="text">
271+ <string>Get Help With Proxies</string>
272+ </property>
273+ </widget>
274+ </item>
275+ <item>
276+ <spacer name="horizontalSpacer">
277+ <property name="orientation">
278+ <enum>Qt::Horizontal</enum>
279+ </property>
280+ <property name="sizeHint" stdset="0">
281+ <size>
282+ <width>40</width>
283+ <height>20</height>
284+ </size>
285+ </property>
286+ </spacer>
287+ </item>
288+ <item>
289+ <widget class="QPushButton" name="cancel_button">
290+ <property name="text">
291+ <string>Cancel and Close</string>
292+ </property>
293+ </widget>
294+ </item>
295+ <item>
296+ <widget class="QPushButton" name="save_button">
297+ <property name="text">
298+ <string>Save</string>
299+ </property>
300+ <property name="default">
301+ <bool>true</bool>
302+ </property>
303+ </widget>
304+ </item>
305+ </layout>
306+ </item>
307+ </layout>
308+ </item>
309+ </layout>
310+ </widget>
311+ <tabstops>
312+ <tabstop>username_entry</tabstop>
313+ <tabstop>password_entry</tabstop>
314+ <tabstop>save_button</tabstop>
315+ <tabstop>cancel_button</tabstop>
316+ <tabstop>help_button</tabstop>
317+ </tabstops>
318+ <resources/>
319+ <connections/>
320+</ui>
321
322=== added file 'ubuntu_sso/qt/proxy_dialog.py'
323--- ubuntu_sso/qt/proxy_dialog.py 1970-01-01 00:00:00 +0000
324+++ ubuntu_sso/qt/proxy_dialog.py 2012-02-13 16:19:17 +0000
325@@ -0,0 +1,79 @@
326+# -*- coding: utf-8 -*-
327+#
328+# Copyright 2012 Canonical Ltd.
329+#
330+# This program is free software: you can redistribute it and/or modify it
331+# under the terms of the GNU General Public License version 3, as published
332+# by the Free Software Foundation.
333+#
334+# This program is distributed in the hope that it will be useful, but
335+# WITHOUT ANY WARRANTY; without even the implied warranties of
336+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
337+# PURPOSE. See the GNU General Public License for more details.
338+#
339+# You should have received a copy of the GNU General Public License along
340+# with this program. If not, see <http://www.gnu.org/licenses/>.
341+"""Qt implementation of proxy UI."""
342+
343+
344+from PyQt4.QtGui import QDialog, QIcon
345+
346+from ubuntu_sso.qt.ui.proxy_credentials_dialog_ui import Ui_ProxyCredsDialog
347+from ubuntu_sso.utils.ui import (
348+ PROXY_CREDS_DIALOG_TITLE,
349+ PROXY_CREDS_HEADER,
350+ PROXY_CREDS_EXPLANATION,
351+ PROXY_CREDS_CONNECTION,
352+ PROXY_CREDS_ERROR,
353+ PROXY_CREDS_USER_LABEL,
354+ PROXY_CREDS_PSWD_LABEL,
355+ PROXY_CREDS_HELP_BUTTON,
356+ PROXY_CREDS_CANCEL_BUTTON,
357+ PROXY_CREDS_SAVE_BUTTON,
358+)
359+
360+
361+class ProxyCredsDialog(QDialog):
362+ """"Dialog used to require the proxy credentials."""
363+
364+ def __init__(self, is_error=False, domain=None):
365+ """Create a new instance."""
366+ QDialog.__init__(self)
367+ self.ui = Ui_ProxyCredsDialog()
368+ self.ui.setupUi(self)
369+ # lets set the different basic contents for the ui
370+ self._set_labels()
371+ self._set_buttons()
372+ self._set_icon()
373+ if is_error:
374+ self.ui.error_label.setVisible(True)
375+ else:
376+ self.ui.error_label.setVisible(False)
377+ if domain is None:
378+ self.ui.domain_label.setText('')
379+ else:
380+ self.ui.domain_label.setText(domain)
381+
382+ def _set_labels(self):
383+ """Set the labels translations."""
384+ self.setWindowTitle(PROXY_CREDS_DIALOG_TITLE)
385+ self.ui.title_label.setText(PROXY_CREDS_HEADER)
386+ self.ui.explanation_label.setText(PROXY_CREDS_EXPLANATION)
387+ self.ui.connection_label.setText(PROXY_CREDS_CONNECTION)
388+ # HACK: later this should be set using qss
389+ self.ui.error_label.setText("<font color='#a62626'><b>%s</b></font>"
390+ % PROXY_CREDS_ERROR)
391+ self.ui.username_label.setText(PROXY_CREDS_USER_LABEL)
392+ self.ui.password_label.setText(PROXY_CREDS_PSWD_LABEL)
393+
394+ def _set_buttons(self):
395+ """Set the labels of the buttons."""
396+ self.ui.help_button.setText(PROXY_CREDS_HELP_BUTTON)
397+ self.ui.cancel_button.setText(PROXY_CREDS_CANCEL_BUTTON)
398+ self.ui.save_button.setText(PROXY_CREDS_SAVE_BUTTON)
399+
400+ def _set_icon(self):
401+ """Set the icon used in the dialog."""
402+ icon = QIcon.fromTheme('gtk-dialog-authentication')
403+ self.ui.logo_label.setText('')
404+ self.ui.logo_label.setPixmap(icon.pixmap(48, 48))
405
406=== added file 'ubuntu_sso/qt/tests/test_proxy_dialog.py'
407--- ubuntu_sso/qt/tests/test_proxy_dialog.py 1970-01-01 00:00:00 +0000
408+++ ubuntu_sso/qt/tests/test_proxy_dialog.py 2012-02-13 16:19:17 +0000
409@@ -0,0 +1,158 @@
410+# -*- coding: utf-8 -*-
411+#
412+# Copyright 2012 Canonical Ltd.
413+#
414+# This program is free software: you can redistribute it and/or modify it
415+# under the terms of the GNU General Public License version 3, as published
416+# by the Free Software Foundation.
417+#
418+# This program is distributed in the hope that it will be useful, but
419+# WITHOUT ANY WARRANTY; without even the implied warranties of
420+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
421+# PURPOSE. See the GNU General Public License for more details.
422+#
423+# You should have received a copy of the GNU General Public License along
424+# with this program. If not, see <http://www.gnu.org/licenses/>.
425+"""Test the proxy UI."""
426+
427+from twisted.internet import defer
428+from twisted.trial.unittest import TestCase
429+
430+from ubuntu_sso.qt import proxy_dialog
431+
432+# pylint: disable=E1101,
433+
434+
435+class FakeTextWidget(object):
436+ """A fake widget that contains text."""
437+
438+ def __init__(self, object_name, called):
439+ """Create a new instance."""
440+ self.object_name = object_name
441+ self.called = called
442+
443+ # pylint: disable=C0103
444+ def setText(self, text):
445+ """Set the text of the widget."""
446+ if not self.object_name in self.called:
447+ self.called[self.object_name] = [('setText', text)]
448+ else:
449+ self.called[self.object_name].append(('setText', text))
450+
451+ def setPixmap(self, pixmap):
452+ """Set a pixmap."""
453+ if not self.object_name in self.called:
454+ self.called[self.object_name] = [('setPixmap', pixmap)]
455+ else:
456+ self.called[self.object_name].append(('setPixmap', pixmap))
457+
458+ def setVisible(self, visible):
459+ """Set the ui element visible."""
460+ if not self.object_name in self.called:
461+ self.called[self.object_name] = [('setVisible', visible)]
462+ else:
463+ self.called[self.object_name].append(('setVisible', visible))
464+ # pylint: enable=C0103
465+
466+
467+class FakeUIProxyCredsDialog(object):
468+ """The fake .ui for the creds dialog."""
469+
470+ ui_labels = ('title_label', 'explanation_label', 'connection_label',
471+ 'error_label', 'username_label', 'password_label',
472+ 'domain_label', 'logo_label')
473+ ui_buttons = ('help_button', 'cancel_button', 'save_button')
474+
475+ def __init__(self):
476+ """Create a new instance."""
477+ self.called = {}
478+ for name in self.ui_labels + self.ui_buttons:
479+ setattr(self, name, FakeTextWidget(name, self.called))
480+
481+ # pylint: disable=C0103
482+ def setupUi(self, dialog):
483+ """Set the ui."""
484+ self.called['FakeUIProxyCredsDialog'] = ('setupUi', dialog)
485+ # pylint: enable=C0103
486+
487+
488+class FakeQIcon(object):
489+ """QIcon class."""
490+
491+ def __init__(self):
492+ """Create a new instance."""
493+ self.called = []
494+
495+ # pylint: disable=C0103
496+ def fromTheme(self, icon_id):
497+ """Return the icon with the given id."""
498+ self.called.append(('fromTheme', icon_id))
499+ return self
500+ # pylint: enable=C0103
501+
502+ # pylint: disable=C0103
503+ def pixmap(self, h, w):
504+ """Get the pixmap with the given size."""
505+ self.called.append(('pixmap', h, w))
506+ return self
507+ # pylint: disable=C0103
508+
509+
510+class ProxyCredsDialogTest(TestCase):
511+ """Test the proxy creds dialog."""
512+
513+ @defer.inlineCallbacks
514+ def setUp(self):
515+ """Set tests."""
516+ yield super(ProxyCredsDialogTest, self).setUp()
517+ self.patch(proxy_dialog, 'Ui_ProxyCredsDialog',
518+ FakeUIProxyCredsDialog)
519+ self.icon = FakeQIcon()
520+ self.patch(proxy_dialog, 'QIcon', self.icon)
521+
522+ def test_set_labels(self):
523+ """Ensure the correct labels are used."""
524+ dialog = proxy_dialog.ProxyCredsDialog()
525+ for label in dialog.ui.ui_labels:
526+ self.assertIn(label, dialog.ui.called, label)
527+
528+ def test_set_buttons(self):
529+ """Ensure that buttons are set."""
530+ dialog = proxy_dialog.ProxyCredsDialog()
531+ for label in dialog.ui.ui_buttons:
532+ self.assertIn(label, dialog.ui.called)
533+
534+ def test_domain_empty(self):
535+ """Test that if the domain is not passed we set ''"""
536+ dialog = proxy_dialog.ProxyCredsDialog()
537+ self.assertIn('domain_label', dialog.ui.called)
538+ self.assertIn(('setText', ''), dialog.ui.called['domain_label'])
539+
540+ def test_domain_not_empty(self):
541+ """Test that we do set the domain."""
542+ domain = '192.168.1.100'
543+ dialog = proxy_dialog.ProxyCredsDialog(domain=domain)
544+ self.assertIn('domain_label', dialog.ui.called)
545+ self.assertIn(('setText', domain), dialog.ui.called['domain_label'])
546+
547+ def test_is_error(self):
548+ """Test that we do set the error label correctly."""
549+ dialog = proxy_dialog.ProxyCredsDialog(is_error=False)
550+ self.assertIn('error_label', dialog.ui.called)
551+ self.assertIn(('setVisible', False), dialog.ui.called['error_label'])
552+
553+ def test_is_not_error(self):
554+ """Test that we do set the error label correctly."""
555+ dialog = proxy_dialog.ProxyCredsDialog(is_error=True)
556+ self.assertIn('error_label', dialog.ui.called)
557+ self.assertIn(('setVisible', True), dialog.ui.called['error_label'])
558+
559+ def test_icon(self):
560+ """Test that we correctly set the icon."""
561+ dialog = proxy_dialog.ProxyCredsDialog()
562+ self.assertIn(('fromTheme', 'gtk-dialog-authentication'),
563+ self.icon.called)
564+ self.assertIn(('pixmap', 48, 48),
565+ self.icon.called)
566+ self.assertIn(('setPixmap', self.icon),
567+ dialog.ui.called['logo_label'])
568
569=== modified file 'ubuntu_sso/utils/ui.py'
570--- ubuntu_sso/utils/ui.py 2012-02-11 19:36:09 +0000
571+++ ubuntu_sso/utils/ui.py 2012-02-13 16:19:17 +0000
572@@ -36,6 +36,17 @@
573 CAPTCHA_RELOAD_TOOLTIP = _('Reload')
574 CAPTCHA_REQUIRED_ERROR = _('The captcha is a required field')
575 CONGRATULATIONS = _("Congratulations, {app_name} is installed!")
576+PROXY_CREDS_DIALOG_TITLE = _('Add proxy settings')
577+PROXY_CREDS_HEADER = _('You are connecting through a proxy.')
578+PROXY_CREDS_EXPLANATION = _('Please provide login details below, ' \
579+ 'or check your system settings.')
580+PROXY_CREDS_CONNECTION = _('Connecting to:')
581+PROXY_CREDS_ERROR = _('These credentials are incorrect; please try again.')
582+PROXY_CREDS_USER_LABEL = _('Proxy username:')
583+PROXY_CREDS_PSWD_LABEL = _('Proxy password:')
584+PROXY_CREDS_HELP_BUTTON = _('Get Help With Proxies')
585+PROXY_CREDS_CANCEL_BUTTON = _('Cancel And Close')
586+PROXY_CREDS_SAVE_BUTTON = _('Save')
587 CONNECT_HELP_LABEL = _('To connect this computer to %(app_name)s ' \
588 'enter your details below.')
589 EMAIL_LABEL = EMAIL1_ENTRY = _('Email address')

Subscribers

People subscribed via source and target branches