Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ int main(int argc, char* argv[])
try {
Controller controller(app.parseArgs());

QObject::connect(&controller, &Controller::quit, &app, &QApplication::quit);
QObject::connect(&controller, &Controller::finished, &app, &Application::requestQuit);
// Pass control to Controller::run() when the event loop starts.
QTimer::singleShot(0, &controller, &Controller::run);

Expand Down
5 changes: 5 additions & 0 deletions src/controller/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ Application::Application(int& argc, char** argv, const QString& name) :
#endif
}

void Application::requestQuit() noexcept
{
QMetaObject::invokeMethod(this, [] { QCoreApplication::quit(); }, Qt::QueuedConnection);
}

bool Application::isDarkTheme()
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
Expand Down
2 changes: 2 additions & 0 deletions src/controller/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class Application : public QApplication
public:
Application(int& argc, char** argv, const QString& name);

void requestQuit() noexcept;

static bool isDarkTheme();
void loadTranslations(const QString& lang = {});
static CommandWithArguments parseArgs();
Expand Down
18 changes: 9 additions & 9 deletions src/controller/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ try {
WebEidUI::showAboutPage();
return;
case CommandType::QUIT:
// If quit is requested, respond with empty JSON object and quit immediately.
qInfo() << "Quit requested, exiting";
// If quit is requested, respond with empty JSON object and finish immediately.
qInfo() << "Quit requested, finishing";
writeResponseToStdOut(true, {}, "quit");
emit quit();
finish();
return;
default:
break;
Expand Down Expand Up @@ -218,7 +218,7 @@ try {
_result = res;
writeResponseToStdOut(isInStdinMode, res, commandHandler->commandType());

exit();
finish();
} catch (const std::exception& error) {
onCriticalFailure(error.what());
}
Expand Down Expand Up @@ -263,7 +263,7 @@ try {
qDebug() << "User cancelled";
_result = makeErrorObject(RESP_USER_CANCEL, QStringLiteral("User cancelled"));
writeResponseToStdOut(isInStdinMode, _result, commandType());
exit();
finish();
} catch (const std::exception& e) {
onCriticalFailure(e.what());
}
Expand All @@ -285,17 +285,17 @@ try {
// user.
writeResponseToStdOut(isInStdinMode, _result, commandType());
}
exit();
finish();
} catch (const std::exception& e) {
qCritical() << "Failed to write stdout" << e.what();
exit();
finish();
}

void Controller::exit() noexcept
void Controller::finish() noexcept
{
disposeUI();
waitForChildThreads();
emit quit();
emit finished();
}

void Controller::waitForChildThreads() noexcept
Expand Down
6 changes: 3 additions & 3 deletions src/controller/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Controller : public QObject
const QVariantMap& result() const { return _result; }

signals:
void quit();
void finished();
void retry(const RetriableError error);
void statusUpdate(RetriableError status);
void stopCardEventMonitorThread();
Expand Down Expand Up @@ -65,15 +65,15 @@ class Controller : public QObject
void onDialogOK(const EidCertificateAndPinInfo& certAndPinInfo) noexcept;
void onDialogCancel() noexcept;

// Failure handler, reports the error and quits the application.
// Failure handler, reports the error and finishes the operation.
void onCriticalFailure(const QString& error) noexcept;

private:
void startCommandExecution();
void connectRetry(const ControllerChildThread* childThread) const;
void createWindow();
void disposeUI() noexcept;
void exit() noexcept;
void finish() noexcept;
void waitForChildThreads() noexcept;
CommandType commandType() const noexcept;

Expand Down
6 changes: 3 additions & 3 deletions src/mac/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ - (void)notificationEvent:(NSNotification*)notification
Controller controller({
CommandType(QString::fromNSString(req[@"command"])),
argumentJson.object().toVariantMap()});
controller.run();
QEventLoop e;
QObject::connect(&controller, &Controller::quit, &e, &QEventLoop::quit);
QObject::connect(&controller, &Controller::finished, &e, &QEventLoop::quit);
QTimer::singleShot(0, &controller, &Controller::run);
e.exec();
resp = [NSApplication toNSDictionary:controller.result()];
} catch (const std::exception& error) {
Expand Down Expand Up @@ -198,7 +198,7 @@ int main(int argc, char* argv[])

Controller controller(std::move(args));

QObject::connect(&controller, &Controller::quit, &app, &QApplication::quit);
QObject::connect(&controller, &Controller::finished, &app, &Application::requestQuit);
// Pass control to Controller::run() when the event loop starts.
QTimer::singleShot(0, &controller, &Controller::run);

Expand Down
2 changes: 1 addition & 1 deletion src/ui/webeiddialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ void WebEidDialog::showAboutPage()
d->ui->pageStack->setCurrentIndex(int(Page::ABOUT));
d->resizeHeight();
d->open();
connect(d, &WebEidDialog::finished, qApp, &QApplication::quit);
connect(d, &WebEidDialog::finished, qApp, &Application::requestQuit);
}

void WebEidDialog::showFatalErrorPage()
Expand Down
4 changes: 2 additions & 2 deletions tests/mock-ui/mock-ui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ class MockUI : public WebEidUI
void onSmartCardStatusUpdate(const RetriableError) override
{
emit rejected();
// Schedule invoking Controller::exit().
// Schedule invoking Controller::finish().
emit destroyed();
}

void quit() final
{
// Schedule invoking Controller::exit().
// Schedule invoking Controller::finish().
emit destroyed();
}
};
21 changes: 10 additions & 11 deletions tests/tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ private slots:

void authenticate_validArgumentsResultInValidToken();

void quit_exits();
void quit_finishes();

private:
void runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool waitForQuit = true);
void runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool waitForFinish = true);
void initGetCert();
void initAuthenticate();
void initCard(bool withSigningScript = true);
Expand Down Expand Up @@ -197,34 +197,33 @@ void WebEidTests::authenticate_validArgumentsResultInValidToken()
QStringLiteral("MIIEAzCCA2WgAwIBAgIQOWkBW"));
}

void WebEidTests::quit_exits()
void WebEidTests::quit_finishes()
{
try {
controller = std::make_unique<Controller>(CommandWithArguments {CommandType::QUIT, {}});

QSignalSpy quitSpy(controller.get(), &Controller::quit);
QSignalSpy finishedSpy(controller.get(), &Controller::finished);
QTimer::singleShot(0, controller.get(), &Controller::run);
QVERIFY(quitSpy.wait());
QVERIFY(finishedSpy.wait());

} catch (const std::exception& e) {
QFAIL(QStringLiteral("WebEidTests::quit_exits() failed with exception: %s")
QFAIL(QStringLiteral("WebEidTests::quit_finishes() failed with exception: %s")
.arg(QLatin1String(e.what()))
.toUtf8());
}
}

void WebEidTests::runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool waitForQuit)
void WebEidTests::runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool waitForFinish)
{
// Waits until Controller emits quit.
QSignalSpy quitSpy(controller.get(), &Controller::quit);
QSignalSpy finishedSpy(controller.get(), &Controller::finished);

// Pass control to Controller::run() when the event loop starts.
QTimer::singleShot(0, controller.get(), &Controller::run);

// Run the event loop, verify that signals were emitted.
QVERIFY(actionSpy.wait());
if (waitForQuit && quitSpy.count() < 1) {
QVERIFY(quitSpy.wait());
if (waitForFinish && finishedSpy.count() < 1) {
QVERIFY(finishedSpy.wait());
}
}

Expand Down
Loading