170 lines
6.5 KiB
C++
170 lines
6.5 KiB
C++
|
#include <IOTestHelpers.h>
|
||
|
|
||
|
#include "ServiceMock.h"
|
||
|
|
||
|
#include <Constants.h>
|
||
|
|
||
|
#include <Onboarding/Accounts/AccountsService.h>
|
||
|
#include <Onboarding/OnboardingController.h>
|
||
|
|
||
|
#include <StatusGo/SignalsManager.h>
|
||
|
#include <StatusGo/Accounts/Accounts.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) {
|
||
|
std::this_thread::sleep_for(iterationSleepTime);
|
||
|
|
||
|
QCoreApplication::sendPostedEvents();
|
||
|
}
|
||
|
|
||
|
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()) {
|
||
|
if(createAndLogin) {
|
||
|
createAndLogin = false;
|
||
|
} else
|
||
|
createAndLogin = true;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
constexpr auto accountName = "TestLoginAccountName";
|
||
|
constexpr auto accountPassword = "1234567890";
|
||
|
ScopedTestAccount testAccount(test_info_->name(), accountName, accountPassword, true);
|
||
|
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.fusedTestFolder());
|
||
|
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().count(), 0);
|
||
|
|
||
|
auto accounts = accountsService->openAndListAccounts();
|
||
|
//ASSERT_EQ(accounts.size(), 1);
|
||
|
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]() {
|
||
|
accountLoggedInError = true;
|
||
|
});
|
||
|
|
||
|
// Workaround until we reset the status-go state
|
||
|
auto ourAccountRes = std::find_if(accounts.begin(), accounts.end(), [accountName](const auto &a) { return a.name == accountName; });
|
||
|
auto errorString = accountsService->login(*ourAccountRes, accountPassword);
|
||
|
ASSERT_EQ(errorString.length(), 0);
|
||
|
|
||
|
testAccount.processMessages(1000, [accountLoggedInCount, accountLoggedInError]() {
|
||
|
return accountLoggedInCount == 0 && !accountLoggedInError;
|
||
|
});
|
||
|
ASSERT_EQ(accountLoggedInCount, 1);
|
||
|
ASSERT_EQ(accountLoggedInError, 0);
|
||
|
}
|
||
|
|
||
|
} // namespace
|