summaryrefslogtreecommitdiff
path: root/src/leap
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap')
-rw-r--r--src/leap/gui/firstrun/__init__.py2
-rw-r--r--src/leap/gui/firstrun/connect.py231
-rw-r--r--src/leap/gui/firstrun/providerselect.py22
-rw-r--r--src/leap/gui/firstrun/register.py82
-rwxr-xr-xsrc/leap/gui/firstrun/wizard.py32
-rw-r--r--src/leap/gui/progress.py1
-rw-r--r--src/leap/gui/tests/test_firstrun_providerselect.py162
-rw-r--r--src/leap/gui/tests/test_firstrun_register.py224
-rw-r--r--src/leap/gui/tests/test_firstrun_wizard.py3
9 files changed, 458 insertions, 301 deletions
diff --git a/src/leap/gui/firstrun/__init__.py b/src/leap/gui/firstrun/__init__.py
index a2ca704d..d380b75a 100644
--- a/src/leap/gui/firstrun/__init__.py
+++ b/src/leap/gui/firstrun/__init__.py
@@ -5,7 +5,6 @@ try:
except ValueError:
pass
-import connect
import intro
import last
import login
@@ -17,7 +16,6 @@ import register
import regvalidation
__all__ = [
- 'connect',
'intro',
'last',
'login',
diff --git a/src/leap/gui/firstrun/connect.py b/src/leap/gui/firstrun/connect.py
deleted file mode 100644
index a0fe021c..00000000
--- a/src/leap/gui/firstrun/connect.py
+++ /dev/null
@@ -1,231 +0,0 @@
-"""
-Connecting Page, used in First Run Wizard
-"""
-# XXX FIXME
-# DEPRECATED. All functionality moved to regvalidation
-# This file should be removed after checking that one is ok.
-# XXX
-
-import logging
-
-from PyQt4 import QtGui
-
-logger = logging.getLogger(__name__)
-
-from leap.base import auth
-
-from leap.gui.constants import APP_LOGO
-from leap.gui.styles import ErrorLabelStyleSheet
-
-
-class ConnectingPage(QtGui.QWizardPage):
-
- # XXX change to a ValidationPage
-
- def __init__(self, parent=None):
- super(ConnectingPage, self).__init__(parent)
-
- self.setTitle("Connecting")
- self.setSubTitle('Connecting to provider.')
-
- self.setPixmap(
- QtGui.QWizard.LogoPixmap,
- QtGui.QPixmap(APP_LOGO))
-
- self.status = QtGui.QLabel("")
- self.status.setWordWrap(True)
- self.progress = QtGui.QProgressBar()
- self.progress.setMaximum(100)
- self.progress.hide()
-
- # for pre-checks
- self.status_line_1 = QtGui.QLabel()
- self.status_line_2 = QtGui.QLabel()
- self.status_line_3 = QtGui.QLabel()
- self.status_line_4 = QtGui.QLabel()
-
- # for connecting signals...
- self.status_line_5 = QtGui.QLabel()
-
- layout = QtGui.QGridLayout()
- layout.addWidget(self.status, 0, 1)
- layout.addWidget(self.progress, 5, 1)
- layout.addWidget(self.status_line_1, 8, 1)
- layout.addWidget(self.status_line_2, 9, 1)
- layout.addWidget(self.status_line_3, 10, 1)
- layout.addWidget(self.status_line_4, 11, 1)
-
- # XXX to be used?
- #self.validation_status = QtGui.QLabel("")
- #self.validation_status.setStyleSheet(
- #ErrorLabelStyleSheet)
- #self.validation_msg = QtGui.QLabel("")
-
- self.setLayout(layout)
-
- self.goto_login_again = False
-
- def set_status(self, status):
- self.status.setText(status)
- self.status.setWordWrap(True)
-
- def set_status_line(self, line, status):
- line = getattr(self, 'status_line_%s' % line)
- if line:
- line.setText(status)
-
- def set_validation_status(self, status):
- # Do not remember if we're using
- # status lines > 3 now...
- # if we are, move below
- self.status_line_3.setStyleSheet(
- ErrorLabelStyleSheet)
- self.status_line_3.setText(status)
-
- def set_validation_message(self, message):
- self.status_line_4.setText(message)
- self.status_line_4.setWordWrap(True)
-
- def get_donemsg(self, msg):
- return "%s ... done" % msg
-
- def run_eip_checks_for_provider_and_connect(self, domain):
- wizard = self.wizard()
- conductor = wizard.conductor
- start_eip_signal = getattr(
- wizard,
- 'start_eipconnection_signal', None)
-
- if conductor:
- conductor.set_provider_domain(domain)
- conductor.run_checks()
- self.conductor = conductor
- errors = self.eip_error_check()
- if not errors and start_eip_signal:
- start_eip_signal.emit()
-
- else:
- logger.warning(
- "No conductor found. This means that "
- "probably the wizard has been launched "
- "in an stand-alone way")
-
- def eip_error_check(self):
- """
- a version of the main app error checker,
- but integrated within the connecting page of the wizard.
- consumes the conductor error queue.
- pops errors, and add those to the wizard page
- """
- logger.debug('eip error check from connecting page')
- errq = self.conductor.error_queue
- # XXX missing!
-
- def fetch_and_validate(self):
- # XXX MOVE TO validate function in register-validation
- import time
- domain = self.field('provider_domain')
- wizard = self.wizard()
- #pconfig = wizard.providerconfig
- eipconfigchecker = wizard.eipconfigchecker()
- pCertChecker = wizard.providercertchecker(
- domain=domain)
-
- # username and password are in different fields
- # if they were stored in log_in or sign_up pages.
- from_login = self.wizard().from_login
- unamek_base = 'userName'
- passwk_base = 'userPassword'
- unamek = 'login_%s' % unamek_base if from_login else unamek_base
- passwk = 'login_%s' % passwk_base if from_login else passwk_base
-
- username = self.field(unamek)
- password = self.field(passwk)
- credentials = username, password
-
- self.progress.show()
-
- fetching_eip_conf_msg = 'Fetching eip service configuration'
- self.set_status(fetching_eip_conf_msg)
- self.progress.setValue(30)
-
- # Fetching eip service
- eipconfigchecker.fetch_eip_service_config(
- domain=domain)
-
- self.status_line_1.setText(
- self.get_donemsg(fetching_eip_conf_msg))
-
- getting_client_cert_msg = 'Getting client certificate'
- self.set_status(getting_client_cert_msg)
- self.progress.setValue(66)
-
- # Download cert
- try:
- pCertChecker.download_new_client_cert(
- credentials=credentials,
- # FIXME FIXME FIXME
- # XXX FIX THIS!!!!!
- # BUG #638. remove verify
- # FIXME FIXME FIXME
- verify=False)
- except auth.SRPAuthenticationError as exc:
- self.set_validation_status(
- "Authentication error: %s" % exc.message)
- return False
-
- time.sleep(2)
- self.status_line_2.setText(
- self.get_donemsg(getting_client_cert_msg))
-
- validating_clientcert_msg = 'Validating client certificate'
- self.set_status(validating_clientcert_msg)
- self.progress.setValue(90)
- time.sleep(2)
- self.status_line_3.setText(
- self.get_donemsg(validating_clientcert_msg))
-
- self.progress.setValue(100)
- time.sleep(3)
-
- # here we go! :)
- self.run_eip_checks_for_provider_and_connect(domain)
-
- #self.validation_block = self.wait_for_validation_block()
-
- # XXX signal timeout!
- return True
-
- #
- # wizardpage methods
- #
-
- def nextId(self):
- wizard = self.wizard()
- # XXX this does not work because
- # page login has already been met
- #if self.goto_login_again:
- #next_ = "login"
- #else:
- #next_ = "lastpage"
- next_ = "lastpage"
- return wizard.get_page_index(next_)
-
- def initializePage(self):
- # XXX if we're coming from signup page
- # we could say something like
- # 'registration successful!'
- self.status.setText(
- "We have "
- "all we need to connect with the provider.<br><br> "
- "Click <i>next</i> to continue. ")
- self.progress.setValue(0)
- self.progress.hide()
- self.status_line_1.setText('')
- self.status_line_2.setText('')
- self.status_line_3.setText('')
-
- def validatePage(self):
- # XXX remove
- validated = self.fetch_and_validate()
- return validated
diff --git a/src/leap/gui/firstrun/providerselect.py b/src/leap/gui/firstrun/providerselect.py
index a4be51a9..fd48f7f9 100644
--- a/src/leap/gui/firstrun/providerselect.py
+++ b/src/leap/gui/firstrun/providerselect.py
@@ -40,7 +40,7 @@ class SelectProviderPage(InlineValidationPage):
self.did_cert_check = False
- self.is_done = False
+ self.done = False
self.setupSteps()
self.setupUI()
@@ -131,7 +131,7 @@ class SelectProviderPage(InlineValidationPage):
# certinfo
- def setupCertInfoGroup(self):
+ def setupCertInfoGroup(self): # pragma: no cover
# XXX not used now.
certinfoGroup = QtGui.QGroupBox(
self.tr("Certificate validation"))
@@ -188,7 +188,6 @@ class SelectProviderPage(InlineValidationPage):
_domain = u"%s:%s" % (domain, port) if port != 443 else unicode(domain)
netchecker = wizard.netchecker()
-
providercertchecker = wizard.providercertchecker()
eipconfigchecker = wizard.eipconfigchecker(domain=_domain)
@@ -205,6 +204,7 @@ class SelectProviderPage(InlineValidationPage):
this domain
"""
try:
+ #import ipdb;ipdb.set_trace()
netchecker.check_name_resolution(
domain)
@@ -306,7 +306,7 @@ class SelectProviderPage(InlineValidationPage):
# done!
- self.is_done = True
+ self.done = True
yield(("end_sentinel", 100), lambda: None)
def on_checks_validation_ready(self):
@@ -316,7 +316,7 @@ class SelectProviderPage(InlineValidationPage):
self.domain_checked = True
self.completeChanged.emit()
# let's set focus...
- if self.is_done:
+ if self.is_done():
self.wizard().clean_validation_error(self.current_page)
nextbutton = self.wizard().button(QtGui.QWizard.NextButton)
nextbutton.setFocus()
@@ -329,7 +329,7 @@ class SelectProviderPage(InlineValidationPage):
def is_insecure_cert_trusted(self):
return self.trustProviderCertCheckBox.isChecked()
- def onTrustCheckChanged(self, state):
+ def onTrustCheckChanged(self, state): # pragma: no cover XXX
checked = False
if state == 2:
checked = True
@@ -342,7 +342,7 @@ class SelectProviderPage(InlineValidationPage):
# trigger signal to redraw next button
self.completeChanged.emit()
- def add_cert_info(self, certinfo):
+ def add_cert_info(self, certinfo): # pragma: no cover XXX
self.certWarning.setText(
"Do you want to <b>trust this provider certificate?</b>")
self.certInfo.setText(
@@ -351,7 +351,7 @@ class SelectProviderPage(InlineValidationPage):
self.certinfoGroup.show()
def onProviderChanged(self, text):
- self.is_done = False
+ self.done = False
provider = self.providerNameEdit.text()
if provider:
self.providerCheckButton.setDisabled(False)
@@ -374,7 +374,7 @@ class SelectProviderPage(InlineValidationPage):
def isComplete(self):
provider = self.providerNameEdit.text()
- if not self.is_done:
+ if not self.is_done():
return False
if not provider:
@@ -383,7 +383,7 @@ class SelectProviderPage(InlineValidationPage):
if self.is_insecure_cert_trusted():
return True
if not self.did_cert_check:
- if self.is_done:
+ if self.is_done():
# XXX sure?
return True
return False
@@ -452,7 +452,7 @@ class SelectProviderPage(InlineValidationPage):
if hasattr(self, 'certinfoGroup'):
# XXX remove ?
self.certinfoGroup.hide()
- self.is_done = False
+ self.done = False
self.providerCheckButton.setDisabled(True)
self.valFrame.hide()
self.steps.removeAllSteps()
diff --git a/src/leap/gui/firstrun/register.py b/src/leap/gui/firstrun/register.py
index e85723cb..7fd5c574 100644
--- a/src/leap/gui/firstrun/register.py
+++ b/src/leap/gui/firstrun/register.py
@@ -131,6 +131,16 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
field.setDisabled(True)
# error painting
+ def paintEvent(self, event):
+ """
+ we hook our populate errors
+ on paintEvent because we need it to catch
+ when user enters the page coming from next,
+ and initializePage does not cover that case.
+ Maybe there's a better event to hook upon.
+ """
+ super(RegisterUserPage, self).paintEvent(event)
+ self.populateErrors()
def markRedAndGetFocus(self, field):
field.setStyleSheet(styles.ErrorLineEdit)
@@ -193,16 +203,21 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
"""
self.bad_string = None
- def paintEvent(self, event):
+ def green_validation_status(self):
+ val = self.validationMsg
+ val.setText(self.tr('Registration succeeded!'))
+ val.setStyleSheet(styles.GreenLineEdit)
+
+ def reset_validation_status(self):
"""
- we hook our populate errors
- on paintEvent because we need it to catch
- when user enters the page coming from next,
- and initializePage does not cover that case.
- Maybe there's a better event to hook upon.
+ empty the validation msg
+ and clean the inline validation widget.
"""
- super(RegisterUserPage, self).paintEvent(event)
- self.populateErrors()
+ self.validationMsg.setText('')
+ self.steps.removeAllSteps()
+ self.clearTable()
+
+ # actual checks
def _do_checks(self):
"""
@@ -255,6 +270,7 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
schema="https",
provider=provider,
verify=verify)
+ #import ipdb;ipdb.set_trace()
try:
ok, req = signup.register_user(
username, password)
@@ -277,9 +293,15 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
self.tr(
"Error during registration (%s)") % req.status_code)
- validation_msgs = json.loads(req.content)
- errors = validation_msgs.get('errors', None)
- logger.debug('validation errors: %s' % validation_msgs)
+ try:
+ validation_msgs = json.loads(req.content)
+ errors = validation_msgs.get('errors', None)
+ logger.debug('validation errors: %s' % validation_msgs)
+ except ValueError:
+ # probably bad json returned
+ return self.fail(
+ self.tr(
+ "Could not register (bad response)"))
if errors and errors.get('login', None):
# XXX this sometimes catch the blank username
@@ -287,11 +309,13 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
return self.fail(
self.tr('Username not available.'))
+ return True
+
logger.debug('registering user')
yield(("registering with provider", 40), register)
self.set_done()
- yield(("end_sentinel", 0), lambda: None)
+ yield(("end_sentinel", 100), lambda: None)
def on_checks_validation_ready(self):
"""
@@ -308,20 +332,6 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
self.green_validation_status()
self.do_confirm_next = True
- def green_validation_status(self):
- val = self.validationMsg
- val.setText(self.tr('Registration succeeded!'))
- val.setStyleSheet(styles.GreenLineEdit)
-
- def reset_validation_status(self):
- """
- empty the validation msg
- and clean the inline validation widget.
- """
- self.validationMsg.setText('')
- self.steps.removeAllSteps()
- self.clearTable()
-
# pagewizard methods
def validatePage(self):
@@ -352,10 +362,22 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
"""
inits wizard page
"""
- provider = self.field('provider_domain')
- self.setSubTitle(
- self.tr("Register a new user with provider %s.") %
- provider)
+ provider = unicode(self.field('provider_domain'))
+ # hack. don't get why I'm getting a QVariant there,
+ # making segfault in tests.
+ provider = QtCore.QString(provider)
+ if provider:
+ # here we should have provider
+ # but in tests we might not.
+
+ # XXX this error causes a segfault on free()
+ # that we might want to get fixed ...
+ #self.setSubTitle(
+ #self.tr("Register a new user with provider %s.") %
+ #provider)
+ self.setSubTitle(
+ self.tr("Register a new user with provider %s." %
+ provider))
self.validationMsg.setText('')
self.userPassword2LineEdit.setText('')
self.valFrame.hide()
diff --git a/src/leap/gui/firstrun/wizard.py b/src/leap/gui/firstrun/wizard.py
index bd3fe903..89209401 100755
--- a/src/leap/gui/firstrun/wizard.py
+++ b/src/leap/gui/firstrun/wizard.py
@@ -49,12 +49,29 @@ TODO-ish:
"""
+def get_pages_dict():
+ return OrderedDict((
+ ('intro', firstrun.intro.IntroPage),
+ ('providerselection',
+ firstrun.providerselect.SelectProviderPage),
+ ('login', firstrun.login.LogInPage),
+ ('providerinfo', firstrun.providerinfo.ProviderInfoPage),
+ ('providersetupvalidation',
+ firstrun.providersetup.ProviderSetupValidationPage),
+ ('signup', firstrun.register.RegisterUserPage),
+ ('signupvalidation',
+ firstrun.regvalidation.RegisterUserValidationPage),
+ ('lastpage', firstrun.last.LastPage)
+ ))
+
+
class FirstRunWizard(QtGui.QWizard):
def __init__(
self,
conductor_instance,
parent=None,
+ pages_dict=None,
eip_username=None,
providers=None,
success_cb=None, is_provider_setup=False,
@@ -115,20 +132,7 @@ class FirstRunWizard(QtGui.QWizard):
self.is_previously_registered = bool(self.eip_username)
self.from_login = False
- pages_dict = OrderedDict((
- ('intro', firstrun.intro.IntroPage),
- ('providerselection',
- firstrun.providerselect.SelectProviderPage),
- ('login', firstrun.login.LogInPage),
- ('providerinfo', firstrun.providerinfo.ProviderInfoPage),
- ('providersetupvalidation',
- firstrun.providersetup.ProviderSetupValidationPage),
- ('signup', firstrun.register.RegisterUserPage),
- ('signupvalidation',
- firstrun.regvalidation.RegisterUserValidationPage),
- ('connecting', firstrun.connect.ConnectingPage),
- ('lastpage', firstrun.last.LastPage)
- ))
+ pages_dict = pages_dict or get_pages_dict()
self.add_pages_from_dict(pages_dict)
self.validation_errors = {}
diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py
index f0bb4cfc..ffea80de 100644
--- a/src/leap/gui/progress.py
+++ b/src/leap/gui/progress.py
@@ -248,6 +248,7 @@ class WithStepsMixIn(object):
# slot
#@QtCore.pyqtSlot(str, int)
def onStepStatusChanged(self, status, progress=None):
+ status = unicode(status)
if status not in ("head_sentinel", "end_sentinel"):
self.add_status_line(status)
if status in ("end_sentinel"):
diff --git a/src/leap/gui/tests/test_firstrun_providerselect.py b/src/leap/gui/tests/test_firstrun_providerselect.py
index be7cc9c1..976c68cd 100644
--- a/src/leap/gui/tests/test_firstrun_providerselect.py
+++ b/src/leap/gui/tests/test_firstrun_providerselect.py
@@ -4,23 +4,29 @@ import unittest
import mock
from leap.testing import qunittest
-from leap.testing import pyqt
+#from leap.testing import pyqt
from PyQt4 import QtGui
#from PyQt4 import QtCore
-import PyQt4.QtCore # some weirdness with mock module
+#import PyQt4.QtCore # some weirdness with mock module
from PyQt4.QtTest import QTest
-#from PyQt4.QtCore import Qt
+from PyQt4.QtCore import Qt
from leap.gui import firstrun
+try:
+ from collections import OrderedDict
+except ImportError:
+ # We must be in 2.6
+ from leap.util.dicts import OrderedDict
+
class TestPage(firstrun.providerselect.SelectProviderPage):
pass
-class SelectProviderPageTestCase(qunittest.TestCase):
+class SelectProviderPageLogicTestCase(qunittest.TestCase):
# XXX can spy on signal connections
@@ -29,7 +35,18 @@ class SelectProviderPageTestCase(qunittest.TestCase):
QtGui.qApp = self.app
self.page = TestPage(None)
self.page.wizard = mock.MagicMock()
- self.page.wizard().netchecker.return_value = True
+
+ mocknetchecker = mock.Mock()
+ self.page.wizard().netchecker.return_value = mocknetchecker
+ self.mocknetchecker = mocknetchecker
+
+ mockpcertchecker = mock.Mock()
+ self.page.wizard().providercertchecker.return_value = mockpcertchecker
+ self.mockpcertchecker = mockpcertchecker
+
+ mockeipconfchecker = mock.Mock()
+ self.page.wizard().eipconfigchecker.return_value = mockeipconfchecker
+ self.mockeipconfchecker = mockeipconfchecker
def tearDown(self):
QtGui.qApp = None
@@ -38,6 +55,9 @@ class SelectProviderPageTestCase(qunittest.TestCase):
def test__do_checks(self):
eq = self.assertEqual
+
+ self.page.providerNameEdit.setText('test_provider1')
+
checks = [x for x in self.page._do_checks()]
eq(len(checks), 5)
labels = [str(x) for (x, y), z in checks]
@@ -47,15 +67,135 @@ class SelectProviderPageTestCase(qunittest.TestCase):
progress = [y for (x, y), z in checks]
eq(progress, [0, 20, 40, 80, 100])
- # XXX now: execute the functions
- # with proper mocks (for checkers and so on)
- # and try to cover all the exceptions
+ # normal run, ie, no exceptions
+
checkfuns = [z for (x, y), z in checks]
- #import ipdb;ipdb.set_trace()
+ namecheck, httpscheck, fetchinfo = checkfuns[1:-1]
+
+ self.assertTrue(namecheck())
+ self.mocknetchecker.check_name_resolution.assert_called_with(
+ 'test_provider1')
+
+ self.assertTrue(httpscheck())
+ self.mockpcertchecker.is_https_working.assert_called_with(
+ "https://test_provider1", verify=True)
+
+ self.assertTrue(fetchinfo())
+ self.mockeipconfchecker.fetch_definition.assert_called_with(
+ domain="test_provider1")
+
+ # XXX missing: inject failing exceptions
+ # XXX TODO make it break
+
- def test_next_button_is_disabled(self):
- pass
+class SelectProviderPageUITestCase(qunittest.TestCase):
+ # XXX can spy on signal connections
+ __name__ = "Select Provider Page UI tests"
+
+ def setUp(self):
+ self.app = QtGui.QApplication(sys.argv)
+ QtGui.qApp = self.app
+
+ self.pagename = "providerselection"
+ pages = OrderedDict((
+ (self.pagename, TestPage),
+ ('providerinfo',
+ firstrun.providerinfo.ProviderInfoPage)))
+ self.wizard = firstrun.wizard.FirstRunWizard(None, pages_dict=pages)
+ self.page = self.wizard.page(self.wizard.get_page_index(self.pagename))
+
+ self.page.do_checks = mock.Mock()
+
+ # wizard would do this for us
+ self.page.initializePage()
+
+ def tearDown(self):
+ QtGui.qApp = None
+ self.app = None
+ self.wizard = None
+
+ def fill_provider(self):
+ """
+ fills provider line edit
+ """
+ keyp = QTest.keyPress
+ pedit = self.page.providerNameEdit
+ pedit.setFocus(True)
+ for c in "testprovider":
+ keyp(pedit, c)
+ self.assertEqual(pedit.text(), "testprovider")
+
+ def del_provider(self):
+ """
+ deletes entried provider in
+ line edit
+ """
+ keyp = QTest.keyPress
+ pedit = self.page.providerNameEdit
+ for c in range(len("testprovider")):
+ keyp(pedit, Qt.Key_Backspace)
+ self.assertEqual(pedit.text(), "")
+
+ def test_buttons_disabled_until_textentry(self):
+ nextbutton = self.wizard.button(QtGui.QWizard.NextButton)
+ checkbutton = self.page.providerCheckButton
+
+ self.assertFalse(nextbutton.isEnabled())
+ self.assertFalse(checkbutton.isEnabled())
+
+ self.fill_provider()
+ # checkbutton should be enabled
+ self.assertTrue(checkbutton.isEnabled())
+ self.assertFalse(nextbutton.isEnabled())
+
+ self.del_provider()
+ # after rm provider checkbutton disabled again
+ self.assertFalse(checkbutton.isEnabled())
+ self.assertFalse(nextbutton.isEnabled())
+
+ def test_check_button_triggers_tests(self):
+ checkbutton = self.page.providerCheckButton
+ self.assertFalse(checkbutton.isEnabled())
+ self.assertFalse(self.page.do_checks.called)
+
+ self.fill_provider()
+
+ self.assertTrue(checkbutton.isEnabled())
+ mclick = QTest.mouseClick
+ # click!
+ mclick(checkbutton, Qt.LeftButton)
+ self.waitFor(seconds=0.1)
+ self.assertTrue(self.page.do_checks.called)
+
+ # XXX
+ # can play with different side_effects for do_checks mock...
+ # so we can see what happens with errors and so on
+
+ def test_page_completed_after_checks(self):
+ nextbutton = self.wizard.button(QtGui.QWizard.NextButton)
+ self.assertFalse(nextbutton.isEnabled())
+
+ self.assertFalse(self.page.isComplete())
+ self.fill_provider()
+ # simulate checks done
+ self.page.done = True
+ self.page.on_checks_validation_ready()
+ self.assertTrue(self.page.isComplete())
+ # cannot test for nexbutton enabled
+ # cause it's the the wizard loop
+ # that would do that I think
+
+ def test_validate_page(self):
+ self.assertTrue(self.page.validatePage())
+
+ def test_next_id(self):
+ self.assertEqual(self.page.nextId(), 1)
+
+ def test_paint_event(self):
+ self.page.populateErrors = mock.Mock()
+ self.page.paintEvent(None)
+ self.page.populateErrors.assert_called_with()
if __name__ == "__main__":
unittest.main()
diff --git a/src/leap/gui/tests/test_firstrun_register.py b/src/leap/gui/tests/test_firstrun_register.py
new file mode 100644
index 00000000..be38e87c
--- /dev/null
+++ b/src/leap/gui/tests/test_firstrun_register.py
@@ -0,0 +1,224 @@
+import sys
+import unittest
+
+import mock
+
+from leap.testing import qunittest
+#from leap.testing import pyqt
+
+from PyQt4 import QtGui
+#from PyQt4 import QtCore
+#import PyQt4.QtCore # some weirdness with mock module
+
+from PyQt4.QtTest import QTest
+from PyQt4.QtCore import Qt
+
+from leap.gui import firstrun
+
+try:
+ from collections import OrderedDict
+except ImportError:
+ # We must be in 2.6
+ from leap.util.dicts import OrderedDict
+
+
+class TestPage(firstrun.register.RegisterUserPage):
+
+ def field(self, field):
+ if field == "provider_domain":
+ return "testprovider"
+
+
+class RegisterUserPageLogicTestCase(qunittest.TestCase):
+
+ # XXX can spy on signal connections
+ __name__ = "register user page logic tests"
+
+ def setUp(self):
+ self.app = QtGui.QApplication(sys.argv)
+ QtGui.qApp = self.app
+ self.page = TestPage(None)
+ self.page.wizard = mock.MagicMock()
+
+ #mocknetchecker = mock.Mock()
+ #self.page.wizard().netchecker.return_value = mocknetchecker
+ #self.mocknetchecker = mocknetchecker
+#
+ #mockpcertchecker = mock.Mock()
+ #self.page.wizard().providercertchecker.return_value = mockpcertchecker
+ #self.mockpcertchecker = mockpcertchecker
+#
+ #mockeipconfchecker = mock.Mock()
+ #self.page.wizard().eipconfigchecker.return_value = mockeipconfchecker
+ #self.mockeipconfchecker = mockeipconfchecker
+
+ def tearDown(self):
+ QtGui.qApp = None
+ self.app = None
+ self.page = None
+
+ def test__do_checks(self):
+ eq = self.assertEqual
+
+ self.page.userNameLineEdit.setText('testuser')
+ self.page.userPasswordLineEdit.setText('testpassword')
+ self.page.userPassword2LineEdit.setText('testpassword')
+
+ # fake register process
+ with mock.patch('leap.base.auth.LeapSRPRegister') as mockAuth:
+ mockSignup = mock.MagicMock()
+
+ reqMockup = mock.Mock()
+ # XXX should inject bad json to get error
+ reqMockup.content = '{"errors": null}'
+ mockSignup.register_user.return_value = (True, reqMockup)
+ mockAuth.return_value = mockSignup
+ checks = [x for x in self.page._do_checks()]
+
+ eq(len(checks), 3)
+ labels = [str(x) for (x, y), z in checks]
+ eq(labels, ['head_sentinel',
+ 'registering with provider',
+ 'end_sentinel'])
+ progress = [y for (x, y), z in checks]
+ eq(progress, [0, 40, 100])
+
+ # normal run, ie, no exceptions
+
+ checkfuns = [z for (x, y), z in checks]
+ passcheck, register = checkfuns[:-1]
+
+ self.assertTrue(passcheck())
+ #self.mocknetchecker.check_name_resolution.assert_called_with(
+ #'test_provider1')
+
+ self.assertTrue(register())
+ #self.mockpcertchecker.is_https_working.assert_called_with(
+ #"https://test_provider1", verify=True)
+
+ # XXX missing: inject failing exceptions
+ # XXX TODO make it break
+
+
+class RegisterUserPageUITestCase(qunittest.TestCase):
+
+ # XXX can spy on signal connections
+ __name__ = "Register User Page UI tests"
+
+ def setUp(self):
+ self.app = QtGui.QApplication(sys.argv)
+ QtGui.qApp = self.app
+
+ self.pagename = "signup"
+ pages = OrderedDict((
+ (self.pagename, TestPage),
+ ('signupvalidation',
+ firstrun.regvalidation.RegisterUserValidationPage)))
+ self.wizard = firstrun.wizard.FirstRunWizard(None, pages_dict=pages)
+ self.page = self.wizard.page(self.wizard.get_page_index(self.pagename))
+
+ self.page.do_checks = mock.Mock()
+
+ # wizard would do this for us
+ self.page.initializePage()
+
+ def tearDown(self):
+ QtGui.qApp = None
+ self.app = None
+ self.wizard = None
+
+ def fill_field(self, field, text):
+ """
+ fills a field (line edit) that is passed along
+ :param field: the qLineEdit
+ :param text: the text to be filled
+ :type field: QLineEdit widget
+ :type text: str
+ """
+ keyp = QTest.keyPress
+ field.setFocus(True)
+ for c in text:
+ keyp(field, c)
+ self.assertEqual(field.text(), text)
+
+ def del_field(self, field):
+ """
+ deletes entried text in
+ field line edit
+ :param field: the QLineEdit
+ :type field: QLineEdit widget
+ """
+ keyp = QTest.keyPress
+ for c in range(len(field.text())):
+ keyp(field, Qt.Key_Backspace)
+ self.assertEqual(field.text(), "")
+
+ def test_buttons_disabled_until_textentry(self):
+ # it's a commit button this time
+ nextbutton = self.wizard.button(QtGui.QWizard.CommitButton)
+
+ self.assertFalse(nextbutton.isEnabled())
+
+ f_username = self.page.userNameLineEdit
+ f_password = self.page.userPasswordLineEdit
+ f_passwor2 = self.page.userPassword2LineEdit
+
+ self.fill_field(f_username, "testuser")
+ self.fill_field(f_password, "testpassword")
+ self.fill_field(f_passwor2, "testpassword")
+
+ # commit should be enabled
+ # XXX Need a workaround here
+ # because the isComplete is not being evaluated...
+ # (no event loop running??)
+ #import ipdb;ipdb.set_trace()
+ #self.assertTrue(nextbutton.isEnabled())
+ self.assertTrue(self.page.isComplete())
+
+ self.del_field(f_username)
+ self.del_field(f_password)
+ self.del_field(f_passwor2)
+
+ # after rm fields commit button
+ # should be disabled again
+ #self.assertFalse(nextbutton.isEnabled())
+ self.assertFalse(self.page.isComplete())
+
+ @unittest.skip
+ def test_check_button_triggers_tests(self):
+ checkbutton = self.page.providerCheckButton
+ self.assertFalse(checkbutton.isEnabled())
+ self.assertFalse(self.page.do_checks.called)
+
+ self.fill_provider()
+
+ self.assertTrue(checkbutton.isEnabled())
+ mclick = QTest.mouseClick
+ # click!
+ mclick(checkbutton, Qt.LeftButton)
+ self.waitFor(seconds=0.1)
+ self.assertTrue(self.page.do_checks.called)
+
+ # XXX
+ # can play with different side_effects for do_checks mock...
+ # so we can see what happens with errors and so on
+
+ def test_validate_page(self):
+ self.assertFalse(self.page.validatePage())
+ # XXX TODO MOAR CASES...
+ # add errors, False
+ # change done, False
+ # not done, do_checks called
+ # click confirm, True
+ # done and do_confirm, True
+
+ def test_next_id(self):
+ self.assertEqual(self.page.nextId(), 1)
+
+ def test_paint_event(self):
+ self.page.populateErrors = mock.Mock()
+ self.page.paintEvent(None)
+ self.page.populateErrors.assert_called_with()
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/src/leap/gui/tests/test_firstrun_wizard.py b/src/leap/gui/tests/test_firstrun_wizard.py
index c63781fc..091cd932 100644
--- a/src/leap/gui/tests/test_firstrun_wizard.py
+++ b/src/leap/gui/tests/test_firstrun_wizard.py
@@ -31,7 +31,6 @@ PAGES_DICT = dict((
('signup', firstrun.register.RegisterUserPage),
('signupvalidation',
firstrun.regvalidation.RegisterUserValidationPage),
- ('connecting', firstrun.connect.ConnectingPage),
('lastpage', firstrun.last.LastPage)
))
@@ -115,7 +114,7 @@ class FirstRunWizardTestCase(qunittest.TestCase):
pagenames = ('intro', 'providerselection', 'login', 'providerinfo',
'providersetupvalidation', 'signup', 'signupvalidation',
- 'connecting', 'lastpage')
+ 'lastpage')
eq = self.assertEqual
w = self.wizard
for index, name in enumerate(pagenames):