/*
    Copyright 2015 Elvis Angelaccio <elvis.angelaccio@kdemail.net>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "knewpasswordwidgettest.h"

#include <QLineEdit>
#include <QTest>

#include <knewpasswordwidget.h>

QTEST_MAIN(KNewPasswordWidgetTest)

void KNewPasswordWidgetTest::testEmptyPasswordAllowed()
{
    KNewPasswordWidget pwdWidget;

    QVERIFY(pwdWidget.allowEmptyPasswords());
    QCOMPARE(pwdWidget.minimumPasswordLength(), 0);
    QCOMPARE(pwdWidget.passwordStatus(), KNewPasswordWidget::WeakPassword);
}

void KNewPasswordWidgetTest::testEmptyPasswordNotAllowed()
{
    KNewPasswordWidget pwdWidget;

    pwdWidget.setAllowEmptyPasswords(false);

    QVERIFY(!pwdWidget.allowEmptyPasswords());
    QCOMPARE(pwdWidget.minimumPasswordLength(), 1);
    QCOMPARE(pwdWidget.passwordStatus(), KNewPasswordWidget::EmptyPasswordNotAllowed);
}

void KNewPasswordWidgetTest::testPasswordTooShort()
{
    KNewPasswordWidget pwdWidget;

    pwdWidget.setMinimumPasswordLength(5);
    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    const QString password = QStringLiteral("1234");
    linePassword->setText(password);
    lineVerifyPassword->setText(password);

    QCOMPARE(pwdWidget.passwordStatus(), KNewPasswordWidget::PasswordTooShort);
}

void KNewPasswordWidgetTest::testPasswordMatch()
{
    KNewPasswordWidget pwdWidget;

    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    const QString password = QStringLiteral("1234");
    linePassword->setText(password);
    lineVerifyPassword->setText(password);

    QVERIFY(pwdWidget.passwordStatus() != KNewPasswordWidget::PasswordNotVerified);
    QCOMPARE(pwdWidget.password(), password);
}

void KNewPasswordWidgetTest::testPasswordNotVerified()
{
    KNewPasswordWidget pwdWidget;

    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));

    QVERIFY(linePassword);

    const QString password = QStringLiteral("1234");
    linePassword->setText(password);

    QCOMPARE(pwdWidget.passwordStatus(), KNewPasswordWidget::PasswordNotVerified);
}

void KNewPasswordWidgetTest::testWeakPassword()
{
    KNewPasswordWidget pwdWidget;

    pwdWidget.setPasswordStrengthWarningLevel(30 );
    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    const QString password = QStringLiteral("1234");
    linePassword->setText(password);
    lineVerifyPassword->setText(password);

    QCOMPARE(pwdWidget.passwordStatus(), KNewPasswordWidget::WeakPassword);
}

void KNewPasswordWidgetTest::testStrongPassword()
{
    KNewPasswordWidget pwdWidget;

    pwdWidget.setPasswordStrengthWarningLevel(99);
    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    const auto password = QStringLiteral("DHlKOJ1GotXWVE_fnqm1");    // generated by KeePass
    linePassword->setText(password);
    lineVerifyPassword->setText(password);

    QCOMPARE(pwdWidget.passwordStatus(), KNewPasswordWidget::StrongPassword);
}

void KNewPasswordWidgetTest::testReasonablePasswordLength()
{
    KNewPasswordWidget pwdWidget;

    pwdWidget.setReasonablePasswordLength(10);
    QCOMPARE(pwdWidget.reasonablePasswordLength(), 10);

    pwdWidget.setReasonablePasswordLength(0);
    QCOMPARE(pwdWidget.reasonablePasswordLength(), 1);

    pwdWidget.setReasonablePasswordLength(pwdWidget.maximumPasswordLength() + 1);
    QCOMPARE(pwdWidget.reasonablePasswordLength(), pwdWidget.maximumPasswordLength());
}

void KNewPasswordWidgetTest::testPasswordStrengthWarningLevel()
{
    KNewPasswordWidget pwdWidget;

    pwdWidget.setPasswordStrengthWarningLevel(40);
    QCOMPARE(pwdWidget.passwordStrengthWarningLevel(), 40);

    pwdWidget.setPasswordStrengthWarningLevel(-1);
    QCOMPARE(pwdWidget.passwordStrengthWarningLevel(), 0);

    pwdWidget.setPasswordStrengthWarningLevel(100);
    QCOMPARE(pwdWidget.passwordStrengthWarningLevel(), 99);
}

void KNewPasswordWidgetTest::testNoWarningColorBeforeMismatch()
{
    KNewPasswordWidget pwdWidget;
    QColor defaultColor = pwdWidget.palette().color(QPalette::Base);
    QColor warningColor(Qt::red);

    pwdWidget.setBackgroundWarningColor(warningColor);

    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    linePassword->setText(QStringLiteral("1234"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), defaultColor);

    lineVerifyPassword->setText(QStringLiteral("12"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), defaultColor);
}

void KNewPasswordWidgetTest::testWarningColorIfMismatch()
{
    KNewPasswordWidget pwdWidget;
    QColor defaultColor = pwdWidget.palette().color(QPalette::Base);
    QColor warningColor(Qt::red);

    pwdWidget.setBackgroundWarningColor(warningColor);

    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    linePassword->setText(QStringLiteral("1234"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), defaultColor);

    lineVerifyPassword->setText(QStringLiteral("122"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), warningColor);

    lineVerifyPassword->setText(QStringLiteral("1224"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), warningColor);
}

void KNewPasswordWidgetTest::testWarningColorPostMatch()
{
    KNewPasswordWidget pwdWidget;
    QColor defaultColor = pwdWidget.palette().color(QPalette::Base);
    QColor warningColor(Qt::red);

    pwdWidget.setBackgroundWarningColor(warningColor);

    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword);
    QVERIFY(lineVerifyPassword);

    linePassword->setText(QStringLiteral("1234"));
    lineVerifyPassword->setText(QStringLiteral("1234"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), defaultColor);

    lineVerifyPassword->setText(QStringLiteral("12345"));
    QCOMPARE(lineVerifyPassword->palette().color(QPalette::Base), warningColor);
}

void KNewPasswordWidgetTest::disablingWidgetShouldUseDisabledPalette()
{
    KNewPasswordWidget pwdWidget;

    auto linePassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget.findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword && linePassword->isEnabled());
    QVERIFY(lineVerifyPassword && lineVerifyPassword->isEnabled());

    pwdWidget.setEnabled(false);

    QVERIFY(!linePassword->isEnabled());
    QVERIFY(!lineVerifyPassword->isEnabled());

    QCOMPARE(linePassword->palette(), pwdWidget.palette());
    QCOMPARE(lineVerifyPassword->palette(), pwdWidget.palette());
}

void KNewPasswordWidgetTest::disablingParentShouldUseDisabledPalette()
{
    auto widget = new QWidget();
    widget->setEnabled(false);

    auto pwdWidget = new KNewPasswordWidget(widget);
    QVERIFY(!pwdWidget->isEnabled());

    auto linePassword = pwdWidget->findChild<QLineEdit*>(QStringLiteral("linePassword"));
    auto lineVerifyPassword = pwdWidget->findChild<QLineEdit*>(QStringLiteral("lineVerifyPassword"));

    QVERIFY(linePassword && !linePassword->isEnabled());
    QVERIFY(lineVerifyPassword && !lineVerifyPassword->isEnabled());

    QCOMPARE(linePassword->palette(), widget->palette());
    QCOMPARE(lineVerifyPassword->palette(), widget->palette());

    delete widget;
}
