mirror of
https://github.com/RetroAchievements/RAIntegration.git
synced 2026-10-12 02:09:25 +00:00
1556 lines
68 KiB
C++
1556 lines
68 KiB
C++
#include "CppUnitTest.h"
|
|
|
|
#include "ui\viewmodels\AssetUploadViewModel.hh"
|
|
#include "ui\viewmodels\MessageBoxViewModel.hh"
|
|
|
|
#include "data\models\AchievementModel.hh"
|
|
#include "data\models\GameAssets.hh"
|
|
#include "data\models\LeaderboardModel.hh"
|
|
|
|
#include "tests\ui\UIAsserts.hh"
|
|
#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
|
|
#include "tests\devkit\context\mocks\MockRcClient.hh"
|
|
#include "tests\devkit\context\mocks\MockUserContext.hh"
|
|
#include "tests\devkit\services\mocks\MockLocalStorage.hh"
|
|
#include "tests\devkit\services\mocks\MockThreadPool.hh"
|
|
#include "tests\devkit\testutil\AssetAsserts.hh"
|
|
#include "tests\devkit\testutil\ValueAsserts.hh"
|
|
#include "tests\devkit\ui\mocks\MockImageRepository.hh"
|
|
#include "tests\mocks\MockAchievementRuntime.hh"
|
|
#include "tests\mocks\MockDesktop.hh"
|
|
#include "tests\mocks\MockGameContext.hh"
|
|
#include "tests\mocks\MockServer.hh"
|
|
|
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
|
|
|
namespace ra {
|
|
namespace ui {
|
|
namespace viewmodels {
|
|
namespace tests {
|
|
|
|
using ra::data::models::AchievementModel;
|
|
using ra::data::models::AssetCategory;
|
|
using ra::data::models::AssetChanges;
|
|
using ra::data::models::LeaderboardModel;
|
|
|
|
TEST_CLASS(AssetUploadViewModel_Tests)
|
|
{
|
|
private:
|
|
class AssetUploadViewModelHarness : public AssetUploadViewModel
|
|
{
|
|
public:
|
|
AssetUploadViewModelHarness() noexcept
|
|
{
|
|
GSL_SUPPRESS_F6 mockGameContext.SetGameId(GameId);
|
|
}
|
|
|
|
static constexpr unsigned GameId = 22U;
|
|
|
|
ra::api::mocks::MockServer mockServer;
|
|
ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
|
|
ra::context::mocks::MockRcClient mockRcClient;
|
|
ra::context::mocks::MockUserContext mockUserContext;
|
|
ra::data::context::mocks::MockGameContext mockGameContext;
|
|
ra::services::mocks::MockThreadPool mockThreadPool;
|
|
ra::ui::mocks::MockImageRepository mockImageRepository;
|
|
ra::ui::mocks::MockDesktop mockDesktop;
|
|
|
|
void DoUpload(int nExpectedProgress = 100)
|
|
{
|
|
Assert::AreEqual(std::wstring(), GetMessage());
|
|
Assert::AreEqual(0, GetProgress());
|
|
Assert::AreEqual({ 0U }, mockThreadPool.PendingTasks());
|
|
|
|
// setting visible starts the task threads
|
|
SetIsVisible(true);
|
|
Assert::AreEqual(DialogResult::None, GetDialogResult());
|
|
|
|
Assert::AreEqual(ra::util::String::Printf(L"Uploading %d items...", TaskCount()), GetMessage());
|
|
Assert::AreEqual(0, GetProgress());
|
|
|
|
// "run" the background thread - all pending tasks will be processed in one worker because the threads are virtual
|
|
Assert::AreNotEqual({ 0U }, mockThreadPool.PendingTasks());
|
|
mockThreadPool.ExecuteNextTask();
|
|
|
|
// clean up any other workers that were spawned
|
|
for (size_t i = mockThreadPool.PendingTasks(); i > 0; --i)
|
|
mockThreadPool.ExecuteNextTask();
|
|
|
|
// expect all tasks to have been processed
|
|
Assert::AreEqual(nExpectedProgress, GetProgress());
|
|
|
|
// dialog should automatically close once all tasks are completed
|
|
if (nExpectedProgress == 100)
|
|
Assert::AreEqual(DialogResult::OK, GetDialogResult());
|
|
else
|
|
Assert::AreEqual(DialogResult::Cancel, GetDialogResult());
|
|
|
|
// simulate the hiding - tasks should not restart
|
|
SetIsVisible(false);
|
|
Assert::AreEqual({ 0U }, mockThreadPool.PendingTasks());
|
|
|
|
}
|
|
|
|
AchievementModel& AddAchievement(AssetCategory nCategory, unsigned nPoints, const std::wstring& sTitle,
|
|
const std::wstring& sDescription, const std::wstring& sBadge, const std::string& sTrigger)
|
|
{
|
|
auto vmAchievement = std::make_unique<AchievementModel>();
|
|
if (nCategory == AssetCategory::Local)
|
|
{
|
|
vmAchievement->SetID(gsl::narrow_cast<unsigned>(m_pAssets.Count()) + ra::data::models::GameAssets::FirstLocalId);
|
|
vmAchievement->CreateServerCheckpoint();
|
|
}
|
|
else
|
|
{
|
|
vmAchievement->SetID(gsl::narrow_cast<unsigned>(m_pAssets.Count()) + 1);
|
|
}
|
|
|
|
vmAchievement->SetCategory(nCategory);
|
|
vmAchievement->SetDescription(sDescription);
|
|
vmAchievement->SetPoints(nPoints);
|
|
vmAchievement->SetBadge(sBadge);
|
|
vmAchievement->SetTrigger(sTrigger);
|
|
|
|
if (nCategory != AssetCategory::Local)
|
|
vmAchievement->CreateServerCheckpoint();
|
|
|
|
// set name after creating the server checkpoint so the model appears Unpublished
|
|
vmAchievement->SetName(sTitle);
|
|
|
|
vmAchievement->CreateLocalCheckpoint();
|
|
|
|
return dynamic_cast<AchievementModel&>(m_pAssets.Append(std::move(vmAchievement)));
|
|
}
|
|
|
|
LeaderboardModel& AddLeaderboard(AssetCategory nCategory, const std::wstring& sTitle,
|
|
const std::wstring& sDescription, const std::string& sStartTrigger, const std::string& sSubmitTrigger,
|
|
const std::string& sCancelTrigger, const std::string& sValueDefinition, ra::data::Value::Format nFormat)
|
|
{
|
|
auto vmLeaderboard = std::make_unique<LeaderboardModel>();
|
|
if (nCategory == AssetCategory::Local)
|
|
{
|
|
vmLeaderboard->SetID(gsl::narrow_cast<unsigned>(m_pAssets.Count()) + ra::data::models::GameAssets::FirstLocalId);
|
|
vmLeaderboard->CreateServerCheckpoint();
|
|
}
|
|
else
|
|
{
|
|
vmLeaderboard->SetID(gsl::narrow_cast<unsigned>(m_pAssets.Count()) + 1);
|
|
}
|
|
|
|
vmLeaderboard->SetCategory(nCategory);
|
|
vmLeaderboard->SetName(sTitle);
|
|
vmLeaderboard->SetDescription(sDescription);
|
|
vmLeaderboard->SetStartTrigger(sStartTrigger);
|
|
vmLeaderboard->SetSubmitTrigger(sSubmitTrigger);
|
|
vmLeaderboard->SetCancelTrigger(sCancelTrigger);
|
|
vmLeaderboard->SetValueDefinition(sValueDefinition);
|
|
vmLeaderboard->SetValueFormat(nFormat);
|
|
|
|
if (nCategory != AssetCategory::Local)
|
|
vmLeaderboard->CreateServerCheckpoint();
|
|
|
|
vmLeaderboard->CreateLocalCheckpoint();
|
|
|
|
return dynamic_cast<LeaderboardModel&>(m_pAssets.Append(std::move(vmLeaderboard)));
|
|
}
|
|
|
|
ra::data::models::RichPresenceModel& RichPresence()
|
|
{
|
|
auto* pRichPresence = m_pAssets.FindRichPresence();
|
|
if (pRichPresence == nullptr)
|
|
{
|
|
auto pNewRichPresence = std::make_unique<ra::data::models::RichPresenceModel>();
|
|
pNewRichPresence->SetScript("Display:\nTest\n");
|
|
pNewRichPresence->CreateServerCheckpoint();
|
|
pNewRichPresence->CreateLocalCheckpoint();
|
|
m_pAssets.Append(std::move(pNewRichPresence));
|
|
pRichPresence = m_pAssets.FindRichPresence();
|
|
}
|
|
|
|
return *pRichPresence;
|
|
}
|
|
|
|
ra::data::models::MemoryNotesModel& MemoryNotes()
|
|
{
|
|
auto* pNotes = m_pAssets.FindMemoryNotes();
|
|
if (pNotes == nullptr)
|
|
{
|
|
auto pMemoryNotes = std::make_unique<ra::data::models::MemoryNotesModel>();
|
|
m_pAssets.Append(std::move(pMemoryNotes));
|
|
pNotes = m_pAssets.FindMemoryNotes();
|
|
}
|
|
|
|
return *pNotes;
|
|
}
|
|
|
|
void AssertSuccess(int nItems)
|
|
{
|
|
bool bDialogSeen = false;
|
|
mockDesktop.ResetExpectedWindows();
|
|
mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bDialogSeen, nItems](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
bDialogSeen = true;
|
|
|
|
Assert::AreEqual(std::wstring(L"Publish succeeded."), vmMessageBox.GetHeader());
|
|
|
|
const auto sMessage = ra::util::String::Printf(L"%d items successfully uploaded.", nItems);
|
|
Assert::AreEqual(sMessage, vmMessageBox.GetMessage());
|
|
|
|
return DialogResult::OK;
|
|
});
|
|
|
|
ShowResults();
|
|
|
|
Assert::IsTrue(bDialogSeen);
|
|
}
|
|
|
|
void AssertFailed(int nSuccessfulItems, int nFailedItems, const std::wstring& sFailedDetail)
|
|
{
|
|
bool bDialogSeen = false;
|
|
const auto sMessage = ra::util::String::Printf(L"%d items successfully uploaded.\n\n%d items failed:\n%s", nSuccessfulItems, nFailedItems, sFailedDetail);
|
|
|
|
mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bDialogSeen, &sMessage](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
bDialogSeen = true;
|
|
|
|
Assert::AreEqual(std::wstring(L"Publish failed."), vmMessageBox.GetHeader());
|
|
Assert::AreEqual(sMessage, vmMessageBox.GetMessage());
|
|
|
|
return DialogResult::OK;
|
|
});
|
|
|
|
ShowResults();
|
|
|
|
Assert::IsTrue(bDialogSeen);
|
|
}
|
|
|
|
void AssertAbort(int nSuccessfulItems, int nFailedItems, const std::wstring& sFailedDetail)
|
|
{
|
|
bool bDialogSeen = false;
|
|
auto sMessage = ra::util::String::Printf(L"%d items successfully uploaded.", nSuccessfulItems);
|
|
if (nFailedItems)
|
|
sMessage += ra::util::String::Printf(L"\n\n%d items failed:\n%s", nFailedItems, sFailedDetail);
|
|
|
|
mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bDialogSeen, &sMessage](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
bDialogSeen = true;
|
|
|
|
Assert::AreEqual(std::wstring(L"Publish canceled."), vmMessageBox.GetHeader());
|
|
Assert::AreEqual(sMessage, vmMessageBox.GetMessage());
|
|
|
|
return DialogResult::OK;
|
|
});
|
|
|
|
ShowResults();
|
|
|
|
Assert::IsTrue(bDialogSeen);
|
|
}
|
|
|
|
protected:
|
|
void Rest() const noexcept override {}
|
|
|
|
private:
|
|
ra::data::models::GameAssets m_pAssets;
|
|
};
|
|
|
|
public:
|
|
TEST_METHOD(TestSingleUnpromotedAchievement)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Unpromoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&bApiCalled]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
bApiCalled = true;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(std::wstring(L"Title1"), pRequest.Title);
|
|
Assert::AreEqual(std::wstring(L"Desc1"), pRequest.Description);
|
|
Assert::AreEqual(std::string("0xH1234=1"), pRequest.Trigger);
|
|
Assert::AreEqual(5U, pRequest.Points);
|
|
Assert::AreEqual(std::string("12345"), pRequest.Badge);
|
|
Assert::AreEqual(5U, pRequest.Category);
|
|
Assert::AreEqual(1U, pRequest.AchievementId);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSinglePromotedAchievement)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&bApiCalled]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
bApiCalled = true;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(std::wstring(L"Title1"), pRequest.Title);
|
|
Assert::AreEqual(std::wstring(L"Desc1"), pRequest.Description);
|
|
Assert::AreEqual(std::string("0xH1234=1"), pRequest.Trigger);
|
|
Assert::AreEqual(5U, pRequest.Points);
|
|
Assert::AreEqual(std::string("12345"), pRequest.Badge);
|
|
Assert::AreEqual(3U, pRequest.Category);
|
|
Assert::AreEqual(1U, pRequest.AchievementId);
|
|
Assert::AreEqual(0U, pRequest.Type);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSinglePromotedAchievementMissable)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
pAchievement.SetAchievementType(ra::data::models::AchievementType::Missable);
|
|
pAchievement.UpdateLocalCheckpoint();
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&bApiCalled]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
bApiCalled = true;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(std::wstring(L"Title1"), pRequest.Title);
|
|
Assert::AreEqual(std::wstring(L"Desc1"), pRequest.Description);
|
|
Assert::AreEqual(std::string("0xH1234=1"), pRequest.Trigger);
|
|
Assert::AreEqual(5U, pRequest.Points);
|
|
Assert::AreEqual(std::string("12345"), pRequest.Badge);
|
|
Assert::AreEqual(3U, pRequest.Category);
|
|
Assert::AreEqual(1U, pRequest.AchievementId);
|
|
Assert::AreEqual(1U, pRequest.Type);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleLocalAchievement)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Local, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&bApiCalled]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
bApiCalled = true;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(std::wstring(L"Title1"), pRequest.Title);
|
|
Assert::AreEqual(std::wstring(L"Desc1"), pRequest.Description);
|
|
Assert::AreEqual(std::string("0xH1234=1"), pRequest.Trigger);
|
|
Assert::AreEqual(5U, pRequest.Points);
|
|
Assert::AreEqual(std::string("12345"), pRequest.Badge);
|
|
Assert::AreEqual(5U, pRequest.Category);
|
|
Assert::AreEqual(0U, pRequest.AchievementId);
|
|
|
|
pResponse.AchievementId = 7716U;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
|
|
// published local achievement should be changed to unpromoted and have it's ID updated
|
|
Assert::AreEqual(AssetCategory::Unpromoted, pAchievement.GetCategory());
|
|
Assert::AreEqual(7716U, pAchievement.GetID());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleLocalAchievementSubset)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockGameContext.SetGameId(11U);
|
|
vmUpload.mockGameContext.Assets().AddAchievementSet(22, 33, L"Subset", ra::data::models::AchievementSetType::Bonus);
|
|
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Local, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
pAchievement.SetSubsetID(22U);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({1U}, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>(
|
|
[&bApiCalled](const ra::api::UpdateAchievement::Request& pRequest,
|
|
ra::api::UpdateAchievement::Response& pResponse) {
|
|
bApiCalled = true;
|
|
Assert::AreEqual(33U, pRequest.GameId);
|
|
Assert::AreEqual(std::wstring(L"Title1"), pRequest.Title);
|
|
Assert::AreEqual(std::wstring(L"Desc1"), pRequest.Description);
|
|
Assert::AreEqual(std::string("0xH1234=1"), pRequest.Trigger);
|
|
Assert::AreEqual(5U, pRequest.Points);
|
|
Assert::AreEqual(std::string("12345"), pRequest.Badge);
|
|
Assert::AreEqual(5U, pRequest.Category);
|
|
Assert::AreEqual(0U, pRequest.AchievementId);
|
|
|
|
pResponse.AchievementId = 7716U;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
|
|
// published local achievement should be changed to unpromoted and have it's ID updated
|
|
Assert::AreEqual(AssetCategory::Unpromoted, pAchievement.GetCategory());
|
|
Assert::AreEqual(7716U, pAchievement.GetID());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSinglePromotedAchievementError)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&bApiCalled]
|
|
(const ra::api::UpdateAchievement::Request&, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
bApiCalled = true;
|
|
pResponse.Result = ra::api::ApiResult::Error;
|
|
pResponse.ErrorMessage = "You must be a developer to modify promoted achievements!";
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertFailed(0, 1, L"* Title1: You must be a developer to modify promoted achievements!");
|
|
}
|
|
|
|
TEST_METHOD(TestSinglePromotedAchievementApiErrorTrigger)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement =
|
|
vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
pAchievement.UpdateServerCheckpoint();
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
|
|
pAchievement.SetTrigger(""); // trigger is a required field at the API level
|
|
pAchievement.UpdateLocalCheckpoint();
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({1U}, vmUpload.TaskCount());
|
|
|
|
// mockServer doesn't call the API that would return Error/Invalid state, so update the mockServer
|
|
// to behave as if the failure happened at the API level.
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>(
|
|
[&bApiCalled](const ra::api::UpdateAchievement::Request&, ra::api::UpdateAchievement::Response& pResponse) {
|
|
bApiCalled = true;
|
|
pResponse.Result = ra::api::ApiResult::Error;
|
|
pResponse.ErrorMessage = "Invalid state";
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertFailed(0, 1, L"* Title1: At least one condition is required");
|
|
|
|
// This simulates the failure code in AssetListViewModel::Publish. The test can't be in
|
|
// AssetListViewModel_Tests, because AssetListViewModel_Tests overrides Publish to avoid
|
|
// using the AssetUploadViewModel.
|
|
pAchievement.RestoreLocalCheckpoint();
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
}
|
|
|
|
TEST_METHOD(TestSinglePromotedAchievementApiErrorDescription)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = // description is a required field at the API level
|
|
vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({1U}, vmUpload.TaskCount());
|
|
|
|
// mockServer doesn't call the API that would return Error/Invalid state, so update the mockServer
|
|
// to behave as if the failure happened at the API level.
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>(
|
|
[&bApiCalled](const ra::api::UpdateAchievement::Request&, ra::api::UpdateAchievement::Response& pResponse) {
|
|
bApiCalled = true;
|
|
pResponse.Result = ra::api::ApiResult::Error;
|
|
pResponse.ErrorMessage = "Invalid state";
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.AssertFailed(0, 1, L"* Title1: Description is required");
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievements)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"12345", "0xH1234=1");
|
|
auto& pAchievement3 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title3", L"Desc3", L"12345", "0xH1234=1");
|
|
auto& pAchievement4 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title4", L"Desc4", L"12345", "0xH1234=1");
|
|
auto& pAchievement5 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title5", L"Desc5", L"12345", "0xH1234=1");
|
|
auto& pAchievement6 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title6", L"Desc6", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement3.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement4.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement5.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement6.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
vmUpload.QueueAsset(pAchievement3);
|
|
vmUpload.QueueAsset(pAchievement4);
|
|
vmUpload.QueueAsset(pAchievement5);
|
|
vmUpload.QueueAsset(pAchievement6);
|
|
Assert::AreEqual({ 6U }, vmUpload.TaskCount());
|
|
|
|
int nApiCount = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nApiCount]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nApiCount;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(3U, pRequest.Category);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(6, nApiCount);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement2.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement3.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement4.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement5.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement6.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(6);
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsPartialFailure)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"12345", "0xH1234=1");
|
|
auto& pAchievement3 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title3", L"Desc3", L"12345", "0xH1234=1");
|
|
auto& pAchievement4 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title4", L"Desc4", L"12345", "0xH1234=1");
|
|
auto& pAchievement5 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title5", L"Desc5", L"12345", "0xH1234=1");
|
|
auto& pAchievement6 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title6", L"Desc6", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement3.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement4.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement5.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement6.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
vmUpload.QueueAsset(pAchievement3);
|
|
vmUpload.QueueAsset(pAchievement4);
|
|
vmUpload.QueueAsset(pAchievement5);
|
|
vmUpload.QueueAsset(pAchievement6);
|
|
Assert::AreEqual({ 6U }, vmUpload.TaskCount());
|
|
|
|
int nApiCount = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nApiCount]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nApiCount;
|
|
|
|
if (nApiCount == 4)
|
|
{
|
|
pResponse.Result = ra::api::ApiResult::Failed;
|
|
pResponse.ErrorMessage = "Timeout";
|
|
}
|
|
else
|
|
{
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(6, nApiCount);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement2.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement3.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement4.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement5.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement6.GetChanges());
|
|
|
|
vmUpload.AssertFailed(5, 1, L"* Title4: Timeout");
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsAborted)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"12345", "0xH1234=1");
|
|
auto& pAchievement3 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title3", L"Desc3", L"12345", "0xH1234=1");
|
|
auto& pAchievement4 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title4", L"Desc4", L"12345", "0xH1234=1");
|
|
auto& pAchievement5 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title5", L"Desc5", L"12345", "0xH1234=1");
|
|
auto& pAchievement6 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title6", L"Desc6", L"12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement3.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement4.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement5.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement6.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
vmUpload.QueueAsset(pAchievement3);
|
|
vmUpload.QueueAsset(pAchievement4);
|
|
vmUpload.QueueAsset(pAchievement5);
|
|
vmUpload.QueueAsset(pAchievement6);
|
|
Assert::AreEqual({ 6U }, vmUpload.TaskCount());
|
|
|
|
int nApiCount = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&vmUpload, &nApiCount]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nApiCount;
|
|
|
|
if (nApiCount == 4)
|
|
vmUpload.SetDialogResult(DialogResult::Cancel);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload(50); // fourth item will complete, but isn't tallied
|
|
|
|
Assert::AreEqual(4, nApiCount);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement2.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement3.GetChanges());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement4.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement5.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement6.GetChanges());
|
|
|
|
vmUpload.AssertAbort(4, 0, L"");
|
|
}
|
|
|
|
TEST_METHOD(TestSinglePromotedAchievementWithImage)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bImageUploaded = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&bImageUploaded]
|
|
(const ra::api::UploadBadge::Request& pRequest, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
bImageUploaded = true;
|
|
Assert::AreEqual(std::wstring(L"RACache\\Badges\\local\\12345"), pRequest.ImageFilePath);
|
|
|
|
pResponse.BadgeId = "76543";
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
bool bAchievementUploaded = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&bAchievementUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
bAchievementUploaded = true;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(std::wstring(L"Title1"), pRequest.Title);
|
|
Assert::AreEqual(std::wstring(L"Desc1"), pRequest.Description);
|
|
Assert::AreEqual(std::string("0xH1234=1"), pRequest.Trigger);
|
|
Assert::AreEqual(5U, pRequest.Points);
|
|
Assert::AreEqual(std::string("76543"), pRequest.Badge);
|
|
Assert::AreEqual(3U, pRequest.Category);
|
|
Assert::AreEqual(1U, pRequest.AchievementId);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bImageUploaded);
|
|
Assert::IsTrue(bAchievementUploaded);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"76543"), pAchievement.GetBadge());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsWithImages)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"local\\22222", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
int nImagesUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&nImagesUploaded]
|
|
(const ra::api::UploadBadge::Request& pRequest, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
++nImagesUploaded;
|
|
|
|
if (pRequest.ImageFilePath == L"RACache\\Badges\\local\\12345")
|
|
pResponse.BadgeId = "76543";
|
|
else
|
|
pResponse.BadgeId = "55555";
|
|
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
int nAchievementsUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nAchievementsUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nAchievementsUploaded;
|
|
|
|
if (pRequest.Title == L"Title1")
|
|
Assert::AreEqual(std::string("76543"), pRequest.Badge);
|
|
else
|
|
Assert::AreEqual(std::string("55555"), pRequest.Badge);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(2, nImagesUploaded);
|
|
Assert::AreEqual(2, nAchievementsUploaded);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"76543"), pAchievement1.GetBadge());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement2.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"55555"), pAchievement2.GetBadge());
|
|
|
|
vmUpload.AssertSuccess(2);
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsWithImages429)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"local\\22222", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
int nImagesUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&nImagesUploaded]
|
|
(const ra::api::UploadBadge::Request& pRequest, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
++nImagesUploaded;
|
|
|
|
if (pRequest.ImageFilePath == L"RACache\\Badges\\local\\12345")
|
|
pResponse.BadgeId = "76543";
|
|
else
|
|
pResponse.BadgeId = "55555";
|
|
|
|
if (nImagesUploaded % 2 == 0)
|
|
pResponse.Result = ra::api::ApiResult::Incomplete;
|
|
else
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
int nAchievementsUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nAchievementsUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nAchievementsUploaded;
|
|
|
|
if (pRequest.Title == L"Title1")
|
|
Assert::AreEqual(std::string("76543"), pRequest.Badge);
|
|
else
|
|
Assert::AreEqual(std::string("55555"), pRequest.Badge);
|
|
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
|
|
if (nAchievementsUploaded % 2 == 0)
|
|
pResponse.Result = ra::api::ApiResult::Incomplete;
|
|
else
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(3, nImagesUploaded);
|
|
Assert::AreEqual(3, nAchievementsUploaded);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"76543"), pAchievement1.GetBadge());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement2.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"55555"), pAchievement2.GetBadge());
|
|
|
|
vmUpload.AssertSuccess(2);
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsWithSameImage)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"local\\12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount()); // single task for image upload - that will queue the two achievement tasks
|
|
|
|
int nImagesUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&nImagesUploaded]
|
|
(const ra::api::UploadBadge::Request& pRequest, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
++nImagesUploaded;
|
|
|
|
if (pRequest.ImageFilePath == L"RACache\\Badges\\local\\12345")
|
|
pResponse.BadgeId = "76543";
|
|
else
|
|
pResponse.BadgeId = "55555";
|
|
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
int nAchievementsUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nAchievementsUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nAchievementsUploaded;
|
|
Assert::AreEqual(std::string("76543"), pRequest.Badge);
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(1, nImagesUploaded);
|
|
Assert::AreEqual(2, nAchievementsUploaded);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"76543"), pAchievement1.GetBadge());
|
|
Assert::AreEqual(AssetChanges::None, pAchievement2.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"76543"), pAchievement2.GetBadge());
|
|
|
|
vmUpload.AssertSuccess(2);
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsWithFailedImages)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"local\\22222", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
int nImagesUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&nImagesUploaded]
|
|
(const ra::api::UploadBadge::Request&, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
++nImagesUploaded;
|
|
pResponse.Result = ra::api::ApiResult::Error;
|
|
pResponse.ErrorMessage = "Unsupported image format";
|
|
return true;
|
|
});
|
|
|
|
int nAchievementsUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nAchievementsUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nAchievementsUploaded;
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(2, nImagesUploaded);
|
|
Assert::AreEqual(0, nAchievementsUploaded);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"local\\12345"), pAchievement1.GetBadge());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"local\\22222"), pAchievement2.GetBadge());
|
|
|
|
vmUpload.AssertFailed(0, 2, L"* Title1: Unsupported image format\n* Title2: Unsupported image format");
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsWithSameFailedImage)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"local\\12345", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
int nImagesUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&nImagesUploaded]
|
|
(const ra::api::UploadBadge::Request&, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
++nImagesUploaded;
|
|
pResponse.Result = ra::api::ApiResult::Error;
|
|
pResponse.ErrorMessage = "Unsupported image format";
|
|
return true;
|
|
});
|
|
|
|
int nAchievementsUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nAchievementsUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nAchievementsUploaded;
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(1, nImagesUploaded);
|
|
Assert::AreEqual(0, nAchievementsUploaded);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"local\\12345"), pAchievement1.GetBadge());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"local\\12345"), pAchievement2.GetBadge());
|
|
|
|
vmUpload.AssertFailed(0, 2, L"* Title1: Unsupported image format\n* Title2: Unsupported image format");
|
|
}
|
|
|
|
TEST_METHOD(TestMultiplePromotedAchievementsWithImagesOneFailed)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
auto& pAchievement1 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title1", L"Desc1", L"local\\12345", "0xH1234=1");
|
|
auto& pAchievement2 = vmUpload.AddAchievement(AssetCategory::Promoted, 5, L"Title2", L"Desc2", L"local\\22222", "0xH1234=1");
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement1.GetChanges());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pAchievement2.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pAchievement1);
|
|
vmUpload.QueueAsset(pAchievement2);
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
int nImagesUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UploadBadge>([&nImagesUploaded]
|
|
(const ra::api::UploadBadge::Request& pRequest, ra::api::UploadBadge::Response& pResponse)
|
|
{
|
|
++nImagesUploaded;
|
|
|
|
if (pRequest.ImageFilePath == L"RACache\\Badges\\local\\12345")
|
|
pResponse.BadgeId = "76543";
|
|
else
|
|
pResponse.BadgeId = "55555";
|
|
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
int nAchievementsUploaded = 0;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateAchievement>([&nAchievementsUploaded]
|
|
(const ra::api::UpdateAchievement::Request& pRequest, ra::api::UpdateAchievement::Response& pResponse)
|
|
{
|
|
++nAchievementsUploaded;
|
|
|
|
if (pRequest.Title == L"Title1")
|
|
{
|
|
Assert::AreEqual(std::string("76543"), pRequest.Badge);
|
|
pResponse.AchievementId = pRequest.AchievementId;
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
}
|
|
else
|
|
{
|
|
Assert::AreEqual(std::string("55555"), pRequest.Badge);
|
|
pResponse.Result = ra::api::ApiResult::Error;
|
|
pResponse.ErrorMessage = "Timeout";
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(2, nImagesUploaded);
|
|
Assert::AreEqual(2, nAchievementsUploaded);
|
|
Assert::AreEqual(AssetChanges::None, pAchievement1.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"76543"), pAchievement1.GetBadge());
|
|
|
|
// badge was successfully uploaded, but achievement failed so it should remain modified
|
|
// the AssetListViewModel will follow up with a save local, which will change the state to Unpublished
|
|
Assert::AreEqual(AssetChanges::Modified, pAchievement2.GetChanges());
|
|
Assert::AreEqual(std::wstring(L"55555"), pAchievement2.GetBadge());
|
|
|
|
vmUpload.AssertFailed(1, 1, L"* Title2: Timeout");
|
|
}
|
|
|
|
TEST_METHOD(TestSingleLocalLeaderboard)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
auto& pLeaderboard = vmUpload.AddLeaderboard(AssetCategory::Local, L"Title1", L"Desc1", "0xH1234=1", "0xH1234=2", "0xH1234=3", "0xH2345", ra::data::Value::Format::Score);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pLeaderboard.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pLeaderboard);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=uploadleaderboard&u=User&t=APITOKEN&g=22&n=Title1&d=Desc1&s=0xH1234%3d1&b=0xH1234%3d2&c=0xH1234%3d3&l=0xH2345&w=0&f=SCORE&m=unpromoted&h=b9e48151adc764317296ac777ab550f1",
|
|
"{\"Success\":\"true\",\"LeaderboardID\":7716}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
|
|
// newly published local leaderboard should be changed to unpromoted and have it's ID updated
|
|
Assert::AreEqual(AssetCategory::Unpromoted, pLeaderboard.GetCategory());
|
|
Assert::AreEqual(7716U, pLeaderboard.GetID());
|
|
Assert::AreEqual(AssetChanges::None, pLeaderboard.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleLocalLeaderboardSubset)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.mockGameContext.Assets().AddAchievementSet(22, 33, L"Subset", ra::data::models::AchievementSetType::Bonus);
|
|
auto& pLeaderboard = vmUpload.AddLeaderboard(AssetCategory::Local, L"Title1", L"Desc1", "0xH1234=1",
|
|
"0xH1234=2", "0xH1234=3", "0xH2345", ra::data::Value::Format::Score);
|
|
pLeaderboard.SetSubsetID(22U);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pLeaderboard.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pLeaderboard);
|
|
Assert::AreEqual({1U}, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=uploadleaderboard&u=User&t=APITOKEN&g=33&n=Title1&d=Desc1&s=0xH1234%3d1&b=0xH1234%3d2&c=0xH1234%3d3&l=0xH2345&w=0&f=SCORE&m=unpromoted&h=b9e48151adc764317296ac777ab550f1",
|
|
"{\"Success\":\"true\",\"LeaderboardID\":7716}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
|
|
// newly published local leaderboard should be changed to unpromoted and have it's ID updated
|
|
Assert::AreEqual(AssetCategory::Unpromoted, pLeaderboard.GetCategory());
|
|
Assert::AreEqual(7716U, pLeaderboard.GetID());
|
|
Assert::AreEqual(AssetChanges::None, pLeaderboard.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleLocalLeaderboardNoClaim)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
auto& pLeaderboard = vmUpload.AddLeaderboard(AssetCategory::Local, L"Title1", L"Desc1", "0xH1234=1", "0xH1234=2", "0xH1234=3", "0xH2345", ra::data::Value::Format::Score);
|
|
Assert::AreEqual(AssetChanges::Unpublished, pLeaderboard.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pLeaderboard);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=uploadleaderboard&u=User&t=APITOKEN&g=22&n=Title1&d=Desc1&s=0xH1234%3d1&b=0xH1234%3d2&c=0xH1234%3d3&l=0xH2345&w=0&f=SCORE&m=unpromoted&h=b9e48151adc764317296ac777ab550f1",
|
|
"{\"Success\":false,\"Status\":403,\"Code\":\"access_denied\",\"Error\":\"You must have an active claim on this game to perform this action.\"}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
|
|
// newly published local leaderboard should be changed to unofficial and have it's ID updated
|
|
Assert::AreEqual(AssetCategory::Local, pLeaderboard.GetCategory());
|
|
Assert::AreEqual(AssetChanges::Unpublished, pLeaderboard.GetChanges());
|
|
|
|
vmUpload.AssertFailed(0, 1, L"* Title1: You must have an active claim on this game to perform this action.");
|
|
}
|
|
|
|
TEST_METHOD(TestRichPresence)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
ra::services::mocks::MockAchievementRuntime mockRuntime;
|
|
ra::services::mocks::MockLocalStorage mockStorage;
|
|
mockStorage.MockStoredData(ra::services::StorageItemType::RichPresence, std::to_wstring(vmUpload.GameId), "Display:\nThis is a test.");
|
|
|
|
auto& pRichPresence = vmUpload.RichPresence();
|
|
pRichPresence.ReloadRichPresenceScript();
|
|
Assert::AreEqual(AssetChanges::Unpublished, pRichPresence.GetChanges());
|
|
|
|
vmUpload.QueueAsset(pRichPresence);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
bool bApiCalled = false;
|
|
vmUpload.mockServer.HandleRequest<ra::api::UpdateRichPresence>(
|
|
[&bApiCalled](const ra::api::UpdateRichPresence::Request& pRequest, ra::api::UpdateRichPresence::Response& pResponse)
|
|
{
|
|
bApiCalled = true;
|
|
Assert::AreEqual(AssetUploadViewModelHarness::GameId, pRequest.GameId);
|
|
Assert::AreEqual(std::string("Display:\nThis is a test.\n"), pRequest.Script);
|
|
|
|
pResponse.Result = ra::api::ApiResult::Success;
|
|
return true;
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::IsTrue(bApiCalled);
|
|
Assert::AreEqual(AssetChanges::None, pRichPresence.GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteNew)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"This is a note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
Assert::IsFalse(vmUpload.mockDesktop.WasDialogShown());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:This+is+a+note.%0a",
|
|
"{\"Success\":true,\"SuccessfulAddresses\":[4660]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteNewSubset)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.mockGameContext.Assets().AddAchievementSet(22, 33, L"Subset", ra::data::models::AchievementSetType::Bonus);
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"This is a note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({1U}, vmUpload.TaskCount());
|
|
Assert::IsFalse(vmUpload.mockDesktop.WasDialogShown());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:This+is+a+note.%0a",
|
|
"{\"Success\":true,\"SuccessfulAddresses\":[4660]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteDeleted)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetServerNote(0x1234, L"This is a note.");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
Assert::IsFalse(vmUpload.mockDesktop.WasDialogShown());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:%0a",
|
|
"{\"Success\":true,\"SuccessfulAddresses\":[4660]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteDifferentAuthor)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.SetUsername("Author");
|
|
vmUpload.MemoryNotes().SetServerNote(0x1234, L"Test");
|
|
vmUpload.mockUserContext.SetUsername("Me");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"Test2");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
bool bWindowSeen = false;
|
|
vmUpload.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bWindowSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
Assert::AreEqual(std::wstring(L"Overwrite note for address 0x1234?"), vmMessageBox.GetHeader());
|
|
Assert::AreEqual(std::wstring(L"Are you sure you want to replace Author's note:\n\nTest\n\nWith your note:\n\nTest2"), vmMessageBox.GetMessage());
|
|
Assert::AreEqual(ra::ui::viewmodels::MessageBoxViewModel::Buttons::YesNo, vmMessageBox.GetButtons());
|
|
|
|
bWindowSeen = true;
|
|
return ra::ui::DialogResult::Yes;
|
|
});
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::IsTrue(bWindowSeen);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=Me&t=APITOKEN&g=22&n=4660:Test2%0a",
|
|
"{\"Success\":true,\"SuccessfulAddresses\":[4660]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteDeletedDifferentAuthor)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.SetUsername("Author");
|
|
vmUpload.MemoryNotes().SetServerNote(0x1234, L"Test");
|
|
vmUpload.mockUserContext.SetUsername("Me");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
bool bWindowSeen = false;
|
|
vmUpload.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bWindowSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
Assert::AreEqual(std::wstring(L"Delete note for address 0x1234?"), vmMessageBox.GetHeader());
|
|
Assert::AreEqual(std::wstring(L"Are you sure you want to delete Author's note:\n\nTest"), vmMessageBox.GetMessage());
|
|
Assert::AreEqual(ra::ui::viewmodels::MessageBoxViewModel::Buttons::YesNo, vmMessageBox.GetButtons());
|
|
|
|
bWindowSeen = true;
|
|
return ra::ui::DialogResult::Yes;
|
|
});
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::IsTrue(bWindowSeen);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=Me&t=APITOKEN&g=22&n=4660:%0a",
|
|
"{\"Success\":true,\"SuccessfulAddresses\":[4660]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteDifferentAuthorCancel)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.SetUsername("Author");
|
|
vmUpload.MemoryNotes().SetServerNote(0x1234, L"Test");
|
|
vmUpload.mockUserContext.SetUsername("Me");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"Test2");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
bool bWindowSeen = false;
|
|
vmUpload.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bWindowSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
Assert::AreEqual(std::wstring(L"Overwrite note for address 0x1234?"), vmMessageBox.GetHeader());
|
|
Assert::AreEqual(std::wstring(L"Are you sure you want to replace Author's note:\n\nTest\n\nWith your note:\n\nTest2"), vmMessageBox.GetMessage());
|
|
Assert::AreEqual(ra::ui::viewmodels::MessageBoxViewModel::Buttons::YesNo, vmMessageBox.GetButtons());
|
|
|
|
bWindowSeen = true;
|
|
return ra::ui::DialogResult::No;
|
|
});
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::IsTrue(bWindowSeen);
|
|
Assert::AreEqual({ 0U }, vmUpload.TaskCount());
|
|
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
}
|
|
|
|
TEST_METHOD(TestSingleMemoryNoteDifferentLong)
|
|
{
|
|
std::wstring sLongNote;
|
|
for (int i = 0; i < 48; ++i)
|
|
sLongNote += L"Test" + std::to_wstring(i) + L" ";
|
|
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.SetUsername("Author");
|
|
vmUpload.MemoryNotes().SetServerNote(0x1234, sLongNote);
|
|
vmUpload.mockUserContext.SetUsername("Me");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"Test");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
bool bWindowSeen = false;
|
|
vmUpload.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bWindowSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
|
|
{
|
|
Assert::AreEqual(std::wstring(L"Overwrite note for address 0x1234?"), vmMessageBox.GetHeader());
|
|
Assert::AreEqual(std::wstring(L"Are you sure you want to replace Author's note:\n\n" \
|
|
"Test0 Test1 Test2 Test3 Test4 Test5 Test6 Test7 Test8 Test9 Test10 Test11 Test12 Test13 " \
|
|
"Test14 Test15 Test16 Test17 Test18 Test19 Test20 Test21 Test22 Test23 Test24 Test25 " \
|
|
"Test26 Test27 Test28 Test29 Test30 Test31 Test32 Test33 Test34 Test35 Test36 Test..." \
|
|
"\n\nWith your note:\n\nTest"), vmMessageBox.GetMessage());
|
|
Assert::AreEqual(ra::ui::viewmodels::MessageBoxViewModel::Buttons::YesNo, vmMessageBox.GetButtons());
|
|
|
|
bWindowSeen = true;
|
|
return ra::ui::DialogResult::Yes;
|
|
});
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::IsTrue(bWindowSeen);
|
|
Assert::AreEqual({ 1U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=Me&t=APITOKEN&g=22&n=4660:Test%0a",
|
|
"{\"Success\":true,\"SuccessfulAddresses\":[4660]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(1);
|
|
}
|
|
|
|
TEST_METHOD(TestMultipleMemoryNotes)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"This is a note.");
|
|
vmUpload.MemoryNotes().SetNote(0x1235, L"This is another note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:This+is+a+note.%0a4661:This+is+another+note.%0a",
|
|
"{\"Success\":\"true\",\"SuccessfulAddresses\":[4660,4661]}"
|
|
);
|
|
vmUpload.DoUpload();
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(2);
|
|
}
|
|
|
|
TEST_METHOD(TestMultipleMemoryNotesBatching)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
|
|
constexpr size_t NumNotes = 614;
|
|
for (uint32_t nAddress = 0x1000; nAddress < 0x1000 + NumNotes * 2; nAddress += 2)
|
|
vmUpload.MemoryNotes().SetNote(nAddress, ra::util::String::Printf(L"Note %u", nAddress));
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual(NumNotes, vmUpload.TaskCount());
|
|
|
|
// setting visible starts the workers
|
|
vmUpload.SetIsVisible(true);
|
|
|
|
// this one task should run through all of the note requests
|
|
vmUpload.mockThreadPool.ExecuteNextTask();
|
|
|
|
Assert::AreEqual({ 100 }, vmUpload.GetProgress()); // 100%
|
|
|
|
vmUpload.mockRcClient.AssertNumRequestsHandled(7); // 6 * 100 + 1 * 14
|
|
}
|
|
|
|
TEST_METHOD(TestMultipleMemoryNotesWithNewlines)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"[8-bit]\r\n0=True\r\n1=False");
|
|
vmUpload.MemoryNotes().SetNote(0x1235, L"This is another note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
vmUpload.mockRcClient.MockResponse(
|
|
"r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:%5b8-bit%5d%5cr%5cn0%3dTrue%5cr%5cn1%3dFalse%0a4661:This+is+another+note.%0a",
|
|
"{\"Success\":\"true\",\"SuccessfulAddresses\":[4660,4661]}"
|
|
);
|
|
|
|
vmUpload.DoUpload();
|
|
vmUpload.mockRcClient.AssertNoPendingRequests();
|
|
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(2);
|
|
}
|
|
|
|
TEST_METHOD(TestMultipleMemoryNotes429)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"This is a note.");
|
|
vmUpload.MemoryNotes().SetNote(0x1235, L"This is another note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({2U}, vmUpload.TaskCount());
|
|
|
|
// first response returns 429
|
|
const std::string sApiParams = "r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:This+is+a+note.%0a4661:This+is+another+note.%0a";
|
|
vmUpload.mockRcClient.MockResponse(sApiParams, "{\"Success\":\"true\"}", 429);
|
|
|
|
// second response returns success
|
|
int apiCount = 0;
|
|
vmUpload.mockRcClient.OnBeforeResponse(sApiParams, [&apiCount, &vmUpload, &sApiParams]()
|
|
{
|
|
if (++apiCount == 2)
|
|
vmUpload.mockRcClient.MockResponse(sApiParams, "{\"Success\":\"true\",\"SuccessfulAddresses\":[4660,4661]}");
|
|
});
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
Assert::AreEqual(AssetChanges::None, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.AssertSuccess(2);
|
|
}
|
|
|
|
TEST_METHOD(TestMultipleMemoryNotesCompleteFailure)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"This is a note.");
|
|
vmUpload.MemoryNotes().SetNote(0x1235, L"This is another note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
const std::string sApiParams = "r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:This+is+a+note.%0a4661:This+is+another+note.%0a";
|
|
vmUpload.mockRcClient.MockResponse(sApiParams, "{\"Success\":\"false\",\"Code\":\"invalid_parameter\",\"Error\":\"Improperly encoded notes list.\"}", 422);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.AssertFailed(0, 2, L"* Memory Note 0x1234: Improperly encoded notes list.\n* Memory Note 0x1235: Improperly encoded notes list.");
|
|
}
|
|
|
|
TEST_METHOD(TestMultipleMemoryNotesPartialFailure)
|
|
{
|
|
AssetUploadViewModelHarness vmUpload;
|
|
vmUpload.mockUserContext.Initialize("User", "APITOKEN");
|
|
vmUpload.MemoryNotes().SetNote(0x1234, L"This is a note.");
|
|
vmUpload.MemoryNotes().SetNote(0x1235, L"This is another note.");
|
|
Assert::AreEqual(AssetChanges::Unpublished, vmUpload.MemoryNotes().GetChanges());
|
|
|
|
vmUpload.QueueAsset(vmUpload.MemoryNotes());
|
|
Assert::AreEqual({ 2U }, vmUpload.TaskCount());
|
|
|
|
const std::string sApiParams = "r=submitcodenotes&u=User&t=APITOKEN&g=22&n=4660:This+is+a+note.%0a4661:This+is+another+note.%0a";
|
|
vmUpload.mockRcClient.MockResponse(sApiParams, "{\"Success\":\"false\",\"Code\":\"access_denied\",\"Error\":\"Access denied.\",\"SuccessfulAddresses\":[4661],\"AccessDeniedAddresses\":[4660]}", 403);
|
|
|
|
vmUpload.DoUpload();
|
|
|
|
vmUpload.AssertFailed(1, 1, L"* Memory Note 0x1234: Access denied.");
|
|
}
|
|
};
|
|
|
|
} // namespace tests
|
|
} // namespace viewmodels
|
|
} // namespace ui
|
|
} // namespace ra
|