From 1340e6949c0762585b0de844863c91c859fb19b1 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Wed, 15 Feb 2023 15:55:00 +0100 Subject: [PATCH] Revert "[MOS-578] Fix incorrect logic with SMS notifications" This reverts commit de99e12e000c89088a6d9e79cac3cf2d2e73a90c. --- .../ApplicationMessages.cpp | 38 +- .../models/SMSThreadModel.cpp | 8 +- module-db/Database/Database.cpp | 3 +- module-db/Interface/NotificationsRecord.cpp | 26 +- module-db/Interface/NotificationsRecord.hpp | 5 +- .../QueryNotificationsDecrement.cpp | 10 +- .../QueryNotificationsDecrement.hpp | 7 +- module-db/tests/CMakeLists.txt | 1 + module-db/tests/NotificationsRecord_tests.cpp | 397 ++++++++++++++++++ pure_changelog.md | 1 - 10 files changed, 433 insertions(+), 63 deletions(-) create mode 100644 module-db/tests/NotificationsRecord_tests.cpp diff --git a/module-apps/application-messages/ApplicationMessages.cpp b/module-apps/application-messages/ApplicationMessages.cpp index 06b12f9ee0de77b0fc8d6faa0082da21f80c3cda..c4330adc2c5f2388f7f75ca4a86c6a177a5db89e 100644 --- a/module-apps/application-messages/ApplicationMessages.cpp +++ b/module-apps/application-messages/ApplicationMessages.cpp @@ -175,10 +175,10 @@ namespace app this, db::Interface::Name::SMSThread, std::make_unique(record->ID, MarkAsRead::Read::True)); if (record->unreadMsgCount) { - DBServiceAPI::GetQuery(this, - db::Interface::Name::Notifications, - std::make_unique( - NotificationsRecord::Key::Sms, record->numberID, record->unreadMsgCount)); + DBServiceAPI::GetQuery( + this, + db::Interface::Name::Notifications, + std::make_unique(NotificationsRecord::Key::Sms, record->unreadMsgCount)); } return true; } @@ -230,23 +230,21 @@ namespace app auto query = std::make_unique(record.ID); auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMSThread); - task->setCallback( - [this, threadId = record.ID, unreadMsgCount = record.unreadMsgCount, numberID = record.numberID]( - auto response) { - const auto result = dynamic_cast(response); - if ((result != nullptr) && result->success()) { - if (unreadMsgCount) { - DBServiceAPI::GetQuery(this, - db::Interface::Name::Notifications, - std::make_unique( - NotificationsRecord::Key::Sms, numberID, unreadMsgCount)); - } - switchWindow(gui::name::window::main_window); - return true; + task->setCallback([this, threadId = record.ID, unreadMsgCount = record.unreadMsgCount](auto response) { + const auto result = dynamic_cast(response); + if ((result != nullptr) && result->success()) { + if (unreadMsgCount) { + DBServiceAPI::GetQuery(this, + db::Interface::Name::Notifications, + std::make_unique( + NotificationsRecord::Key::Sms, unreadMsgCount)); } - LOG_ERROR("ThreadRemove id=%" PRIu32 " failed", threadId); - return false; - }); + switchWindow(gui::name::window::main_window); + return true; + } + LOG_ERROR("ThreadRemove id=%" PRIu32 " failed", threadId); + return false; + }); task->execute(this, this); return true; } diff --git a/module-apps/application-messages/models/SMSThreadModel.cpp b/module-apps/application-messages/models/SMSThreadModel.cpp index bbf3e1e4404a609433985a1343df72ea297ace41..e6655ee678e5b7d5b882c15bbf0dbdf8739c94a3 100644 --- a/module-apps/application-messages/models/SMSThreadModel.cpp +++ b/module-apps/application-messages/models/SMSThreadModel.cpp @@ -150,10 +150,10 @@ void SMSThreadModel::markCurrentThreadAsRead() db::Interface::Name::SMSThread, std::make_unique(smsThreadID, db::query::MarkAsRead::Read::True)); - DBServiceAPI::GetQuery(application, - db::Interface::Name::Notifications, - std::make_unique( - NotificationsRecord::Key::Sms, numberID, unreadMsgCount)); + DBServiceAPI::GetQuery( + application, + db::Interface::Name::Notifications, + std::make_unique(NotificationsRecord::Key::Sms, unreadMsgCount)); } } } diff --git a/module-db/Database/Database.cpp b/module-db/Database/Database.cpp index 6bedf291324b2d7abc77867f1a12f20fb1b184dc..a8c99b59208cb15e31663232cf23673702ebdfd7 100644 --- a/module-db/Database/Database.cpp +++ b/module-db/Database/Database.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, 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 "Database.hpp" @@ -166,6 +166,7 @@ std::unique_ptr Database::query(const char *format, ...) va_start(ap, format); sqlite3_vsnprintf(maxQueryLen, queryStatementBuffer, format, ap); va_end(ap); + auto queryResult = std::make_unique(); if (const int result = sqlite3_exec(dbConnection, queryStatementBuffer, queryCallback, queryResult.get(), nullptr); result != SQLITE_OK) { diff --git a/module-db/Interface/NotificationsRecord.cpp b/module-db/Interface/NotificationsRecord.cpp index 44351d15f3c11a64318b3f4f3bcc3891108efc2f..9a36e5f471e76bf24fde4d0a7a8e5ac105f5743c 100644 --- a/module-db/Interface/NotificationsRecord.cpp +++ b/module-db/Interface/NotificationsRecord.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, 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 "NotificationsRecord.hpp" @@ -182,7 +182,7 @@ std::unique_ptr NotificationsRecordIn std::unique_ptr NotificationsRecordInterface::runQueryImpl( const db::query::notifications::Decrement *query) { - auto ret = processDecrement(query->getKey(), query->getNumberID(), query->getCount()); + auto ret = processDecrement(query->getKey(), query->getCount()); return std::make_unique(ret); } @@ -211,7 +211,6 @@ std::unique_ptr NotificationsRecordInterf if (auto record = GetByKey(query->getKey()); record.isValid()) { record.value = 0; record.contactRecord.reset(); - unreadMsgNumberIDs.clear(); ret = Update(record); } return std::make_unique(ret); @@ -242,10 +241,6 @@ bool NotificationsRecordInterface::processIncrement(NotificationsRecord::Key key numberMatch.value().contactId != currentContactRecord.value().ID) { currentContactRecord.reset(); } - if (key == NotificationsRecord::Key::Sms && - std::find(unreadMsgNumberIDs.begin(), unreadMsgNumberIDs.end(), numberMatch.value().numberId) == - unreadMsgNumberIDs.end()) - unreadMsgNumberIDs.push_back(numberMatch.value().numberId); } else { currentContactRecord.reset(); @@ -261,9 +256,7 @@ bool NotificationsRecordInterface::processIncrement(NotificationsRecord::Key key return ret; } -bool NotificationsRecordInterface::processDecrement(const NotificationsRecord::Key key, - const std::uint32_t numberID, - const size_t delta) +bool NotificationsRecordInterface::processDecrement(NotificationsRecord::Key key, size_t delta) { auto ret = false; @@ -271,22 +264,9 @@ bool NotificationsRecordInterface::processDecrement(const NotificationsRecord::K if (delta >= record.value) { record.contactRecord.reset(); record.value = 0; - if (key == NotificationsRecord::Key::Sms) { - unreadMsgNumberIDs.clear(); - } } else { record.value -= delta; - if (key == NotificationsRecord::Key::Sms) { - unreadMsgNumberIDs.erase(std::remove_if(unreadMsgNumberIDs.begin(), - unreadMsgNumberIDs.end(), - [numberID](std::uint32_t value) { return numberID == value; }), - unreadMsgNumberIDs.end()); - if (unreadMsgNumberIDs.size() == 1) { - auto contactRecord = contactsDb->GetByNumberID(unreadMsgNumberIDs.at(0)); - record.contactRecord = std::move(contactRecord); - } - } } ret = Update(record); diff --git a/module-db/Interface/NotificationsRecord.hpp b/module-db/Interface/NotificationsRecord.hpp index f9b1a7e75a0f95609d06facb8c8c3ca48c4df534..0026371966e40dbc4707c68f85347c22f4ecb37b 100644 --- a/module-db/Interface/NotificationsRecord.hpp +++ b/module-db/Interface/NotificationsRecord.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, 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 @@ -84,7 +84,6 @@ class NotificationsRecordInterface : public RecordInterface unreadMsgNumberIDs; std::optional getContactRecord(uint32_t id) const; std::unique_ptr runQueryImpl(const db::query::notifications::Get *query); @@ -99,5 +98,5 @@ class NotificationsRecordInterface : public RecordInterface &&number, size_t size); - [[nodiscard]] bool processDecrement(NotificationsRecord::Key key, std::uint32_t numberID, size_t size); + [[nodiscard]] bool processDecrement(NotificationsRecord::Key key, size_t size); }; diff --git a/module-db/queries/notifications/QueryNotificationsDecrement.cpp b/module-db/queries/notifications/QueryNotificationsDecrement.cpp index a5b266c29eabea757fcb4311834c5b30649c8941..3e356565c1f0c207647a024c93ea998707970a2c 100644 --- a/module-db/queries/notifications/QueryNotificationsDecrement.cpp +++ b/module-db/queries/notifications/QueryNotificationsDecrement.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023, 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 "QueryNotificationsDecrement.hpp" namespace db::query::notifications { - Decrement::Decrement(NotificationsRecord::Key key, size_t numberID, const size_t count) - : Query(Query::Type::Update), key(key), count(count), numberID(numberID) + Decrement::Decrement(NotificationsRecord::Key key, const size_t count) + : Query(Query::Type::Update), key(key), count(count) {} auto Decrement::getKey() const noexcept -> NotificationsRecord::Key @@ -22,10 +22,6 @@ namespace db::query::notifications { return "Decrement"; } - auto Decrement::getNumberID() const noexcept -> size_t - { - return numberID; - } DecrementResult::DecrementResult(bool ret) : ret(ret) {} diff --git a/module-db/queries/notifications/QueryNotificationsDecrement.hpp b/module-db/queries/notifications/QueryNotificationsDecrement.hpp index 177e7fbc615c12a59b3eccf69d93ef869262d553..590a67e6ebf9866fe50fbda9f6ae6cabc31038be 100644 --- a/module-db/queries/notifications/QueryNotificationsDecrement.hpp +++ b/module-db/queries/notifications/QueryNotificationsDecrement.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, 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 @@ -15,14 +15,13 @@ namespace db::query::notifications { const NotificationsRecord::Key key; const size_t count; - size_t numberID = 0; public: - Decrement(NotificationsRecord::Key key, size_t numberID, size_t count); + Decrement(NotificationsRecord::Key key, const size_t count); [[nodiscard]] auto getKey() const noexcept -> NotificationsRecord::Key; [[nodiscard]] auto getCount() const noexcept -> size_t; - [[nodiscard]] auto getNumberID() const noexcept -> size_t; + [[nodiscard]] auto debugInfo() const -> std::string override; }; diff --git a/module-db/tests/CMakeLists.txt b/module-db/tests/CMakeLists.txt index 5bacae2ba79e423fd1902fbecb6635b393698995..cb6cb59a076e06be2a16393f5e5e0bfb9d74fd0a 100644 --- a/module-db/tests/CMakeLists.txt +++ b/module-db/tests/CMakeLists.txt @@ -21,6 +21,7 @@ add_catch2_executable( MultimediaFilesTable_tests.cpp NotesRecord_tests.cpp NotesTable_tests.cpp + NotificationsRecord_tests.cpp NotificationsTable_tests.cpp QueryInterface.cpp SMSRecord_tests.cpp diff --git a/module-db/tests/NotificationsRecord_tests.cpp b/module-db/tests/NotificationsRecord_tests.cpp new file mode 100644 index 0000000000000000000000000000000000000000..75f559da88aae84d54823aae17e2b35ead5a25ad --- /dev/null +++ b/module-db/tests/NotificationsRecord_tests.cpp @@ -0,0 +1,397 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include +#include "Helpers.hpp" +#include +#include +#include +#include "module-db/databases/NotificationsDB.hpp" +#include "module-db/databases/ContactsDB.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +TEST_CASE("Notifications Record tests") +{ + + SECTION("Default Constructor") + { + NotificationsRecord testRec; + REQUIRE_FALSE(testRec.isValid()); + REQUIRE(testRec.ID == DB_ID_NONE); + REQUIRE(testRec.key == NotificationsRecord::Key::NotValidKey); + REQUIRE(testRec.value == 0); + REQUIRE_FALSE(testRec.contactRecord.has_value()); + } + + SECTION("Constructor from NotificationsTableRow") + { + NotificationsTableRow tableRow{ + Record(10), .key = static_cast(NotificationsRecord::Key::Calls), .value = 2}; + NotificationsRecord testRec(tableRow); + REQUIRE(testRec.isValid()); + REQUIRE(testRec.ID == 10); + REQUIRE(testRec.key == NotificationsRecord::Key::Calls); + REQUIRE(testRec.value == 2); + REQUIRE_FALSE(testRec.contactRecord.has_value()); + } + + db::tests::DatabaseUnderTest notificationsDb{"notifications.db", + db::tests::getPurePhoneScriptsPath()}; + db::tests::DatabaseUnderTest contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()}; + + const auto notificationsCount = notificationsDb.get().notifications.count() + 1; + // clear notifications table + for (std::size_t id = 1; id <= notificationsCount; id++) { + REQUIRE(notificationsDb.get().notifications.removeById(id)); + } + + ContactRecordInterface contactRecordInterface(&contactsDb.get()); + NotificationsRecordInterface notificationsRecordInterface(¬ificationsDb.get(), &contactRecordInterface); + REQUIRE(contactRecordInterface.GetCount() == 0); + REQUIRE(notificationsRecordInterface.GetCount() == 0); + + NotificationsTableRow callsRow{ + Record(DB_ID_NONE), .key = static_cast(NotificationsRecord::Key::Calls), .value = 0}; + + REQUIRE(notificationsDb.get().notifications.add(callsRow)); + + NotificationsTableRow smsRow{ + Record(DB_ID_NONE), .key = static_cast(NotificationsRecord::Key::Sms), .value = 0}; + + REQUIRE(notificationsDb.get().notifications.add(smsRow)); + NotificationsRecord testRec; + auto numberOfNotifcations = notificationsRecordInterface.GetCount(); + REQUIRE(numberOfNotifcations == 2); // calls and sms notifications + + SECTION("Get entry by ID") + { + auto callsNotifications = notificationsRecordInterface.GetByID(1); + REQUIRE(callsNotifications.isValid()); + REQUIRE(callsNotifications.ID == 1); + REQUIRE(callsNotifications.key == NotificationsRecord::Key::Calls); + REQUIRE(callsNotifications.value == 0); + REQUIRE_FALSE(callsNotifications.contactRecord.has_value()); + + auto smsNotifications = notificationsRecordInterface.GetByID(2); + REQUIRE(smsNotifications.isValid()); + REQUIRE(smsNotifications.ID == 2); + REQUIRE(smsNotifications.key == NotificationsRecord::Key::Sms); + REQUIRE(smsNotifications.value == 0); + REQUIRE_FALSE(smsNotifications.contactRecord.has_value()); + } + + SECTION("Get entry by key") + { + auto callsNotifications = notificationsRecordInterface.GetByKey(NotificationsRecord::Key::Calls); + REQUIRE(callsNotifications.isValid()); + REQUIRE(callsNotifications.ID == 1); + REQUIRE(callsNotifications.key == NotificationsRecord::Key::Calls); + REQUIRE(callsNotifications.value == 0); + + auto smsNotifications = notificationsRecordInterface.GetByKey(NotificationsRecord::Key::Sms); + REQUIRE(smsNotifications.isValid()); + REQUIRE(smsNotifications.ID == 2); + REQUIRE(smsNotifications.key == NotificationsRecord::Key::Sms); + REQUIRE(smsNotifications.value == 0); + } + + SECTION("Get entry - invalid ID") + { + auto entry = notificationsRecordInterface.GetByID(100); + REQUIRE_FALSE(entry.isValid()); + REQUIRE(entry.ID == DB_ID_NONE); + REQUIRE(entry.key == NotificationsRecord::Key::NotValidKey); + REQUIRE(entry.value == 0); + } + + SECTION("Get entry by invalid key") + { + auto callsNotifications = notificationsRecordInterface.GetByKey(NotificationsRecord::Key::NotValidKey); + REQUIRE_FALSE(callsNotifications.isValid()); + REQUIRE(callsNotifications.ID == DB_ID_NONE); + REQUIRE(callsNotifications.key == NotificationsRecord::Key::NotValidKey); + REQUIRE(callsNotifications.value == 0); + + auto smsNotifications = notificationsRecordInterface.GetByKey(NotificationsRecord::Key::NumberOfKeys); + REQUIRE_FALSE(smsNotifications.isValid()); + REQUIRE(smsNotifications.ID == DB_ID_NONE); + REQUIRE(smsNotifications.key == NotificationsRecord::Key::NotValidKey); + REQUIRE(smsNotifications.value == 0); + } + + SECTION("Get entries") + { + SECTION("Get records using valid offset/limit parameters") + { + auto retOffsetLimit = notificationsRecordInterface.GetLimitOffset(0, numberOfNotifcations); + REQUIRE(retOffsetLimit->size() == numberOfNotifcations); + } + + SECTION("Get table rows using bigger limit parameters") + { + auto retOffsetLimit = notificationsRecordInterface.GetLimitOffset(0, 100); + REQUIRE(retOffsetLimit->size() == numberOfNotifcations); + } + + SECTION("Get table rows using invalid offset/limit parameters(should return empty object)") + { + auto retOffsetLimit = notificationsRecordInterface.GetLimitOffset(5, 4); + REQUIRE(retOffsetLimit->size() == 0); + } + + SECTION("0 - get all") + { + auto retOffsetLimit = notificationsRecordInterface.GetLimitOffset(0, 0); + REQUIRE(retOffsetLimit->size() == numberOfNotifcations); + } + } + + SECTION("Entry update value") + { + auto entryPre = notificationsRecordInterface.GetByID(1); + entryPre.value = entryPre.value + 100; + + REQUIRE(notificationsRecordInterface.Update(entryPre)); + + auto entryPost = notificationsRecordInterface.GetByID(1); + REQUIRE(entryPost.ID == entryPre.ID); + REQUIRE(entryPost.key == entryPre.key); + REQUIRE(entryPost.value == entryPre.value); + } + + SECTION("Entry update key") + { + auto entryPre = notificationsRecordInterface.GetByID(1); + entryPre.key = NotificationsRecord::Key::Sms; + + REQUIRE_FALSE(notificationsRecordInterface.Update(entryPre)); + + auto entryPost = notificationsRecordInterface.GetByID(1); + REQUIRE(entryPost.ID == entryPre.ID); + REQUIRE_FALSE(entryPost.key == entryPre.key); + REQUIRE(entryPost.value == entryPre.value); + } + + auto getByKey = [&](NotificationsRecord::Key key, + uint32_t expectedValue, + const std::optional &expectedContactRecord = std::nullopt) { + auto query = std::make_shared(key); + auto ret = notificationsRecordInterface.runQuery(query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + auto record = result->getResult(); + REQUIRE(record.isValid()); + REQUIRE(record.key == key); + REQUIRE(record.value == expectedValue); + REQUIRE(record.contactRecord.has_value() == expectedContactRecord.has_value()); + if (expectedContactRecord.has_value()) { + REQUIRE(record.contactRecord.value().ID == expectedContactRecord.value().ID); + } + }; + + auto incrementByKey = [&](NotificationsRecord::Key key, const std::string &phoneNumber = "+48500500500") { + utils::PhoneNumber number(phoneNumber); + auto query = std::make_shared(key, number.getView()); + auto ret = notificationsRecordInterface.runQuery(query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + REQUIRE(result->getResult()); + }; + + auto decrementByKey = [&](NotificationsRecord::Key key, size_t count = 1) { + auto query = std::make_shared(key, count); + auto ret = notificationsRecordInterface.runQuery(query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + REQUIRE(result->getResult()); + }; + + auto clearByKey = [&](NotificationsRecord::Key key) { + auto query = std::make_shared(key); + auto ret = notificationsRecordInterface.runQuery(query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + REQUIRE(result->getResult()); + }; + + SECTION("Get via query") + { + getByKey(NotificationsRecord::Key::Calls, 0); + getByKey(NotificationsRecord::Key::Sms, 0); + } + + SECTION("Increment via query") + { + auto incrementAndCheckCase = [&](NotificationsRecord::Key key) { + getByKey(key, 0); + incrementByKey(key); + getByKey(key, 1); + incrementByKey(key); + incrementByKey(key); + getByKey(key, 3); + }; + + incrementAndCheckCase(NotificationsRecord::Key::Calls); + incrementAndCheckCase(NotificationsRecord::Key::Sms); + } + + SECTION("Clear via query") + { + auto clearCase = [&](NotificationsRecord::Key key) { + getByKey(key, 0); + for (int i = 0; i < 100; i++) + incrementByKey(key); + getByKey(key, 100); + clearByKey(key); + getByKey(key, 0); + }; + + clearCase(NotificationsRecord::Key::Calls); + clearCase(NotificationsRecord::Key::Sms); + } + + SECTION("Get All via query") + { + auto query = std::make_shared(); + auto ret = notificationsRecordInterface.runQuery(query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + auto records = result->getResult(); + REQUIRE(records->size() == numberOfNotifcations); + } + + SECTION("Notification DB and Contact DB connection tests") + { + const std::string primaryNameTest_1 = "PrimaryTestNameOne"; + const std::string numberUserTest_1 = "600123456"; + ContactRecord testContactRecord_1; + testContactRecord_1.primaryName = primaryNameTest_1; + testContactRecord_1.numbers = + std::vector({ContactRecord::Number(utils::PhoneNumber(numberUserTest_1).getView())}); + + const std::string primaryNameTest_2 = "PrimaryTestNameTwo"; + const std::string numberUserTest_2 = "600600600"; + ContactRecord testContactRecord_2; + testContactRecord_2.primaryName = primaryNameTest_2; + testContactRecord_2.numbers = + std::vector({ContactRecord::Number(utils::PhoneNumber(numberUserTest_2).getView())}); + + REQUIRE(contactRecordInterface.Add(testContactRecord_1)); + REQUIRE(contactRecordInterface.Add(testContactRecord_2)); + + const auto someUnknownNumber = "500200300"; + const auto noNotificationExpected = 0; + const auto contactNotExpected = std::nullopt; + + SECTION("Tests preconditions") + { + getByKey(NotificationsRecord::Key::Calls, noNotificationExpected); + } + + SECTION("Single call notification from unknown number") + { + const auto expectedNotificationValue = 1; + incrementByKey(NotificationsRecord::Key::Calls, someUnknownNumber); + getByKey(NotificationsRecord::Key::Calls, expectedNotificationValue, contactNotExpected); + } + + SECTION("Single call notification from known number") + { + const auto expectedNotificationValue = 1; + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_1); + getByKey(NotificationsRecord::Key::Calls, expectedNotificationValue, testContactRecord_1); + clearByKey(NotificationsRecord::Key::Calls); + getByKey(NotificationsRecord::Key::Calls, noNotificationExpected, contactNotExpected); + } + + SECTION("Multiple call notifications from single known number") + { + const auto expectedNotificationValue = 3; + for (int i = 0; i < expectedNotificationValue; i++) + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_1); + getByKey(NotificationsRecord::Key::Calls, expectedNotificationValue, testContactRecord_1); + clearByKey(NotificationsRecord::Key::Calls); + getByKey(NotificationsRecord::Key::Calls, noNotificationExpected, contactNotExpected); + } + + SECTION("Multiple call notifications from multiple known numbers") + { + const auto expectedNotificationValue = 2 * 3; + for (int i = 0; i < expectedNotificationValue / 2; i++) { + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_1); + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_2); + } + getByKey(NotificationsRecord::Key::Calls, expectedNotificationValue, contactNotExpected); + clearByKey(NotificationsRecord::Key::Calls); + getByKey(NotificationsRecord::Key::Calls, noNotificationExpected, contactNotExpected); + } + + SECTION("Multiple call notifications in sequence of known-unknown-known numbers") + { + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_1); + getByKey(NotificationsRecord::Key::Calls, 1, testContactRecord_1); + + incrementByKey(NotificationsRecord::Key::Calls, someUnknownNumber); + getByKey(NotificationsRecord::Key::Calls, 2, contactNotExpected); + + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_1); + getByKey(NotificationsRecord::Key::Calls, 3, contactNotExpected); + } + + SECTION("Multiple call notifications in sequence of unknown-known-unknown numbers") + { + incrementByKey(NotificationsRecord::Key::Calls, someUnknownNumber); + getByKey(NotificationsRecord::Key::Calls, 1, contactNotExpected); + + incrementByKey(NotificationsRecord::Key::Calls, numberUserTest_1); + getByKey(NotificationsRecord::Key::Calls, 2, contactNotExpected); + + incrementByKey(NotificationsRecord::Key::Calls, someUnknownNumber); + getByKey(NotificationsRecord::Key::Calls, 3, contactNotExpected); + } + + SECTION("Clear SMS notifications from multiple known numbers") + { + const auto expectedNotificationPerContact = 3; + const auto expectedNotificationValue = 2 * expectedNotificationPerContact; + for (int i = 0; i < expectedNotificationValue / 2; i++) { + incrementByKey(NotificationsRecord::Key::Sms, numberUserTest_1); + incrementByKey(NotificationsRecord::Key::Sms, numberUserTest_2); + } + getByKey(NotificationsRecord::Key::Sms, expectedNotificationValue, contactNotExpected); + + decrementByKey(NotificationsRecord::Key::Sms, expectedNotificationPerContact); + getByKey(NotificationsRecord::Key::Sms, expectedNotificationPerContact, contactNotExpected); + + decrementByKey(NotificationsRecord::Key::Sms, expectedNotificationPerContact); + getByKey(NotificationsRecord::Key::Sms, noNotificationExpected, contactNotExpected); + } + + SECTION("Clear SMS notifications overflowing actual count") + { + const auto expectedNotificationPerContact = 3; + const auto expectedNotificationValue = 2 * expectedNotificationPerContact; + for (int i = 0; i < expectedNotificationValue / 2; i++) { + incrementByKey(NotificationsRecord::Key::Sms, numberUserTest_1); + incrementByKey(NotificationsRecord::Key::Sms, numberUserTest_2); + } + getByKey(NotificationsRecord::Key::Sms, expectedNotificationValue, contactNotExpected); + + decrementByKey(NotificationsRecord::Key::Sms, expectedNotificationPerContact + 1); + getByKey(NotificationsRecord::Key::Sms, 2, contactNotExpected); + + decrementByKey(NotificationsRecord::Key::Sms, expectedNotificationPerContact); + getByKey(NotificationsRecord::Key::Sms, noNotificationExpected, contactNotExpected); + } + } +} diff --git a/pure_changelog.md b/pure_changelog.md index d4d515bf65a0bdeafc630045436ce89e9f599463..e7551b17416b67a74f23b82ff41d99d059eb0968 100644 --- a/pure_changelog.md +++ b/pure_changelog.md @@ -65,7 +65,6 @@ * Fixed displaying an incorrect window after double ending a phone call * Fixed templates list not looping * Fixed inability to import contacts from Orange SIM cards -* Fixed SMS notification behaviour when only one thread is unread * Fixed improper asterisk button behavior when adding new contact * Fixed for contacts removed and imported from SIM card once again were added to database without names * Fixed (removed) redundant leading zero from time representation unless exactly midnight