GemCatalogTests.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/UnitTest/TestTypes.h>
  9. #include <AzTest/Utils.h>
  10. #include <GemCatalog/GemSortFilterProxyModel.h>
  11. namespace O3DE::ProjectManager
  12. {
  13. class GemCatalogTests
  14. : public ::UnitTest::LeakDetectionFixture
  15. {
  16. public:
  17. void SetUp() override
  18. {
  19. m_gemModel.reset(new GemModel());
  20. }
  21. void TearDown() override
  22. {
  23. m_gemModel.release();
  24. }
  25. protected:
  26. AZStd::unique_ptr<GemModel> m_gemModel;
  27. };
  28. TEST_F(GemCatalogTests, GemCatalog_GemWithDependencies_DisplaysButDoesNotAddDependencies)
  29. {
  30. // given 3 gems a,b,c where a depends on b which depends on c
  31. GemInfo gemA, gemB, gemC;
  32. QModelIndex indexA, indexB, indexC;
  33. gemA.m_name = "a";
  34. gemB.m_name = "b";
  35. gemC.m_name = "c";
  36. gemA.m_dependencies = QStringList({ "b" });
  37. gemB.m_dependencies = QStringList({ "c" });
  38. indexA = m_gemModel->AddGem(gemA);
  39. indexB = m_gemModel->AddGem(gemB);
  40. indexC = m_gemModel->AddGem(gemC);
  41. m_gemModel->UpdateGemDependencies();
  42. EXPECT_FALSE(GemModel::IsAdded(indexA));
  43. EXPECT_FALSE(GemModel::IsAddedDependency(indexB) || GemModel::IsAddedDependency(indexC));
  44. // when a is added
  45. GemModel::SetIsAdded(*m_gemModel, indexA, true);
  46. // expect b and c are now dependencies of an added gem but not themselves added
  47. // cmake will handle dependencies
  48. EXPECT_TRUE(GemModel::IsAddedDependency(indexB) && GemModel::IsAddedDependency(indexC));
  49. EXPECT_FALSE(GemModel::IsAdded(indexB) || GemModel::IsAdded(indexC));
  50. const QVector<QModelIndex>& gemsToAdd = m_gemModel->GatherGemsToBeAdded();
  51. EXPECT_TRUE(gemsToAdd.size() == 1);
  52. EXPECT_EQ(GemModel::GetName(gemsToAdd.at(0)), gemA.m_name);
  53. }
  54. class GemCatalogFilterTests
  55. : public GemCatalogTests
  56. {
  57. public:
  58. void SetUp() override
  59. {
  60. GemCatalogTests::SetUp();
  61. m_proxyModel.reset(new GemSortFilterProxyModel(m_gemModel.get()));
  62. }
  63. void TearDown() override
  64. {
  65. m_proxyModel.release();
  66. GemCatalogTests::TearDown();
  67. }
  68. protected:
  69. AZStd::unique_ptr<GemSortFilterProxyModel> m_proxyModel;
  70. };
  71. class GemCatalogSearchFilterTests
  72. : public GemCatalogFilterTests
  73. {
  74. public:
  75. void SetUp() override
  76. {
  77. GemCatalogFilterTests::SetUp();
  78. GemInfo gemfilterName, gemfilterDisplayName, gemfilterCreator, gemfilterSummary, gemfilterFeature;
  79. gemfilterName.m_name = "Name";
  80. gemfilterDisplayName.m_name = "D";
  81. gemfilterCreator.m_name = "C";
  82. gemfilterSummary.m_name = "S";
  83. gemfilterFeature.m_name = "F";
  84. gemfilterDisplayName.m_displayName = "Display Name";
  85. gemfilterCreator.m_origin = "Johnathon Doe";
  86. gemfilterSummary.m_summary = "Unique Summary";
  87. gemfilterFeature.m_features.append("Creative Feature");
  88. m_gemRows.append(m_gemModel->AddGem(gemfilterName).row());
  89. m_gemRows.append(m_gemModel->AddGem(gemfilterDisplayName).row());
  90. m_gemRows.append(m_gemModel->AddGem(gemfilterCreator).row());
  91. m_gemRows.append(m_gemModel->AddGem(gemfilterSummary).row());
  92. m_gemRows.append(m_gemModel->AddGem(gemfilterFeature).row());
  93. }
  94. protected:
  95. enum RowOrder
  96. {
  97. Name,
  98. DisplayName,
  99. Creator,
  100. Summary,
  101. Features
  102. };
  103. QVector<int> m_gemRows;
  104. };
  105. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringName_ShowsNameGems)
  106. {
  107. m_proxyModel->SetSearchString("Name");
  108. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  109. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  110. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  111. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  112. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  113. }
  114. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringDisplayName_ShowsDisplayNameGem)
  115. {
  116. m_proxyModel->SetSearchString("Display Name");
  117. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  118. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  119. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  120. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  121. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  122. }
  123. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringCreator_ShowsCreatorGem)
  124. {
  125. m_proxyModel->SetSearchString("Johnathon Doe");
  126. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  127. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  128. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  129. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  130. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  131. }
  132. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringSummary_ShowsSummaryGem)
  133. {
  134. m_proxyModel->SetSearchString("Unique Summary");
  135. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  136. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  137. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  138. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  139. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  140. }
  141. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringFeatures_ShowsFeatureGem)
  142. {
  143. m_proxyModel->SetSearchString("Creative");
  144. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  145. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  146. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  147. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  148. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  149. }
  150. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringEmpty_ShowsAll)
  151. {
  152. m_proxyModel->SetSearchString("");
  153. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  154. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  155. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  156. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  157. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  158. }
  159. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringCommonCharacter_ShowsAll)
  160. {
  161. // All gems contain "a" in a searchable field so all should be shown
  162. m_proxyModel->SetSearchString("a");
  163. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  164. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  165. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  166. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  167. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  168. }
  169. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringDifferentCaseCommonCharacter_ShowsAll)
  170. {
  171. // No gems contain the character "A" but search should be case insensitive
  172. m_proxyModel->SetSearchString("A");
  173. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  174. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  175. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  176. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  177. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  178. }
  179. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringNoneContainCharacter_ShowsNone)
  180. {
  181. // No gems contain the character "z" or "Z" so none should be shown
  182. m_proxyModel->SetSearchString("z");
  183. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  184. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  185. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  186. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  187. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  188. }
  189. TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringPartialMatchString_ShowsNone)
  190. {
  191. // Token matching is currently not supported
  192. // The whole string must match a substring
  193. m_proxyModel->SetSearchString("Name Token");
  194. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex()));
  195. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex()));
  196. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex()));
  197. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex()));
  198. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex()));
  199. }
  200. class GemCatalogSelectedActiveFilterTests
  201. : public GemCatalogFilterTests
  202. {
  203. public:
  204. void SetUp() override
  205. {
  206. GemCatalogFilterTests::SetUp();
  207. GemInfo gemSelected, gemSelectedDep, gemUnselected, gemUnselectedDep, gemActive, gemInactive;
  208. gemSelected.m_name = "selected";
  209. gemSelectedDep.m_name = "selectedDep";
  210. gemUnselected.m_name = "unselected";
  211. gemUnselectedDep.m_name = "unselectedDep";
  212. gemActive.m_name = "active";
  213. gemInactive.m_name = "inactive";
  214. gemSelected.m_dependencies = QStringList({ "selectedDep" });
  215. gemUnselected.m_dependencies = QStringList({ "unselectedDep" });
  216. m_gemIndices.append(m_gemModel->AddGem(gemSelected));
  217. m_gemIndices.append(m_gemModel->AddGem(gemSelectedDep));
  218. m_gemIndices.append(m_gemModel->AddGem(gemUnselected));
  219. m_gemIndices.append(m_gemModel->AddGem(gemUnselectedDep));
  220. m_gemIndices.append(m_gemModel->AddGem(gemActive));
  221. m_gemIndices.append(m_gemModel->AddGem(gemInactive));
  222. m_gemModel->UpdateGemDependencies();
  223. // Set intial state of catalog with the to be unselected gem currently added along with active gem
  224. GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Unselected], true);
  225. GemModel::SetWasPreviouslyAdded(*m_gemModel, m_gemIndices[Unselected], true);
  226. GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Active], true);
  227. GemModel::SetWasPreviouslyAdded(*m_gemModel, m_gemIndices[Active], true);
  228. // Add selected gem and remove unselected gem
  229. GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Selected], true);
  230. GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Unselected], false);
  231. }
  232. protected:
  233. enum IndexOrder
  234. {
  235. Selected,
  236. SelectedDep,
  237. Unselected,
  238. UnselectedDep,
  239. Active,
  240. Inactive
  241. };
  242. QVector<QModelIndex> m_gemIndices;
  243. };
  244. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_SelectedActiveIntialState_AddedGemsAndDependenciesAreAdded)
  245. {
  246. // Check if gems are all in expected state
  247. // if this test fails all other Selected/Active tests are invalid
  248. EXPECT_TRUE(GemModel::IsAdded(m_gemIndices[Selected]));
  249. EXPECT_TRUE(GemModel::IsAddedDependency(m_gemIndices[SelectedDep]));
  250. EXPECT_FALSE(GemModel::IsAdded(m_gemIndices[Unselected]));
  251. EXPECT_FALSE(GemModel::IsAddedDependency(m_gemIndices[UnselectedDep]));
  252. EXPECT_TRUE(GemModel::IsAdded(m_gemIndices[Active]));
  253. EXPECT_FALSE(GemModel::IsAdded(m_gemIndices[Inactive]));
  254. }
  255. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_SelectedActiveNoFilter_ShowsAll)
  256. {
  257. // Filter is clear
  258. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex()));
  259. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex()));
  260. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex()));
  261. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex()));
  262. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex()));
  263. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex()));
  264. }
  265. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterSelected_ShowsSelectedAndDependencies)
  266. {
  267. // Check selected filter
  268. // Selected dependencies should also be shown
  269. m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Selected);
  270. EXPECT_TRUE(m_proxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Selected);
  271. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex()));
  272. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex()));
  273. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex()));
  274. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex()));
  275. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex()));
  276. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex()));
  277. }
  278. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterUnselected_ShowsUnselectedAndDependencies)
  279. {
  280. // Check unselected filter
  281. // Unselected dependencies should also be shown
  282. m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected);
  283. EXPECT_TRUE(m_proxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Unselected);
  284. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex()));
  285. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex()));
  286. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex()));
  287. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex()));
  288. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex()));
  289. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex()));
  290. }
  291. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterSelectedAndUnselected_ShowsAllChangesAndDependencies)
  292. {
  293. // Check both un/selected filter
  294. m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Both);
  295. EXPECT_TRUE(m_proxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Both);
  296. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex()));
  297. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex()));
  298. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex()));
  299. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex()));
  300. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex()));
  301. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex()));
  302. }
  303. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterActive_ShowsActive)
  304. {
  305. // Check active filter
  306. // Active dependencies should also be shown
  307. m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Active);
  308. EXPECT_TRUE(m_proxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Active);
  309. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex()));
  310. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex()));
  311. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex()));
  312. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex()));
  313. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex()));
  314. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex()));
  315. }
  316. TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterActive_ShowsInactive)
  317. {
  318. // Check inactive filter
  319. m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive);
  320. EXPECT_TRUE(m_proxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Inactive);
  321. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex()));
  322. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex()));
  323. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex()));
  324. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex()));
  325. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex()));
  326. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex()));
  327. }
  328. class GemCatalogMiscFilterTests
  329. : public GemCatalogFilterTests
  330. {
  331. public:
  332. void SetUp() override
  333. {
  334. GemCatalogFilterTests::SetUp();
  335. GemInfo gemA, gemB, gemC;
  336. gemA.m_name = "Default Audio";
  337. gemB.m_name = "Mobile UX";
  338. gemC.m_name = "City Props";
  339. gemA.m_gemOrigin = GemInfo::GemOrigin::Open3DEngine;
  340. gemB.m_gemOrigin = GemInfo::GemOrigin::Local;
  341. gemC.m_gemOrigin = GemInfo::GemOrigin::Remote;
  342. gemA.m_types = GemInfo::Type::Code;
  343. gemB.m_types = GemInfo::Type::Code | GemInfo::Type::Tool;
  344. gemC.m_types = GemInfo::Type::Asset;
  345. using Plat = GemInfo::Platform;
  346. gemA.m_platforms = Plat::Windows;
  347. gemB.m_platforms = Plat::Android | Plat::iOS;
  348. gemC.m_platforms = Plat::Android | Plat::iOS | Plat::Linux | Plat::macOS | Plat::Windows;
  349. gemA.m_features = QStringList({ "Audio", "Framework", "SDK" });
  350. gemB.m_features = QStringList({ "Framework", "Tools", "UI" });
  351. gemC.m_features = QStringList({ "Assets", "Content", "Environment" });
  352. m_gemRows.append(m_gemModel->AddGem(gemA).row());
  353. m_gemRows.append(m_gemModel->AddGem(gemB).row());
  354. m_gemRows.append(m_gemModel->AddGem(gemC).row());
  355. }
  356. protected:
  357. enum RowOrder
  358. {
  359. DefaultAudio,
  360. MobileUX,
  361. CityProps
  362. };
  363. QVector<int> m_gemRows;
  364. };
  365. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_MiscNoFilter_ShowsAll)
  366. {
  367. // No filter
  368. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  369. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  370. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  371. }
  372. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleOrigin_ShowsOriginMatch)
  373. {
  374. m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine);
  375. EXPECT_TRUE(m_proxyModel->GetGemOrigins() == GemInfo::GemOrigin::Open3DEngine);
  376. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  377. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  378. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  379. m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Local);
  380. EXPECT_TRUE(m_proxyModel->GetGemOrigins() == GemInfo::GemOrigin::Local);
  381. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  382. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  383. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  384. m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Remote);
  385. EXPECT_TRUE(m_proxyModel->GetGemOrigins() == GemInfo::GemOrigin::Remote);
  386. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  387. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  388. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  389. }
  390. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleOrigins_ShowsMultipleOriginMatches)
  391. {
  392. m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine | GemInfo::GemOrigin::Local);
  393. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  394. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  395. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  396. }
  397. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleType_ShowsTypeMatch)
  398. {
  399. m_proxyModel->SetTypes(GemInfo::Type::Code);
  400. EXPECT_TRUE(m_proxyModel->GetTypes() == GemInfo::Type::Code);
  401. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  402. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  403. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  404. m_proxyModel->SetTypes(GemInfo::Type::Tool);
  405. EXPECT_TRUE(m_proxyModel->GetTypes() == GemInfo::Type::Tool);
  406. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  407. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  408. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  409. m_proxyModel->SetTypes(GemInfo::Type::Asset);
  410. EXPECT_TRUE(m_proxyModel->GetTypes() == GemInfo::Type::Asset);
  411. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  412. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  413. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  414. }
  415. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleTypes_ShowsMultipleTypeMatches)
  416. {
  417. m_proxyModel->SetTypes(GemInfo::Type::Tool | GemInfo::Type::Asset);
  418. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  419. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  420. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  421. }
  422. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSinglePlatform_ShowsPlatformMatch)
  423. {
  424. m_proxyModel->SetPlatforms(GemInfo::Platform::Windows);
  425. EXPECT_TRUE(m_proxyModel->GetPlatforms() == GemInfo::Platform::Windows);
  426. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  427. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  428. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  429. m_proxyModel->SetPlatforms(GemInfo::Platform::Android);
  430. EXPECT_TRUE(m_proxyModel->GetPlatforms() == GemInfo::Platform::Android);
  431. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  432. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  433. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  434. m_proxyModel->SetPlatforms(GemInfo::Platform::macOS);
  435. EXPECT_TRUE(m_proxyModel->GetPlatforms() == GemInfo::Platform::macOS);
  436. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  437. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  438. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  439. }
  440. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultiplePlatforms_ShowsMultiplePlatformMatches)
  441. {
  442. m_proxyModel->SetPlatforms(GemInfo::Platform::Android | GemInfo::Platform::iOS);
  443. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  444. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  445. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  446. }
  447. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleFeature_ShowsFeatureMatch)
  448. {
  449. m_proxyModel->SetFeatures({ "Audio" });
  450. EXPECT_TRUE(m_proxyModel->GetFeatures().contains("Audio"));
  451. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  452. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  453. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  454. m_proxyModel->SetFeatures({ "Tools", });
  455. EXPECT_TRUE(m_proxyModel->GetFeatures().contains("Tools"));
  456. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  457. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  458. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  459. m_proxyModel->SetFeatures({ "Environment" });
  460. EXPECT_TRUE(m_proxyModel->GetFeatures().contains( "Environment" ));
  461. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  462. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  463. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  464. }
  465. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleFeatures_ShowsMultipleFeatureMatches)
  466. {
  467. m_proxyModel->SetFeatures({ "Assets", "Framework" });
  468. EXPECT_TRUE(m_proxyModel->GetFeatures().contains({ "Assets", "Framework" }));
  469. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  470. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  471. EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  472. }
  473. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterPartialMatchFeature_ShowsNone)
  474. {
  475. // Features must be an exact match to filter by them directly
  476. m_proxyModel->SetFeatures({ "Frame" });
  477. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex()));
  478. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex()));
  479. EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex()));
  480. }
  481. TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_ResetFilters_FiltersReset)
  482. {
  483. // Set up all filter values that are reset
  484. m_proxyModel->SetSearchString("Name");
  485. m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Selected);
  486. m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Active);
  487. m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine);
  488. m_proxyModel->SetPlatforms(GemInfo::Platform::Windows);
  489. m_proxyModel->SetTypes(GemInfo::Type::Code);
  490. m_proxyModel->SetFeatures({ "Audio" });
  491. m_proxyModel->ResetFilters(true);
  492. EXPECT_TRUE(m_proxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::NoFilter);
  493. EXPECT_TRUE(m_proxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::NoFilter);
  494. EXPECT_TRUE(m_proxyModel->GetGemOrigins() == GemInfo::GemOrigins({}));
  495. EXPECT_TRUE(m_proxyModel->GetPlatforms() == GemInfo::Platforms({}));
  496. EXPECT_TRUE(m_proxyModel->GetTypes() == GemInfo::Types({}));
  497. EXPECT_TRUE(m_proxyModel->GetFeatures().isEmpty());
  498. }
  499. }