M => +3 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "QuotesPresenter.hpp"
@@ 15,9 15,7 @@ namespace gui
void QuotesPresenter::requestQuote()
{
// TODO: get quote: only enabled, from currently selected language
constexpr auto quoteID = 1;
auto query = std::make_unique<Quotes::Messages::ReadQuoteRequest>(quoteID);
auto query = std::make_unique<Quotes::Messages::ReadRandomizedQuoteRequest>();
auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Quotes);
task->setCallback([this](auto response) { return onQuoteRetreived(response); });
task->execute(application, this);
@@ 25,7 23,7 @@ namespace gui
bool QuotesPresenter::onQuoteRetreived(db::QueryResult *queryResult)
{
auto msgResponse = dynamic_cast<Quotes::Messages::ReadQuoteResponse *>(queryResult);
auto msgResponse = dynamic_cast<Quotes::Messages::ReadRandomizedQuoteResponse *>(queryResult);
assert(msgResponse != nullptr);
if (quoteDisplayCallback) {
M => +2 -1
@@ 1,10 1,11 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include <service-db/QuotesMessages.hpp>
#include <ApplicationCommon.hpp>
#include <module-services/service-db/agents/quotes/RandomizedQuoteModel.hpp>
namespace gui
{
M module-services/service-db/CMakeLists.txt => module-services/service-db/CMakeLists.txt +3 -1
@@ 19,7 19,9 @@ set(SOURCES
agents/settings/SettingsCache.cpp
agents/settings/FactorySettings.cpp
agents/quotes/QuotesAgent.cpp
-)
+ agents/quotes/RandomizedQuoteModel.cpp
+ agents/quotes/QuotesSettingsSerializer.cpp
+ )
add_library(${PROJECT_NAME} STATIC ${SOURCES})
M module-services/service-db/agents/quotes/QuotesAgent.cpp => module-services/service-db/agents/quotes/QuotesAgent.cpp +34 -4
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "QuotesAgent.hpp"
@@ 9,8 9,11 @@
namespace Quotes
{
- QuotesAgent::QuotesAgent(Database *quotesDB) : database(quotesDB)
+ QuotesAgent::QuotesAgent(Database *quotesDB, std::unique_ptr<settings::Settings> settings)
+ : database(quotesDB), randomizedQuoteModel(std::move(settings), quotesDB)
{
+ constexpr auto forced = false;
+ randomizedQuoteModel.updateList(forced);
}
auto QuotesAgent::runQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>
@@ 42,6 45,9 @@ namespace Quotes
else if (typeid(*query) == typeid(Messages::ReadQuoteRequest)) {
return handleReadQuote(query);
}
+ else if (typeid(*query) == typeid(Messages::ReadRandomizedQuoteRequest)) {
+ return handleReadRandomizedQuote(query);
+ }
else if (typeid(*query) == typeid(Messages::WriteQuoteRequest)) {
return handleWriteQuote(query);
}
@@ 66,6 72,8 @@ namespace Quotes
auto req = std::dynamic_pointer_cast<Messages::EnableCategoryByIdRequest>(query);
auto queryResult = database->execute(Queries::enableCategory, req->enable, req->categoryId);
auto response = std::make_unique<Messages::EnableCategoryByIdResponse>(std::move(queryResult));
+ constexpr auto forced = true;
+ randomizedQuoteModel.updateList(forced);
response->setRequestQuery(query);
return response;
}
@@ 116,6 124,8 @@ namespace Quotes
auto req = std::dynamic_pointer_cast<Messages::EnableQuoteByIdRequest>(query);
auto queryResult = database->execute(Queries::enableQuote, req->enable, req->quoteId);
auto response = std::make_unique<Messages::EnableQuoteByIdResponse>(queryResult);
+ constexpr auto forced = true;
+ randomizedQuoteModel.updateList(forced);
response->setRequestQuery(query);
return response;
}
@@ 133,6 143,10 @@ namespace Quotes
CategoryRecord categoryRecord(queryResult.get());
auto success = database->execute(Queries::addQuoteToQuoteCategoryMapTable, categoryRecord.category_id, quoteId);
+ if (success) {
+ constexpr auto forced = true;
+ randomizedQuoteModel.updateList(forced);
+ }
auto response = std::make_unique<Messages::AddQuoteResponse>(success, quoteId);
response->setRequestQuery(query);
@@ 150,11 164,26 @@ namespace Quotes
return response;
}
+ auto QuotesAgent::handleReadRandomizedQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>
+ {
+ auto req = std::dynamic_pointer_cast<Messages::ReadRandomizedQuoteRequest>(query);
+ auto randomizedId = randomizedQuoteModel.getId();
+ LOG_DEBUG("Randomized id: %d", randomizedId);
+ auto queryResult = database->query(Queries::readQuote, randomizedId);
+ QuoteRecord quoteRecord(queryResult.get());
+ auto response = std::make_unique<Messages::ReadRandomizedQuoteResponse>(
+ quoteRecord.quote_id, quoteRecord.lang_id, quoteRecord.quote, quoteRecord.author, quoteRecord.enabled);
+ response->setRequestQuery(query);
+ return response;
+ }
+
auto QuotesAgent::handleWriteQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>
{
auto req = std::dynamic_pointer_cast<Messages::WriteQuoteRequest>(query);
auto queryResult = database->execute(
Queries::writeQuote, req->langId, req->quote.c_str(), req->author.c_str(), req->enabled, req->quoteId);
+ constexpr auto forced = true;
+ randomizedQuoteModel.updateList(forced);
auto response = std::make_unique<Messages::WriteQuoteResponse>(queryResult);
response->setRequestQuery(query);
return response;
@@ 164,11 193,12 @@ namespace Quotes
{
auto req = std::dynamic_pointer_cast<Messages::DeleteQuoteRequest>(query);
database->execute(Queries::deleteQuoteFromQuoteCategoryMapTable, req->quoteId);
-
auto queryResult = database->execute(Queries::deleteQuoteFromQuoteTable, req->quoteId);
-
+ constexpr auto forced = true;
+ randomizedQuoteModel.updateList(forced);
auto response = std::make_unique<Messages::DeleteQuoteResponse>(queryResult);
response->setRequestQuery(query);
return response;
}
+
} // namespace Quotes
M module-services/service-db/agents/quotes/QuotesAgent.hpp => module-services/service-db/agents/quotes/QuotesAgent.hpp +5 -2
@@ 1,10 1,11 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include <service-db/QuotesMessages.hpp>
#include <Interface/Record.hpp>
+#include "RandomizedQuoteModel.hpp"
namespace Quotes
{
@@ 15,7 16,7 @@ namespace Quotes
class QuotesAgent : public RecordInterface<QuoteRecord, QuotesRecordField>
{
public:
- explicit QuotesAgent(Database *quotesDB);
+ QuotesAgent(Database *quotesDB, std::unique_ptr<settings::Settings> settings);
~QuotesAgent() = default;
auto runQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
@@ 30,10 31,12 @@ namespace Quotes
auto handleEnableQuoteById(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleAddQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleReadQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
+ auto handleReadRandomizedQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleWriteQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleDeleteQuote(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
private:
Database *database;
+ RandomizedQuoteModel randomizedQuoteModel;
};
} // namespace Quotes
A module-services/service-db/agents/quotes/QuotesSettingsSerializer.cpp => module-services/service-db/agents/quotes/QuotesSettingsSerializer.cpp +31 -0
@@ 0,0 1,31 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "QuotesSettingsSerializer.hpp"
+#include <log/log.hpp>
+#include <module-utils/utility/Utils.hpp>
+
+namespace Quotes
+{
+
+ auto QuotesSettingsSerializer::serialize(const IdList &list) -> std::string
+ {
+ std::string output;
+ for (const auto &item : list) {
+ output.append(utils::to_string(item) + ',');
+ }
+ return output;
+ }
+ auto QuotesSettingsSerializer::deserialize(const std::string &listString) -> IdList
+ {
+ std::stringstream ss(listString);
+ IdList list;
+ for (int i; ss >> i;) {
+ list.push_back(i);
+ if (ss.peek() == ',' || ss.peek() == ' ') {
+ ss.ignore();
+ }
+ }
+ return list;
+ }
+} // namespace Quotes
A module-services/service-db/agents/quotes/QuotesSettingsSerializer.hpp => module-services/service-db/agents/quotes/QuotesSettingsSerializer.hpp +18 -0
@@ 0,0 1,18 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+#include <deque>
+#include <string>
+
+namespace Quotes
+{
+ using IdList = std::deque<int>;
+
+ class QuotesSettingsSerializer
+ {
+ public:
+ [[nodiscard]] auto serialize(const IdList &list) -> std::string;
+ [[nodiscard]] auto deserialize(const std::string &listString) -> IdList;
+ };
+} // namespace Quotes
A module-services/service-db/agents/quotes/RandomizedQuoteModel.cpp => module-services/service-db/agents/quotes/RandomizedQuoteModel.cpp +98 -0
@@ 0,0 1,98 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "RandomizedQuoteModel.hpp"
+#include "log/log.hpp"
+#include "QuotesQueries.hpp"
+#include <service-db/agents/settings/SystemSettings.hpp>
+#include <algorithm> // std::random_shuffle
+#include <memory>
+#include <sstream>
+
+namespace Quotes
+{
+ constexpr inline auto zeroOffset = 0;
+ constexpr inline auto maxLimit = std::numeric_limits<unsigned int>().max();
+ RandomizedQuoteModel::RandomizedQuoteModel(std::unique_ptr<settings::Settings> settings, Database *quotesDB)
+ : settings(std::move(settings)), quotesDB(quotesDB), serializer(std::make_unique<QuotesSettingsSerializer>())
+ {}
+
+ void RandomizedQuoteModel::randomize(IdList &list)
+ {
+ srand(time(NULL));
+ std::random_shuffle(std::begin(list), std::end(list));
+ }
+ void RandomizedQuoteModel::updateList(bool forced)
+ {
+ auto queryResult = quotesDB->query(Queries::getEnabledQuotes);
+ auto quotesList = getList<QuotesList, QuoteRecord>(zeroOffset, maxLimit, std::move(queryResult));
+ populateList(std::move(quotesList), forced);
+ }
+ void RandomizedQuoteModel::populateList(std::unique_ptr<QuotesList> quotesList, bool forcedUpdate)
+ {
+ IdList list;
+ for (const auto &item : quotesList->data) {
+ list.push_back(item.quote_id);
+ }
+
+ randomize(list);
+ if (not forcedUpdate) {
+ auto settingsList = settings->getValue(settings::Quotes::randomQuotesList, settings::SettingsScope::Global);
+ if (not settingsList.empty()) {
+ return;
+ }
+ }
+ settings->setValue(
+ settings::Quotes::randomQuotesList, serializer->serialize(list), settings::SettingsScope::Global);
+ LOG_ERROR("ID queue length: %zu", list.size());
+ }
+
+ auto RandomizedQuoteModel::getId() -> int
+ {
+
+ if (isIdExpired()) {
+ shiftIdList();
+ }
+
+ auto list = serializer->deserialize(
+ settings->getValue(settings::Quotes::randomQuotesList, settings::SettingsScope::Global));
+ return list.front();
+ }
+
+ void RandomizedQuoteModel::shiftIdList()
+ {
+ auto list = serializer->deserialize(
+ settings->getValue(settings::Quotes::randomQuotesList, settings::SettingsScope::Global));
+ list.pop_front();
+ if (list.empty()) {
+ updateList(true);
+ }
+ settings->setValue(
+ settings::Quotes::randomQuotesList, serializer->serialize(list), settings::SettingsScope::Global);
+ LOG_DEBUG("Selected quote ID: %d, remaining quotes to next shuffle: %zu", list.front(), list.size());
+ }
+ auto RandomizedQuoteModel::isIdExpired() -> bool
+ {
+ auto lastTimestampString =
+ settings->getValue(settings::Quotes::randomQuoteIDUpdateTime, settings::SettingsScope::Global);
+ long lastTimestamp;
+
+ try {
+ lastTimestamp = stol(lastTimestampString);
+ }
+ catch (std::invalid_argument &e) {
+ LOG_ERROR("Invalid timestamp, zeroing! Cause: %s", e.what());
+ lastTimestamp = 0;
+ }
+
+ auto currentTimestamp = std::time(nullptr);
+ if ((currentTimestamp - lastTimestamp) >= quotesChangingInterval) {
+ lastTimestamp = currentTimestamp;
+ settings->setValue(settings::Quotes::randomQuoteIDUpdateTime,
+ utils::to_string(lastTimestamp),
+ settings::SettingsScope::Global);
+ return true;
+ }
+ return false;
+ }
+} // namespace Quotes
A module-services/service-db/agents/quotes/RandomizedQuoteModel.hpp => module-services/service-db/agents/quotes/RandomizedQuoteModel.hpp +35 -0
@@ 0,0 1,35 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <AsyncTask.hpp>
+#include <ApplicationCommon.hpp>
+#include <service-db/Settings.hpp>
+#include <service-db/QuotesMessages.hpp>
+#include "QuotesSettingsSerializer.hpp"
+
+namespace Quotes
+{
+ using namespace std::chrono;
+ inline constexpr auto quotesChangingInterval = duration_cast<seconds>(hours{24}).count();
+
+ class RandomizedQuoteModel
+ {
+ private:
+ app::ApplicationCommon *app = nullptr;
+ std::unique_ptr<settings::Settings> settings;
+ Database *quotesDB = nullptr;
+ void populateList(std::unique_ptr<QuotesList> quotesList, bool forcedUpdate = false);
+ void shiftIdList();
+ auto isIdExpired() -> bool;
+ void randomize(IdList &list);
+ std::unique_ptr<QuotesSettingsSerializer> serializer;
+
+ public:
+ RandomizedQuoteModel(std::unique_ptr<settings::Settings> settings, Database *quotesDB);
+ void updateList(bool forced);
+ [[nodiscard]] auto getId() -> int;
+ };
+
+} // namespace Quotes
M module-services/service-db/agents/settings/SystemSettings.hpp => module-services/service-db/agents/settings/SystemSettings.hpp +7 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 73,6 73,12 @@ namespace settings
constexpr inline auto option = "wallpaper_option";
} // namespace Wallpaper
+ namespace Quotes
+ {
+ constexpr inline auto randomQuotesList = "quotes_random_list";
+ constexpr inline auto randomQuoteIDUpdateTime = "quotes_random_id_update_time";
+ } // namespace Quotes
+
namespace Display
{
constexpr inline auto invertedMode = "display_inverted_mode";
M module-services/service-db/include/service-db/QuotesMessages.hpp => module-services/service-db/include/service-db/QuotesMessages.hpp +32 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 387,6 387,37 @@ namespace Quotes
}
};
+ class ReadRandomizedQuoteRequest : public db::Query
+ {
+ public:
+ ReadRandomizedQuoteRequest() : Query(Query::Type::Read)
+ {}
+
+ auto debugInfo() const -> std::string
+ {
+ return "ReadRandomizedQuoteRequest";
+ }
+ };
+
+ class ReadRandomizedQuoteResponse : public db::QueryResult
+ {
+ public:
+ explicit ReadRandomizedQuoteResponse(
+ unsigned int quoteId, unsigned int langId, std::string quote, std::string author, bool enabled)
+ : quoteId(quoteId), langId(langId), quote(std::move(quote)), author(std::move(author)), enabled(enabled)
+ {}
+ const unsigned int quoteId;
+ const unsigned int langId;
+ const std::string quote;
+ const std::string author;
+ const bool enabled;
+
+ auto debugInfo() const -> std::string
+ {
+ return "ReadRandomizedQuoteResponse";
+ }
+ };
+
class WriteQuoteRequest : public db::Query
{
public:
M module-services/service-db/include/service-db/Settings.hpp => module-services/service-db/include/service-db/Settings.hpp +5 -5
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 33,9 33,9 @@ namespace settings
void init(const service::ServiceProxy &interface);
void deinit();
- void setValue(const std::string &variableName,
- const std::string &variableValue,
- SettingsScope scope = SettingsScope::AppLocal);
+ virtual void setValue(const std::string &variableName,
+ const std::string &variableValue,
+ SettingsScope scope = SettingsScope::AppLocal);
void registerValueChange(const std::string &variableName,
ValueChangedCallback cb,
SettingsScope scope = SettingsScope::AppLocal);
@@ 44,7 44,7 @@ namespace settings
SettingsScope scope = SettingsScope::AppLocal);
void unregisterValueChange(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
/// unregisters all registered variables (both global and local)
- std::string getValue(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
+ virtual std::string getValue(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
SettingsCache *getCache();
M module-services/service-db/test/test-service-db-quotes.cpp => module-services/service-db/test/test-service-db-quotes.cpp +155 -4
@@ 1,10 1,9 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
#include "test-service-db-quotes.hpp"
-
#include <purefs/filesystem_paths.hpp>
#include <iostream>
@@ 19,7 18,10 @@ TEST_CASE("Quotes")
{
Database::initialize();
auto database = std::make_unique<Database>((purefs::dir::getUserDiskPath() / "quotes.db").string().c_str());
- auto tester = std::make_unique<QuotesAgentTester>(database.get());
+ std::string timestampString{};
+ std::string quotesString{};
+ auto settings = std::make_unique<Quotes::SettingsMock>(quotesString, timestampString);
+ auto tester = std::make_unique<QuotesAgentTester>(database.get(), std::move(settings));
SECTION("Get categories with limit and offset")
{
@@ 60,6 62,11 @@ TEST_CASE("Quotes")
bool enable = false;
const unsigned int categoryId = 1;
+ // Get current random quote
+ auto queryResult = tester->readRandomizedQuote();
+ auto randomQuoteId = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get())->quoteId;
+ REQUIRE(randomQuoteId != 0);
+
auto success = tester->enableCategory(categoryId, enable);
REQUIRE(success);
@@ 67,6 74,12 @@ TEST_CASE("Quotes")
auto quotes = tester->getQuotesByCategoryId(categoryId);
REQUIRE(quotes.size() == 0);
+ // verify rerandomizing the quotes list
+ queryResult = tester->readRandomizedQuote();
+ auto newRandomQuoteId = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get())->quoteId;
+ REQUIRE(newRandomQuoteId != 0);
+ REQUIRE(randomQuoteId != newRandomQuoteId);
+
enable = true;
success = tester->enableCategory(categoryId, enable);
@@ 82,6 95,11 @@ TEST_CASE("Quotes")
bool enable = false;
const unsigned int quoteId = 1;
+ // Get current random quote
+ auto queryResult = tester->readRandomizedQuote();
+ auto randomQuoteId = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get())->quoteId;
+ REQUIRE(randomQuoteId != 0);
+
auto success = tester->enableQuote(quoteId, enable);
REQUIRE(success);
@@ 89,6 107,12 @@ TEST_CASE("Quotes")
auto quotes = tester->getEnabledQuotes();
REQUIRE(quotes.size() == totalNumOfQuotesInDb - 1);
+ // verify rerandomizing the quotes list
+ queryResult = tester->readRandomizedQuote();
+ auto newRandomQuoteId = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get())->quoteId;
+ REQUIRE(newRandomQuoteId != 0);
+ REQUIRE(randomQuoteId != newRandomQuoteId);
+
enable = true;
success = tester->enableQuote(quoteId, enable);
@@ 106,6 130,11 @@ TEST_CASE("Quotes")
std::string author = "TEST AUTHOR";
bool enabled = true;
+ // Get current random quote
+ auto queryResult = tester->readRandomizedQuote();
+ auto randomQuoteId = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get())->quoteId;
+ REQUIRE(randomQuoteId != 0);
+
// Add a new quote
auto quoteId = tester->addQuote(langId, quote, author, enabled);
@@ 114,8 143,14 @@ TEST_CASE("Quotes")
REQUIRE(quotes.size() == totalNumOfQuotesInDb + 1);
+ // verify rerandomizing the quotes list
+ queryResult = tester->readRandomizedQuote();
+ auto newRandomQuoteId = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get())->quoteId;
+ REQUIRE(newRandomQuoteId != 0);
+ REQUIRE(randomQuoteId != newRandomQuoteId);
+
// Read added quote
- auto queryResult = tester->readQuote(quoteId);
+ queryResult = tester->readQuote(quoteId);
auto readQuoteResponse = dynamic_cast<Messages::ReadQuoteResponse *>(queryResult.get());
REQUIRE(readQuoteResponse->quoteId == quoteId);
@@ 146,5 181,121 @@ TEST_CASE("Quotes")
REQUIRE(quotes.size() == totalNumOfQuotesInDb);
}
+ SECTION("Randomizer test - double request")
+ {
+
+ auto queryResult = tester->readRandomizedQuote();
+ auto response = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get());
+
+ REQUIRE(response);
+ auto quoteId = response->quoteId;
+
+ queryResult = tester->readRandomizedQuote();
+ response = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get());
+ REQUIRE(response);
+ auto newQuoteId = response->quoteId;
+
+ REQUIRE(quoteId == newQuoteId);
+ }
+ SECTION("Randomizer test - time shift correct")
+ {
+ constexpr auto timeshift24h = 24 * 3600;
+
+ auto queryResult = tester->readRandomizedQuote();
+ auto response = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get());
+ REQUIRE(response);
+ auto quoteId = response->quoteId;
+
+ timestampString = std::to_string(std::time(nullptr) - timeshift24h);
+ queryResult = tester->readRandomizedQuote();
+ response = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get());
+ REQUIRE(response);
+ auto newQuoteId = response->quoteId;
+
+ REQUIRE(quoteId != newQuoteId);
+ }
+ SECTION("Randomizer test - time shift wrong")
+ {
+ constexpr auto timeshift23h = 23 * 3600;
+
+ auto queryResult = tester->readRandomizedQuote();
+ auto response = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get());
+ REQUIRE(response);
+ auto quoteId = response->quoteId;
+
+ timestampString = std::to_string(std::time(nullptr) - timeshift23h);
+ queryResult = tester->readRandomizedQuote();
+ response = dynamic_cast<Messages::ReadRandomizedQuoteResponse *>(queryResult.get());
+ REQUIRE(response);
+ auto newQuoteId = response->quoteId;
+
+ REQUIRE(quoteId == newQuoteId);
+ }
+
Database::deinitialize();
}
+
+TEST_CASE("Serializer test")
+{
+
+ QuotesSettingsSerializer serializer;
+
+ SECTION("Serialize - correct input")
+ {
+ IdList list{1, 2, 3, 4};
+ auto result = serializer.serialize(list);
+ REQUIRE(result == "1,2,3,4,");
+
+ IdList list2{1};
+ result = serializer.serialize(list2);
+ REQUIRE(result == "1,");
+ }
+
+ SECTION("Serialize - wrong input")
+ {
+ IdList list{};
+ auto result = serializer.serialize(list);
+ REQUIRE(result.empty());
+ }
+
+ SECTION("Deserialize - correct input")
+ {
+ std::string serializedData = "1,2,3,4,";
+ auto result = serializer.deserialize(serializedData);
+ REQUIRE(result.size() == 4);
+ REQUIRE(result.front() == 1);
+ REQUIRE(result.back() == 4);
+ }
+
+ SECTION("Deserialize - empty input")
+ {
+ std::string serializedData = " ";
+ IdList result;
+ REQUIRE_NOTHROW(result = serializer.deserialize(serializedData));
+ REQUIRE(result.empty());
+ }
+
+ SECTION("Deserialize - wrong input 1/3")
+ {
+ std::string serializedData = "abc";
+ IdList result;
+ REQUIRE_NOTHROW(result = serializer.deserialize(serializedData));
+ REQUIRE(result.empty());
+ }
+
+ SECTION("Deserialize - wrong input 2/3")
+ {
+ std::string serializedData = "a,b,c";
+ IdList result;
+ REQUIRE_NOTHROW(result = serializer.deserialize(serializedData));
+ REQUIRE(result.empty());
+ }
+
+ SECTION("Deserialize - wrong input 3/3")
+ {
+ std::string serializedData = ",1,2,3,4";
+ IdList result;
+ REQUIRE_NOTHROW(result = serializer.deserialize(serializedData));
+ REQUIRE(result.empty());
+ }
+}
M module-services/service-db/test/test-service-db-quotes.hpp => module-services/service-db/test/test-service-db-quotes.hpp +44 -2
@@ 1,17 1,19 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include <service-db/QuotesMessages.hpp>
#include <service-db/agents/quotes/QuotesAgent.hpp>
+#include <service-db/agents/settings/SystemSettings.hpp>
namespace Quotes
{
class QuotesAgentTester : public QuotesAgent
{
public:
- QuotesAgentTester(Database *quotesDB) : QuotesAgent(quotesDB){};
+ QuotesAgentTester(Database *quotesDB, std::unique_ptr<settings::Settings> settings)
+ : QuotesAgent(quotesDB, std::move(settings)){};
~QuotesAgentTester() = default;
auto handleCategoryList(std::shared_ptr<Messages::GetCategoryListRequest> query)
@@ 91,6 93,11 @@ namespace Quotes
auto request = std::make_shared<Messages::ReadQuoteRequest>(quoteId);
return handleReadQuote(request);
}
+ auto readRandomizedQuote() -> std::unique_ptr<db::QueryResult>
+ {
+ auto request = std::make_shared<Messages::ReadRandomizedQuoteRequest>();
+ return handleReadRandomizedQuote(request);
+ }
auto writeQuote(unsigned int quoteId, unsigned int langId, std::string quote, std::string author, bool enabled)
-> bool
@@ 110,4 117,39 @@ namespace Quotes
return response->success;
}
};
+
+ class SettingsMock : public settings::Settings
+ {
+ public:
+ SettingsMock(std::string "esStr, std::string ×tampStr)
+ : quotesString(quotesStr), timestampString(timestampStr)
+ {}
+ void setValue(const std::string &variableName,
+ const std::string &variableValue,
+ settings::SettingsScope scope = settings::SettingsScope::AppLocal)
+ {
+ if (variableName == settings::Quotes::randomQuotesList) {
+ quotesString = variableValue;
+ }
+ else if (variableName == settings::Quotes::randomQuoteIDUpdateTime) {
+ timestampString = variableValue;
+ }
+ }
+ std::string getValue(const std::string &variableName,
+ settings::SettingsScope scope = settings::SettingsScope::AppLocal)
+ {
+ if (variableName == settings::Quotes::randomQuotesList) {
+ return quotesString;
+ }
+ else if (variableName == settings::Quotes::randomQuoteIDUpdateTime) {
+ return timestampString;
+ }
+ else {
+ return std::string();
+ }
+ }
+ std::string "esString;
+ std::string ×tampString;
+ };
+
} // namespace Quotes
M products/PurePhone/services/db/ServiceDB.cpp => products/PurePhone/services/db/ServiceDB.cpp +6 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <db/ServiceDB.hpp>
@@ 245,10 245,8 @@ sys::ReturnCodes ServiceDB::InitHandler()
countryCodeRecordInterface = std::make_unique<CountryCodeRecordInterface>(countryCodesDB.get());
notificationsRecordInterface =
std::make_unique<NotificationsRecordInterface>(notificationsDB.get(), contactRecordInterface.get());
- quotesRecordInterface = std::make_unique<Quotes::QuotesAgent>(quotesDB.get());
multimediaFilesRecordInterface =
std::make_unique<db::multimedia_files::MultimediaFilesRecordInterface>(multimediaFilesDB.get());
-
databaseAgents.emplace(std::make_unique<SettingsAgent>(this, "settings_v2.db"));
for (auto &dbAgent : databaseAgents) {
@@ 256,6 254,11 @@ sys::ReturnCodes ServiceDB::InitHandler()
dbAgent->registerMessages();
}
+ auto settings = std::make_unique<settings::Settings>();
+ settings->init(service::ServiceProxy(shared_from_this()));
+
+ quotesRecordInterface = std::make_unique<Quotes::QuotesAgent>(quotesDB.get(), std::move(settings));
+
return sys::ReturnCodes::Success;
}