/* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #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(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); init_platforms(); QTest::qWait(1000); } QList genericDialogTest::scanDialog(QWidget *dialog) { QList result; foreach(QLineEdit *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QCheckBox *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QComboBox *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QRadioButton *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QTextEdit *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(TextEditWidget *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QSpinBox *item, dialog->findChildren()) result.append(dynamic_cast(item)); return result; } // Activates tab which contains widget void genericDialogTest::activateTab(QWidget *widget) { QWidget *current = widget; while (current->parent() != NULL) { if (dynamic_cast(current->parent()) != NULL) { QTabWidget *tabs = dynamic_cast(current->parent()); for (int i=0; icount(); i++) { if (tabs->widget(i)->findChildren(widget->objectName()).contains(widget)) { tabs->setCurrentIndex(i); break; } } } current = dynamic_cast(current->parent()); } } bool genericDialogTest::testControl(QWidget *control) { if (dynamic_cast(control) != NULL) { QSpinBox *box = dynamic_cast(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(control) != NULL) { QLineEdit *line = dynamic_cast(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(control) != NULL) { QCheckBox *box = dynamic_cast(control); QTest::mouseClick(box, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); } else if (dynamic_cast(control) != NULL) { QRadioButton *box = dynamic_cast(control); // if it is not checked, jut clicking it if (!box->isChecked()) QTest::mouseClick(box, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); else { QList buttons; if (box->group() == NULL) { foreach(QRadioButton *button, box->parent()->findChildren()) { 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(control) != NULL) { QComboBox *box = dynamic_cast(control); if (box->count() < 2) { for (int i=0; icount(); 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(control) != NULL) { QTextEdit *edit = dynamic_cast(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 widgets = scanDialog(dialog); qDebug() << "it contains" << widgets.size() << "controls"; QList tabs = dialog->findChildren(); FWObject *old = mw->db()->create(object->getTypeName()); for (int i=0; iduplicate(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(dialog) != NULL) dynamic_cast(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(dialog) != NULL) dynamic_cast(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(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(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 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(DialogFactory::createDialog(mw->activeProject(), Rule::TYPENAME)); dynamic_cast(dialog)->attachToProjectWindow(mw->activeProject()); dialog->setVisible(true); dynamic_cast(dialog)->loadFWObject(rule); testDialog(dynamic_cast(dialog), FWObject::cast(rule)); } } void genericDialogTest::testRoutingRuleOptionsDialog() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); /* QMap 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(DialogFactory::createDialog(mw->activeProject(), RoutingRule::TYPENAME)); dynamic_cast(dialog)->attachToProjectWindow(mw->activeProject()); dialog->setVisible(true); dynamic_cast(dialog)->loadFWObject(rule); testDialog(dynamic_cast(dialog), FWObject::cast(rule)); } void genericDialogTest::testNATRuleOptionsDialog() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); QMap 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(DialogFactory::createDialog(mw->activeProject(), NATRule::TYPENAME)); dynamic_cast(dialog)->attachToProjectWindow(mw->activeProject()); dialog->setVisible(true); dynamic_cast(dialog)->loadFWObject(rule); testDialog(dynamic_cast(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; }