Files
MuditaOS/module-db/tests/ThreadRecord_tests.cpp
RobertPiet cafeb52103 [EGD-5317] Module-db UT solved
Vfs init.
Convertion time string to unix time returns 1 hour later than should.
DatabaseInitializer stub that just creates empty dbs with table
structure but without data. Notification table initial records moved
to Database Initilize section. UT run with a stub of Database
Initialize - new test section introduced to test original
initializer: test-initializer.
Added missing data for contacts db to run the sorted list test
and test fix.
2021-02-04 16:45:50 +01:00

265 lines
9.7 KiB
C++

// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
#include "Database/Database.hpp"
#include "Databases/ContactsDB.hpp"
#include "Databases/SmsDB.hpp"
#include "Interface/ContactRecord.hpp"
#include "Interface/SMSRecord.hpp"
#include "Interface/ThreadRecord.hpp"
#include "queries/messages/threads/QueryThreadMarkAsRead.hpp"
#include "queries/messages/threads/QueryThreadsSearchForList.hpp"
#include "queries/messages/threads/QueryThreadGetByID.hpp"
#include "queries/messages/threads/QueryThreadGetByContactID.hpp"
#include "queries/messages/threads/QueryThreadGetByNumber.hpp"
#include "queries/messages/threads/QueryThreadRemove.hpp"
#include "queries/messages/threads/QueryThreadsGet.hpp"
#include "queries/messages/sms/QuerySMSGetLastByThreadID.hpp"
#include <vfs.hpp>
#include <purefs/filesystem_paths.hpp>
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cstring>
TEST_CASE("Thread Record tests")
{
vfs.Init();
Database::initialize();
const auto contactsPath = purefs::dir::getUserDiskPath() / "contacts.db";
const auto smsPath = purefs::dir::getUserDiskPath() / "sms.db";
std::filesystem::remove(contactsPath);
std::filesystem::remove(smsPath);
SmsDB smsDB(smsPath.c_str());
REQUIRE(smsDB.isInitialized());
ContactsDB contactsDB(contactsPath.c_str());
REQUIRE(contactsDB.isInitialized());
const uint32_t dateTest = 123456789;
const char *snippetTest = "Test snippet";
const char *snippetTest2 = "Test snippet2";
const SMSType typeTest = SMSType ::UNKNOWN;
const uint32_t contactIDTest = 100;
ThreadRecordInterface threadRecordInterface1(&smsDB, &contactsDB);
ThreadRecord recordIN;
recordIN.date = dateTest;
recordIN.snippet = snippetTest;
recordIN.type = typeTest;
recordIN.contactID = contactIDTest;
// Add 2 records
REQUIRE(threadRecordInterface1.Add(recordIN));
REQUIRE(threadRecordInterface1.Add(recordIN));
SECTION("isUnread")
{
REQUIRE_FALSE(recordIN.isUnread());
recordIN.unreadMsgCount = 10;
REQUIRE(recordIN.isUnread());
}
SECTION("Get Count")
{
recordIN.unreadMsgCount = 10;
REQUIRE(threadRecordInterface1.Add(recordIN));
REQUIRE(threadRecordInterface1.GetCount() == 3);
REQUIRE(threadRecordInterface1.GetCount(EntryState::ALL) == 3);
REQUIRE(threadRecordInterface1.GetCount(EntryState::READ) == 2);
REQUIRE(threadRecordInterface1.GetCount(EntryState::UNREAD) == 1);
}
SECTION("Get all available records")
{
auto records = threadRecordInterface1.GetLimitOffset(0, 100);
REQUIRE((*records).size() == 2);
// Check if fetched records contain valid data
for (const auto &w : *records) {
REQUIRE(w.date == dateTest);
REQUIRE(w.snippet == snippetTest);
REQUIRE(w.type == typeTest);
REQUIRE(w.contactID == contactIDTest);
}
}
SECTION("Get all available records with query")
{
auto query = std::make_shared<db::query::ThreadsGet>(0, 100);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::ThreadsGetResults *>(ret.get());
REQUIRE(result != nullptr);
auto results = result->getResults();
REQUIRE(results.size() == 2);
// Check if fetched records contain valid data
for (const auto &w : results) {
REQUIRE(w.date == dateTest);
REQUIRE(w.snippet == snippetTest);
REQUIRE(w.type == typeTest);
REQUIRE(w.contactID == contactIDTest);
}
}
SECTION("Get all available records by specified thread ID and check for invalid data")
{
auto records = threadRecordInterface1.GetLimitOffsetByField(
0, 100, ThreadRecordField ::ContactID, std::to_string(contactIDTest).c_str());
REQUIRE((*records).size() == 2);
for (const auto &w : *records) {
REQUIRE(w.date == dateTest);
REQUIRE(w.snippet == snippetTest);
REQUIRE(w.type == typeTest);
REQUIRE(w.contactID == contactIDTest);
}
}
SECTION("Get record by id with query")
{
auto query = std::make_shared<db::query::ThreadGetByID>(1);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::ThreadGetByIDResult *>(ret.get());
REQUIRE(result->getRecord().has_value());
}
SECTION("Get record by contact id")
{
auto query = std::make_shared<db::query::ThreadGetByContactID>(contactIDTest);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::ThreadGetByContactIDResult *>(ret.get());
REQUIRE(result->getRecord().has_value());
REQUIRE(result->getRecord()->contactID == contactIDTest);
}
SECTION("Remove records one by one")
{
REQUIRE(threadRecordInterface1.RemoveByID(1));
REQUIRE(threadRecordInterface1.RemoveByID(2));
// SMS database should not contain any records
REQUIRE(threadRecordInterface1.GetCount() == 0);
}
SECTION("Remove records with query")
{
auto query1 = std::make_shared<db::query::ThreadRemove>(1);
auto ret1 = threadRecordInterface1.runQuery(query1);
auto result1 = dynamic_cast<db::query::ThreadRemoveResult *>(ret1.get());
REQUIRE(result1->success());
auto query2 = std::make_shared<db::query::ThreadRemove>(2);
auto ret2 = threadRecordInterface1.runQuery(query2);
auto result2 = dynamic_cast<db::query::ThreadRemoveResult *>(ret2.get());
REQUIRE(result2->success());
// SMS database should not contain any records
REQUIRE(threadRecordInterface1.GetCount() == 0);
}
SECTION("Test updating record")
{
// REQUIRE(threadRecordInterface1.Add(recordIN));
recordIN.ID = 1;
recordIN.snippet = snippetTest2;
REQUIRE(threadRecordInterface1.Update(recordIN));
auto record = threadRecordInterface1.GetByID(1);
REQUIRE(record.isValid());
REQUIRE(record.snippet == snippetTest2);
}
SECTION("Mark as read / unread")
{
recordIN.unreadMsgCount = 10;
REQUIRE(threadRecordInterface1.Add(recordIN));
auto rec = threadRecordInterface1.GetByID(3);
REQUIRE(rec.isUnread());
{
auto query = std::make_shared<db::query::MarkAsRead>(3, db::query::MarkAsRead::Read::True);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::MarkAsReadResult *>(ret.get());
REQUIRE(result != nullptr);
REQUIRE(result->getResult());
rec = threadRecordInterface1.GetByID(3);
REQUIRE_FALSE(rec.isUnread());
}
{
auto query = std::make_shared<db::query::MarkAsRead>(3, db::query::MarkAsRead::Read::False);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::MarkAsReadResult *>(ret.get());
REQUIRE(result != nullptr);
REQUIRE(result->getResult());
rec = threadRecordInterface1.GetByID(3);
REQUIRE(rec.isUnread());
}
}
SECTION("SMS search")
{
const utils::PhoneNumber phoneNumber("+48600123456", utils::country::Id::UNKNOWN);
const std::string lastSmsBody = "Ola";
SMSRecordInterface smsRecInterface(&smsDB, &contactsDB);
SMSRecord recordIN;
recordIN.date = 123456789;
recordIN.dateSent = 987654321;
recordIN.errorCode = 0;
recordIN.number = phoneNumber.getView();
recordIN.body = "Ala";
recordIN.type = SMSType ::DRAFT;
REQUIRE(smsRecInterface.Add(recordIN));
recordIN.body = lastSmsBody;
REQUIRE(smsRecInterface.Add(recordIN));
{
auto query = std::make_shared<db::query::ThreadsSearchForList>("A", 0, 10);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::ThreadsSearchResultForList *>(ret.get());
REQUIRE(result != nullptr);
auto results = result->getResults();
REQUIRE(results.size() == 2);
}
{
auto query = std::make_shared<db::query::ThreadsSearchForList>("O", 0, 10);
auto ret = threadRecordInterface1.runQuery(query);
auto result = dynamic_cast<db::query::ThreadsSearchResultForList *>(ret.get());
REQUIRE(result != nullptr);
auto results = result->getResults();
REQUIRE(results.size() == 1);
}
SECTION("Get last SMS by thread id")
{
auto getThreadQuery = std::make_shared<db::query::ThreadGetByNumber>(phoneNumber.getView());
auto getThreadRet = threadRecordInterface1.runQuery(getThreadQuery);
auto getThreatResult = dynamic_cast<db::query::ThreadGetByNumberResult *>(getThreadRet.get());
REQUIRE(getThreatResult != nullptr);
auto threadRec = getThreatResult->getThread();
REQUIRE(threadRec.isValid());
auto getLastQuery = std::make_shared<db::query::SMSGetLastByThreadID>(threadRec.ID);
auto getLastRet = smsRecInterface.runQuery(getLastQuery);
auto getLastResult = dynamic_cast<db::query::SMSGetLastByThreadIDResult *>(getLastRet.get());
REQUIRE(getLastResult != nullptr);
auto smsRec = getLastResult->record;
REQUIRE(smsRec.has_value());
REQUIRE(smsRec->body == lastSmsBody);
}
}
Database::deinitialize();
}