1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-23 19:57:21 +01:00
fwbuilder/src/unit_tests/genericDialogTest/genericDialogTest.cpp
Vadim Kurland 3a2041d16d per Mikes request, the GUI now opens rule set object of the firewall
when user opens the firewall or any of its children objects in the
editor. This includes any rule set, interface or any other child
object.

Also moved function Interface::getParentHost() from class Interface to
class Host as static FWObject* Host::getParentHost(FWObject *o). Its
behavior is now more logical, it returns non-NULL pointer only if an
object actually has a parent that is host, firewall or cluster. Old
function Interface::getParentHost() returned non-NULL pointer even
when object was not in the proper position in the tree.

Now this function can be used to get parent host/firewall/cluster for
any child object rather than only interface.

I had to fix bunch of problems in unit tests that got uncovered because
new function behaves in a more strict way (returns NULL when there is
no parent of correct type).
2011-06-05 21:38:46 -07:00

370 lines
14 KiB
C++

/*
Firewall Builder
Copyright (C) 2010 NetCitadel, LLC
Author: Roman Bovsunivskiy a2k0001@gmail.com
$Id: genericDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $
This program is free software which we release under the GNU General Public
License. You may redistribute and/or modify this program under the terms
of that license as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program 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 General Public License for more details.
To get a copy of the GNU General Public License, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "genericDialogTest.h"
#include "../../../../config.h"
//#include "../../global.h"
#include <qapplication.h>
#include <qfile.h>
#include <qtextstream.h>
#include <QTest>
#include <iostream>
#include <QProcess>
#include <QRegExp>
#include <QDebug>
#include <QToolButton>
#include <QRadioButton>
#include <QMessageBox>
#include <QWidget>
#include <QLineEdit>
#include <QUndoStack>
#include "FWWindow.h"
#include "ProjectPanel.h"
#include "ObjectTreeView.h"
#include "ObjectTreeViewItem.h"
#include "ObjectEditor.h"
#include "FWObjectClipboard.h"
#include "TextEditWidget.h"
#include "fwbuilder/Address.h"
#include "fwbuilder/IPv4.h"
#include "fwbuilder/IPv6.h"
#include "FWBTree.h"
#include "fwbuilder/Library.h"
#include "fwbuilder/FWObjectDatabase.h"
#include "FirewallDialog.h"
#include "StartTipDialog.h"
#include "fwbuilder/FWObjectDatabase.h"
#include "fwbuilder/Interface.h"
#include "genericDialogTest.h"
#include "fwbuilder/IPService.h"
#include "DialogFactory.h"
#include "FWCmdChange.h"
#include "RuleOptionsDialog.h"
#include "fwbuilder/Rule.h"
#include "fwbuilder/Policy.h"
#include "fwbuilder/Routing.h"
#include "fwbuilder/NAT.h"
#include "RoutingRuleOptionsDialog.h"
#include "platforms.h"
#include "NATRuleOptionsDialog.h"
#include "UserWorkflow.h"
using namespace std;
using namespace libfwbuilder;
void genericDialogTest::initTestCase()
{
new FWObjectClipboard();
mw = new FWWindow();
wfl = new UserWorkflow();
mw->show();
mw->startupLoad();
mw->resize(1200, 600);
StartTipDialog *d = mw->findChild<StartTipDialog*>();
if (d!=NULL) d->close();
om = dynamic_cast<ObjectManipulator*>(mw->getCurrentObjectTree()->parent()->parent());
init_platforms();
QTest::qWait(1000);
}
QList<QWidget*> genericDialogTest::scanDialog(QWidget *dialog)
{
QList<QWidget*> result;
foreach(QLineEdit *item, dialog->findChildren<QLineEdit*>())
result.append(dynamic_cast<QWidget*>(item));
foreach(QCheckBox *item, dialog->findChildren<QCheckBox*>())
result.append(dynamic_cast<QWidget*>(item));
foreach(QComboBox *item, dialog->findChildren<QComboBox*>())
result.append(dynamic_cast<QWidget*>(item));
foreach(QRadioButton *item, dialog->findChildren<QRadioButton*>())
result.append(dynamic_cast<QWidget*>(item));
foreach(QTextEdit *item, dialog->findChildren<QTextEdit*>())
result.append(dynamic_cast<QWidget*>(item));
foreach(TextEditWidget *item, dialog->findChildren<TextEditWidget*>())
result.append(dynamic_cast<QWidget*>(item));
foreach(QSpinBox *item, dialog->findChildren<QSpinBox*>())
result.append(dynamic_cast<QWidget*>(item));
return result;
}
// Activates tab which contains widget
void genericDialogTest::activateTab(QWidget *widget)
{
QWidget *current = widget;
while (current->parent() != NULL)
{
if (dynamic_cast<QTabWidget*>(current->parent()) != NULL)
{
QTabWidget *tabs = dynamic_cast<QTabWidget*>(current->parent());
for (int i=0; i<tabs->count(); i++)
{
if (tabs->widget(i)->findChildren<QWidget*>(widget->objectName()).contains(widget))
{
tabs->setCurrentIndex(i);
break;
}
}
}
current = dynamic_cast<QWidget*>(current->parent());
}
}
bool genericDialogTest::testControl(QWidget *control)
{
if (dynamic_cast<QSpinBox*>(control) != NULL)
{
QSpinBox *box = dynamic_cast<QSpinBox*>(control);
QTest::keyClick(box, Qt::Key_Up);
QTest::keyClick(box, Qt::Key_Up);
QTest::keyClick(box, Qt::Key_Enter);
QTest::keyClick(box, Qt::Key_Tab);
}
else if (dynamic_cast<QLineEdit*>(control) != NULL)
{
QLineEdit *line = dynamic_cast<QLineEdit*>(control);
line->clear();
QTest::keyClicks(line, QString("Some text for %1").arg(line->objectName()));
//line->setText(QString("Some text for %1").arg(control->objectName()));
QTest::keyClick(line, Qt::Key_Enter);
}
else if (dynamic_cast<QCheckBox*>(control) != NULL)
{
QCheckBox *box = dynamic_cast<QCheckBox*>(control);
QTest::mouseClick(box, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
}
else if (dynamic_cast<QRadioButton*>(control) != NULL)
{
QRadioButton *box = dynamic_cast<QRadioButton*>(control);
// if it is not checked, jut clicking it
if (!box->isChecked())
QTest::mouseClick(box, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
else
{
QList<QAbstractButton*> buttons;
if (box->group() == NULL)
{
foreach(QRadioButton *button, box->parent()->findChildren<QRadioButton*>())
{
if (button->group() == NULL)
buttons.append(button);
}
if (buttons.isEmpty())
{
qDebug() << "Can not test QRadioButton" << box << "that is not in group and has no buttons nearby.";
return false;
}
}
else
{
buttons = box->group()->buttons();
}
if (buttons.count() < 2)
{
qDebug() << "Can not test QRadioButton" << box << " that is only one button in group.";
return false;
}
// looking for first radio button in same group that is not checked and clicking it
foreach(QAbstractButton *button, buttons)
{
if (button->isChecked() == false && button != box)
{
QTest::mouseClick(button, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
return true;
}
}
}
}
else if (dynamic_cast<QComboBox*>(control) != NULL)
{
QComboBox *box = dynamic_cast<QComboBox*>(control);
if (box->count() < 2)
{
for (int i=0; i<box->count(); i++)
qDebug() << box->itemText(i);
qDebug() << "Can not change value of QComboBox" << box << "which has less than two items.";
return false;
}
box->setCurrentIndex((box->currentIndex() + 1) % box->count());
}
else if (dynamic_cast<QTextEdit*>(control) != NULL)
{
QTextEdit *edit = dynamic_cast<QTextEdit*>(control);
QTest::mouseClick(edit, Qt::LeftButton, Qt::NoModifier);
QTest::keyClicks(edit, "Some test input for " + edit->objectName());
QTest::mouseClick(edit, Qt::LeftButton, Qt::NoModifier);
QTest::keyClick(edit, Qt::Key_Tab);
}
else return false;
return true;
}
void genericDialogTest::testDialog(QWidget *dialog, FWObject *object)
{
qDebug() << "testing dialog" << dialog;
QList<QWidget*> widgets = scanDialog(dialog);
qDebug() << "it contains" << widgets.size() << "controls";
QList<QTabWidget*> tabs = dialog->findChildren<QTabWidget*>();
FWObject *old = mw->db()->create(object->getTypeName());
for (int i=0; i<widgets.size(); i++)
{
//qDebug() << "testing control" << widgets.at(i);
old->duplicate(object);
QWidget *widget = widgets.at(i);
// Skipping QSpinBox (which inherits QLineEdit) with QLineEdit type
// there should be another one with right type in list
if (widget->objectName() == "qt_spinbox_lineedit") continue;
if (dynamic_cast<QDialog*>(dialog) != NULL)
dynamic_cast<QDialog*>(dialog)->open();
activateTab(widget);
if (!widget->isVisible() || !widget->isEnabled()) continue;
if (!testControl(widget))
{
QWARN(QString("Dont know how to test widget %1. It might be unknown class, empty QComboBox or QRadioButton with not other QRadio button in group.")
.arg(widgets.at(i)->objectName()).toAscii().data());
continue;
}
if (dynamic_cast<QDialog*>(dialog) != NULL)
dynamic_cast<QDialog*>(dialog)->accept();
else
{
QMetaObject::invokeMethod(dialog, "changed");
QMetaObject::invokeMethod(dialog, "applyChanges");
}
QVERIFY2(!old->cmp(object, true),
QString("Widget %1 does not affect object").arg(widget->objectName()).toAscii().data());
}
}
void genericDialogTest::testFirewallSettingsDialog_iptables()
{
Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall"));
firewall->setStr("platform", "iptables");
firewall->setStr("host_OS", "linux24");
QDialog *dialog = dynamic_cast<QDialog*>(DialogFactory::createFWDialog(mw, firewall));
testDialog(dialog, firewall);
}
void genericDialogTest::testHostOSSettingsDialog_linux24()
{
Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall"));
firewall->setStr("platform", "iptables");
firewall->setStr("host_OS", "linux24");
QDialog *dialog = dynamic_cast<QDialog*>(DialogFactory::createOSDialog(mw, firewall));
testDialog(dialog, firewall);
}
#if 0
// rule options dialog uses stacked widget with only one page visible,
// depending on the firewall platform. Some widgets in invisible pages
// are not even initialized, also depending on the platform. Need to
// devise better test that would take this into account.
void genericDialogTest::testRuleOptionsDialog()
{
Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall"));
QMap<QString, QString> platforms = getAllPlatforms();
platforms.remove("unknown"); // dialog does not set options for it
foreach(QString platform, platforms.keys())
{
qDebug() << "Testing platform:" << platform;
firewall->setStr("platform", platform.toStdString());
PolicyRule *rule = PolicyRule::cast(firewall->getPolicy()->createRule());
firewall->getPolicy()->add(rule);
QWidget *dialog = dynamic_cast<QWidget*>(DialogFactory::createDialog(mw->activeProject(), Rule::TYPENAME));
dynamic_cast<BaseObjectDialog*>(dialog)->attachToProjectWindow(mw->activeProject());
dialog->setVisible(true);
dynamic_cast<RuleOptionsDialog*>(dialog)->loadFWObject(rule);
testDialog(dynamic_cast<QWidget*>(dialog), FWObject::cast(rule));
}
}
void genericDialogTest::testRoutingRuleOptionsDialog()
{
Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall"));
/* QMap<QString, QString> platforms = getAllPlatforms();
platforms.remove("unknown"); // dialog does not set options for it
foreach(QString platform, platforms.keys())
{
firewall->setStr("platform", platform.toStdString());
*/
// it currently works only with iptables
firewall->setStr("platform", "iptables");
RoutingRule *rule = RoutingRule::cast(firewall->getRouting()->createRule());
firewall->getRouting()->add(rule);
QWidget *dialog = dynamic_cast<QWidget*>(DialogFactory::createDialog(mw->activeProject(), RoutingRule::TYPENAME));
dynamic_cast<BaseObjectDialog*>(dialog)->attachToProjectWindow(mw->activeProject());
dialog->setVisible(true);
dynamic_cast<RoutingRuleOptionsDialog*>(dialog)->loadFWObject(rule);
testDialog(dynamic_cast<QWidget*>(dialog), FWObject::cast(rule));
}
void genericDialogTest::testNATRuleOptionsDialog()
{
Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall"));
QMap<QString, QString> platforms = getAllPlatforms();
platforms.remove("unknown"); // dialog does not set options for it
foreach(QString platform, platforms.keys())
{
qDebug() << "Testing platform:" << platform;
firewall->setStr("platform", platform.toStdString());
NATRule *rule = NATRule::cast(firewall->getNAT()->createRule());
firewall->getNAT()->add(rule);
QWidget *dialog = dynamic_cast<QWidget*>(DialogFactory::createDialog(mw->activeProject(), NATRule::TYPENAME));
dynamic_cast<BaseObjectDialog*>(dialog)->attachToProjectWindow(mw->activeProject());
dialog->setVisible(true);
dynamic_cast<NATRuleOptionsDialog*>(dialog)->loadFWObject(rule);
testDialog(dynamic_cast<QWidget*>(dialog), FWObject::cast(rule));
}
}
#endif
Library* genericDialogTest::findUserLibrary()
{
Library *lib = NULL;
foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME))
{
if (obj->getName() == "User")
{
lib = Library::cast(obj);
break;
}
}
return lib;
}