mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-17 23:56:56 +00:00
GODT-1553: RPC definition and mocks
WIP: updates WIP: cache on disk and autostart. WIP: mail, keychain and more. WIP: updated grpc version in go mod file. WIP: user list. WIP: RPC service placeholder WIP: test C++ RPC client skeleton. Other: missing license script update. WIP: use Qt test framework. WIP: test for app and login calls. WIP: test for update & cache on disk calls. WIP: tests for mail settings calls. WIP: all client tests. WIP: linter fixes. WIP: fix missing license link. WIP: update dependency_license script for gRPC and protobuf. WIP: removed unused file. WIP: app & login event streaming tests. WIP: update event stream tests. WIP: completed event streaming tests.
This commit is contained in:
25
test/rpc/client/BridgeRpcClientTest.cpp
Normal file
25
test/rpc/client/BridgeRpcClientTest.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "RpcClient.h"
|
||||
#include <QtCore>
|
||||
#include <QtTest>
|
||||
|
||||
|
||||
QTEST_MAIN(RpcClient) // This macro will generate the main() function
|
||||
|
||||
66
test/rpc/client/CMakeLists.txt
Normal file
66
test/rpc/client/CMakeLists.txt
Normal file
@ -0,0 +1,66 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
project(BridgeRpcClientTest VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
if (NOT DEFINED ENV{QTDIR})
|
||||
message(FATAL_ERROR "QTDIR needs to be defined and point to the root of your Qt folder. (e.g. /Users/MyName/Qt/6.3/clang_64).")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOMATIC ON)
|
||||
|
||||
find_package(Protobuf CONFIG REQUIRED)
|
||||
message(STATUS "Using protobuf ${Protobuf_VERSION}")
|
||||
|
||||
find_package(gRPC CONFIG REQUIRED)
|
||||
message(STATUS "Using gRPC ${gRPC_VERSION}")
|
||||
|
||||
find_package(Qt6 COMPONENTS Core Test REQUIRED)
|
||||
|
||||
find_program(PROTOC_EXE protoc)
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
|
||||
set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../internal/rpc")
|
||||
set(PROTO_FILE "${PROTO_DIR}/bridge_rpc.proto")
|
||||
set(GRPC_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/rpc")
|
||||
set(PROTO_CPP_FILE "${GRPC_OUT_DIR}/bridge_rpc.pb.cc")
|
||||
set(PROTO_H_FILE "${GRPC_OUT_DIR}/bridge_rpc.pb.h")
|
||||
set(GRPC_CPP_FILE "${GRPC_OUT_DIR}/bridge_rpc.grpc.pb.cc")
|
||||
set(GRPC_H_FILE "${GRPC_OUT_DIR}/bridge_rpc.grpc.pb.h")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${PROTO_CPP_FILE}
|
||||
${PROTO_H_FILE}
|
||||
${GRPC_CPP_FILE}
|
||||
${GRPC_H_FILE}
|
||||
COMMAND
|
||||
${PROTOC_EXE}
|
||||
ARGS
|
||||
--proto_path=${PROTO_DIR}
|
||||
--plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}"
|
||||
--cpp_out=${GRPC_OUT_DIR}
|
||||
--grpc_out=${GRPC_OUT_DIR}
|
||||
${PROTO_FILE}
|
||||
DEPENDS
|
||||
${PROTO_FILE}
|
||||
COMMENT "Generating gPRC/Protobuf C++ code"
|
||||
)
|
||||
|
||||
add_executable(BridgeRpcClientTest
|
||||
BridgeRpcClientTest.cpp
|
||||
RpcClient.cpp RpcClient.h
|
||||
Exception.cpp Exception.h
|
||||
${PROTO_CPP_FILE}
|
||||
${PROTO_H_FILE}
|
||||
${GRPC_CPP_FILE}
|
||||
${GRPC_H_FILE}
|
||||
)
|
||||
|
||||
target_link_libraries(BridgeRpcClientTest
|
||||
Qt::Core Qt::Test
|
||||
protobuf::libprotobuf
|
||||
gRPC::grpc++ gRPC::grpc++_reflection
|
||||
)
|
||||
|
||||
67
test/rpc/client/Exception.cpp
Normal file
67
test/rpc/client/Exception.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "Exception.h"
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \param[in] what A description of the exception
|
||||
//**********************************************************************************************************************
|
||||
Exception::Exception(QString what) noexcept
|
||||
: std::exception()
|
||||
, what_(std::move(what))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \param[in] ref The Exception to copy from
|
||||
//**********************************************************************************************************************
|
||||
Exception::Exception(Exception const& ref) noexcept
|
||||
: std::exception(ref)
|
||||
, what_(ref.what_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \param[in] ref The Exception to copy from
|
||||
//**********************************************************************************************************************
|
||||
Exception::Exception(Exception&& ref) noexcept
|
||||
: std::exception(ref)
|
||||
, what_(ref.what_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \return a string describing the exception
|
||||
//**********************************************************************************************************************
|
||||
QString const& Exception::qwhat() const noexcept
|
||||
{
|
||||
return what_;
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \return A pointer to the description string of the exception.
|
||||
//**********************************************************************************************************************
|
||||
const char* Exception::what() const noexcept
|
||||
{
|
||||
return what_.toLocal8Bit().constData();
|
||||
}
|
||||
44
test/rpc/client/Exception.h
Normal file
44
test/rpc/client/Exception.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef BRIDGE_RPC_CLIENT_TEST_EXCEPTION_H
|
||||
#define BRIDGE_RPC_CLIENT_TEST_EXCEPTION_H
|
||||
|
||||
|
||||
#include <QtCore>
|
||||
#include <stdexcept>
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \brief Exception class
|
||||
//**********************************************************************************************************************
|
||||
class Exception: public std::exception
|
||||
{
|
||||
public: // member functions
|
||||
explicit Exception(QString what = QString()) noexcept; ///< Constructor
|
||||
Exception(Exception const& ref) noexcept; ///< copy constructor
|
||||
Exception(Exception&& ref) noexcept; ///< copy constructor
|
||||
Exception& operator=(Exception const&) = delete; ///< Disabled assignment operator
|
||||
Exception& operator=(Exception&&) = delete; ///< Disabled assignment operator
|
||||
~Exception() noexcept = default; ///< Destructor
|
||||
QString const& 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
|
||||
|
||||
private: // data members
|
||||
QString const what_; ///< The description of the exception
|
||||
};
|
||||
|
||||
#endif //BRIDGE_RPC_CLIENT_TEST_EXCEPTION_H
|
||||
925
test/rpc/client/RpcClient.cpp
Normal file
925
test/rpc/client/RpcClient.cpp
Normal file
@ -0,0 +1,925 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
|
||||
|
||||
|
||||
#include "RpcClient.h"
|
||||
#include <QtTest>
|
||||
|
||||
|
||||
using namespace google::protobuf;
|
||||
using namespace bridgerpc;
|
||||
using namespace grpc;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
||||
// \todo Decide where to store this certificate.
|
||||
std::string cert = R"(-----BEGIN CERTIFICATE-----
|
||||
MIIC5TCCAc2gAwIBAgIJAJL2PajH8kFjMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
||||
BAMMCWxvY2FsaG9zdDAeFw0yMjA1MTAwNjEzMzdaFw0yMjA2MDkwNjEzMzdaMBQx
|
||||
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBAKyb48XL+08YI8m4X/eeD9TQshV+vybKbU7MOG7BnH3Hv7kUH0aVP7OPnU51
|
||||
eYRgUu+bkJ8qWhxD7wOLVJBcU5T1lgd+k6St83ix25P02nUc3UeU4MCxMwhjMjYu
|
||||
R5F9bfSG0UlCCGAEjjmGh+CfnZkS+rgCwE/xGswFnVrynTMvrLQyN02dz/r4zJPp
|
||||
yyVhTOmjdsUDs0zGDbubLf+ypR8VCXg55qYMw7Abpe+rx3BF+NCEjKlATjMeIZNx
|
||||
iS0dl0OGjJZ+bfHGhnPiQxP8HxyJ0NjFNtWgblQev2sHmIq65Rry3RP1gbDAW3sk
|
||||
MiIfjbnp4gGspYrmHWeWXH8g6WMCAwEAAaM6MDgwFAYDVR0RBA0wC4IJbG9jYWxo
|
||||
b3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEAO2WDYnzy9SkaS9VU2jw3nd9MEaILZsXFcVU2+52TKwRBty7b0A1x
|
||||
zyxT6nT0pN0Im7DcT5/TvwFuVBJUTFs4c2gW09WUvtfuN8HVFOeX/1Pt10lMPJjR
|
||||
I+wTAUQrXJHt57JE9x13gQEOW/mGUDNuoUH2cE9C1f+TrO0LaRj8dubS/gHMuV1i
|
||||
aTyxu7hgbLAYq0NGD86CSOwvUvTvs6o628xvfmqqdzlpWIlQq18t2GZYFVWjrISY
|
||||
LWw3OCormKSASOPrW1FXhrgwoyDXHNmZT1MHL3Rh9U5qyCwV5kDAcY956sc9lD3G
|
||||
XHtSxOHLE1eDKGCUKRcYop/99inTGjJ6Xg==
|
||||
-----END CERTIFICATE-----)";
|
||||
|
||||
Empty empty; // A protobuf empty message reused for the sake of simplicity
|
||||
}
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \brief Help class that manage a client context. Provided context cannot be re-used, the underlying context is freed
|
||||
/// and re-allocated at every call to get() (or at destruction).
|
||||
//**********************************************************************************************************************
|
||||
class Ctx
|
||||
{
|
||||
public: // member functions
|
||||
Ctx()
|
||||
{} ///< Default constructor.
|
||||
Ctx(Ctx const &) = delete; ///< Disabled copy-constructor.
|
||||
Ctx(Ctx &&) = delete; ///< Disabled assignment copy-constructor.
|
||||
~Ctx() = default; ///< Destructor.
|
||||
Ctx &operator=(Ctx const &) = delete; ///< Disabled assignment operator.
|
||||
Ctx &operator=(Ctx &&) = delete; ///< Disabled move assignment operator.
|
||||
ClientContext *get()
|
||||
{
|
||||
ctx_ = std::make_unique<ClientContext>();
|
||||
return ctx_.get();
|
||||
} ///< Release the previous context, if any and allocate a new one
|
||||
private: // data members
|
||||
std::unique_ptr<ClientContext> ctx_{nullptr};
|
||||
};
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
RpcClient::RpcClient()
|
||||
: QObject(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::initTestCase()
|
||||
{
|
||||
SslCredentialsOptions opts;
|
||||
opts.pem_root_certs += cert;
|
||||
|
||||
channel_ = CreateChannel("localhost:9292", grpc::SslCredentials(opts));
|
||||
QVERIFY2(channel_, "Channel creation failed.");
|
||||
|
||||
stub_ = bridgerpc::BridgeRpc::NewStub(channel_);
|
||||
QVERIFY2(stub_, "Stub creation failed.");
|
||||
|
||||
QVERIFY2(channel_->WaitForConnected(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
|
||||
gpr_time_from_seconds(10, GPR_TIMESPAN))), "Connection to the RPC server failed.");
|
||||
|
||||
QVERIFY2(channel_ && stub_ && (channel_->GetState(true) == GRPC_CHANNEL_READY), "connection check failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testGetCursorPos()
|
||||
{
|
||||
Ctx ctx;
|
||||
PointResponse resp;
|
||||
Status s = stub_->GetCursorPos(ctx.get(), empty, &resp);
|
||||
QVERIFY2(s.ok(), "GetCursorPos failed.");
|
||||
QVERIFY2(resp.x() == 100, "Invalid x value");
|
||||
QVERIFY2(resp.y() == 200, "Invalid y value");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testGuiReady()
|
||||
{
|
||||
Ctx ctx;
|
||||
QVERIFY2(stub_->GuiReady(ctx.get(), empty, &empty).ok(), "GuiReady failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testQuit()
|
||||
{
|
||||
Ctx ctx;
|
||||
QVERIFY2(stub_->Quit(ctx.get(), empty, &empty).ok(), "Quit failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testRestart()
|
||||
{
|
||||
Ctx ctx;
|
||||
QVERIFY2(stub_->Restart(ctx.get(), empty, &empty).ok(), "Restart failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testShowOnStartup()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue showOnStartup;
|
||||
QVERIFY2(stub_->ShowOnStartup(ctx.get(), empty, &showOnStartup).ok(), "ShowOnStartup failed.");
|
||||
bool const newValue = !showOnStartup.value();
|
||||
|
||||
showOnStartup.set_value(newValue);
|
||||
QVERIFY2(stub_->SetShowOnStartup(ctx.get(), showOnStartup, &empty).ok(), "SetShowOnStartup failed.");
|
||||
|
||||
QVERIFY2(stub_->ShowOnStartup(ctx.get(), empty, &showOnStartup).ok(), "ShowOnStartup failed.");
|
||||
QVERIFY2(showOnStartup.value() == newValue, "ShowOnStartup failed readback.");
|
||||
}
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testShowSplashScreen()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue showSplashScreen;
|
||||
QVERIFY2(stub_->ShowSplashScreen(ctx.get(), empty, &showSplashScreen).ok(), "ShowSplashScreen failed.");
|
||||
bool const newValue = !showSplashScreen.value();
|
||||
|
||||
showSplashScreen.set_value(newValue);
|
||||
QVERIFY2(stub_->SetShowSplashScreen(ctx.get(), showSplashScreen, &empty).ok(), "SetShowSplashScreen failed.");
|
||||
|
||||
QVERIFY2(stub_->ShowOnStartup(ctx.get(), empty, &showSplashScreen).ok(), "ShowSplashScreen failed.");
|
||||
QVERIFY2(showSplashScreen.value() == newValue, "ShowSplashScreen failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testDockIconVisible()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue dockIconVisible;
|
||||
QVERIFY2(stub_->DockIconVisible(ctx.get(), empty, &dockIconVisible).ok(), "DockIconVisible failed.");
|
||||
bool const newValue = !dockIconVisible.value();
|
||||
|
||||
dockIconVisible.set_value(newValue);
|
||||
QVERIFY2(stub_->SetDockIconVisible(ctx.get(), dockIconVisible, &empty).ok(), "SetShowSplashScreen failed.");
|
||||
|
||||
QVERIFY2(stub_->DockIconVisible(ctx.get(), empty, &dockIconVisible).ok(), "DockIconVisible failed.");
|
||||
QVERIFY2(dockIconVisible.value() == newValue, "DockIconVisible failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsFirstGuiStart()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isFirst;
|
||||
QVERIFY2(stub_->IsFirstGuiStart(ctx.get(), empty, &isFirst).ok(), "IsFirstGuiStart failed.");
|
||||
bool const newValue = !isFirst.value();
|
||||
|
||||
isFirst.set_value(newValue);
|
||||
QVERIFY2(stub_->SetIsFirstGuiStart(ctx.get(), isFirst, &empty).ok(), "SetIsFirstGuiStart failed.");
|
||||
|
||||
QVERIFY2(stub_->IsFirstGuiStart(ctx.get(), empty, &isFirst).ok(), "IsFirstGuiStart failed.");
|
||||
QVERIFY2(isFirst.value() == newValue, "IsFirstGuiStart failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsAutostartOn()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isOn;
|
||||
QVERIFY2(stub_->IsAutostartOn(ctx.get(), empty, &isOn).ok(), "IsAutostartOn failed.");
|
||||
bool const newValue = !isOn.value();
|
||||
|
||||
isOn.set_value(newValue);
|
||||
QVERIFY2(stub_->SetIsAutostartOn(ctx.get(), isOn, &empty).ok(), "SetIsAutostartOn failed.");
|
||||
|
||||
QVERIFY2(stub_->IsAutostartOn(ctx.get(), empty, &isOn).ok(), "IsAutostartOn failed.");
|
||||
QVERIFY2(isOn.value() == newValue, "IsAutostartOn failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsBetaEnabled()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isOn;
|
||||
QVERIFY2(stub_->IsBetaEnabled(ctx.get(), empty, &isOn).ok(), "IsBetaEnabled failed.");
|
||||
bool const newValue = !isOn.value();
|
||||
|
||||
isOn.set_value(newValue);
|
||||
QVERIFY2(stub_->SetIsBetaEnabled(ctx.get(), isOn, &empty).ok(), "SetIsBetaEnabled failed.");
|
||||
|
||||
QVERIFY2(stub_->IsBetaEnabled(ctx.get(), empty, &isOn).ok(), "IsBetaEnabled failed.");
|
||||
QVERIFY2(isOn.value() == newValue, "IsBetaEnabled failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testGoOs()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue goos;
|
||||
QVERIFY2(stub_->GoOs(ctx.get(), empty, &goos).ok(), "GoOs failed.");
|
||||
QVERIFY2(goos.value().length() > 0, "Invalid GoOs value.");
|
||||
}
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testTriggerReset()
|
||||
{
|
||||
Ctx ctx;
|
||||
QVERIFY2(stub_->TriggerReset(ctx.get(), empty, &empty).ok(), "TriggerReset failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testVersion()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue version;
|
||||
QVERIFY2(stub_->Version(ctx.get(), empty, &version).ok(), "Version failed.");
|
||||
QVERIFY2(version.value().length() > 0, "Invalid version number.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLogPath()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue logPath;
|
||||
QVERIFY2(stub_->LogPath(ctx.get(), empty, &logPath).ok(), "LogPath failed.");
|
||||
QVERIFY2(logPath.value().length() > 0, "Invalid LogPath.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLicensePath()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue licensePath;
|
||||
QVERIFY2(stub_->LicensePath(ctx.get(), empty, &licensePath).ok(), "LicensePath failed.");
|
||||
QVERIFY2(licensePath.value().length() > 0, "Invalid LicensePath.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testReleaseNotesLink()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue link;
|
||||
QVERIFY2(stub_->ReleaseNotesLink(ctx.get(), empty, &link).ok(), "ReleaseNotesLink failed.");
|
||||
QVERIFY2(link.value().length() > 0, "Invalid ReleaseNotesLink.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLandingPageLink()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue link;
|
||||
QVERIFY2(stub_->LandingPageLink(ctx.get(), empty, &link).ok(), "LandingPageLink failed.");
|
||||
QVERIFY2(link.value().length() > 0, "Invalid LandingPageLink.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testColorScheme()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue name;
|
||||
string const schemeName = "dummyColors";
|
||||
name.set_value(schemeName);
|
||||
QVERIFY2(stub_->SetColorSchemeName(ctx.get(), name, &empty).ok(), "SetColorSchemeName failed.");
|
||||
|
||||
QVERIFY2(stub_->ColorSchemeName(ctx.get(), empty, &name).ok(), "ColorSchemeName failed.");
|
||||
QVERIFY2(name.value() == schemeName, "ColorSchemeName failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testCurrentEmailClient()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue name;
|
||||
string const clientName = "dummyClient";
|
||||
name.set_value(clientName);
|
||||
QVERIFY2(stub_->SetCurrentEmailClient(ctx.get(), name, &empty).ok(), "SeturrentEmailClient failed.");
|
||||
|
||||
QVERIFY2(stub_->CurrentEmailClient(ctx.get(), empty, &name).ok(), "CurrentEmailClient failed.");
|
||||
QVERIFY2(name.value() == clientName, "CurrentEmailClient failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testReportBug()
|
||||
{
|
||||
Ctx ctx;
|
||||
ReportBugRequest report;
|
||||
report.set_description("dummy description");
|
||||
report.set_address("dummy@proton.me");
|
||||
report.set_emailclient("dummyClient");
|
||||
report.set_includelogs(true);
|
||||
QVERIFY2(stub_->ReportBug(ctx.get(), report, &empty).ok(), "ReportBug failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLogin()
|
||||
{
|
||||
Ctx ctx;
|
||||
LoginRequest login;
|
||||
login.set_username("dummyuser");
|
||||
login.set_password("dummypassword");
|
||||
QVERIFY2(stub_->Login(ctx.get(), login, &empty).ok(), "Login failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLogin2FA()
|
||||
{
|
||||
Ctx ctx;
|
||||
LoginRequest login;
|
||||
login.set_username("dummyuser");
|
||||
login.set_password("dummypassword");
|
||||
QVERIFY2(stub_->Login2FA(ctx.get(), login, &empty).ok(), "Login2FA failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLogin2Passwords()
|
||||
{
|
||||
Ctx ctx;
|
||||
LoginRequest login;
|
||||
login.set_username("dummyuser");
|
||||
login.set_password("dummypassword");
|
||||
QVERIFY2(stub_->Login2Passwords(ctx.get(), login, &empty).ok(), "Login2Passwords failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testLoginAbort()
|
||||
{
|
||||
Ctx ctx;
|
||||
LoginAbortRequest loginAbort;
|
||||
loginAbort.set_username("dummyuser");
|
||||
QVERIFY2(stub_->LoginAbort(ctx.get(), loginAbort, &empty).ok(), "loginAbort failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testCheckUpdate()
|
||||
{
|
||||
Ctx ctx;
|
||||
QVERIFY2(stub_->CheckUpdate(ctx.get(), empty, &empty).ok(), "CheckUpdate failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testInstallUpdate()
|
||||
{
|
||||
Ctx ctx;
|
||||
QVERIFY2(stub_->InstallUpdate(ctx.get(), empty, &empty).ok(), "InstallUpdate failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsAutomaticUpdateOn()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isOn;
|
||||
QVERIFY2(stub_->IsAutomaticUpdateOn(ctx.get(), empty, &isOn).ok(), "IsAutomaticUpdateOn failed.");
|
||||
bool newValue = !isOn.value();
|
||||
|
||||
isOn.set_value(newValue);
|
||||
QVERIFY2(stub_->SetIsAutomaticUpdateOn(ctx.get(), isOn, &empty).ok(), "SetIsAutomaticUpdateOn failed.");
|
||||
|
||||
QVERIFY2(stub_->IsAutomaticUpdateOn(ctx.get(), empty, &isOn).ok(), "IsAutomaticUpdateOn failed.");
|
||||
QVERIFY2(isOn.value() == newValue, "IsAutomaticUpdateOn failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsCacheOnDiskEnabled()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isEnabled;
|
||||
QVERIFY2(stub_->IsCacheOnDiskEnabled(ctx.get(), empty, &isEnabled).ok(), "IsCacheOnDiskEnabled failed.");
|
||||
bool const newValue = !isEnabled.value();
|
||||
|
||||
isEnabled.set_value(newValue);
|
||||
QVERIFY2(stub_->SetIsCacheOnDiskEnabled(ctx.get(), isEnabled, &empty).ok(), "SetIsCacheOnDiskEnabled failed.");
|
||||
|
||||
QVERIFY2(stub_->IsCacheOnDiskEnabled(ctx.get(), empty, &isEnabled).ok(), "IsCacheOnDiskEnabled failed.");
|
||||
QVERIFY2(isEnabled.value() == newValue, "IsCacheOnDiskEnabled failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testDiskCachePath()
|
||||
{
|
||||
Ctx ctx;
|
||||
string const dummyPath = "/dummy/path";
|
||||
StringValue path;
|
||||
path.set_value(dummyPath);
|
||||
QVERIFY2(stub_->SetDiskCachePath(ctx.get(), path, &empty).ok(), "SetDiskCachePath failed.");
|
||||
|
||||
QVERIFY2(stub_->DiskCachePath(ctx.get(), empty, &path).ok(), "DiskCachePath failed.");
|
||||
QVERIFY2(path.value() == dummyPath, "DiskCachePath failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testChangeLocalCache()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isEnabled;
|
||||
QVERIFY2(stub_->IsCacheOnDiskEnabled(ctx.get(), empty, &isEnabled).ok(), "IsCacheOnDiskEnabled failed.");
|
||||
bool const newEnabled = !isEnabled.value();
|
||||
|
||||
string const dummyPath = "/another/dummy/path";
|
||||
ChangeLocalCacheRequest request;
|
||||
request.set_enablediskcache(newEnabled);
|
||||
request.set_diskcachepath(dummyPath);
|
||||
QVERIFY2(stub_->ChangeLocalCache(ctx.get(), request, &empty).ok(), "ChangeLocalCache failed.");
|
||||
|
||||
QVERIFY2(stub_->IsCacheOnDiskEnabled(ctx.get(), empty, &isEnabled).ok(), "IsCacheOnDiskEnabled failed.");
|
||||
QVERIFY2(isEnabled.value() == newEnabled, "IsCacheOnDiskEnabled readback failed.");
|
||||
|
||||
StringValue path;
|
||||
QVERIFY2(stub_->DiskCachePath(ctx.get(), empty, &path).ok(), "DiskCachePath failed.");
|
||||
QVERIFY2(path.value() == dummyPath, "DiskCachePath failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsDohEnabled()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue isEnabled;
|
||||
QVERIFY2(stub_->IsDoHEnabled(ctx.get(), empty, &isEnabled).ok(), "IsDoHEnabled failed.");
|
||||
bool const newValue = !isEnabled.value();
|
||||
|
||||
isEnabled.set_value(newValue);
|
||||
QVERIFY2(stub_->SetIsDoHEnabled(ctx.get(), isEnabled, &empty).ok(), "SetIsDoHEnabled failed.");
|
||||
|
||||
QVERIFY2(stub_->IsDoHEnabled(ctx.get(), empty, &isEnabled).ok(), "IsDoHEnabled failed.");
|
||||
QVERIFY2(isEnabled.value() == newValue, "IsDoHEnabled failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testUseSslForSmtp()
|
||||
{
|
||||
Ctx ctx;
|
||||
BoolValue useSsl;
|
||||
QVERIFY2(stub_->UseSslForSmtp(ctx.get(), empty, &useSsl).ok(), "UseSslForSmtp failed.");
|
||||
bool const newValue = !useSsl.value();
|
||||
|
||||
useSsl.set_value(newValue);
|
||||
QVERIFY2(stub_->SetUseSslForSmtp(ctx.get(), useSsl, &empty).ok(), "SetUseSslForSmtp failed.");
|
||||
|
||||
QVERIFY2(stub_->UseSslForSmtp(ctx.get(), empty, &useSsl).ok(), "UseSslForSmtp failed.");
|
||||
QVERIFY2(useSsl.value() == newValue, "UseSslForSmtp failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testHostname()
|
||||
{
|
||||
Ctx ctx;
|
||||
StringValue hostname;
|
||||
QVERIFY2(stub_->Hostname(ctx.get(), empty, &hostname).ok(), "Hostname failed.");
|
||||
QVERIFY2(hostname.value().length() > 0, "Hostname failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testImapPort()
|
||||
{
|
||||
Ctx ctx;
|
||||
Int32Value port;
|
||||
QVERIFY2(stub_->ImapPort(ctx.get(), empty, &port).ok(), "ImapPort failed.");
|
||||
qint16 const newValue = qint16(port.value()) + 1;
|
||||
|
||||
port.set_value(qint32(newValue));
|
||||
QVERIFY2(stub_->SetImapPort(ctx.get(), port, &empty).ok(), "SetImapPort failed.");
|
||||
|
||||
QVERIFY2(stub_->ImapPort(ctx.get(), empty, &port).ok(), "ImapPort failed.");
|
||||
QVERIFY2(qint16(port.value()) == newValue, "ImapPort failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testSmtpPort()
|
||||
{
|
||||
Ctx ctx;
|
||||
Int32Value port;
|
||||
QVERIFY2(stub_->SmtpPort(ctx.get(), empty, &port).ok(), "SmtpPort failed.");
|
||||
qint16 const newValue = qint16(port.value()) + 1;
|
||||
|
||||
port.set_value(qint32(newValue));
|
||||
QVERIFY2(stub_->SetSmtpPort(ctx.get(), port, &empty).ok(), "SetSmtpPort failed.");
|
||||
|
||||
QVERIFY2(stub_->SmtpPort(ctx.get(), empty, &port).ok(), "SmtpPort failed.");
|
||||
QVERIFY2(qint16(port.value()) == newValue, "SmtpPort failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testChangePorts()
|
||||
{
|
||||
Ctx ctx;
|
||||
ChangePortsRequest request;
|
||||
const qint32 imapPort = 2143, smtpPort = 2025;
|
||||
request.set_imapport(imapPort);
|
||||
request.set_smtpport(smtpPort);
|
||||
QVERIFY2(stub_->ChangePorts(ctx.get(), request, &empty).ok(), "");
|
||||
|
||||
Int32Value port;
|
||||
QVERIFY2(stub_->ImapPort(ctx.get(), empty, &port).ok(), "ImapPort failed.");
|
||||
QVERIFY2(port.value() == imapPort, "ImapPort failed readback.");
|
||||
|
||||
QVERIFY2(stub_->SmtpPort(ctx.get(), empty, &port).ok(), "SmtpPort failed.");
|
||||
QVERIFY2(port.value() == smtpPort, "SmtpPort failed readback.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testIsPortFree()
|
||||
{
|
||||
Ctx ctx;
|
||||
Int32Value port;
|
||||
port.set_value(143);
|
||||
BoolValue isFree;
|
||||
|
||||
QVERIFY2(stub_->IsPortFree(ctx.get(), port, &isFree).ok(), "IsPortFree failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testKeychain()
|
||||
{
|
||||
Ctx ctx;
|
||||
AvailableKeychainsResponse resp;
|
||||
QVERIFY2(stub_->AvailableKeychains(ctx.get(), empty, &resp).ok(), "AvailableKeychains failed.");
|
||||
QVERIFY2(resp.keychains().size() > 0, "AvailableKeychains returned an invalid result.");
|
||||
|
||||
string const newKeychain = resp.keychains().at(resp.keychains_size() - 1);
|
||||
|
||||
StringValue keychain;
|
||||
keychain.set_value(newKeychain);
|
||||
QVERIFY2(stub_->SetCurrentKeychain(ctx.get(), keychain, &empty).ok(), "SetCurrentKeychain failed.");
|
||||
|
||||
QVERIFY2(stub_->CurrentKeychain(ctx.get(), empty, &keychain).ok(), "CurrentKeychain failed.");
|
||||
QVERIFY2(newKeychain == keychain.value(), "CurrentKeychain readback failed.");
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
//
|
||||
//**********************************************************************************************************************
|
||||
void RpcClient::testUser()
|
||||
{
|
||||
Ctx ctx;
|
||||
UserListResponse users;
|
||||
QVERIFY2(stub_->GetUserList(ctx.get(), empty, &users).ok(), "GetUserList failed.");
|
||||
QVERIFY2(users.users_size() > 0, "GetUserList returned an invalid value.");
|
||||
|
||||
std::string const userID = users.users(0).id();
|
||||
|
||||
UserSplitModeRequest splitModeRequest;
|
||||
splitModeRequest.set_userid(userID);
|
||||
splitModeRequest.set_active(true);
|
||||
QVERIFY2(stub_->SetUserSplitMode(ctx.get(), splitModeRequest, &empty).ok(), "SetUserSplitMode failed");
|
||||
|
||||
ConfigureAppleMailRequest appleMailRequest;
|
||||
appleMailRequest.set_userid(userID);
|
||||
appleMailRequest.set_address("dummy@proton.ch");
|
||||
QVERIFY2(stub_->ConfigureUserAppleMail(ctx.get(), appleMailRequest, &empty).ok(), "ConfigureUserAppleMail failed.");
|
||||
|
||||
StringValue stringValue;
|
||||
stringValue.set_value(userID);
|
||||
QVERIFY2(stub_->LogoutUser(ctx.get(), stringValue, &empty).ok(), "LogoutUser failed.");
|
||||
|
||||
QVERIFY2(stub_->RemoveUser(ctx.get(), stringValue, &empty).ok(), "RemoveUser failed.");
|
||||
}
|
||||
|
||||
void checkAppEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<AppEvent::EventCase> expected = {
|
||||
AppEvent::kInternetStatus,
|
||||
AppEvent::kAutostartFinished,
|
||||
AppEvent::kResetFinished,
|
||||
AppEvent::kReportBugFinished,
|
||||
AppEvent::kReportBugSuccess,
|
||||
AppEvent::kReportBugError,
|
||||
AppEvent::kShowMainWindow,
|
||||
};
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event)) {
|
||||
QVERIFY2(event.event_case() == StreamEvent::kApp, "Received invalid event while waiting for app event.");
|
||||
AppEvent const& appEvent = event.app();
|
||||
AppEvent::EventCase const eventCase = appEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected app event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected app event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for app events.");
|
||||
}
|
||||
|
||||
|
||||
void checkLoginEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<LoginEvent::EventCase> expected = {
|
||||
LoginEvent::kError,
|
||||
LoginEvent::kTfaRequested,
|
||||
LoginEvent::kTwoPasswordRequested,
|
||||
LoginEvent::kFinished,
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kLogin, "Received invalid event while waiting for login event.");
|
||||
LoginEvent const& loginEvent = event.login();
|
||||
LoginEvent::EventCase const eventCase = loginEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected login event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected login event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for login events.");
|
||||
}
|
||||
|
||||
|
||||
void checkUpdateEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<UpdateEvent::EventCase> expected = {
|
||||
UpdateEvent::kError,
|
||||
UpdateEvent::kManualReady,
|
||||
UpdateEvent::kManualRestartNeeded,
|
||||
UpdateEvent::kForce,
|
||||
UpdateEvent::kSilentRestartNeeded,
|
||||
UpdateEvent::kIsLatestVersion,
|
||||
UpdateEvent::kCheckFinished
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kUpdate, "Received invalid event while waiting for update event.");
|
||||
UpdateEvent const& updateEvent = event.update();
|
||||
UpdateEvent::EventCase const eventCase = updateEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected update event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected update event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for update events.");
|
||||
}
|
||||
|
||||
|
||||
void checkCacheEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<CacheEvent::EventCase> expected = {
|
||||
CacheEvent::kError,
|
||||
CacheEvent::kLocationChangedSuccess,
|
||||
CacheEvent::kChangeLocalCacheFinished,
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kCache, "Received invalid event while waiting for cache event.");
|
||||
CacheEvent const& cacheEvent = event.cache();
|
||||
CacheEvent::EventCase const eventCase = cacheEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected cache event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected cache event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for cache events.");
|
||||
}
|
||||
|
||||
|
||||
void checkMailsSettingsEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<MailSettingsEvent::EventCase> expected = {
|
||||
MailSettingsEvent::kError,
|
||||
MailSettingsEvent::kUseSslForSmtpFinished,
|
||||
MailSettingsEvent::kChangePortsFinished,
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kMailSettings, "Received invalid event while waiting for mail settings event.");
|
||||
MailSettingsEvent const& mailSettingsEvent = event.mailsettings();
|
||||
MailSettingsEvent::EventCase const eventCase = mailSettingsEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected mail settings event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected mail settings event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for mail settings events.");
|
||||
}
|
||||
|
||||
|
||||
void checkKeychainEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<KeychainEvent::EventCase> expected = {
|
||||
KeychainEvent::kChangeKeychainFinished,
|
||||
KeychainEvent::kHasNoKeychain,
|
||||
KeychainEvent::kRebuildKeychain,
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kKeychain, "Received invalid event while waiting for keychain event.");
|
||||
KeychainEvent const& keychainEvent = event.keychain();
|
||||
KeychainEvent::EventCase const eventCase = keychainEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected keychain event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected keychain event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for keychain events.");
|
||||
}
|
||||
|
||||
|
||||
void checkMailEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<MailEvent::EventCase> expected = {
|
||||
MailEvent::kNoActiveKeyForRecipientEvent,
|
||||
MailEvent::kAddressChanged,
|
||||
MailEvent::kAddressChangedLogout,
|
||||
MailEvent::kApiCertIssue,
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kMail, "Received invalid event while waiting for mail event.");
|
||||
MailEvent const& mailEvent = event.mail();
|
||||
MailEvent::EventCase const eventCase = mailEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected mail event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected mail event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for mail events.");
|
||||
}
|
||||
|
||||
|
||||
void checkUserEvents(ClientReader<StreamEvent>& reader)
|
||||
{
|
||||
QList<UserEvent::EventCase> expected = {
|
||||
UserEvent::kToggleSplitModeFinished,
|
||||
UserEvent::kUserDisconnected,
|
||||
UserEvent::kUserChanged,
|
||||
};
|
||||
|
||||
StreamEvent event;
|
||||
while (reader.Read(&event))
|
||||
{
|
||||
QVERIFY2(event.event_case() == StreamEvent::kUser, "Received invalid event while waiting for user event.");
|
||||
UserEvent const& userEvent = event.user();
|
||||
UserEvent::EventCase const eventCase = userEvent.event_case();
|
||||
QVERIFY2(expected.size() > 0, "Empty expected user event list.");
|
||||
QVERIFY2(eventCase == expected.front(), "Unexpected user event received.");
|
||||
expected.pop_front();
|
||||
if (expected.isEmpty())
|
||||
return;
|
||||
}
|
||||
QFAIL("Stream ended while waiting for user events.");
|
||||
}
|
||||
|
||||
|
||||
void RpcClient::testStream()
|
||||
{
|
||||
Ctx ctx;
|
||||
std::unique_ptr<ClientReader<StreamEvent>> reader = stub_->GetEvents(ctx.get(), empty);
|
||||
QVERIFY2(reader, "Could not instanciate event stream reader");
|
||||
|
||||
checkAppEvents(*reader);
|
||||
checkLoginEvents(*reader);
|
||||
checkUpdateEvents(*reader);
|
||||
checkCacheEvents(*reader);
|
||||
checkMailsSettingsEvents(*reader);
|
||||
checkKeychainEvents(*reader);
|
||||
checkMailEvents(*reader);
|
||||
checkUserEvents(*reader);
|
||||
}
|
||||
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
98
test/rpc/client/RpcClient.h
Normal file
98
test/rpc/client/RpcClient.h
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_RPC_CLIENT_TEST_RPC_CLIENT_H
|
||||
#define BRIDGE_RPC_CLIENT_TEST_RPC_CLIENT_H
|
||||
|
||||
|
||||
#include "rpc/bridge_rpc.grpc.pb.h"
|
||||
#include "grpc++/grpc++.h"
|
||||
#include <QtCore>
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \brief Rpc Client class.
|
||||
//**********************************************************************************************************************
|
||||
class RpcClient: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public: // member functions
|
||||
explicit RpcClient(); ///< Default constructor.
|
||||
RpcClient(RpcClient const &) = delete; ///< Disabled copy-constructor.
|
||||
RpcClient(RpcClient &&) = delete; ///< Disabled assignment copy-constructor.
|
||||
~RpcClient() override = default; ///< Destructor.
|
||||
RpcClient &operator=(RpcClient const &) = delete; ///< Disabled assignment operator.
|
||||
RpcClient &operator=(RpcClient &&) = delete; ///< Disabled move assignment operator.
|
||||
|
||||
private slots:
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
|
||||
|
||||
void initTestCase(); ///< Check if the connection with the RPC server is established.
|
||||
void testGetCursorPos(); ///< Test the GetCursorPos call.
|
||||
void testGuiReady(); ///< Test the GuiReady call.
|
||||
void testQuit(); ///< Test the Quit call.
|
||||
void testRestart(); ///< Test the Restart call.
|
||||
void testShowOnStartup(); ///< Test the ShowOnStartup calls.
|
||||
void testShowSplashScreen(); ///< Test the ShowSplashScreen calls.
|
||||
void testDockIconVisible(); ///< Test the DockIconVisible calls.
|
||||
void testIsFirstGuiStart(); ///< Test the IsFirstGuiStart calls.
|
||||
void testIsAutostartOn(); ///< Test the IsAutostartOn calls.
|
||||
void testIsBetaEnabled(); ///< Test the IsBetaEnabled calls.
|
||||
void testGoOs(); ///< Test the GoOs call.
|
||||
void testTriggerReset(); ///< Test the TriggerReset call.
|
||||
void testVersion(); ///< Test the Version call.
|
||||
void testLogPath(); ///< Test the LogPath call.
|
||||
void testLicensePath(); ///< Test the LicensePath call.
|
||||
void testReleaseNotesLink(); ///< Test the ReleastNotesLink call.
|
||||
void testLandingPageLink(); ///< Test the LandingPageLink call.
|
||||
void testColorScheme(); ///< Test the ColorScheme calls.
|
||||
void testCurrentEmailClient(); ///< Test the CurrentEmailClient calls.
|
||||
void testReportBug(); ///< Test the ReportBug call.
|
||||
void testLogin(); ///< Test the Login call.
|
||||
void testLogin2FA(); ///< Test the Login2FA call.
|
||||
void testLogin2Passwords(); ///< Test the Login2Passwords call.
|
||||
void testLoginAbort(); ///< Test the LoginAbort call.
|
||||
void testCheckUpdate(); ///< Test the CheckUpdate call.
|
||||
void testInstallUpdate(); ///< Test the CheckUpdate call.
|
||||
void testIsAutomaticUpdateOn(); ///< Test the IsAutomaticUpdateOn calls.
|
||||
void testIsCacheOnDiskEnabled(); ///< Test the IsCacheOnDiskEnabled calls.
|
||||
void testDiskCachePath(); ///< Test the DiskCachePath calls.
|
||||
void testChangeLocalCache(); ///< Test the ChangeLocalPath calls.
|
||||
void testIsDohEnabled(); ///< Test the IsDohEnabled calls.
|
||||
void testUseSslForSmtp(); ///< Test the UseSslForSmtp calls.
|
||||
void testHostname(); ///< Test the Hostname call.
|
||||
void testImapPort(); ///< Test the ImapPort calls.
|
||||
void testSmtpPort(); ///< Test the SmtpPort calls.
|
||||
void testChangePorts(); ///< Test the ChangePorts call.
|
||||
void testIsPortFree(); ///< Test the IsPortFree call.
|
||||
void testKeychain(); ///< Test the keychains related calls.
|
||||
void testUser(); ///< Test the user related calls.
|
||||
void testStream(); ///< Test the server to client stream
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
private: // data members
|
||||
std::shared_ptr<grpc::Channel> channel_ { nullptr }; ///< The gRPC channel.
|
||||
std::shared_ptr<bridgerpc::BridgeRpc::Stub> stub_ { nullptr }; ///< The gRPC stub (a.k.a. client).
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BRIDGE_RPC_CLIENT_TEST_RPC_CLIENT_H
|
||||
2641
test/rpc/client/rpc/bridge_rpc.grpc.pb.cc
Normal file
2641
test/rpc/client/rpc/bridge_rpc.grpc.pb.cc
Normal file
File diff suppressed because it is too large
Load Diff
9864
test/rpc/client/rpc/bridge_rpc.grpc.pb.h
Normal file
9864
test/rpc/client/rpc/bridge_rpc.grpc.pb.h
Normal file
File diff suppressed because it is too large
Load Diff
12270
test/rpc/client/rpc/bridge_rpc.pb.cc
Normal file
12270
test/rpc/client/rpc/bridge_rpc.pb.cc
Normal file
File diff suppressed because it is too large
Load Diff
14440
test/rpc/client/rpc/bridge_rpc.pb.h
Normal file
14440
test/rpc/client/rpc/bridge_rpc.pb.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user