diff --git a/src/plugin/CMakeLists.txt b/src/plugin/CMakeLists.txt index c69d0a97d..e0b17fe1a 100644 --- a/src/plugin/CMakeLists.txt +++ b/src/plugin/CMakeLists.txt @@ -699,7 +699,7 @@ set(src__prenote prenote/PlayNewPrenoteMessageSound.cpp prenote/PlayNewPrenoteMessageSound.h prenote/SendNewPrenoteChatAreaMessage.cpp prenote/SendNewPrenoteChatAreaMessage.h prenote/PrenoteIsTargetedToUser.cpp prenote/PrenoteIsTargetedToUser.h - prenote/PrenoteUserRelevanceChecker.h prenote/SendPrenoteCancelledChatAreaMessage.cpp prenote/SendPrenoteCancelledChatAreaMessage.h prenote/PrenoteIsSentFromUsersPosition.cpp prenote/PrenoteIsSentFromUsersPosition.h prenote/SendPrenoteAcknowledgedChatAreaMessage.cpp prenote/SendPrenoteAcknowledgedChatAreaMessage.h) + prenote/PrenoteUserRelevanceChecker.h prenote/SendPrenoteCancelledChatAreaMessage.cpp prenote/SendPrenoteCancelledChatAreaMessage.h prenote/PrenoteIsSentFromUsersPosition.cpp prenote/PrenoteIsSentFromUsersPosition.h prenote/SendPrenoteAcknowledgedChatAreaMessage.cpp prenote/SendPrenoteAcknowledgedChatAreaMessage.h prenote/SendPrenoteTimeoutChatAreaMessage.cpp prenote/SendPrenoteTimeoutChatAreaMessage.h) source_group("src\\prenote" FILES ${src__prenote}) set(src__push diff --git a/src/plugin/prenote/PrenoteMessageCollection.cpp b/src/plugin/prenote/PrenoteMessageCollection.cpp index bd0ce1014..afd0efdd4 100644 --- a/src/plugin/prenote/PrenoteMessageCollection.cpp +++ b/src/plugin/prenote/PrenoteMessageCollection.cpp @@ -52,11 +52,16 @@ namespace UKControllerPlugin::Prenote { } } - void - PrenoteMessageCollection::RemoveWhere(const std::function&)>& predicate) + void PrenoteMessageCollection::RemoveWhere( + const std::function&)>& predicate, + const std::function& onRemove) { for (auto prenote = this->prenotes.cbegin(); prenote != this->prenotes.cend();) { if (predicate(*prenote)) { + if (onRemove) { + onRemove(**prenote); + } + prenote = this->prenotes.erase(prenote); } else { ++prenote; diff --git a/src/plugin/prenote/PrenoteMessageCollection.h b/src/plugin/prenote/PrenoteMessageCollection.h index e424fa0a1..d093c0552 100644 --- a/src/plugin/prenote/PrenoteMessageCollection.h +++ b/src/plugin/prenote/PrenoteMessageCollection.h @@ -17,7 +17,9 @@ namespace UKControllerPlugin::Prenote { [[nodiscard]] auto GetById(int id) -> const std::shared_ptr&; void Iterate(const std::function&)>& function); void Remove(int id); - void RemoveWhere(const std::function&)>& predicate); + void RemoveWhere( + const std::function&)>& predicate, + const std::function& onRemove = {}); private: [[nodiscard]] auto GetByIdUnsafe(int id) -> const std::shared_ptr&; diff --git a/src/plugin/prenote/PrenoteMessageEventHandlerCollection.cpp b/src/plugin/prenote/PrenoteMessageEventHandlerCollection.cpp index d28f7341e..20927b28f 100644 --- a/src/plugin/prenote/PrenoteMessageEventHandlerCollection.cpp +++ b/src/plugin/prenote/PrenoteMessageEventHandlerCollection.cpp @@ -28,6 +28,14 @@ namespace UKControllerPlugin::Prenote { handler->MessageAcknowledged(message); } } + + void PrenoteMessageEventHandlerCollection::MessageTimeout(const PrenoteMessage& message) const + { + for (const auto& handler : handlers) { + handler->MessageTimeout(message); + } + } + auto PrenoteMessageEventHandlerCollection::CountHandlers() const -> size_t { return handlers.size(); diff --git a/src/plugin/prenote/PrenoteMessageEventHandlerCollection.h b/src/plugin/prenote/PrenoteMessageEventHandlerCollection.h index 4e8a91ca0..9d3e44e47 100644 --- a/src/plugin/prenote/PrenoteMessageEventHandlerCollection.h +++ b/src/plugin/prenote/PrenoteMessageEventHandlerCollection.h @@ -15,6 +15,7 @@ namespace UKControllerPlugin::Prenote { void MessageAcknowledged(const PrenoteMessage& message) const; void MessageCancelled(const PrenoteMessage& message) const; void NewMessage(const PrenoteMessage& message) const; + void MessageTimeout(const PrenoteMessage& message) const; private: // All the handlers diff --git a/src/plugin/prenote/PrenoteMessageEventHandlerInterface.h b/src/plugin/prenote/PrenoteMessageEventHandlerInterface.h index 88f828eac..0e4a1d81f 100644 --- a/src/plugin/prenote/PrenoteMessageEventHandlerInterface.h +++ b/src/plugin/prenote/PrenoteMessageEventHandlerInterface.h @@ -21,5 +21,9 @@ namespace UKControllerPlugin::Prenote { virtual void MessageAcknowledged(const PrenoteMessage& message) { } + + virtual void MessageTimeout(const PrenoteMessage& message) + { + } }; } // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PrenoteMessageTimeout.cpp b/src/plugin/prenote/PrenoteMessageTimeout.cpp index 77bf25a41..5b44ed840 100644 --- a/src/plugin/prenote/PrenoteMessageTimeout.cpp +++ b/src/plugin/prenote/PrenoteMessageTimeout.cpp @@ -1,5 +1,6 @@ #include "PrenoteMessage.h" #include "PrenoteMessageCollection.h" +#include "PrenoteMessageEventHandlerCollection.h" #include "PrenoteMessageTimeout.h" #include "time/SystemClock.h" @@ -7,17 +8,22 @@ using UKControllerPlugin::Time::TimeNow; namespace UKControllerPlugin::Prenote { - PrenoteMessageTimeout::PrenoteMessageTimeout(std::shared_ptr messages) - : messages(std::move(messages)) + PrenoteMessageTimeout::PrenoteMessageTimeout( + std::shared_ptr messages, const PrenoteMessageEventHandlerCollection& eventHandlers) + : messages(std::move(messages)), eventHandlers(eventHandlers) { } void PrenoteMessageTimeout::TimedEventTrigger() { - this->messages->RemoveWhere([](const std::shared_ptr& message) -> bool { - return message->IsAcknowledged() - ? message->GetAcknowledgedAt() < TimeNow() - std::chrono::minutes(ACKNOWLEDGED_PRENOTE_TIMEOUT) - : message->GetExpiresAt() < TimeNow(); - }); + this->messages->RemoveWhere( + [](const std::shared_ptr& message) -> bool { + return message->IsAcknowledged() ? message->GetAcknowledgedAt() < + TimeNow() - std::chrono::minutes(ACKNOWLEDGED_PRENOTE_TIMEOUT) + : message->GetExpiresAt() < TimeNow(); + }, + [this](const PrenoteMessage& message) { + eventHandlers.MessageTimeout(message); + }); } } // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PrenoteMessageTimeout.h b/src/plugin/prenote/PrenoteMessageTimeout.h index 3dcb6c208..8449b9686 100644 --- a/src/plugin/prenote/PrenoteMessageTimeout.h +++ b/src/plugin/prenote/PrenoteMessageTimeout.h @@ -3,17 +3,23 @@ namespace UKControllerPlugin::Prenote { class PrenoteMessageCollection; + class PrenoteMessageEventHandlerCollection; class PrenoteMessageTimeout : public UKControllerPlugin::TimedEvent::AbstractTimedEvent { public: - explicit PrenoteMessageTimeout(std::shared_ptr messages); + explicit PrenoteMessageTimeout( + std::shared_ptr messages, + const PrenoteMessageEventHandlerCollection& eventHandlers); void TimedEventTrigger() override; private: // Collection of prenote messages const std::shared_ptr messages; + // Handlers of prenote events + const PrenoteMessageEventHandlerCollection& eventHandlers; + static const int ACKNOWLEDGED_PRENOTE_TIMEOUT = 10; }; } // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PrenoteModule.cpp b/src/plugin/prenote/PrenoteModule.cpp index ad49dd534..d09c32dea 100644 --- a/src/plugin/prenote/PrenoteModule.cpp +++ b/src/plugin/prenote/PrenoteModule.cpp @@ -21,6 +21,7 @@ #include "SendPrenoteAcknowledgedChatAreaMessage.h" #include "SendPrenoteCancelledChatAreaMessage.h" #include "SendPrenoteMenu.h" +#include "SendPrenoteTimeoutChatAreaMessage.h" #include "TriggerPrenoteMessageStatusView.h" #include "bootstrap/BootstrapWarningMessage.h" #include "bootstrap/PersistenceContainer.h" @@ -96,6 +97,8 @@ namespace UKControllerPlugin::Prenote { userTargetPrenoteRelevance, *persistence.plugin, *persistence.pluginUserSettingHandler)); persistence.prenoteMessageHandlers->AddHandler(std::make_shared( userSendingPrenoteRelevance, *persistence.plugin, *persistence.pluginUserSettingHandler)); + persistence.prenoteMessageHandlers->AddHandler(std::make_shared( + userSendingPrenoteRelevance, *persistence.plugin, *persistence.pluginUserSettingHandler)); // Push event processors persistence.pushEventProcessors->AddProcessor(std::make_shared( @@ -105,7 +108,8 @@ namespace UKControllerPlugin::Prenote { persistence.pushEventProcessors->AddProcessor(std::make_shared( persistence.prenotes, *persistence.prenoteMessageHandlers)); persistence.timedHandler->RegisterEvent( - std::make_shared(persistence.prenotes), MESSAGE_TIMEOUT_CHECK_INTERVAL); + std::make_shared(persistence.prenotes, *persistence.prenoteMessageHandlers), + MESSAGE_TIMEOUT_CHECK_INTERVAL); // Status indicator tag item persistence.tagHandler->RegisterTagItem( diff --git a/src/plugin/prenote/SendPrenoteTimeoutChatAreaMessage.cpp b/src/plugin/prenote/SendPrenoteTimeoutChatAreaMessage.cpp new file mode 100644 index 000000000..707c9df39 --- /dev/null +++ b/src/plugin/prenote/SendPrenoteTimeoutChatAreaMessage.cpp @@ -0,0 +1,42 @@ +#include "PrenoteMessage.h" +#include "PrenoteUserRelevanceChecker.h" +#include "SendPrenoteTimeoutChatAreaMessage.h" +#include "controller/ControllerPosition.h" +#include "euroscope/EuroscopePluginLoopbackInterface.h" +#include "euroscope/GeneralSettingsEntries.h" +#include "euroscope/UserSetting.h" + +namespace UKControllerPlugin::Prenote { + + SendPrenoteTimeoutChatAreaMessage::SendPrenoteTimeoutChatAreaMessage( + std::shared_ptr prenoteRelevance, + Euroscope::EuroscopePluginLoopbackInterface& plugin, + Euroscope::UserSetting& userSettings) + : prenoteRelevance(prenoteRelevance), plugin(plugin), userSettings(userSettings) + { + assert(prenoteRelevance && "Prenote relevance is nullptr"); + } + + void SendPrenoteTimeoutChatAreaMessage::MessageTimeout(const PrenoteMessage& message) + { + if (message.IsAcknowledged() || !UserWantsChatAreaMessages() || !prenoteRelevance->IsRelevant(message)) { + return; + } + + plugin.ChatAreaMessage( + "UKCP_COORDINATION", + "UKCP", + "Prenote message to " + message.GetTargetController()->GetCallsign() + " for " + message.GetCallsign() + + " has timed out without acknowledgement.", + true, + true, + true, + true, + true); + } + + auto SendPrenoteTimeoutChatAreaMessage::UserWantsChatAreaMessages() const -> bool + { + return userSettings.GetBooleanEntry(Euroscope::GeneralSettingsEntries::prenoteChatAreaMessagesSettingsKey); + } +} // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/SendPrenoteTimeoutChatAreaMessage.h b/src/plugin/prenote/SendPrenoteTimeoutChatAreaMessage.h new file mode 100644 index 000000000..0798c8c14 --- /dev/null +++ b/src/plugin/prenote/SendPrenoteTimeoutChatAreaMessage.h @@ -0,0 +1,32 @@ +#pragma once +#include "PrenoteMessageEventHandlerInterface.h" + +namespace UKControllerPlugin::Euroscope { + class EuroscopePluginLoopbackInterface; + class UserSetting; +} // namespace UKControllerPlugin::Euroscope + +namespace UKControllerPlugin::Prenote { + class PrenoteUserRelevanceChecker; + + class SendPrenoteTimeoutChatAreaMessage : public PrenoteMessageEventHandlerInterface + { + public: + SendPrenoteTimeoutChatAreaMessage( + std::shared_ptr prenoteRelevance, + Euroscope::EuroscopePluginLoopbackInterface& plugin, + Euroscope::UserSetting& userSettings); + void MessageTimeout(const PrenoteMessage& message) override; + + private: + [[nodiscard]] auto UserWantsChatAreaMessages() const -> bool; + // Checks relevance of prenotes + const std::shared_ptr prenoteRelevance; + + // For sending messages + Euroscope::EuroscopePluginLoopbackInterface& plugin; + + // User settings + Euroscope::UserSetting& userSettings; + }; +} // namespace UKControllerPlugin::Prenote diff --git a/test/plugin/CMakeLists.txt b/test/plugin/CMakeLists.txt index 12f8a1de2..234606c01 100644 --- a/test/plugin/CMakeLists.txt +++ b/test/plugin/CMakeLists.txt @@ -451,7 +451,7 @@ set(test__prenote prenote/PrenoteIsTargetedToUserTest.cpp prenote/SendNewPrenoteChatAreaMessageTest.cpp prenote/SendPrenoteCancelledChatAreaMessageTest.cpp - prenote/PrenoteIsSentFromUserPositionTest.cpp prenote/SendPrenoteAcknowledgedChatAreaMessageTest.cpp) + prenote/PrenoteIsSentFromUserPositionTest.cpp prenote/SendPrenoteAcknowledgedChatAreaMessageTest.cpp prenote/SendPrenoteTimeoutChatAreaMessageTest.cpp) source_group("test\\prenote" FILES ${test__prenote}) set(test__push diff --git a/test/plugin/mock/MockPrenoteMessageEventHandlerInterface.h b/test/plugin/mock/MockPrenoteMessageEventHandlerInterface.h index b9175c8a1..7aea485ab 100644 --- a/test/plugin/mock/MockPrenoteMessageEventHandlerInterface.h +++ b/test/plugin/mock/MockPrenoteMessageEventHandlerInterface.h @@ -12,5 +12,6 @@ namespace UKControllerPluginTest::Prenote { MOCK_METHOD(void, NewMessage, (const PrenoteMessage&), (override)); MOCK_METHOD(void, MessageCancelled, (const PrenoteMessage&), (override)); MOCK_METHOD(void, MessageAcknowledged, (const PrenoteMessage&), (override)); + MOCK_METHOD(void, MessageTimeout, (const PrenoteMessage&), (override)); }; } // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/prenote/AcknowledgePrenoteMessageTest.cpp b/test/plugin/prenote/AcknowledgePrenoteMessageTest.cpp index 52f19fd47..689d96ee5 100644 --- a/test/plugin/prenote/AcknowledgePrenoteMessageTest.cpp +++ b/test/plugin/prenote/AcknowledgePrenoteMessageTest.cpp @@ -39,7 +39,7 @@ namespace UKControllerPluginTest::Prenote { userPosition = std::make_shared( 2, "LON_S_CTR", 129.420, std::vector{"EGKK"}, true, false, true); callsigns.AddUserCallsign(ActiveCallsign("LON_S_CTR", "Test", *userPosition, true)); - + // Add the prenotes collection->Add(std::make_shared( 1, "BAW123", "EGGD", "BADIM1X", "EGLL", sendingPosition, userPosition, TimeNow())); diff --git a/test/plugin/prenote/NewPrenotePushEventHandlerTest.cpp b/test/plugin/prenote/NewPrenotePushEventHandlerTest.cpp index 77614fa6c..9fa63fe0c 100644 --- a/test/plugin/prenote/NewPrenotePushEventHandlerTest.cpp +++ b/test/plugin/prenote/NewPrenotePushEventHandlerTest.cpp @@ -96,7 +96,7 @@ namespace UKControllerPluginTest::Prenote { TEST_F(NewPrenotePushEventHandlerTest, ItAddsPrenoteFromMessageWithOptionalData) { EXPECT_CALL(*mockHandler, NewMessage(testing::_)).Times(1); - + this->handler.ProcessPushEvent(MakePushEvent(nlohmann::json{ {"departure_sid", nlohmann::json::value_t::null}, {"destination_airfield", nlohmann::json::value_t::null}, @@ -123,11 +123,11 @@ namespace UKControllerPluginTest::Prenote { EXPECT_EQ(1, this->messages->Count()); EXPECT_TRUE(this->messages->GetById(1)->IsAcknowledged()); } - + TEST_F(NewPrenotePushEventHandlerTest, ItTriggersNewMessageEventIfPrenoteExists) { EXPECT_CALL(*mockHandler, NewMessage(testing::_)).Times(2); - + this->handler.ProcessPushEvent(MakePushEvent()); this->messages->GetById(1)->Acknowledge(); this->handler.ProcessPushEvent(MakePushEvent()); diff --git a/test/plugin/prenote/PrenoteDeletedPushEventHandlerTest.cpp b/test/plugin/prenote/PrenoteDeletedPushEventHandlerTest.cpp index aadf93c6c..f8622e154 100644 --- a/test/plugin/prenote/PrenoteDeletedPushEventHandlerTest.cpp +++ b/test/plugin/prenote/PrenoteDeletedPushEventHandlerTest.cpp @@ -24,8 +24,8 @@ namespace UKControllerPluginTest::Prenote { receivingPosition = std::make_shared( 2, "EGKK_F_APP", 124.225, std::vector{"EGKK"}, true, false); this->messages->Add(std::make_shared( - 1,+ - "BAW123", + 1, + +"BAW123", "EGGD", "BADIM1X", "EGLL", diff --git a/test/plugin/prenote/PrenoteMessageCollectionTest.cpp b/test/plugin/prenote/PrenoteMessageCollectionTest.cpp index acf82894e..9a4c1077b 100644 --- a/test/plugin/prenote/PrenoteMessageCollectionTest.cpp +++ b/test/plugin/prenote/PrenoteMessageCollectionTest.cpp @@ -21,7 +21,9 @@ namespace UKControllerPluginTest::Prenote { message1 = std::make_shared( 1, "BAW123", "EGGD", "BADIM1X", "EGLL", sendingPosition, receivingPosition, TimeNow()); message2 = std::make_shared( - 5, "BAW456", "EGGD", "BADIM1X", "EGLL", sendingPosition, receivingPosition, TimeNow()); + 5, "BAW456", "EGGD", "BADIM1X", "EGKK", sendingPosition, receivingPosition, TimeNow()); + message3 = std::make_shared( + 3, "BAW456", "EGGD", "BADIM1X", "EGLL", sendingPosition, receivingPosition, TimeNow()); } std::shared_ptr sendingPosition; @@ -29,6 +31,7 @@ namespace UKControllerPluginTest::Prenote { PrenoteMessageCollection collection; std::shared_ptr message1; std::shared_ptr message2; + std::shared_ptr message3; }; TEST_F(PrenoteMessageCollectionTest, ItStartsEmpty) @@ -128,4 +131,18 @@ namespace UKControllerPluginTest::Prenote { EXPECT_EQ(0, collection.Count()); EXPECT_EQ(nullptr, collection.GetById(5)); } + + TEST_F(PrenoteMessageCollectionTest, ItemsRemovedByPredicateArePassedToCallback) + { + std::vector prenoteIds; + collection.Add(message1); + collection.Add(message2); + collection.Add(message3); + collection.RemoveWhere( + [](const std::shared_ptr& message) { return message->GetDestinationAirfield() == "EGLL"; }, + [&prenoteIds](const PrenoteMessage& message) { prenoteIds.push_back(message.GetId()); }); + + EXPECT_EQ(1, collection.Count()); + EXPECT_EQ(std::vector({1, 3}), prenoteIds); + } } // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/prenote/PrenoteMessageEventHandlerCollectionTest.cpp b/test/plugin/prenote/PrenoteMessageEventHandlerCollectionTest.cpp index c63c7387f..d759ff881 100644 --- a/test/plugin/prenote/PrenoteMessageEventHandlerCollectionTest.cpp +++ b/test/plugin/prenote/PrenoteMessageEventHandlerCollectionTest.cpp @@ -75,4 +75,21 @@ namespace UKControllerPluginTest::Prenote { collection.MessageAcknowledged(message); } + + TEST_F(PrenoteMessageEventHandlerCollectionTest, ItProcessesTimeoutMessageEvent) + { + auto handler1 = std::make_shared>(); + auto handler2 = std::make_shared>(); + collection.AddHandler(handler1); + collection.AddHandler(handler2); + + const PrenoteMessage message( + 1, "BAW123", "EGKK", "TEST1A", "EGLL", nullptr, nullptr, std::chrono::system_clock::now()); + + EXPECT_CALL(*handler1, MessageTimeout(testing::Ref(message))).Times(1); + + EXPECT_CALL(*handler2, MessageTimeout(testing::Ref(message))).Times(1); + + collection.MessageTimeout(message); + } } // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/prenote/PrenoteMessageTimeoutTest.cpp b/test/plugin/prenote/PrenoteMessageTimeoutTest.cpp index 6d21704d0..4d0384afb 100644 --- a/test/plugin/prenote/PrenoteMessageTimeoutTest.cpp +++ b/test/plugin/prenote/PrenoteMessageTimeoutTest.cpp @@ -1,12 +1,14 @@ #include "controller/ControllerPosition.h" #include "prenote/PrenoteMessage.h" #include "prenote/PrenoteMessageCollection.h" +#include "prenote/PrenoteMessageEventHandlerCollection.h" #include "prenote/PrenoteMessageTimeout.h" #include "time/SystemClock.h" using UKControllerPlugin::Controller::ControllerPosition; using UKControllerPlugin::Prenote::PrenoteMessage; using UKControllerPlugin::Prenote::PrenoteMessageCollection; +using UKControllerPlugin::Prenote::PrenoteMessageEventHandlerCollection; using UKControllerPlugin::Prenote::PrenoteMessageTimeout; using UKControllerPlugin::Time::SetTestNow; using UKControllerPlugin::Time::TimeNow; @@ -15,7 +17,8 @@ namespace UKControllerPluginTest::Prenote { class PrenoteMessageTimeoutTest : public ::testing::Test { public: - PrenoteMessageTimeoutTest() : messages(std::make_shared()), timeout(messages) + PrenoteMessageTimeoutTest() + : messages(std::make_shared()), timeout(messages, eventHandlers) { SetTestNow(TimeNow()); sendingPosition = std::make_shared( @@ -63,8 +66,14 @@ namespace UKControllerPluginTest::Prenote { messages->Add(message2); messages->Add(message3); messages->Add(message4); + + // Prenote event handlers + mockHandler = std::make_shared>(); + eventHandlers.AddHandler(mockHandler); } + std::shared_ptr> mockHandler; + PrenoteMessageEventHandlerCollection eventHandlers; std::shared_ptr sendingPosition; std::shared_ptr receivingPosition; std::shared_ptr messages; @@ -77,18 +86,32 @@ namespace UKControllerPluginTest::Prenote { TEST_F(PrenoteMessageTimeoutTest, ItPreservesNonAcknowledgedNonExpiredMessages) { + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message1))).Times(0); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message2))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message3))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message4))).Times(1); + timeout.TimedEventTrigger(); EXPECT_EQ(message1, messages->GetById(1)); } TEST_F(PrenoteMessageTimeoutTest, ItRemovesNonAcknowledgedExpiredMessages) { + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message2))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message3))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message4))).Times(1); + timeout.TimedEventTrigger(); EXPECT_EQ(nullptr, messages->GetById(2)); } TEST_F(PrenoteMessageTimeoutTest, ItPreservesMessagesAcknowledgedInThePastTenMinutes) { + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message1))).Times(0); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message2))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message3))).Times(0); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message4))).Times(1); + auto timeBefore = TimeNow(); SetTestNow(TimeNow() - std::chrono::minutes(9)); message3->Acknowledge(); @@ -99,6 +122,10 @@ namespace UKControllerPluginTest::Prenote { TEST_F(PrenoteMessageTimeoutTest, ItRemovesMessagesAcknowledgedMoreThanTenMinutesAgo) { + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message2))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message3))).Times(1); + EXPECT_CALL(*mockHandler, MessageTimeout(testing::Ref(*message4))).Times(1); + auto timeBefore = TimeNow(); SetTestNow(TimeNow() - std::chrono::minutes(11)); message4->Acknowledge(); diff --git a/test/plugin/prenote/PrenoteModuleTest.cpp b/test/plugin/prenote/PrenoteModuleTest.cpp index 377982479..eea5c7a39 100644 --- a/test/plugin/prenote/PrenoteModuleTest.cpp +++ b/test/plugin/prenote/PrenoteModuleTest.cpp @@ -146,7 +146,7 @@ namespace UKControllerPluginTest::Prenote { TEST_F(PrenoteModuleTest, ItRegistersPrenoteMessageEventHandlerCollectionWithContainer) { PrenoteModule::BootstrapPlugin(container, dependency); - EXPECT_EQ(4, container.prenoteMessageHandlers->CountHandlers()); + EXPECT_EQ(5, container.prenoteMessageHandlers->CountHandlers()); } TEST_F(PrenoteModuleTest, ItRegistersRenderables) diff --git a/test/plugin/prenote/SendPrenoteTimeoutChatAreaMessageTest.cpp b/test/plugin/prenote/SendPrenoteTimeoutChatAreaMessageTest.cpp new file mode 100644 index 000000000..09807909e --- /dev/null +++ b/test/plugin/prenote/SendPrenoteTimeoutChatAreaMessageTest.cpp @@ -0,0 +1,120 @@ +#include "controller/ControllerPosition.h" +#include "euroscope/UserSetting.h" +#include "prenote/PrenoteMessage.h" +#include "prenote/SendPrenoteTimeoutChatAreaMessage.h" + +using UKControllerPlugin::Controller::ControllerPosition; +using UKControllerPlugin::Euroscope::UserSetting; +using UKControllerPlugin::Prenote::PrenoteMessage; +using UKControllerPlugin::Prenote::SendPrenoteTimeoutChatAreaMessage; + +namespace UKControllerPluginTest::Prenote { + class SendPrenoteTimeoutChatAreaMessageTest : public testing::Test + { + public: + SendPrenoteTimeoutChatAreaMessageTest() + : userSettings(userSettingProvider), + mockPrenoteRelevance(std::make_shared>()), + sendMessage(mockPrenoteRelevance, plugin, userSettings) + { + sendingPosition = std::make_shared( + 1, "EGKK_TWR", 124.225, std::vector{"EGKK"}, true, false); + receivingPosition = std::make_shared( + 2, "EGKK_F_APP", 124.225, std::vector{"EGKK"}, true, false); + } + + testing::NiceMock userSettingProvider; + UserSetting userSettings; + std::shared_ptr sendingPosition; + std::shared_ptr receivingPosition; + std::shared_ptr> mockPrenoteRelevance; + testing::NiceMock plugin; + SendPrenoteTimeoutChatAreaMessage sendMessage; + }; + + TEST_F(SendPrenoteTimeoutChatAreaMessageTest, ItSendsChatAreaMessageOnPrenoteMessageTimedOut) + { + ON_CALL(userSettingProvider, KeyExists("sendPrenotesToChat")).WillByDefault(testing::Return(true)); + ON_CALL(userSettingProvider, GetKey("sendPrenotesToChat")).WillByDefault(testing::Return("1")); + const PrenoteMessage message( + 1, + "BAW123", + "EGKK", + "TEST1A", + "EGLL", + sendingPosition, + receivingPosition, + std::chrono::system_clock::now()); + EXPECT_CALL( + plugin, + ChatAreaMessage( + "UKCP_COORDINATION", + "UKCP", + "Prenote message to EGKK_F_APP for BAW123 has timed out without acknowledgement.", + true, + true, + true, + true, + true)) + .Times(1); + EXPECT_CALL(*mockPrenoteRelevance, IsRelevant(testing::Ref(message))).Times(1).WillOnce(testing::Return(true)); + sendMessage.MessageTimeout(message); + } + + TEST_F(SendPrenoteTimeoutChatAreaMessageTest, ItDoesntSendMessageIfPrenoteHasBeenAcknowledged) + { + ON_CALL(userSettingProvider, KeyExists("sendPrenotesToChat")).WillByDefault(testing::Return(true)); + ON_CALL(userSettingProvider, GetKey("sendPrenotesToChat")).WillByDefault(testing::Return("1")); + + PrenoteMessage message( + 1, + "BAW123", + "EGKK", + "TEST1A", + "EGLL", + sendingPosition, + receivingPosition, + std::chrono::system_clock::now()); + message.Acknowledge(); + EXPECT_CALL(plugin, ChatAreaMessage).Times(0); + EXPECT_CALL(*mockPrenoteRelevance, IsRelevant(testing::Ref(message))).Times(0); + sendMessage.MessageTimeout(message); + } + + TEST_F(SendPrenoteTimeoutChatAreaMessageTest, ItDoesntSendMessageIfNotUserDoesntWantMessages) + { + ON_CALL(userSettingProvider, KeyExists("sendPrenotesToChat")).WillByDefault(testing::Return(true)); + ON_CALL(userSettingProvider, GetKey("sendPrenotesToChat")).WillByDefault(testing::Return("0")); + + const PrenoteMessage message( + 1, + "BAW123", + "EGKK", + "TEST1A", + "EGLL", + sendingPosition, + receivingPosition, + std::chrono::system_clock::now()); + EXPECT_CALL(plugin, ChatAreaMessage).Times(0); + EXPECT_CALL(*mockPrenoteRelevance, IsRelevant(testing::Ref(message))).Times(0); + sendMessage.MessageTimeout(message); + } + + TEST_F(SendPrenoteTimeoutChatAreaMessageTest, ItDoesntSendMessageIfNotRelevantToController) + { + ON_CALL(userSettingProvider, KeyExists("sendPrenotesToChat")).WillByDefault(testing::Return(true)); + ON_CALL(userSettingProvider, GetKey("sendPrenotesToChat")).WillByDefault(testing::Return("1")); + const PrenoteMessage message( + 1, + "BAW123", + "EGKK", + "TEST1A", + "EGLL", + sendingPosition, + receivingPosition, + std::chrono::system_clock::now()); + EXPECT_CALL(plugin, ChatAreaMessage).Times(0); + EXPECT_CALL(*mockPrenoteRelevance, IsRelevant(testing::Ref(message))).Times(1).WillOnce(testing::Return(false)); + sendMessage.MessageTimeout(message); + } +} // namespace UKControllerPluginTest::Prenote