From 4a3f4f6f14bb1000fdb573b6cdb325f933dae186 Mon Sep 17 00:00:00 2001 From: amzn-hdoke <61443753+hdoke@users.noreply.github.com> Date: Fri, 25 Jun 2021 16:36:52 -0700 Subject: [PATCH] [AWS][Attribution] Consent dialog is generated on first launch (#1593) * Adding AWSAttribution Consent panel * Remove commented code * Create AWSCoreAttributionConsentDialog class. Move hard coded strings to static const variables * Remove #pragma from cpp --- .../Editor/EditorPreferencesPageAWS.cpp | 8 +- .../AWSCoreAttributionConsentDialog.h | 26 ++++ .../Attribution/AWSCoreAttributionManager.h | 9 +- .../AWSCoreAttributionConsentDialog.cpp | 44 +++++++ .../Attribution/AWSCoreAttributionManager.cpp | 111 ++++++++++++++---- .../AWSCoreAttributionSystemComponent.cpp | 1 - .../AWSCoreAttributionManagerTest.cpp | 88 +++++++++++--- Gems/AWSCore/Code/awscore_editor_files.cmake | 2 + 8 files changed, 245 insertions(+), 44 deletions(-) create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h create mode 100644 Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConsentDialog.cpp diff --git a/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp b/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp index 5ba4e94d9a..6db7daa92e 100644 --- a/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp +++ b/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp @@ -27,13 +27,13 @@ void CEditorPreferencesPage_AWS::Reflect(AZ::SerializeContext& serialize) if (editContext) { editContext->Class("Options", "") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &UsageOptions::m_awsAttributionEnabled, "Send Metrics usage to AWS", - "Reports Gem usage to AWS on Editor launch"); + ->DataElement(AZ::Edit::UIHandlers::CheckBox, &UsageOptions::m_awsAttributionEnabled, "Allow O3DE to send information about your use of AWS Core Gem to AWS", + ""); editContext->Class("AWS Preferences", "AWS Preferences") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20)) - ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_AWS::m_usageOptions, "AWS Usage Data", "AWS Usage Options"); + ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_AWS::m_usageOptions, "AWS Data Collection and Use", "AWS Data Collection and Use"); } } @@ -52,7 +52,7 @@ CEditorPreferencesPage_AWS::~CEditorPreferencesPage_AWS() const char* CEditorPreferencesPage_AWS::GetTitle() { - return "AWS"; + return "Cloud"; } QIcon& CEditorPreferencesPage_AWS::GetIcon() diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h new file mode 100644 index 0000000000..88ba1b0f9a --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#include + +namespace AWSCore +{ + //! Defines AWSCoreAttributionConsent QT dialog as QT message box. + class AWSCoreAttributionConsentDialog : + public QMessageBox + { + public: + AZ_CLASS_ALLOCATOR(AWSCoreAttributionConsentDialog, AZ::SystemAllocator, 0); + AWSCoreAttributionConsentDialog(); + virtual ~AWSCoreAttributionConsentDialog() = default; + + }; +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h index 2d15688cbd..5e4ad8c965 100644 --- a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h @@ -11,11 +11,13 @@ #include #include +#include namespace AWSCore { //! Manages operational metrics for AWS gems class AWSAttributionManager + : private AzToolsFramework::EditorEvents::Bus::Handler { public: AWSAttributionManager(); @@ -32,16 +34,21 @@ namespace AWSCore virtual void UpdateMetric(AttributionMetric& metric); void UpdateLastSend(); void SetApiEndpointAndRegion(ServiceAPI::AWSAttributionRequestJob::Config* config); + virtual void ShowConsentDialog(); private: bool ShouldGenerateMetric() const; - + bool CheckAWSCredentialsConfigured(); + bool CheckConsentShown(); AZStd::string GetEngineVersion() const; AZStd::string GetPlatform() const; void GetActiveAWSGems(AZStd::vector& gemNames); void SaveSettingsRegistryFile(); + // AzToolsFramework::EditorEvents interface implementation + void NotifyMainWindowInitialized(QMainWindow* mainWindow) override; + AZStd::unique_ptr m_settingsRegistry; }; diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConsentDialog.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConsentDialog.cpp new file mode 100644 index 0000000000..d67c53f389 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConsentDialog.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include + +namespace AWSCore +{ + constexpr const char* AWSAttributionConsentDialogTitle = "AWS Core Gem Usage Agreement"; + constexpr const char* AWSAttributionConsentDialogMessage = "The AWS Core Gem has detected credentials for an Amazon Web Services account for this
\ + instance of O3DE. Click here to learn more about AWS integration, including how to
\ + manage your AWS credentials.

\ + Please note: when credentials are detected, AWS Core Gem sends telemetry data to AWS,
\ + which helps us improve AWS services for O3DE. You can change this setting below, and at
\ + any time in Settings: Global Preferences. Data sent is subject to the AWS Privacy Policy.
\ + Click here to learn more about what data is sent to AWS."; + + constexpr const char* AWSAttributionConsentDialogCheckboxText = "Please share the information about my use of AWS Core Gem with AWS."; + + AWSCoreAttributionConsentDialog::AWSCoreAttributionConsentDialog() + { + this->setWindowTitle(AWSAttributionConsentDialogTitle); + this->setText(AWSAttributionConsentDialogMessage); + QCheckBox* checkBox = new QCheckBox(AWSAttributionConsentDialogCheckboxText); + checkBox->setChecked(true); + this->setCheckBox(checkBox); + this->setStandardButtons(QMessageBox::Save | QMessageBox::Cancel); + this->setDefaultButton(QMessageBox::Save); + this->button(QMessageBox::Cancel)->hide(); + this->setIcon(QMessageBox::Information); + QGridLayout* layout = (QGridLayout*)this->layout(); + if (layout) + { + layout->setVerticalSpacing(20); + layout->setHorizontalSpacing(10); + } + } +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp index b5788fdc17..c649e509be 100644 --- a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -19,10 +20,10 @@ #include #include #include +#include #include -#include - +#include namespace AWSCore @@ -34,6 +35,7 @@ namespace AWSCore constexpr char AWSAttributionEnabledKey[] = "/Amazon/AWS/Preferences/AWSAttributionEnabled"; constexpr char AWSAttributionDelaySecondsKey[] = "/Amazon/AWS/Preferences/AWSAttributionDelaySeconds"; constexpr char AWSAttributionLastTimeStampKey[] = "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"; + constexpr char AWSAttributionConsentShown[] = "/Amazon/AWS/Preferences/AWSAttributionConsentShown"; constexpr char AWSAttributionApiId[] = "2zxvvmv8d7"; constexpr char AWSAttributionChinaApiId[] = ""; constexpr char AWSAttributionApiStage[] = "prod"; @@ -42,19 +44,49 @@ namespace AWSCore AWSAttributionManager::AWSAttributionManager() { m_settingsRegistry = AZStd::make_unique(); + AzToolsFramework::EditorEvents::Bus::Handler::BusConnect(); } AWSAttributionManager::~AWSAttributionManager() { + AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); m_settingsRegistry.reset(); } void AWSAttributionManager::Init() { + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "File IO is not initialized."); + + // Resolve path to editor_aws_preferences.setreg + AZStd::string editorAWSPreferencesFilePath = + AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName); + AZStd::array resolvedPathAWSPreference{}; + if (!fileIO->ResolvePath(editorAWSPreferencesFilePath.c_str(), resolvedPathAWSPreference.data(), resolvedPathAWSPreference.size())) + { + AZ_Warning("AWSAttributionManager", false, "Error resolving path %s", resolvedPathAWSPreference.data()); + return; + } + + if (fileIO->Exists(resolvedPathAWSPreference.data())) + { + m_settingsRegistry->MergeSettingsFile( + resolvedPathAWSPreference.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + } } void AWSAttributionManager::MetricCheck() { + if (!CheckAWSCredentialsConfigured()) + { + return; + } + + if (!CheckConsentShown()) + { + ShowConsentDialog(); + } + if (ShouldGenerateMetric()) { // Gather metadata and assemble metric @@ -67,30 +99,12 @@ namespace AWSCore } bool AWSAttributionManager::ShouldGenerateMetric() const - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO, "File IO is not initialized."); - - // Resolve path to editor_aws_preferences.setreg - AZStd::string editorAWSPreferencesFilePath = - AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName); - AZStd::array resolvedPathAWSPreference{}; - if (!fileIO->ResolvePath(editorAWSPreferencesFilePath.c_str(), resolvedPathAWSPreference.data(), resolvedPathAWSPreference.size())) - { - AZ_Warning("AWSAttributionManager", false, "Error resolving path %s", resolvedPathAWSPreference.data()); - return false; - } - - if (fileIO->Exists(resolvedPathAWSPreference.data())) - { - m_settingsRegistry->MergeSettingsFile(resolvedPathAWSPreference.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); - } - + { bool awsAttributionEnabled = false; if (!m_settingsRegistry->Get(awsAttributionEnabled, AWSAttributionEnabledKey)) { - // If not found default to sending the metric. - awsAttributionEnabled = true; + AZ_Warning("AWSAttributionManager", false, "Key %s should be set by consent window", AWSAttributionEnabledKey); + return false; } if (!awsAttributionEnabled) @@ -124,6 +138,50 @@ namespace AWSCore return false; } + bool AWSAttributionManager::CheckAWSCredentialsConfigured() + { + AWSCore::AWSCredentialResult credentialResult; + AWSCore::AWSCredentialRequestBus::BroadcastResult(credentialResult, &AWSCore::AWSCredentialRequests::GetCredentialsProvider); + if (credentialResult.result) + { + std::shared_ptr provider = credentialResult.result; + auto creds = provider->GetAWSCredentials(); + if (!creds.IsEmpty()) + { + return true; + } + } + return false; + } + + void AWSAttributionManager::ShowConsentDialog() + { + AWSCoreAttributionConsentDialog* msgBox = aznew AWSCoreAttributionConsentDialog(); + int ret = msgBox->exec(); + m_settingsRegistry->Set(AWSAttributionConsentShown, true); + switch (ret) + { + case QMessageBox::Save: + m_settingsRegistry->Set(AWSAttributionEnabledKey, msgBox->checkBox()); + break; + case QMessageBox::Cancel: + default: + m_settingsRegistry->Set(AWSAttributionEnabledKey, false); + break; + } + + SaveSettingsRegistryFile(); + delete msgBox; + } + + // Waiting on Editor QT main window to be initialized before showing consent window. + // This will have the Editor loading screen in the background when showing consent dialog. + void AWSAttributionManager::NotifyMainWindowInitialized(QMainWindow* mainWindow) + { + AZ_UNUSED(mainWindow); + MetricCheck(); + } + void AWSAttributionManager::SaveSettingsRegistryFile() { AZ::Job* job = AZ::CreateJobFunction( @@ -199,6 +257,13 @@ namespace AWSCore AWSResourceMappingUtils::FormatRESTApiUrl(apiId, config->region.value().c_str(), AWSAttributionApiStage).c_str(); } + bool AWSAttributionManager::CheckConsentShown() + { + bool consentShown = false; + m_settingsRegistry->Get(consentShown, AWSAttributionConsentShown); + return consentShown; + } + AZStd::string AWSAttributionManager::GetEngineVersion() const { AZStd::string engineVersion; diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp index 8a0f8a5790..e19f899905 100644 --- a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp @@ -64,7 +64,6 @@ namespace AWSCore void AWSAttributionSystemComponent::Activate() { - m_manager->MetricCheck(); } void AWSAttributionSystemComponent::Deactivate() diff --git a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp index a99c1b3015..b151596d48 100644 --- a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp +++ b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -102,6 +103,30 @@ namespace AWSAttributionUnitTest MOCK_METHOD1(IsModuleLoaded, bool(const char* modulePath)); }; + class AWSCredentialRquestsBusMock + : public AWSCore::AWSCredentialRequestBus::Handler + { + public: + AWSCredentialRquestsBusMock() + { + m_provider = std::make_shared("TestAccessKey", "TestSecreKey", "TestSession"); + AWSCore::AWSCredentialRequestBus::Handler::BusConnect(); + ON_CALL(*this, GetCredentialsProvider()).WillByDefault(testing::Return(m_provider)); + ON_CALL(*this, GetCredentialHandlerOrder()).WillByDefault(testing::Return(CredentialHandlerOrder::DEFAULT_CREDENTIAL_HANDLER)); + } + + ~AWSCredentialRquestsBusMock() + { + AWSCore::AWSCredentialRequestBus::Handler::BusDisconnect(); + m_provider.reset(); + } + + MOCK_CONST_METHOD0(GetCredentialHandlerOrder, int()); + MOCK_METHOD0(GetCredentialsProvider, std::shared_ptr()); + + std::shared_ptr m_provider; + }; + class AWSAttributionManagerMock : public AWSAttributionManager { @@ -109,7 +134,7 @@ namespace AWSAttributionUnitTest using AWSAttributionManager::SubmitMetric; using AWSAttributionManager::UpdateMetric; using AWSAttributionManager::SetApiEndpointAndRegion; - + using AWSAttributionManager::ShowConsentDialog; AWSAttributionManagerMock() { @@ -117,6 +142,7 @@ namespace AWSAttributionUnitTest } MOCK_METHOD1(SubmitMetric, void(AttributionMetric& metric)); + MOCK_METHOD0(ShowConsentDialog, void()); void SubmitMetricMock(AttributionMetric& metric) { @@ -141,6 +167,7 @@ namespace AWSAttributionUnitTest AZStd::unique_ptr m_jobManager; AZStd::array m_resolvedSettingsPath; ModuleManagerRequestBusMock m_moduleManagerRequestBusMock; + AWSCredentialRquestsBusMock m_credentialRequestBusMock; void SetUp() override { @@ -199,16 +226,16 @@ namespace AWSAttributionUnitTest } }; - TEST_F(AttributionManagerTest, MetricsSettings_AttributionDisabled_SkipsSend) + TEST_F(AttributionManagerTest, MetricsSettings_ConsentShown_AttributionDisabled_SkipsSend) { // GIVEN AWSAttributionManagerMock manager; - manager.Init(); CreateFile(m_resolvedSettingsPath.data(), R"({ "Amazon": { "AWS": { "Preferences": { + "AWSAttributionConsentShown": true, "AWSAttributionEnabled": false, "AWSAttributionDelaySeconds": 30 } @@ -216,8 +243,11 @@ namespace AWSAttributionUnitTest } })"); + manager.Init(); + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(0); EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(0); + EXPECT_CALL(m_credentialRequestBusMock, GetCredentialsProvider()).Times(1); // WHEN manager.MetricCheck(); @@ -231,25 +261,27 @@ namespace AWSAttributionUnitTest RemoveFile(m_resolvedSettingsPath.data()); } - TEST_F(AttributionManagerTest, AttributionEnabled_NoPreviousTimeStamp_SendSuccess) + TEST_F(AttributionManagerTest, AttributionEnabled_ContentShown_NoPreviousTimeStamp_SendSuccess) { // GIVEN AWSAttributionManagerMock manager; - manager.Init(); CreateFile(m_resolvedSettingsPath.data(), R"({ "Amazon": { "AWS": { "Preferences": { + "AWSAttributionConsentShown": true, "AWSAttributionEnabled": true, "AWSAttributionDelaySeconds": 30, } } } })"); + manager.Init(); EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + EXPECT_CALL(m_credentialRequestBusMock, GetCredentialsProvider()).Times(1); // WHEN manager.MetricCheck(); @@ -264,16 +296,16 @@ namespace AWSAttributionUnitTest RemoveFile(m_resolvedSettingsPath.data()); } - TEST_F(AttributionManagerTest, AttributionEnabled_ValidPreviousTimeStamp_SendSuccess) + TEST_F(AttributionManagerTest, AttributionEnabled_ContentShown_ValidPreviousTimeStamp_SendSuccess) { // GIVEN AWSAttributionManagerMock manager; - manager.Init(); CreateFile(m_resolvedSettingsPath.data(), R"({ "Amazon": { "AWS": { "Preferences": { + "AWSAttributionConsentShown": true, "AWSAttributionEnabled": true, "AWSAttributionDelaySeconds": 30, "AWSAttributionLastTimeStamp": 629400 @@ -282,8 +314,11 @@ namespace AWSAttributionUnitTest } })"); + manager.Init(); + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + EXPECT_CALL(m_credentialRequestBusMock, GetCredentialsProvider()).Times(1); // WHEN manager.MetricCheck(); @@ -297,17 +332,16 @@ namespace AWSAttributionUnitTest RemoveFile(m_resolvedSettingsPath.data()); } - TEST_F(AttributionManagerTest, AttributionEnabled_DelayNotSatisfied_SendFail) + TEST_F(AttributionManagerTest, AttributionEnabled_ContentShown_DelayNotSatisfied_SendFail) { // GIVEN AWSAttributionManagerMock manager; - manager.Init(); - CreateFile(m_resolvedSettingsPath.data(), R"({ "Amazon": { "AWS": { "Preferences": { + "AWSAttributionConsentShown": true, "AWSAttributionEnabled": true, "AWSAttributionDelaySeconds": 300, "AWSAttributionLastTimeStamp": 0 @@ -316,11 +350,14 @@ namespace AWSAttributionUnitTest } })"); + manager.Init(); + AZ::u64 delayInSeconds = AZStd::chrono::duration_cast(AZStd::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(m_settingsRegistry->Set("/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp", delayInSeconds)); EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + EXPECT_CALL(m_credentialRequestBusMock, GetCredentialsProvider()).Times(1); // WHEN manager.MetricCheck(); @@ -334,23 +371,26 @@ namespace AWSAttributionUnitTest RemoveFile(m_resolvedSettingsPath.data()); } - TEST_F(AttributionManagerTest, AttributionEnabledNotFound_SendSuccess) + TEST_F(AttributionManagerTest, AttributionEnabledNotFound_ContentShown_SendFail) { // GIVEN AWSAttributionManagerMock manager; - manager.Init(); CreateFile(m_resolvedSettingsPath.data(), R"({ "Amazon": { "AWS": { "Preferences": { + "AWSAttributionConsentShown": true } } } })"); - EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); - EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + manager.Init(); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(0); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(0); + EXPECT_CALL(m_credentialRequestBusMock, GetCredentialsProvider()).Times(1); // WHEN manager.MetricCheck(); @@ -359,11 +399,29 @@ namespace AWSAttributionUnitTest m_settingsRegistry->MergeSettingsFile(m_resolvedSettingsPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); AZ::u64 timeStamp = 0; m_settingsRegistry->Get(timeStamp, "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"); - ASSERT_TRUE(timeStamp != 0); + ASSERT_TRUE(timeStamp == 0); RemoveFile(m_resolvedSettingsPath.data()); } + TEST_F(AttributionManagerTest, AttributionEnabledNotFound_ContentNotShown_SendFail) + { + // GIVEN + AWSAttributionManagerMock manager; + manager.Init(); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(0); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(0); + EXPECT_CALL(m_credentialRequestBusMock, GetCredentialsProvider()).Times(1); + EXPECT_CALL(manager, ShowConsentDialog()).Times(1); + + // WHEN + manager.MetricCheck(); + + // THEN + ASSERT_FALSE(m_localFileIO->Exists(m_resolvedSettingsPath.data())); + } + TEST_F(AttributionManagerTest, SetApiEndpointAndRegion_Success) { // GIVEN diff --git a/Gems/AWSCore/Code/awscore_editor_files.cmake b/Gems/AWSCore/Code/awscore_editor_files.cmake index 8d8661a224..84c58dee67 100644 --- a/Gems/AWSCore/Code/awscore_editor_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_files.cmake @@ -12,6 +12,7 @@ set(FILES Include/Private/Editor/Attribution/AWSCoreAttributionManager.h Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h Include/Private/Editor/Attribution/AWSAttributionServiceApi.h + Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h Include/Private/Editor/AWSCoreEditorManager.h Include/Private/Editor/Constants/AWSCoreEditorMenuLinks.h Include/Private/Editor/Constants/AWSCoreEditorMenuNames.h @@ -23,6 +24,7 @@ set(FILES Source/Editor/Attribution/AWSCoreAttributionManager.cpp Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp Source/Editor/Attribution/AWSAttributionServiceApi.cpp + Source/Editor/Attribution/AWSCoreAttributionConsentDialog.cpp Source/Editor/UI/AWSCoreEditorMenu.cpp Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp )