1
0
mirror of https://github.com/altlinux/admc.git synced 2025-01-09 17:18:15 +03:00
admc/tests/admc_test.cpp
Semyon Knyazev 1c1e83b59d Fixed errors after DC selection.
AdInterface object's actual DC and LDAP connection member
values didn't change after PDC Emulator connection move, it's fixed.
Message about failed connection to DC stored in the settings is
also removed (because it spam after kinit in other domain).
2023-09-01 17:24:11 +04:00

305 lines
9.5 KiB
C++

/*
* ADMC - AD Management Center
*
* Copyright (C) 2020-2022 BaseALT Ltd.
* Copyright (C) 2020-2022 Dmitry Degtyarev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "admc_test.h"
#include "adldap.h"
#include "attribute_edits/attribute_edit.h"
#include "console_impls/object_impl.h"
#include "filter_widget/filter_widget.h"
#include "filter_widget/filter_widget_simple_tab.h"
#include "filter_widget/select_base_widget.h"
#include "filter_widget/ui_filter_widget.h"
#include "filter_widget/ui_filter_widget_simple_tab.h"
#include "filter_widget/ui_select_base_widget.h"
#include "find_widget.h"
#include "globals.h"
#include "select_container_dialog.h"
#include "select_object_advanced_dialog.h"
#include "select_object_dialog.h"
#include "ui_find_widget.h"
#include "ui_select_container_dialog.h"
#include "ui_select_object_advanced_dialog.h"
#include "ui_select_object_dialog.h"
#include "utils.h"
#include "fsmo/fsmo_utils.h"
#include <QFormLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <QModelIndex>
#include <QPushButton>
#include <QTest>
#include <QTimer>
#include <QTreeView>
#define PRINT_FOCUS_WIDGET_BEFORE_TAB false
#define PRINT_FOCUS_WIDGET_AFTER_TAB false
void ADMCTest::initTestCase() {
qRegisterMetaType<QHash<QString, AdObject>>("QHash<QString, AdObject>");
QVERIFY2(ad.is_connected(), "Failed to connect to AD server");
g_adconfig->load(ad, QLocale(QLocale::English));
AdInterface::set_config(g_adconfig);
if (!current_dc_is_master_for_role(ad, FSMORole_PDCEmulation)) {
connect_host_with_role(ad, FSMORole_PDCEmulation);
}
// Cleanup before all tests in-case this test suite was
// previously interrupted and a cleanup wasn't performed
cleanup();
}
void ADMCTest::cleanupTestCase() {
}
void ADMCTest::init() {
parent_widget = new QWidget();
layout = new QFormLayout();
parent_widget->setLayout(layout);
edits.clear();
const QString dn = test_arena_dn();
const bool create_success = ad.object_add(dn, CLASS_OU);
QVERIFY2(create_success, "Failed to create test-arena");
// Show parent widget and wait for it to appear
parent_widget->show();
QVERIFY(QTest::qWaitForWindowExposed(parent_widget, 1000));
}
void ADMCTest::cleanup() {
// Print AD error messages
if (ad.any_error_messages()) {
qInfo() << "AD errors:";
for (const auto &message : ad.messages()) {
if (message.type() == AdMessageType_Error) {
qInfo() << message.text();
}
}
}
ad.clear_messages();
if (parent_widget != nullptr) {
delete parent_widget;
parent_widget = nullptr;
}
// Delete test arena, if it exists
const QString dn = test_arena_dn();
const QHash<QString, AdObject> results = ad.search(dn, SearchScope_Object, QString(), QList<QString>());
const bool test_arena_exists = (results.size() == 1);
if (test_arena_exists) {
const bool delete_success = ad.object_delete(dn);
QVERIFY2(delete_success, "Failed to delete test-arena or it's contents");
QVERIFY2(!object_exists(dn), "Deleted test-arena still exists");
}
}
QString ADMCTest::test_arena_dn() {
const QString head_dn = g_adconfig->domain_dn();
const QString dn = QString("OU=test-arena,%1").arg(head_dn);
return dn;
}
QString ADMCTest::test_object_dn(const QString &name, const QString &object_class) {
const QString parent = test_arena_dn();
const QString dn = dn_from_name_and_parent(name, parent, object_class);
return dn;
}
bool ADMCTest::object_exists(const QString &dn) {
const QHash<QString, AdObject> results = ad.search(dn, SearchScope_Object, QString(), QList<QString>());
const bool exists = (results.size() == 1);
return exists;
}
// Go down the list of objects by pressing Down arrow
// until current item's dn equals to target dn
void navigate_until_object(QTreeView *view, const QString &target_dn, const int dn_role) {
QModelIndex prev_index;
QAbstractItemModel *model = view->model();
QList<QModelIndex> search_stack;
// NOTE: start at invalid index to iterate over top items
search_stack.append(QModelIndex());
while (!search_stack.isEmpty()) {
const QModelIndex index = search_stack.takeFirst();
const QString dn = index.data(dn_role).toString();
// NOTE: need to expand items because some models
// used in ADMC load the model dynamically from
// server as items are expanded (for example, the
// model used by move dialog)
const bool is_parent_of_object = (target_dn.contains(dn));
if (is_parent_of_object) {
view->expand(index);
}
const bool found_object = (dn == target_dn);
if (found_object) {
view->setCurrentIndex(index);
return;
}
for (int row = 0; row < model->rowCount(index); row++) {
const QModelIndex child = model->index(row, 0, index);
search_stack.append(child);
}
}
QFAIL(qPrintable(QString("Failed to navigate to object %1").arg(target_dn)));
}
void ADMCTest::wait_for_find_results_to_load(QTreeView *view) {
int timer = 0;
while (view->model()->rowCount() == 0) {
QTest::qWait(1);
timer++;
QVERIFY2((timer < 1000), "Find results failed to load, took too long");
}
}
void ADMCTest::close_message_box() {
auto message_box = parent_widget->findChild<QMessageBox *>();
if (message_box != nullptr) {
QVERIFY(QTest::qWaitForWindowExposed(message_box, 1000));
message_box->accept();
delete message_box;
}
}
bool ADMCTest::message_box_is_open() const {
auto message_box = parent_widget->findChild<QMessageBox *>();
const bool out = (message_box != nullptr);
return out;
}
void ADMCTest::select_in_select_dialog(SelectObjectDialog *select_dialog, const QString &dn) {
QPushButton *add_button = select_dialog->ui->add_button;
add_button->click();
// Find dialog has been opened, so switch to it
auto find_select_dialog = select_dialog->findChild<SelectObjectAdvancedDialog *>();
QVERIFY(find_select_dialog);
QVERIFY(QTest::qWaitForWindowExposed(find_select_dialog, 1000));
FindWidget *find_widget = find_select_dialog->ui->find_widget;
// Enter group name in "Name" edit
const QString name = dn_get_name(dn);
QLineEdit *name_edit = find_widget->ui->filter_widget->ui->simple_tab->ui->name_edit;
name_edit->setText(name);
// Press "Find" button
auto find_button = find_widget->ui->find_button;
find_button->click();
// Switch to find results
auto find_results_view = find_select_dialog->findChild<QTreeView *>();
QVERIFY(find_results_view);
wait_for_find_results_to_load(find_results_view);
// Select group in view
navigate_until_object(find_results_view, dn, ObjectRole_DN);
const QModelIndex selected_index = find_results_view->selectionModel()->currentIndex();
const QString selected_dn = selected_index.data(ObjectRole_DN).toString();
find_select_dialog->accept();
}
void ADMCTest::select_object_dialog_select(const QString &dn) {
auto select_dialog = parent_widget->findChild<SelectObjectDialog *>();
QVERIFY(select_dialog);
SelectBaseWidget *select_base_widget = select_dialog->ui->select_base_widget;
select_base_widget_add(select_base_widget, test_arena_dn());
QLineEdit *edit = select_dialog->ui->name_edit;
edit->setText(dn_get_name(dn));
QPushButton *add_button = select_dialog->ui->add_button;
add_button->click();
select_dialog->accept();
delete select_dialog;
}
void ADMCTest::add_widget(QWidget *widget) {
layout->addWidget(widget);
}
// Edit should do nothing if value wasn't modified
void ADMCTest::test_edit_apply_unmodified(AttributeEdit *edit, const QString &dn) {
const AdObject object_before = ad.search_object(dn);
edit->load(ad, object_before);
const bool apply_success = edit->apply(ad, dn);
QVERIFY(apply_success);
const AdObject object_after = ad.search_object(dn);
QVERIFY(object_before.get_attributes_data() == object_after.get_attributes_data());
}
void ADMCTest::select_base_widget_add(SelectBaseWidget *widget, const QString &dn) {
QPushButton *browse_button = widget->ui->browse_button;
browse_button->click();
auto select_container_dialog = widget->findChild<SelectContainerDialog *>();
QVERIFY(select_container_dialog);
QVERIFY(QTest::qWaitForWindowExposed(select_container_dialog, 1000));
QTreeView *select_container_view = select_container_dialog->ui->view;
navigate_until_object(select_container_view, dn, ContainerRole_DN);
select_container_dialog->accept();
QVERIFY(QTest::qWaitForWindowExposed(widget, 1000));
}
void test_lineedit_autofill(QLineEdit *src_edit, QLineEdit *dest_edit) {
const QString expected_dest_text = "test";
src_edit->setText(expected_dest_text);
const QString actual_dest_text = dest_edit->text();
QCOMPARE(actual_dest_text, expected_dest_text);
}