diff --git a/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt b/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt
index af03519a..12df7a85 100644
--- a/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt
+++ b/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt
@@ -160,3 +160,38 @@ target_link_libraries(bridgepp
)
target_precompile_headers(bridgepp PRIVATE Pch.h)
+
+#*****************************************************************************************************************************************************
+# GoogleTest
+#*****************************************************************************************************************************************************
+
+if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
+ cmake_policy(SET CMP0135 NEW) # avoid warning DOWNLOAD_EXTRACT_TIMESTAMP
+endif()
+
+include(FetchContent)
+FetchContent_Declare(
+ googletest
+ URL https://github.com/google/googletest/archive/b796f7d44681514f58a683a3a71ff17c94edb0c1.zip
+)
+
+# For Windows: Prevent overriding the parent project's compiler/linker settings
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
+FetchContent_MakeAvailable(googletest)
+
+enable_testing()
+
+#*****************************************************************************************************************************************************
+# Tests
+#*****************************************************************************************************************************************************
+add_executable(bridgepp-test Test/Exception/TestException.cpp)
+add_dependencies(bridgepp-test bridgepp)
+target_precompile_headers(bridgepp-test PRIVATE Pch.h)
+target_link_libraries(bridgepp-test
+ GTest::gtest_main
+ bridgepp
+ )
+
+include(GoogleTest)
+gtest_discover_tests(bridgepp-test)
diff --git a/internal/frontend/bridge-gui/bridgepp/Test/Exception/TestException.cpp b/internal/frontend/bridge-gui/bridgepp/Test/Exception/TestException.cpp
new file mode 100644
index 00000000..9c006f56
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridgepp/Test/Exception/TestException.cpp
@@ -0,0 +1,95 @@
+// Copyright (c) 2023 Proton AG
+//
+// This file is part of Proton Mail Bridge.
+//
+// Proton Mail Bridge 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.
+//
+// Proton Mail Bridge 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 Proton Mail Bridge. If not, see .
+
+#include
+#include
+
+
+using namespace bridgepp;
+
+
+namespace {
+ QString const testQWhat = "What";
+ QString const testDetails = "Some details";
+ QString const testFunction = "function";
+ QByteArray const testAttachment = QString("Some data").toLocal8Bit();
+ Exception const testException(testQWhat, testDetails, testFunction, testAttachment);
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+TEST(Exceptions, ExceptionConstructor) {
+ // Default exception
+ Exception const emptyException;
+ EXPECT_TRUE(emptyException.qwhat().isEmpty());
+ EXPECT_EQ(strlen(emptyException.what()), 0);
+ EXPECT_EQ(emptyException.attachment().size(), 0);
+ EXPECT_TRUE(emptyException.details().isEmpty());
+ EXPECT_TRUE(emptyException.detailedWhat().isEmpty());
+
+ // Fully detailed exception
+ EXPECT_EQ(testException.qwhat(), testQWhat);
+ EXPECT_EQ(QString::fromLocal8Bit(testException.what()), testQWhat);
+ EXPECT_EQ(testException.details(), testDetails);
+ EXPECT_EQ(testException.attachment(), testAttachment);
+ QString const detailed = testException.detailedWhat();
+ EXPECT_TRUE(detailed.contains(testQWhat));
+ EXPECT_TRUE(detailed.contains(testFunction));
+ EXPECT_TRUE(detailed.contains(testDetails));
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+TEST(Exceptions, ExceptionCopyMoveConstructors) {
+ Exception const e(testQWhat, testDetails, testFunction, testAttachment);
+
+ // Check copy-constructor
+ Exception eCopied(e);
+ EXPECT_EQ(eCopied.qwhat(), testQWhat);
+ EXPECT_EQ(eCopied.details(), testDetails);
+ EXPECT_EQ(eCopied.function(), testFunction);
+ EXPECT_EQ(eCopied.attachment(), testAttachment);
+
+ // Check move-constructor
+ Exception eMoved(std::move(eCopied));
+ EXPECT_EQ(eMoved.qwhat(), testQWhat);
+ EXPECT_EQ(eMoved.details(), testDetails);
+ EXPECT_EQ(eMoved.function(), testFunction);
+ EXPECT_EQ(eMoved.attachment(), testAttachment);
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+TEST(Exceptions, ExceptionThrow) {
+ std::function t = []() { throw testException; };
+ EXPECT_THROW(t(), Exception);
+ EXPECT_THROW(t(), std::exception);
+ bool caught = false;
+ try {
+ t();
+ } catch (Exception const &e) {
+ caught = true;
+ EXPECT_EQ(e.detailedWhat(), testException.detailedWhat());
+ }
+ EXPECT_TRUE(caught);
+}
diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h
index 280a0de9..1ca92901 100644
--- a/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h
+++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h
@@ -20,7 +20,7 @@
#define BRIDGE_PP_TESTER_BRIDGE_UTILS_H
-#include
+#include "User/User.h"
namespace bridgepp {
diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp
index dc614b88..db43cac0 100644
--- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp
+++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp
@@ -87,6 +87,14 @@ QString Exception::details() const noexcept {
}
+//****************************************************************************************************************************************************
+/// \return The function that threw the exception.
+//****************************************************************************************************************************************************
+QString Exception::function() const noexcept {
+ return function_;
+}
+
+
//****************************************************************************************************************************************************
/// \return The attachment for the exception.
//****************************************************************************************************************************************************
@@ -109,4 +117,5 @@ QString Exception::detailedWhat() const {
return result;
}
+
} // namespace bridgepp
diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h
index 21a1689d..3b78821f 100644
--- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h
+++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h
@@ -42,6 +42,7 @@ public: // member functions
QString qwhat() const noexcept; ///< Return the description of the exception as a QString
const char *what() const noexcept override; ///< Return the description of the exception as C style string
QString details() const noexcept; ///< Return the details for the exception
+ QString function() const noexcept; ///< Return the function that threw the exception.
QByteArray attachment() const noexcept; ///< Return the attachment for the exception.
QString detailedWhat() const; ///< Return the detailed description of the message (i.e. including the function name and the details).
diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp
index ee3780b2..eb825792 100644
--- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp
+++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp
@@ -17,8 +17,8 @@
#include "LogUtils.h"
-#include
-#include
+#include "../BridgeUtils.h"
+#include "../Exception/Exception.h"
namespace bridgepp {