desk_template_conversion_unittests.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/desks_storage/core/desk_template_conversion.h"
  5. #include <string>
  6. #include "ash/public/cpp/desk_template.h"
  7. #include "base/guid.h"
  8. #include "base/json/json_reader.h"
  9. #include "base/json/values_util.h"
  10. #include "base/strings/utf_string_conversions.h"
  11. #include "base/test/bind.h"
  12. #include "base/test/task_environment.h"
  13. #include "build/build_config.h"
  14. #include "components/account_id/account_id.h"
  15. #include "components/app_constants/constants.h"
  16. #include "components/app_restore/app_launch_info.h"
  17. #include "components/app_restore/app_restore_data.h"
  18. #include "components/app_restore/window_info.h"
  19. #include "components/desks_storage/core/desk_test_util.h"
  20. #include "components/desks_storage/core/saved_desk_builder.h"
  21. #include "components/desks_storage/core/saved_desk_test_util.h"
  22. #include "components/services/app_service/public/cpp/app_registry_cache.h"
  23. #include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h"
  24. #include "components/services/app_service/public/cpp/app_types.h"
  25. #include "components/services/app_service/public/cpp/features.h"
  26. #include "testing/gtest/include/gtest/gtest.h"
  27. namespace desks_storage {
  28. namespace {
  29. const int32_t kTestWindowId = 1234567;
  30. const std::string kEmptyJson = "{}";
  31. const std::string kTestUuidBrowser = "040b6112-67f2-4d3c-8ba8-53a117272eba";
  32. constexpr int kBrowserWindowId = 1555;
  33. const std::string kBrowserUrl1 = "https://example.com/";
  34. const std::string kBrowserUrl2 = "https://example.com/2";
  35. const std::string kTestUuidChromeAndProgressive =
  36. "7f4b7ff0-970a-41bb-aa91-f6c3e2724207";
  37. const std::string kBrowserTemplateName = "BrowserTest";
  38. const std::string kChromePwaTemplateName = "ChromeAppTest";
  39. const constexpr char16_t kSampleTabGroupTitle[] = u"sample_tab_group";
  40. app_restore::TabGroupInfo MakeSampleTabGroup() {
  41. return app_restore::TabGroupInfo(
  42. {1, 2}, tab_groups::TabGroupVisualData(
  43. kSampleTabGroupTitle, tab_groups::TabGroupColorId::kGrey));
  44. }
  45. } // namespace
  46. class DeskTemplateConversionTest : public testing::Test {
  47. public:
  48. DeskTemplateConversionTest(const DeskTemplateConversionTest&) = delete;
  49. DeskTemplateConversionTest& operator=(const DeskTemplateConversionTest&) =
  50. delete;
  51. protected:
  52. DeskTemplateConversionTest()
  53. : account_id_(AccountId::FromUserEmail("test@gmail.com")),
  54. cache_(std::make_unique<apps::AppRegistryCache>()) {}
  55. void SetUp() override {
  56. desk_test_util::PopulateAppRegistryCache(account_id_, cache_.get());
  57. }
  58. AccountId account_id_;
  59. private:
  60. std::unique_ptr<apps::AppRegistryCache> cache_;
  61. };
  62. TEST_F(DeskTemplateConversionTest, ParseBrowserTemplate) {
  63. base::StringPiece raw_json =
  64. base::StringPiece(desk_test_util::kValidPolicyTemplateBrowser);
  65. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  66. EXPECT_TRUE(parsed_json.has_value());
  67. EXPECT_TRUE(parsed_json->is_dict());
  68. std::unique_ptr<ash::DeskTemplate> dt =
  69. desk_template_conversion::ParseDeskTemplateFromSource(
  70. *parsed_json, ash::DeskTemplateSource::kPolicy);
  71. EXPECT_TRUE(dt != nullptr);
  72. EXPECT_EQ(dt->uuid(), base::GUID::ParseCaseInsensitive(kTestUuidBrowser));
  73. EXPECT_EQ(dt->created_time(),
  74. desk_template_conversion::ProtoTimeToTime(1633535632));
  75. EXPECT_EQ(dt->template_name(), base::UTF8ToUTF16(kBrowserTemplateName));
  76. const app_restore::RestoreData* rd = dt->desk_restore_data();
  77. EXPECT_TRUE(rd != nullptr);
  78. EXPECT_EQ(rd->app_id_to_launch_list().size(), 1UL);
  79. EXPECT_NE(rd->app_id_to_launch_list().find(app_constants::kChromeAppId),
  80. rd->app_id_to_launch_list().end());
  81. const app_restore::AppRestoreData* ard =
  82. rd->GetAppRestoreData(app_constants::kChromeAppId, 0);
  83. EXPECT_TRUE(ard != nullptr);
  84. EXPECT_TRUE(ard->display_id.has_value());
  85. EXPECT_EQ(ard->display_id.value(), 100L);
  86. std::unique_ptr<app_restore::AppLaunchInfo> ali =
  87. ard->GetAppLaunchInfo(app_constants::kChromeAppId, 0);
  88. std::unique_ptr<app_restore::WindowInfo> wi = ard->GetWindowInfo();
  89. EXPECT_TRUE(ali != nullptr);
  90. EXPECT_TRUE(wi != nullptr);
  91. EXPECT_TRUE(ali->window_id.has_value());
  92. EXPECT_EQ(ali->window_id.value(), 0);
  93. EXPECT_TRUE(ali->display_id.has_value());
  94. EXPECT_EQ(ali->display_id.value(), 100L);
  95. EXPECT_TRUE(ali->active_tab_index.has_value());
  96. EXPECT_EQ(ali->active_tab_index.value(), 1);
  97. EXPECT_TRUE(ali->first_non_pinned_tab_index.has_value());
  98. EXPECT_EQ(ali->first_non_pinned_tab_index.value(), 1);
  99. EXPECT_TRUE(ali->urls.has_value());
  100. EXPECT_EQ(ali->urls.value()[0].spec(), kBrowserUrl1);
  101. EXPECT_EQ(ali->urls.value()[1].spec(), kBrowserUrl2);
  102. EXPECT_TRUE(ali->tab_group_infos.has_value());
  103. EXPECT_EQ(ali->tab_group_infos.value()[0], MakeSampleTabGroup());
  104. EXPECT_TRUE(wi->window_state_type.has_value());
  105. EXPECT_EQ(wi->window_state_type.value(), chromeos::WindowStateType::kNormal);
  106. EXPECT_TRUE(wi->current_bounds.has_value());
  107. EXPECT_EQ(wi->current_bounds.value().x(), 0);
  108. EXPECT_EQ(wi->current_bounds.value().y(), 1);
  109. EXPECT_EQ(wi->current_bounds.value().height(), 121);
  110. EXPECT_EQ(wi->current_bounds.value().width(), 120);
  111. }
  112. TEST_F(DeskTemplateConversionTest, ParseBrowserTemplateMinimized) {
  113. base::StringPiece raw_json =
  114. base::StringPiece(desk_test_util::kValidPolicyTemplateBrowserMinimized);
  115. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  116. EXPECT_TRUE(parsed_json.has_value());
  117. EXPECT_TRUE(parsed_json->is_dict());
  118. std::unique_ptr<ash::DeskTemplate> dt =
  119. desk_template_conversion::ParseDeskTemplateFromSource(
  120. *parsed_json, ash::DeskTemplateSource::kPolicy);
  121. EXPECT_TRUE(dt != nullptr);
  122. EXPECT_EQ(dt->uuid(), base::GUID::ParseCaseInsensitive(kTestUuidBrowser));
  123. EXPECT_EQ(dt->created_time(),
  124. desk_template_conversion::ProtoTimeToTime(1633535632));
  125. EXPECT_EQ(dt->template_name(), base::UTF8ToUTF16(kBrowserTemplateName));
  126. const app_restore::RestoreData* rd = dt->desk_restore_data();
  127. EXPECT_TRUE(rd != nullptr);
  128. EXPECT_EQ(rd->app_id_to_launch_list().size(), 1UL);
  129. EXPECT_NE(rd->app_id_to_launch_list().find(app_constants::kChromeAppId),
  130. rd->app_id_to_launch_list().end());
  131. const app_restore::AppRestoreData* ard =
  132. rd->GetAppRestoreData(app_constants::kChromeAppId, 0);
  133. EXPECT_TRUE(ard != nullptr);
  134. EXPECT_TRUE(ard->display_id.has_value());
  135. EXPECT_EQ(ard->display_id.value(), 100L);
  136. std::unique_ptr<app_restore::AppLaunchInfo> ali =
  137. ard->GetAppLaunchInfo(app_constants::kChromeAppId, 0);
  138. std::unique_ptr<app_restore::WindowInfo> wi = ard->GetWindowInfo();
  139. EXPECT_TRUE(ali != nullptr);
  140. EXPECT_TRUE(wi != nullptr);
  141. EXPECT_TRUE(ali->window_id.has_value());
  142. EXPECT_EQ(ali->window_id.value(), 0);
  143. EXPECT_TRUE(ali->display_id.has_value());
  144. EXPECT_EQ(ali->display_id.value(), 100L);
  145. EXPECT_TRUE(ali->active_tab_index.has_value());
  146. EXPECT_EQ(ali->active_tab_index.value(), 1);
  147. EXPECT_TRUE(ali->first_non_pinned_tab_index.has_value());
  148. EXPECT_EQ(ali->first_non_pinned_tab_index.value(), 1);
  149. EXPECT_TRUE(ali->urls.has_value());
  150. EXPECT_EQ(ali->urls.value()[0].spec(), kBrowserUrl1);
  151. EXPECT_EQ(ali->urls.value()[1].spec(), kBrowserUrl2);
  152. EXPECT_TRUE(ali->tab_group_infos.has_value());
  153. EXPECT_EQ(ali->tab_group_infos.value()[0], MakeSampleTabGroup());
  154. EXPECT_TRUE(wi->window_state_type.has_value());
  155. EXPECT_EQ(wi->window_state_type.value(),
  156. chromeos::WindowStateType::kMinimized);
  157. EXPECT_TRUE(wi->pre_minimized_show_state_type.has_value());
  158. EXPECT_EQ(wi->pre_minimized_show_state_type.value(),
  159. ui::WindowShowState::SHOW_STATE_NORMAL);
  160. EXPECT_TRUE(wi->current_bounds.has_value());
  161. EXPECT_EQ(wi->current_bounds.value().x(), 0);
  162. EXPECT_EQ(wi->current_bounds.value().y(), 1);
  163. EXPECT_EQ(wi->current_bounds.value().height(), 121);
  164. EXPECT_EQ(wi->current_bounds.value().width(), 120);
  165. }
  166. TEST_F(DeskTemplateConversionTest, ParseChromePwaTemplate) {
  167. base::StringPiece raw_json = base::StringPiece(
  168. desk_test_util::kValidPolicyTemplateChromeAndProgressive);
  169. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  170. EXPECT_TRUE(parsed_json.has_value());
  171. EXPECT_TRUE(parsed_json->is_dict());
  172. std::unique_ptr<ash::DeskTemplate> dt =
  173. desk_template_conversion::ParseDeskTemplateFromSource(
  174. *parsed_json, ash::DeskTemplateSource::kPolicy);
  175. EXPECT_TRUE(dt != nullptr);
  176. EXPECT_EQ(dt->uuid(),
  177. base::GUID::ParseCaseInsensitive(kTestUuidChromeAndProgressive));
  178. EXPECT_EQ(dt->created_time(),
  179. desk_template_conversion::ProtoTimeToTime(1633535632000LL));
  180. EXPECT_EQ(dt->template_name(), base::UTF8ToUTF16(kChromePwaTemplateName));
  181. const app_restore::RestoreData* rd = dt->desk_restore_data();
  182. EXPECT_TRUE(rd != nullptr);
  183. EXPECT_EQ(rd->app_id_to_launch_list().size(), 2UL);
  184. EXPECT_NE(rd->app_id_to_launch_list().find(desk_test_util::kTestChromeAppId1),
  185. rd->app_id_to_launch_list().end());
  186. EXPECT_NE(rd->app_id_to_launch_list().find(desk_test_util::kTestPwaAppId1),
  187. rd->app_id_to_launch_list().end());
  188. const app_restore::AppRestoreData* ard_chrome =
  189. rd->GetAppRestoreData(desk_test_util::kTestChromeAppId1, 0);
  190. const app_restore::AppRestoreData* ard_pwa =
  191. rd->GetAppRestoreData(desk_test_util::kTestPwaAppId1, 1);
  192. EXPECT_TRUE(ard_chrome != nullptr);
  193. EXPECT_TRUE(ard_pwa != nullptr);
  194. std::unique_ptr<app_restore::AppLaunchInfo> ali_chrome =
  195. ard_chrome->GetAppLaunchInfo(desk_test_util::kTestChromeAppId1, 0);
  196. std::unique_ptr<app_restore::AppLaunchInfo> ali_pwa =
  197. ard_pwa->GetAppLaunchInfo(desk_test_util::kTestPwaAppId1, 1);
  198. std::unique_ptr<app_restore::WindowInfo> wi_chrome =
  199. ard_chrome->GetWindowInfo();
  200. std::unique_ptr<app_restore::WindowInfo> wi_pwa = ard_pwa->GetWindowInfo();
  201. EXPECT_TRUE(ali_chrome != nullptr);
  202. EXPECT_TRUE(ali_chrome->window_id.has_value());
  203. EXPECT_EQ(ali_chrome->window_id.value(), 0);
  204. EXPECT_TRUE(ali_chrome->display_id.has_value());
  205. EXPECT_EQ(ali_chrome->display_id.value(), 100L);
  206. EXPECT_FALSE(ali_chrome->active_tab_index.has_value());
  207. EXPECT_FALSE(ali_chrome->urls.has_value());
  208. EXPECT_TRUE(ali_pwa != nullptr);
  209. EXPECT_TRUE(ali_pwa != nullptr);
  210. EXPECT_TRUE(ali_pwa->window_id.has_value());
  211. EXPECT_EQ(ali_pwa->window_id.value(), 1);
  212. EXPECT_TRUE(ali_pwa->display_id.has_value());
  213. EXPECT_EQ(ali_pwa->display_id.value(), 100L);
  214. EXPECT_FALSE(ali_pwa->active_tab_index.has_value());
  215. EXPECT_FALSE(ali_pwa->urls.has_value());
  216. EXPECT_TRUE(wi_chrome != nullptr);
  217. EXPECT_TRUE(wi_chrome->window_state_type.has_value());
  218. EXPECT_EQ(wi_chrome->window_state_type.value(),
  219. chromeos::WindowStateType::kPrimarySnapped);
  220. EXPECT_TRUE(wi_chrome->current_bounds.has_value());
  221. EXPECT_EQ(wi_chrome->current_bounds.value().x(), 200);
  222. EXPECT_EQ(wi_chrome->current_bounds.value().y(), 200);
  223. EXPECT_EQ(wi_chrome->current_bounds.value().height(), 1000);
  224. EXPECT_EQ(wi_chrome->current_bounds.value().width(), 1000);
  225. EXPECT_TRUE(wi_pwa != nullptr);
  226. EXPECT_TRUE(wi_pwa->window_state_type.has_value());
  227. EXPECT_EQ(wi_pwa->window_state_type.value(),
  228. chromeos::WindowStateType::kNormal);
  229. EXPECT_TRUE(wi_pwa->current_bounds.has_value());
  230. EXPECT_EQ(wi_pwa->current_bounds.value().x(), 0);
  231. EXPECT_EQ(wi_pwa->current_bounds.value().y(), 0);
  232. EXPECT_EQ(wi_pwa->current_bounds.value().height(), 120);
  233. EXPECT_EQ(wi_pwa->current_bounds.value().width(), 120);
  234. }
  235. TEST_F(DeskTemplateConversionTest, EmptyJsonTest) {
  236. base::StringPiece raw_json = base::StringPiece(kEmptyJson);
  237. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  238. EXPECT_TRUE(parsed_json.has_value());
  239. EXPECT_TRUE(parsed_json->is_dict());
  240. std::unique_ptr<ash::DeskTemplate> dt =
  241. desk_template_conversion::ParseDeskTemplateFromSource(
  242. *parsed_json, ash::DeskTemplateSource::kPolicy);
  243. EXPECT_TRUE(dt == nullptr);
  244. }
  245. TEST_F(DeskTemplateConversionTest, ParsesWithDefaultValueSetToTemplates) {
  246. base::StringPiece raw_json =
  247. base::StringPiece(desk_test_util::kPolicyTemplateWithoutType);
  248. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  249. EXPECT_TRUE(parsed_json.has_value());
  250. EXPECT_TRUE(parsed_json->is_dict());
  251. std::unique_ptr<ash::DeskTemplate> dt =
  252. desk_template_conversion::ParseDeskTemplateFromSource(
  253. *parsed_json, ash::DeskTemplateSource::kPolicy);
  254. EXPECT_TRUE(dt);
  255. EXPECT_EQ(ash::DeskTemplateType::kTemplate, dt->type());
  256. }
  257. TEST_F(DeskTemplateConversionTest, DeskTemplateFromJsonBrowserTest) {
  258. base::StringPiece raw_json =
  259. base::StringPiece(desk_test_util::kValidPolicyTemplateBrowser);
  260. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  261. EXPECT_TRUE(parsed_json.has_value());
  262. EXPECT_TRUE(parsed_json->is_dict());
  263. std::unique_ptr<ash::DeskTemplate> desk_template =
  264. desk_template_conversion::ParseDeskTemplateFromSource(
  265. *parsed_json, ash::DeskTemplateSource::kPolicy);
  266. apps::AppRegistryCache* app_cache =
  267. apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id_);
  268. base::Value desk_template_value =
  269. desk_template_conversion::SerializeDeskTemplateAsPolicy(
  270. desk_template.get(), app_cache);
  271. EXPECT_EQ(*parsed_json, desk_template_value);
  272. }
  273. TEST_F(DeskTemplateConversionTest, ToJsonIgnoreUnsupportedApp) {
  274. base::StringPiece raw_json =
  275. base::StringPiece(desk_test_util::kValidPolicyTemplateBrowser);
  276. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  277. EXPECT_TRUE(parsed_json.has_value());
  278. EXPECT_TRUE(parsed_json->is_dict());
  279. std::unique_ptr<ash::DeskTemplate> desk_template =
  280. desk_template_conversion::ParseDeskTemplateFromSource(
  281. *parsed_json, ash::DeskTemplateSource::kUser);
  282. // Adding this unsupported app should not change the serialized JSON content.
  283. saved_desk_test_util::AddGenericAppWindow(
  284. kTestWindowId, desk_test_util::kTestUnsupportedAppId,
  285. desk_template->mutable_desk_restore_data());
  286. apps::AppRegistryCache* app_cache =
  287. apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id_);
  288. base::Value desk_template_value =
  289. desk_template_conversion::SerializeDeskTemplateAsPolicy(
  290. desk_template.get(), app_cache);
  291. EXPECT_EQ(*parsed_json, desk_template_value);
  292. }
  293. TEST_F(DeskTemplateConversionTest, DeskTemplateFromJsonAppTest) {
  294. base::StringPiece raw_json = base::StringPiece(
  295. desk_test_util::kValidPolicyTemplateChromeAndProgressive);
  296. auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(raw_json);
  297. EXPECT_TRUE(parsed_json.has_value());
  298. EXPECT_TRUE(parsed_json->is_dict());
  299. std::unique_ptr<ash::DeskTemplate> desk_template =
  300. desk_template_conversion::ParseDeskTemplateFromSource(
  301. *parsed_json, ash::DeskTemplateSource::kPolicy);
  302. apps::AppRegistryCache* app_cache =
  303. apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id_);
  304. base::Value desk_template_value =
  305. desk_template_conversion::SerializeDeskTemplateAsPolicy(
  306. desk_template.get(), app_cache);
  307. EXPECT_EQ(*parsed_json, desk_template_value);
  308. }
  309. TEST_F(DeskTemplateConversionTest, EnsureLacrosBrowserWindowsSavedProperly) {
  310. base::Time created_time = base::Time::Now();
  311. std::unique_ptr<ash::DeskTemplate> desk_template =
  312. SavedDeskBuilder()
  313. .SetUuid(kTestUuidBrowser)
  314. .SetName(kBrowserTemplateName)
  315. .SetType(ash::DeskTemplateType::kSaveAndRecall)
  316. .SetCreatedTime(created_time)
  317. .AddLacrosBrowserAppWindow(kBrowserWindowId,
  318. {GURL(kBrowserUrl1), GURL(kBrowserUrl2)})
  319. .Build();
  320. apps::AppRegistryCache* app_cache =
  321. apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id_);
  322. base::Value desk_template_value =
  323. desk_template_conversion::SerializeDeskTemplateAsPolicy(
  324. desk_template.get(), app_cache);
  325. base::Value::Dict expected_browser_tab1;
  326. expected_browser_tab1.Set("url", base::Value(kBrowserUrl1));
  327. base::Value::Dict expected_browser_tab2;
  328. expected_browser_tab2.Set("url", base::Value(kBrowserUrl2));
  329. base::Value::List expected_tab_list;
  330. expected_tab_list.Append(std::move(expected_browser_tab1));
  331. expected_tab_list.Append(std::move(expected_browser_tab2));
  332. base::Value::Dict expected_browser_app_value;
  333. expected_browser_app_value.Set("app_type", base::Value("BROWSER"));
  334. expected_browser_app_value.Set("event_flag", base::Value(0));
  335. expected_browser_app_value.Set("window_id", base::Value(kBrowserWindowId));
  336. expected_browser_app_value.Set("tabs", std::move(expected_tab_list));
  337. base::Value::List expected_app_list;
  338. expected_app_list.Append(std::move(expected_browser_app_value));
  339. base::Value::Dict expected_desk_value;
  340. expected_desk_value.Set("apps", std::move(expected_app_list));
  341. base::Value::Dict expected_value;
  342. expected_value.Set("version", base::Value(1));
  343. expected_value.Set("uuid", base::Value(kTestUuidBrowser));
  344. expected_value.Set("name", base::Value(kBrowserTemplateName));
  345. expected_value.Set("created_time_usec", base::TimeToValue(created_time));
  346. expected_value.Set("updated_time_usec",
  347. base::TimeToValue(desk_template->GetLastUpdatedTime()));
  348. expected_value.Set("desk_type", base::Value("SAVE_AND_RECALL"));
  349. expected_value.Set("desk", std::move(expected_desk_value));
  350. EXPECT_EQ(expected_value, desk_template_value);
  351. }
  352. } // namespace desks_storage