File indexing completed on 2024-04-28 07:33:11

0001 /*
0002     SPDX-FileCopyrightText: 2017 Csaba Kertesz <csaba.kertesz@gmail.com>
0003     SPDX-FileCopyrightText: 2020 Eric Dejouhanet <eric.dejouhanet@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "config-kstars.h"
0009 
0010 #include <QObject>
0011 #include <QTest>
0012 #include <QDialogButtonBox>
0013 #include <QtConcurrent>
0014 
0015 #include "Options.h"
0016 #include "kstars.h"
0017 #include "kspaths.h"
0018 #include "kswizard.h"
0019 #include <KTipDialog>
0020 
0021 #include "kstars_ui_tests.h"
0022 #include "test_kstars_startup.h"
0023 
0024 
0025 struct TestKStarsStartup::_InitialConditions const TestKStarsStartup::m_InitialConditions;
0026 
0027 TestKStarsStartup::TestKStarsStartup(QObject *parent) : QObject(parent)
0028 {
0029 }
0030 
0031 void TestKStarsStartup::initTestCase()
0032 {
0033     if (KStars::Instance() != nullptr)
0034         KTRY_SHOW_KSTARS();
0035 }
0036 
0037 void TestKStarsStartup::cleanupTestCase()
0038 {
0039     foreach (QDialog * d, KStars::Instance()->findChildren<QDialog*>())
0040         if (d->isVisible())
0041             d->hide();
0042 }
0043 
0044 void TestKStarsStartup::init()
0045 {
0046 }
0047 
0048 void TestKStarsStartup::cleanup()
0049 {
0050 }
0051 
0052 void TestKStarsStartup::createInstanceTest()
0053 {
0054 #if defined(HAVE_INDI)
0055     QWARN("INDI driver registry is unexpectedly required before we start the KStars wizard");
0056 
0057     // Locate INDI drivers like drivermanager.cpp does
0058     Options::setIndiDriversDir(
0059         QStandardPaths::locate(QStandardPaths::GenericDataLocation, "indi", QStandardPaths::LocateDirectory));
0060     QVERIFY(QDir(Options::indiDriversDir()).exists());
0061 
0062     // Look for the second usual place - developer install - OSX should be there too?
0063     if (QFile("/usr/local/bin/indiserver").exists())
0064         Options::setIndiServer("/usr/local/bin/indiserver");
0065     QVERIFY(QFile(Options::indiServer()).exists());
0066 #endif
0067 
0068     // Prepare to close the wizard pages when the KStars instance will start - we could just use the following to bypass
0069     // Options::setRunStartupWizard(false);
0070     // Remaining in the timer signal waiting for the app to load actually prevents the app from
0071     // loading, so retrigger the timer until the app is ready
0072     volatile bool installWizardDone = false;
0073     if (Options::runStartupWizard() == true) {
0074         std::function <void()> closeWizard = [&]
0075         {
0076             QTRY_VERIFY_WITH_TIMEOUT(KStars::Instance() != nullptr, 5000);
0077             KStars * const k = KStars::Instance();
0078             QVERIFY(k != nullptr);
0079 
0080             // Wait for the KStars Wizard to appear, or retrigger the signal
0081             if(k->findChild <KSWizard*>() == nullptr)
0082             {
0083                 QTimer::singleShot(500, KStars::Instance(), closeWizard);
0084                 return;
0085             }
0086 
0087             // Verify it is a KSWizard that appeared
0088             KSWizard * const w = k->findChild <KSWizard*>();
0089             QVERIFY(w != nullptr);
0090             QTRY_VERIFY_WITH_TIMEOUT(w->isVisible(), 1000);
0091 
0092             // Wait for the New Installation Wizard inside that KSWizard
0093             QTRY_VERIFY_WITH_TIMEOUT(w->findChild <QWidget*>("WizWelcome") != nullptr, 1000);
0094             QWidget * ww = KStars::Instance()->findChild <QWidget*>("WizWelcome");
0095             QTRY_VERIFY_WITH_TIMEOUT(ww->isVisible(), 1000);
0096 
0097             // We could shift to all pages one after the other, but the Next button is difficult to locate, so just dismiss the wizard lazily
0098             QDialogButtonBox* buttons = w->findChild<QDialogButtonBox*>();
0099             QVERIFY(nullptr != buttons);
0100 
0101             // search the "Done" button
0102             QAbstractButton *doneButton;
0103             for (QAbstractButton *button: buttons->buttons())
0104             {
0105                 if (button->text().toStdString() == "Done")
0106                     doneButton = button;
0107             }
0108             QVERIFY(nullptr != doneButton);
0109             QTest::mouseClick(doneButton, Qt::LeftButton);
0110 
0111             installWizardDone = true;
0112         };
0113         QTimer::singleShot(500, KStars::Instance(), closeWizard);
0114     }
0115     else {
0116         installWizardDone = true;
0117     }
0118     // Initialize our instance and wait for the test to finish
0119     KTipDialog::setShowOnStart(false);
0120     KStars::createInstance(true, m_InitialConditions.clockRunning, m_InitialConditions.dateTime.toString());
0121     QVERIFY(KStars::Instance() != nullptr);
0122     QTRY_VERIFY_WITH_TIMEOUT(installWizardDone, 10000);
0123 
0124     // With our instance created, initialize our location
0125     // FIXME: do this via UI in the Startup Wizard
0126     KStarsData * const d = KStars::Instance()->data();
0127     QVERIFY(d != nullptr);
0128     GeoLocation * const g = d->locationNamed("Greenwich");
0129     QVERIFY(g != nullptr);
0130     d->setLocation(*g);
0131 
0132     // Verify our location is properly selected
0133     QCOMPARE(d->geo()->lat()->Degrees(), g->lat()->Degrees());
0134     QCOMPARE(d->geo()->lng()->Degrees(), g->lng()->Degrees());
0135 }
0136 
0137 void TestKStarsStartup::testInitialConditions()
0138 {
0139     QVERIFY(KStars::Instance() != nullptr);
0140     QVERIFY(KStars::Instance()->data() != nullptr);
0141     QVERIFY(KStars::Instance()->data()->clock() != nullptr);
0142 
0143     QCOMPARE(KStars::Instance()->data()->clock()->isActive(), m_InitialConditions.clockRunning);
0144 
0145     /*
0146     QEXPECT_FAIL("", "Initial KStars clock is set from system local time, not geolocation, and is untestable for now.",
0147                  Continue);
0148     QCOMPARE(KStars::Instance()->data()->clock()->utc().toString(), m_InitialConditions.dateTime.toString());
0149 
0150     QEXPECT_FAIL("", "Precision of KStars local time conversion to local time does not allow strict millisecond comparison.",
0151                  Continue);
0152     QCOMPARE(KStars::Instance()->data()->clock()->utc().toLocalTime(), m_InitialConditions.dateTime);
0153     */
0154 
0155 #if QT_VERSION >= 0x050800
0156     // However comparison down to nearest second is expected to be OK
0157     QCOMPARE(llround(KStars::Instance()->data()->clock()->utc().toLocalTime().toMSecsSinceEpoch() / 1000.0),
0158              m_InitialConditions.dateTime.toSecsSinceEpoch());
0159 
0160     // Test setting time
0161     KStars::Instance()->data()->clock()->setUTC(KStarsDateTime(m_InitialConditions.dateTime));
0162     QCOMPARE(llround(KStars::Instance()->data()->clock()->utc().toLocalTime().toMSecsSinceEpoch() / 1000.0),
0163              m_InitialConditions.dateTime.toSecsSinceEpoch());
0164 #endif
0165 }