# -*- coding: utf-8 -*-
#
# Copyright 2011-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.
"""Test the Reset Password Page."""

# pylint: disable=F0401,E0611,E1101

from PyQt4 import QtGui, QtCore

from ubuntu_kylin_sso.utils import compat
from ubuntu_kylin_sso.utils.ui import (
    PASSWORD1_ENTRY,
    PASSWORD2_ENTRY,
    RESET_CODE_ENTRY,
)
from ubuntu_kylin_sso.qt import common
from ubuntu_kylin_sso.qt.reset_password_page import (
    ResetPasswordPage,
    RESET_SUBTITLE,
    RESET_TITLE,
)
from ubuntu_kylin_sso.qt.tests import PageBaseTestCase


# We need this Fake until a future refactor.
class FakeForgottenPage(object):

    """Fake Forgotten Page."""

    def __init__(self):
        self.ui = self
        self.email_line_edit = self
        self.line_text = ''

    # pylint: disable=C0103
    def setText(self, text):
        """Fake setText for Line edit."""
        self.line_text = text
    # pylint: enable=C0103

    def text(self):
        """Fake text for line edit."""
        return self.line_text


class ResetPasswordTestCase(PageBaseTestCase):
    """Test the ResetPasswordPage code."""

    ui_class = ResetPasswordPage
    ui_signals = ('passwordChanged',)
    ui_backend_siganls = ('PasswordChanged', 'PasswordChangeError')

    def test_password_line(self):
        """Check the initial state of ResetPassword."""
        self.assertEqual(self.ui.ui.password_line_edit.receivers(
            QtCore.SIGNAL('textEdited(QString)')), 1)
        self.assertEqual(self.ui.ui.confirm_password_line_edit.receivers(
            QtCore.SIGNAL('textEdited(QString)')), 1)

    def test_initialize(self):
        """Check the Title and Subtitle."""
        self.ui.initializePage()
        self.assert_title_correct(RESET_TITLE)
        self.assert_subtitle_correct(RESET_SUBTITLE)
        self.assertEqual(compat.text_type(self.ui.ui.password_label.text()),
            PASSWORD1_ENTRY)
        self.assertEqual(
                compat.text_type(self.ui.ui.confirm_password_label.text()),
                PASSWORD2_ENTRY)
        self.assertEqual(compat.text_type(self.ui.ui.reset_code.text()),
            RESET_CODE_ENTRY)

    def test_focus_changed_password_visibility(self):
        """Check visibility changes when focus_changed() is executed."""
        self.ui.focus_changed(None, self.ui.ui.password_line_edit)
        self.assertTrue(self.ui.ui.password_assistance.isVisible())

    def test_show_hide_event(self):
        """Check connections to focusChanged on show and hide event."""
        self.assertEqual(QtGui.QApplication.instance().receivers(
            QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)")), 1)
        self.ui.hide()
        self.assertEqual(QtGui.QApplication.instance().receivers(
            QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)")), 0)

    # pylint: disable=W0212

    def test_focus_changed_1(self):
        """Check functions execution when focus_changed() is executed."""
        self.patch(common, 'password_default_assistance', self._set_called)
        self.assertFalse(self._called)

        self.ui.focus_changed(None, self.ui.ui.password_line_edit)

        self.assertTrue(self.ui.ui.password_assistance.isVisible())
        self.assertTrue(self._called)

    def test_focus_changed_2(self):
        """Check functions execution when focus_changed() is executed."""
        self.patch(common, 'password_check_match', self._set_called)
        self.assertFalse(self._called)

        self.ui.focus_changed(None, self.ui.ui.confirm_password_line_edit)

        self.assertTrue(self.ui.ui.password_assistance.isVisible())
        self.assertTrue(self._called)

    # pylint: enable=W0212

    def test_set_new_password(self):
        """Test set_new_password method."""
        self.patch(self.ui, "hide_error", self._set_called)
        email = 'email@example.com'
        code = 'code'
        password = 'password'
        forgotten = FakeForgottenPage()
        forgotten.setText(email)
        self.patch(self.wizard, "forgotten", forgotten)
        self.ui.ui.reset_code_line_edit.setText(code)
        self.ui.ui.password_line_edit.setText(password)

        self.ui.set_new_password()

        self.assert_backend_called('set_new_password',
            self.app_name, email, code, password)
        expected = ((), {})
        self.assertEqual(expected, self._called)
