209 lines
8.3 KiB
C++
209 lines
8.3 KiB
C++
#include <IOTestHelpers.h>
|
|
|
|
#include "ServiceMock.h"
|
|
|
|
#include <Constants.h>
|
|
|
|
#include <Onboarding/Accounts/AccountsService.h>
|
|
#include <Onboarding/OnboardingController.h>
|
|
|
|
#include <StatusGo/Accounts/Accounts.h>
|
|
#include <StatusGo/SignalsManager.h>
|
|
|
|
#include <ScopedTestAccount.h>
|
|
|
|
#include <QCoreApplication>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
namespace Testing = Status::Testing;
|
|
namespace Onboarding = Status::Onboarding;
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
namespace Status::Testing
|
|
{
|
|
|
|
static std::unique_ptr<Onboarding::AccountsService> m_accountsServiceMock;
|
|
|
|
TEST(OnboardingModule, TestInitService)
|
|
{
|
|
Testing::AutoCleanTempTestDir fusedTestFolder{test_info_->name()};
|
|
auto testFolderPath = fusedTestFolder.tempFolder() / Constants::statusGoDataDirName;
|
|
fs::create_directory(testFolderPath);
|
|
auto accountsService = std::make_unique<Onboarding::AccountsService>();
|
|
ASSERT_TRUE(accountsService->init(testFolderPath));
|
|
}
|
|
|
|
/// This integration end to end test is here for documentation purpose and until all the functionality is covered by unit-tests
|
|
/// \warning the test depends on IO and it is not deterministic, fast, focused or reliable and uses production classes. It is here for documenting only and dev process
|
|
/// \todo refactor into unit-tests with mocked interfaces
|
|
TEST(OnboardingModule, TestCreateAndLoginAccountEndToEnd)
|
|
{
|
|
int argc = 1;
|
|
std::string appName{"test"};
|
|
char* args[] = {appName.data()};
|
|
QCoreApplication dummyApp{argc, reinterpret_cast<char**>(args)};
|
|
|
|
Testing::AutoCleanTempTestDir fusedTestFolder{test_info_->name()};
|
|
auto testFolderPath = fusedTestFolder.tempFolder() / "Status Desktop";
|
|
fs::create_directory(testFolderPath);
|
|
|
|
// Setup accounts
|
|
auto accountsService = std::make_shared<Onboarding::AccountsService>();
|
|
auto result = accountsService->init(testFolderPath);
|
|
ASSERT_TRUE(result);
|
|
|
|
// TODO refactor and merge account creation events with login into Onboarding controller
|
|
//
|
|
// Create Login early to register and not miss onLoggedIn event signal from setupAccountAndLogin
|
|
//
|
|
|
|
// Beware, smartpointer is a requirement
|
|
auto onboarding = std::make_shared<Onboarding::OnboardingController>(accountsService);
|
|
EXPECT_EQ(onboarding->getOpenedAccounts().size(), 0);
|
|
|
|
int accountLoggedInCount = 0;
|
|
QObject::connect(onboarding.get(), &Onboarding::OnboardingController::accountLoggedIn, [&accountLoggedInCount]() {
|
|
accountLoggedInCount++;
|
|
});
|
|
bool accountLoggedInError = false;
|
|
QObject::connect(onboarding.get(), &Onboarding::OnboardingController::accountLoginError, [&accountLoggedInError]() {
|
|
accountLoggedInError = true;
|
|
});
|
|
|
|
// Create Accounts
|
|
auto genAccounts = accountsService->generatedAccounts();
|
|
ASSERT_GT(genAccounts.size(), 0);
|
|
|
|
ASSERT_FALSE(accountsService->isFirstTimeAccountLogin());
|
|
|
|
constexpr auto accountName = "test_name";
|
|
constexpr auto accountPassword = "test_pwd*";
|
|
ASSERT_TRUE(accountsService->setupAccountAndLogin(genAccounts[0].id, accountPassword, accountName));
|
|
|
|
ASSERT_TRUE(accountsService->isFirstTimeAccountLogin());
|
|
ASSERT_TRUE(accountsService->getLoggedInAccount().isValid());
|
|
ASSERT_TRUE(accountsService->getLoggedInAccount().name == accountName);
|
|
ASSERT_FALSE(accountsService->getImportedAccount().isValid());
|
|
|
|
using namespace std::chrono_literals;
|
|
auto maxWaitTime = 2000ms;
|
|
auto iterationSleepTime = 2ms;
|
|
auto remainingIterations = maxWaitTime / iterationSleepTime;
|
|
while(remainingIterations-- > 0 && accountLoggedInCount == 0)
|
|
{
|
|
QCoreApplication::sendPostedEvents();
|
|
|
|
std::this_thread::sleep_for(iterationSleepTime);
|
|
}
|
|
|
|
EXPECT_EQ(accountLoggedInCount, 1);
|
|
EXPECT_FALSE(accountLoggedInError);
|
|
EXPECT_FALSE(Status::StatusGo::Accounts::logout().containsError());
|
|
}
|
|
|
|
/// This integration end to end test is here for documentation purpose and until all the functionality is covered by unit-tests
|
|
/// \warning the test depends on IO and it is not deterministic, fast, focused or reliable. It is here for validation only
|
|
/// \todo find a way to test the integration within a test environment. Also how about reusing an existing account
|
|
/// \todo due to keeping status-go keeping the state thsi works only run separately
|
|
TEST(OnboardingModule, TestLoginEndToEnd)
|
|
{
|
|
// Create test account and login
|
|
//
|
|
bool createAndLogin = false;
|
|
QObject::connect(StatusGo::SignalsManager::instance(),
|
|
&StatusGo::SignalsManager::nodeLogin,
|
|
[&createAndLogin](const QString& error) {
|
|
if(error.isEmpty()) createAndLogin = !createAndLogin;
|
|
});
|
|
|
|
constexpr auto accountName = "TestLoginAccountName";
|
|
ScopedTestAccount testAccount(test_info_->name(), accountName);
|
|
testAccount.processMessages(1000, [&createAndLogin]() { return !createAndLogin; });
|
|
ASSERT_TRUE(createAndLogin);
|
|
|
|
testAccount.logOut();
|
|
|
|
// Test account log in
|
|
//
|
|
|
|
// Setup accounts
|
|
auto accountsService = std::make_shared<Onboarding::AccountsService>();
|
|
auto result = accountsService->init(testAccount.testDataDir());
|
|
ASSERT_TRUE(result);
|
|
|
|
auto onboarding = std::make_shared<Onboarding::OnboardingController>(accountsService);
|
|
// We don't have a way yet to simulate status-go process exit
|
|
EXPECT_EQ(onboarding->getOpenedAccounts().size(), 1);
|
|
|
|
auto accounts = accountsService->openAndListAccounts();
|
|
ASSERT_GT(accounts.size(), 0);
|
|
|
|
int accountLoggedInCount = 0;
|
|
QObject::connect(onboarding.get(), &Onboarding::OnboardingController::accountLoggedIn, [&accountLoggedInCount]() {
|
|
accountLoggedInCount++;
|
|
});
|
|
bool accountLoggedInError = false;
|
|
QObject::connect(onboarding.get(),
|
|
&Onboarding::OnboardingController::accountLoginError,
|
|
[&accountLoggedInError](const QString& error) {
|
|
qDebug() << "Failed logging in in test" << test_info_->name() << "with error:" << error;
|
|
accountLoggedInError = true;
|
|
});
|
|
|
|
auto ourAccountRes =
|
|
std::find_if(accounts.begin(), accounts.end(), [accountName](const auto& a) { return a.name == accountName; });
|
|
auto errorString = accountsService->login(*ourAccountRes, testAccount.password());
|
|
ASSERT_EQ(errorString.length(), 0);
|
|
|
|
testAccount.processMessages(1000, [&accountLoggedInCount, &accountLoggedInError]() {
|
|
return accountLoggedInCount == 0 && !accountLoggedInError;
|
|
});
|
|
ASSERT_EQ(accountLoggedInError, 0);
|
|
ASSERT_EQ(accountLoggedInCount, 1);
|
|
}
|
|
|
|
TEST(OnboardingModule, TestLoginEndToEnd_WrongPassword)
|
|
{
|
|
constexpr auto testRootAccountName = "test-login_wrong_pass-name";
|
|
ScopedTestAccount testAccount(test_info_->name(), testRootAccountName);
|
|
|
|
testAccount.logOut();
|
|
|
|
auto accountsService = std::make_shared<Onboarding::AccountsService>();
|
|
auto result = accountsService->init(testAccount.testDataDir());
|
|
ASSERT_TRUE(result);
|
|
auto onboarding = std::make_shared<Onboarding::OnboardingController>(accountsService);
|
|
auto accounts = accountsService->openAndListAccounts();
|
|
ASSERT_GT(accounts.size(), 0);
|
|
|
|
int accountLoggedInCount = 0;
|
|
QObject::connect(onboarding.get(), &Onboarding::OnboardingController::accountLoggedIn, [&accountLoggedInCount]() {
|
|
accountLoggedInCount++;
|
|
});
|
|
bool accountLoggedInError = false;
|
|
QString loginErrorMessage;
|
|
QObject::connect(onboarding.get(),
|
|
&Onboarding::OnboardingController::accountLoginError,
|
|
[&loginErrorMessage, &accountLoggedInError](const QString& error) {
|
|
accountLoggedInError = true;
|
|
loginErrorMessage = error;
|
|
});
|
|
|
|
auto ourAccountRes = std::find_if(accounts.begin(), accounts.end(), [testRootAccountName](const auto& a) {
|
|
return a.name == testRootAccountName;
|
|
});
|
|
auto errorString = accountsService->login(*ourAccountRes, testAccount.password() + "extra");
|
|
ASSERT_EQ(errorString.length(), 0);
|
|
|
|
testAccount.processMessages(1000, [&accountLoggedInCount, &accountLoggedInError]() {
|
|
return accountLoggedInCount == 0 && !accountLoggedInError;
|
|
});
|
|
ASSERT_EQ(accountLoggedInError, 1);
|
|
ASSERT_EQ(accountLoggedInCount, 0);
|
|
ASSERT_EQ(loginErrorMessage, "file is not a database");
|
|
}
|
|
|
|
} // namespace Status::Testing
|