# -*- coding: utf-8 -*-
#
# Copyright 2012 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the
# OpenSSL library under certain conditions as described in each
# individual source file, and distribute linked combinations
# including the two.
# You must obey the GNU General Public License in all respects
# for all of the code used other than OpenSSL.  If you modify
# file(s) with this exception, you may extend this exception to your
# version of the file(s), but you are not obligated to do so.  If you
# do not wish to do so, delete this exception statement from your
# version.  If you delete this exception statement from all source
# files in the program, then also delete it here.
"""Tests for the Setup Account page Qt UI."""

from __future__ import unicode_literals

from PyQt4 import QtGui, QtCore

from ubuntu_kylin_sso.utils import compat
from ubuntu_kylin_sso.qt import current_user_sign_in_page as gui
from ubuntu_kylin_sso.qt.tests import (
    PageBaseTestCase,
    FakePageUiStyle,
    FakeWizardButtonStyle,
)
from ubuntu_kylin_sso.tests import EMAIL


# pylint: disable=W0212

class CurrentUserSignInTestCase(PageBaseTestCase):
    """Test the SetupAccountPage code."""

    ui_class = gui.CurrentUserSignInPage
    ui_signals = ('userLoggedIn', 'passwordForgotten', 'userNotValidated',
        'createAccount')
    ui_backend_signals = ('LoggedIn', 'LoginError', 'UserNotValidated')

    def test_initialize_page(self):
        """Test the initialization method."""
        wizard = FakeWizardButtonStyle()
        button = FakePageUiStyle()
        self.patch(self.ui, "wizard", lambda: wizard)
        self.patch(self.ui.ui, "sign_in_button", button)
        self.patch(self.ui, "setButtonText", wizard.setButtonText)
        self.ui.initializePage()
        self.assertEqual(wizard.buttons_text[QtGui.QWizard.CancelButton],
            "Cancel")
        self.assertIn(('setButtonLayout',
            (([],), {})),
            wizard.called)
        self.assertTrue(button.properties['default'])
        self.assertFalse(button.isEnabled())

    def test_unicode_in_forgotten_password_link(self):
        """Ensure that this label supports unicode."""
        forgot_fr = "J'ai oublié mon mot de passe"
        self.patch(gui, "FORGOTTEN_PASSWORD_BUTTON", forgot_fr)
        forgotten_text = gui.LINK_STYLE.format(link_url='#',
                            link_text=forgot_fr)
        self.ui._set_translated_strings()
        self.assertEqual(
                compat.text_type(self.ui.ui.forgot_password_label.text()),
                forgotten_text)

    def test_set_translated_strings(self):
        """Test the translated string method."""
        expected = gui.LOGIN_TITLE.format(app_name=self.app_name)
        self.assertTrue(self.app_name in expected)
        self.assert_title_correct(expected)
        expected = gui.LOGIN_SUBTITLE % dict(app_name=self.app_name)
        self.assertTrue(self.app_name in expected)
        self.assert_subtitle_correct(expected)
        self.assertEqual(compat.text_type(self.ui.ui.email_label.text()),
            gui.EMAIL_LABEL)
        link_text = gui.CREATE_ACCOUNT_LABEL.format(app_name=self.app_name)
        expected = gui.LINK_STYLE.format(link_url='#', link_text=link_text)
        self.assertTrue(self.app_name in expected)
        self.assertEqual(compat.text_type(
            self.ui.ui.create_account_label.text()), expected)
        self.assertEqual(compat.text_type(self.ui.ui.password_label.text()),
            gui.LOGIN_PASSWORD_LABEL)
        text = gui.LINK_STYLE.format(link_url='#',
                                     link_text=gui.FORGOTTEN_PASSWORD_BUTTON)
        self.assertEqual(
                compat.text_type(self.ui.ui.forgot_password_label.text()),
                text)
        self.assertEqual(
                compat.text_type(self.ui.ui.sign_in_button.text()),
                gui.SIGN_IN_BUTTON)

    def test_connect_ui(self):
        """Test the connect ui method."""
        self.assertEqual(self.ui.ui.forgot_password_label.receivers(
            QtCore.SIGNAL("linkActivated(const QString&)")), 1)
        self.assertEqual(self.ui.ui.email_edit.receivers(
            QtCore.SIGNAL("textChanged(const QString&)")), 1)
        self.assertEqual(self.ui.ui.password_edit.receivers(
            QtCore.SIGNAL("textChanged(const QString&)")), 1)
        self.assertEqual(self.ui.ui.sign_in_button.receivers(
            QtCore.SIGNAL("clicked()")), 1)
        self.assertEqual(self.ui.ui.create_account_label.receivers(
            QtCore.SIGNAL("linkActivated(const QString&)")), 1)

    def test_validate_not_valid(self):
        """Test validate method."""
        button = FakePageUiStyle()
        self.patch(self.ui.ui, "sign_in_button", button)
        self.ui.ui.email_edit.setText('not-valid-email')
        self.ui.ui.password_edit.setText('123456')
        self.ui._validate()
        self.assertFalse(button.isEnabled())

    def test_validate_valid(self):
        """Test validate method."""
        button = FakePageUiStyle()
        self.patch(self.ui.ui, "sign_in_button", button)
        self.ui.ui.email_edit.setText('valid@email')
        self.ui.ui.password_edit.setText('123456')
        self.ui._validate()
        self.assertTrue(button.isEnabled())

    def test_login(self):
        """Test the login method."""
        self.patch(self.ui, "hide_error", self._set_called)
        email = 'valid@email'
        password = '123456'
        self.ui.ui.email_edit.setText(email)
        self.ui.ui.password_edit.setText(password)
        self.ui.login()
        self.assertEqual(self._overlay_show_counter, 1)
        self.assertFalse(self.ui.isEnabled())
        self.assert_backend_called('login',
            self.app_name, email, password)
        expected = ((), {})
        self.assertEqual(expected, self._called)

    def test_on_login_error(self):
        """Test the on_login_error method."""
        self.patch(self.ui, "show_error", self._set_called)
        error = {'errtype': 'UserNotValidated'}

        self.ui.on_login_error(self.app_name, error)

        self.assertEqual(self._overlay_hide_counter, 0)
        self.assertTrue(self.ui.isEnabled())
        expected = ((self.ui, self.app_name, ''), {})
        self.assertTrue(expected, self._called)

    def test_on_logged_in(self):
        """Test the on_login_in method."""
        self.ui.ui.email_edit.setText(EMAIL)
        self.assert_signal_emitted(self.ui.userLoggedIn, (EMAIL,),
            self.ui.on_logged_in, self.app_name, EMAIL)
        self.assertTrue(self.ui.isEnabled())

    def test_on_user_not_validated(self):
        """Test the navigation flow on user not validated."""
        self.ui.ui.email_edit.setText(EMAIL)
        self.assert_signal_emitted(self.ui.userNotValidated, (EMAIL,),
            self.ui.on_user_not_validated, self.app_name, EMAIL)

    def test_on_forgotten_password(self):
        """Test the on_forgotten_password method."""
        self.assert_signal_emitted(self.ui.passwordForgotten, (),
            self.ui.on_forgotten_password)

    def test_on_forgotten_password_link_clicked(self):
        """Forgotten passsword clicked emits passwordForgotten signal."""
        self.assert_signal_emitted(self.ui.passwordForgotten, (),
            self.ui.ui.forgot_password_label.linkActivated.emit, "link")

    def test_on_create_account(self):
        """Test the on_create_account method."""
        self.assert_signal_emitted(self.ui.createAccount, (),
            self.ui.on_create_account)

    def test_on_create_account_link_clicked(self):
        """Create account clicked emits createAccount signal."""
        self.assert_signal_emitted(self.ui.createAccount, (),
            self.ui.ui.create_account_label.linkActivated.emit, "link")
