invalidator_registrar_with_memory_unittest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. // Copyright 2019 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/invalidation/impl/invalidator_registrar_with_memory.h"
  5. #include <memory>
  6. #include "base/feature_list.h"
  7. #include "base/json/json_reader.h"
  8. #include "base/test/scoped_feature_list.h"
  9. #include "base/values.h"
  10. #include "components/invalidation/impl/fake_invalidation_handler.h"
  11. #include "components/invalidation/public/invalidation.h"
  12. #include "components/invalidation/public/invalidation_util.h"
  13. #include "components/invalidation/public/invalidator_state.h"
  14. #include "components/invalidation/public/topic_invalidation_map.h"
  15. #include "components/prefs/testing_pref_service.h"
  16. #include "testing/gmock/include/gmock/gmock.h"
  17. #include "testing/gtest/include/gtest/gtest.h"
  18. using testing::IsEmpty;
  19. using testing::Pair;
  20. using testing::UnorderedElementsAre;
  21. namespace invalidation {
  22. namespace {
  23. constexpr char kTopicsToHandler[] = "invalidation.per_sender_topics_to_handler";
  24. base::Value MakeStoredTopicMetadata(const InvalidationHandler* handler,
  25. TopicMetadata topic_metadata) {
  26. base::Value::Dict stored_topic_metadata;
  27. stored_topic_metadata.Set("handler", handler->GetOwnerName());
  28. stored_topic_metadata.Set("is_public", topic_metadata.is_public);
  29. return base::Value(std::move(stored_topic_metadata));
  30. }
  31. // Initialize the invalidator, register a handler, register some topics for that
  32. // handler, and then unregister the handler, dispatching invalidations in
  33. // between. The handler should only see invalidations when it's registered and
  34. // its topics are registered.
  35. TEST(InvalidatorRegistrarWithMemoryTest, Basic) {
  36. const TopicData kTopic1(/*name=*/"a", /*is_public=*/false);
  37. const TopicData kTopic2(/*name=*/"b", /*is_public=*/false);
  38. const TopicData kTopic3(/*name=*/"c", /*is_public=*/false);
  39. TestingPrefServiceSimple pref_service;
  40. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  41. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  42. &pref_service, "sender_id", /*migrate_old_prefs=*/false);
  43. FakeInvalidationHandler handler("owner");
  44. invalidator->RegisterHandler(&handler);
  45. TopicInvalidationMap invalidation_map;
  46. invalidation_map.Insert(Invalidation::Init(kTopic1.name, 1, "1"));
  47. invalidation_map.Insert(Invalidation::Init(kTopic2.name, 2, "2"));
  48. invalidation_map.Insert(Invalidation::Init(kTopic3.name, 3, "3"));
  49. // Should be ignored since no topics are registered to |handler|.
  50. invalidator->DispatchInvalidationsToHandlers(invalidation_map);
  51. EXPECT_EQ(0, handler.GetInvalidationCount());
  52. EXPECT_TRUE(
  53. invalidator->UpdateRegisteredTopics(&handler, {kTopic1, kTopic2}));
  54. invalidator->UpdateInvalidatorState(INVALIDATIONS_ENABLED);
  55. EXPECT_EQ(INVALIDATIONS_ENABLED, handler.GetInvalidatorState());
  56. TopicInvalidationMap expected_invalidations;
  57. expected_invalidations.Insert(Invalidation::Init(kTopic1.name, 1, "1"));
  58. expected_invalidations.Insert(Invalidation::Init(kTopic2.name, 2, "2"));
  59. invalidator->DispatchInvalidationsToHandlers(invalidation_map);
  60. EXPECT_EQ(1, handler.GetInvalidationCount());
  61. EXPECT_EQ(expected_invalidations, handler.GetLastInvalidationMap());
  62. // Remove kTopic1, add kTopic3.
  63. EXPECT_TRUE(
  64. invalidator->UpdateRegisteredTopics(&handler, {kTopic2, kTopic3}));
  65. expected_invalidations = TopicInvalidationMap();
  66. expected_invalidations.Insert(Invalidation::Init(kTopic2.name, 2, "2"));
  67. expected_invalidations.Insert(Invalidation::Init(kTopic3.name, 3, "3"));
  68. // Removed topic should not be notified, newly-added ones should.
  69. invalidator->DispatchInvalidationsToHandlers(invalidation_map);
  70. EXPECT_EQ(2, handler.GetInvalidationCount());
  71. EXPECT_EQ(expected_invalidations, handler.GetLastInvalidationMap());
  72. invalidator->UpdateInvalidatorState(TRANSIENT_INVALIDATION_ERROR);
  73. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler.GetInvalidatorState());
  74. invalidator->UpdateInvalidatorState(INVALIDATION_CREDENTIALS_REJECTED);
  75. EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, handler.GetInvalidatorState());
  76. invalidator->UnregisterHandler(&handler);
  77. // Should be ignored since |handler| isn't registered anymore.
  78. invalidator->DispatchInvalidationsToHandlers(invalidation_map);
  79. EXPECT_EQ(2, handler.GetInvalidationCount());
  80. }
  81. // Register handlers and some topics for those handlers, register a handler with
  82. // no topics, and register a handler with some topics but unregister it. Then,
  83. // dispatch some invalidations. Handlers that are not registered should not get
  84. // invalidations, and the ones that have registered topics should receive
  85. // invalidations for those topics.
  86. TEST(InvalidatorRegistrarWithMemoryTest, MultipleHandlers) {
  87. const TopicData kTopic1(/*name=*/"a", /*is_public=*/false);
  88. const TopicData kTopic2(/*name=*/"b", /*is_public=*/false);
  89. const TopicData kTopic3(/*name=*/"c", /*is_public=*/false);
  90. const TopicData kTopic4(/*name=*/"d", /*is_public=*/false);
  91. TestingPrefServiceSimple pref_service;
  92. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  93. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  94. &pref_service, "sender_id", /*migrate_old_prefs=*/false);
  95. FakeInvalidationHandler handler1("owner_1");
  96. FakeInvalidationHandler handler2("owner_2");
  97. FakeInvalidationHandler handler3("owner_3");
  98. FakeInvalidationHandler handler4("owner_4");
  99. invalidator->RegisterHandler(&handler1);
  100. invalidator->RegisterHandler(&handler2);
  101. invalidator->RegisterHandler(&handler3);
  102. invalidator->RegisterHandler(&handler4);
  103. EXPECT_TRUE(
  104. invalidator->UpdateRegisteredTopics(&handler1, {kTopic1, kTopic2}));
  105. EXPECT_TRUE(invalidator->UpdateRegisteredTopics(&handler2, {kTopic3}));
  106. // Don't register any IDs for handler3.
  107. EXPECT_TRUE(invalidator->UpdateRegisteredTopics(&handler4, {kTopic4}));
  108. invalidator->UnregisterHandler(&handler4);
  109. invalidator->UpdateInvalidatorState(INVALIDATIONS_ENABLED);
  110. EXPECT_EQ(INVALIDATIONS_ENABLED, handler1.GetInvalidatorState());
  111. EXPECT_EQ(INVALIDATIONS_ENABLED, handler2.GetInvalidatorState());
  112. EXPECT_EQ(INVALIDATIONS_ENABLED, handler3.GetInvalidatorState());
  113. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler4.GetInvalidatorState());
  114. TopicInvalidationMap invalidation_map;
  115. invalidation_map.Insert(Invalidation::Init(kTopic1.name, 1, "1"));
  116. invalidation_map.Insert(Invalidation::Init(kTopic2.name, 2, "2"));
  117. invalidation_map.Insert(Invalidation::Init(kTopic3.name, 3, "3"));
  118. invalidation_map.Insert(Invalidation::Init(kTopic4.name, 4, "4"));
  119. invalidator->DispatchInvalidationsToHandlers(invalidation_map);
  120. TopicInvalidationMap expected_invalidations1;
  121. expected_invalidations1.Insert(Invalidation::Init(kTopic1.name, 1, "1"));
  122. expected_invalidations1.Insert(Invalidation::Init(kTopic2.name, 2, "2"));
  123. EXPECT_EQ(1, handler1.GetInvalidationCount());
  124. EXPECT_EQ(expected_invalidations1, handler1.GetLastInvalidationMap());
  125. TopicInvalidationMap expected_invalidations2;
  126. expected_invalidations2.Insert(Invalidation::Init(kTopic3.name, 3, "3"));
  127. EXPECT_EQ(1, handler2.GetInvalidationCount());
  128. EXPECT_EQ(expected_invalidations2, handler2.GetLastInvalidationMap());
  129. EXPECT_EQ(0, handler3.GetInvalidationCount());
  130. EXPECT_EQ(0, handler4.GetInvalidationCount());
  131. invalidator->UpdateInvalidatorState(TRANSIENT_INVALIDATION_ERROR);
  132. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler1.GetInvalidatorState());
  133. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler2.GetInvalidatorState());
  134. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler3.GetInvalidatorState());
  135. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler4.GetInvalidatorState());
  136. invalidator->UnregisterHandler(&handler3);
  137. invalidator->UnregisterHandler(&handler2);
  138. invalidator->UnregisterHandler(&handler1);
  139. }
  140. // Multiple registrations by different handlers on the same topic should
  141. // return false.
  142. TEST(InvalidatorRegistrarWithMemoryTest, MultipleRegistrations) {
  143. const TopicData kTopic1(/*name=*/"a", /*is_public=*/false);
  144. TestingPrefServiceSimple pref_service;
  145. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  146. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  147. &pref_service, "sender_id", /*migrate_old_prefs=*/false);
  148. FakeInvalidationHandler handler1("owner1");
  149. FakeInvalidationHandler handler2("owner2");
  150. invalidator->RegisterHandler(&handler1);
  151. invalidator->RegisterHandler(&handler2);
  152. // Registering both handlers for the same topic. First call should succeed,
  153. // second should fail.
  154. EXPECT_TRUE(invalidator->UpdateRegisteredTopics(&handler1, {kTopic1}));
  155. EXPECT_FALSE(invalidator->UpdateRegisteredTopics(&handler2, {kTopic1}));
  156. // |handler1| should still own subscription to the topic and deregistration
  157. // of its topics should update subscriptions.
  158. EXPECT_TRUE(invalidator->UpdateRegisteredTopics(&handler1, /*topics=*/{}));
  159. EXPECT_TRUE(invalidator->GetAllSubscribedTopics().empty());
  160. invalidator->UnregisterHandler(&handler2);
  161. invalidator->UnregisterHandler(&handler1);
  162. }
  163. // Make sure that passing an empty set to UpdateRegisteredTopics clears the
  164. // corresponding entries for the handler.
  165. TEST(InvalidatorRegistrarWithMemoryTest, EmptySetUnregisters) {
  166. const TopicData kTopic1(/*name=*/"a", /*is_public=*/false);
  167. const TopicData kTopic2(/*name=*/"b", /*is_public=*/false);
  168. const TopicData kTopic3(/*name=*/"c", /*is_public=*/false);
  169. TestingPrefServiceSimple pref_service;
  170. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  171. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  172. &pref_service, "sender_id", /*migrate_old_prefs=*/false);
  173. FakeInvalidationHandler handler1("owner_1");
  174. // Control observer.
  175. FakeInvalidationHandler handler2("owner_2");
  176. invalidator->RegisterHandler(&handler1);
  177. invalidator->RegisterHandler(&handler2);
  178. EXPECT_TRUE(
  179. invalidator->UpdateRegisteredTopics(&handler1, {kTopic1, kTopic2}));
  180. EXPECT_TRUE(invalidator->UpdateRegisteredTopics(&handler2, {kTopic3}));
  181. // Unregister the topics for the first observer. It should not receive any
  182. // further invalidations.
  183. EXPECT_TRUE(invalidator->UpdateRegisteredTopics(&handler1, {}));
  184. invalidator->UpdateInvalidatorState(INVALIDATIONS_ENABLED);
  185. EXPECT_EQ(INVALIDATIONS_ENABLED, handler1.GetInvalidatorState());
  186. EXPECT_EQ(INVALIDATIONS_ENABLED, handler2.GetInvalidatorState());
  187. {
  188. TopicInvalidationMap invalidation_map;
  189. invalidation_map.Insert(Invalidation::Init(kTopic1.name, 1, "1"));
  190. invalidation_map.Insert(Invalidation::Init(kTopic2.name, 2, "2"));
  191. invalidation_map.Insert(Invalidation::Init(kTopic3.name, 3, "3"));
  192. invalidator->DispatchInvalidationsToHandlers(invalidation_map);
  193. EXPECT_EQ(0, handler1.GetInvalidationCount());
  194. EXPECT_EQ(1, handler2.GetInvalidationCount());
  195. }
  196. invalidator->UpdateInvalidatorState(TRANSIENT_INVALIDATION_ERROR);
  197. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler1.GetInvalidatorState());
  198. EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler2.GetInvalidatorState());
  199. invalidator->UnregisterHandler(&handler2);
  200. invalidator->UnregisterHandler(&handler1);
  201. }
  202. TEST(InvalidatorRegistrarWithMemoryTest, RestoresInterestingTopics) {
  203. const base::Feature restore_interesting_topics_feature{
  204. "InvalidatorRestoreInterestingTopics", base::FEATURE_ENABLED_BY_DEFAULT};
  205. base::test::ScopedFeatureList feature_list;
  206. feature_list.InitAndEnableFeature(restore_interesting_topics_feature);
  207. TestingPrefServiceSimple pref_service;
  208. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  209. // Set up some previously-registered topics in the pref.
  210. constexpr char kStoredTopicsJson[] =
  211. R"({"sender_id": {
  212. "topic_1": {"handler": "handler_1", "is_public": true},
  213. "topic_2": {"handler": "handler_2", "is_public": true},
  214. "topic_3": "handler_3",
  215. "topic_4_1": {"handler": "handler_4", "is_public": false},
  216. "topic_4_2": {"handler": "handler_4", "is_public": false},
  217. "topic_4_3": {"handler": "handler_4", "is_public": false}
  218. }})";
  219. auto stored_topics =
  220. base::JSONReader::ReadAndReturnValueWithError(kStoredTopicsJson);
  221. ASSERT_TRUE(stored_topics.has_value()) << stored_topics.error().message;
  222. pref_service.Set(kTopicsToHandler, std::move(*stored_topics));
  223. // Create an invalidator and make sure it correctly restored state from the
  224. // pref.
  225. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  226. &pref_service, "sender_id", /*migrate_old_prefs=*/false);
  227. std::map<std::string, TopicMetadata> expected_subscribed_topics{
  228. {"topic_1", TopicMetadata{true}}, {"topic_2", TopicMetadata{true}},
  229. {"topic_3", TopicMetadata{false}}, {"topic_4_1", TopicMetadata{false}},
  230. {"topic_4_2", TopicMetadata{false}}, {"topic_4_3", TopicMetadata{false}},
  231. };
  232. EXPECT_EQ(expected_subscribed_topics, invalidator->GetAllSubscribedTopics());
  233. }
  234. TEST(InvalidatorRegistrarWithMemoryTest,
  235. ClearsTopicsWithObsoleteOwnerNamesWhenPrefIsEmpty) {
  236. TestingPrefServiceSimple pref_service;
  237. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  238. ASSERT_TRUE(pref_service.GetValueDict(kTopicsToHandler).empty());
  239. InvalidatorRegistrarWithMemory::ClearTopicsWithObsoleteOwnerNames(
  240. &pref_service);
  241. ASSERT_TRUE(pref_service.GetValueDict(kTopicsToHandler).empty());
  242. }
  243. TEST(InvalidatorRegistrarWithMemoryTest, ClearsTopicsWithObsoleteOwnerNames) {
  244. constexpr char kTopicsToHandler[] =
  245. "invalidation.per_sender_topics_to_handler";
  246. TestingPrefServiceSimple pref_service;
  247. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  248. // Set up some previously-registered topics in the pref.
  249. constexpr char kInitialStoredTopics[] =
  250. R"({"sender_without_cloud": {
  251. "topic_1": {"handler": "NonCloud_1", "is_public": true},
  252. "topic_2": {"handler": "NonCloud_2", "is_public": true},
  253. "topic_3": {"handler": "NonCloud_3", "is_public": true}
  254. },
  255. "sender_with_cloud": {
  256. "topic_4": {"handler": "NonCloud_4", "is_public": true},
  257. "topic_5": {"handler": "Cloud", "is_public": true},
  258. "topic_6": "NonCloud_5",
  259. "topic_7": "RemoteCommand"
  260. },
  261. "sender_full_of_cloud": {
  262. "topic_8": {"handler": "Cloud", "is_public": true},
  263. "topic_9": {"handler": "RemoteCommand", "is_public": true},
  264. "topic_10": {"handler": "Cloud", "is_public": true}
  265. }})";
  266. auto initial_stored_topics =
  267. base::JSONReader::ReadAndReturnValueWithError(kInitialStoredTopics);
  268. ASSERT_TRUE(initial_stored_topics.has_value())
  269. << initial_stored_topics.error().message;
  270. pref_service.Set(kTopicsToHandler, initial_stored_topics->Clone());
  271. ASSERT_EQ(*initial_stored_topics,
  272. pref_service.GetValueDict(kTopicsToHandler));
  273. InvalidatorRegistrarWithMemory::ClearTopicsWithObsoleteOwnerNames(
  274. &pref_service);
  275. // Topics 5, 7, 8, 9 and 10 are expected to be gone.
  276. constexpr char kExpectedStoredTopics[] =
  277. R"({"sender_without_cloud": {
  278. "topic_1": {"handler": "NonCloud_1", "is_public": true},
  279. "topic_2": {"handler": "NonCloud_2", "is_public": true},
  280. "topic_3": {"handler": "NonCloud_3", "is_public": true}
  281. },
  282. "sender_with_cloud": {
  283. "topic_4": {"handler": "NonCloud_4", "is_public": true},
  284. "topic_6": "NonCloud_5"
  285. },
  286. "sender_full_of_cloud": {}})";
  287. auto expected_stored_topics =
  288. base::JSONReader::ReadAndReturnValueWithError(kExpectedStoredTopics);
  289. ASSERT_TRUE(expected_stored_topics.has_value())
  290. << expected_stored_topics.error().message;
  291. EXPECT_EQ(*expected_stored_topics,
  292. pref_service.GetValueDict(kTopicsToHandler));
  293. }
  294. // This test verifies that topics are not unsubscribed after browser restart
  295. // even if it's not registered using UpdateRegisteredTopics() method. This is
  296. // useful for Sync invalidations to prevent unsubscribing from some data types
  297. // which require more time to initialize and which are added later in following
  298. // UpdateRegisteredTopics() calls.
  299. //
  300. // TODO(crbug.com/1051893): make the unsubscription behaviour consistent
  301. // regardless of browser restart in between.
  302. TEST(InvalidatorRegistrarWithMemoryTest, ShouldKeepSubscriptionsAfterRestart) {
  303. const TopicData kTopic1(/*name=*/"topic_1", /*is_public=*/true);
  304. const TopicData kTopic2(/*name=*/"topic_2", /*is_public=*/true);
  305. TestingPrefServiceSimple pref_service;
  306. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  307. // Set up some previously-registered topics in the pref.
  308. constexpr char kStoredTopicsJson[] =
  309. R"({"sender_id": {
  310. "topic_1": {"handler": "handler", "is_public": true},
  311. "topic_2": {"handler": "handler", "is_public": true}
  312. }})";
  313. auto stored_topics =
  314. base::JSONReader::ReadAndReturnValueWithError(kStoredTopicsJson);
  315. ASSERT_TRUE(stored_topics.has_value()) << stored_topics.error().message;
  316. pref_service.Set(kTopicsToHandler, std::move(*stored_topics));
  317. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  318. &pref_service, "sender_id", /*migrate_old_prefs=*/false);
  319. FakeInvalidationHandler handler("handler");
  320. invalidator->RegisterHandler(&handler);
  321. // Verify that all topics are successfully subscribed but not registered by
  322. // the |handler|.
  323. ASSERT_THAT(invalidator->GetRegisteredTopics(&handler), IsEmpty());
  324. ASSERT_THAT(invalidator->GetAllSubscribedTopics(),
  325. UnorderedElementsAre(
  326. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public}),
  327. Pair(kTopic2.name, TopicMetadata{kTopic2.is_public})));
  328. // Register fo only one topic, but the previous subscriptions to other topics
  329. // should be kept.
  330. ASSERT_TRUE(invalidator->UpdateRegisteredTopics(&handler, {kTopic1}));
  331. EXPECT_THAT(invalidator->GetRegisteredTopics(&handler),
  332. UnorderedElementsAre(
  333. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public})));
  334. EXPECT_THAT(invalidator->GetAllSubscribedTopics(),
  335. UnorderedElementsAre(
  336. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public}),
  337. Pair(kTopic2.name, TopicMetadata{kTopic2.is_public})));
  338. // To unsubscribe from the topics which were added before browser restart, the
  339. // handler needs to explicitly register this topic, then unregister again.
  340. ASSERT_TRUE(
  341. invalidator->UpdateRegisteredTopics(&handler, {kTopic1, kTopic2}));
  342. ASSERT_TRUE(invalidator->UpdateRegisteredTopics(&handler, {kTopic1}));
  343. EXPECT_THAT(invalidator->GetRegisteredTopics(&handler),
  344. UnorderedElementsAre(
  345. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public})));
  346. EXPECT_THAT(invalidator->GetAllSubscribedTopics(),
  347. UnorderedElementsAre(
  348. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public})));
  349. invalidator->UnregisterHandler(&handler);
  350. }
  351. TEST(InvalidatorRegistrarWithMemoryTest, ShouldRemoveAllTopics) {
  352. const std::string kSenderId = "sender_id";
  353. const TopicData kTopic1(/*name=*/"topic_1", /*is_public=*/true);
  354. const TopicData kTopic2(/*name=*/"topic_2", /*is_public=*/true);
  355. TestingPrefServiceSimple pref_service;
  356. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  357. FakeInvalidationHandler handler("handler");
  358. // Set up some previously-registered topics in the pref.
  359. base::Value::Dict sender_id_topics;
  360. sender_id_topics.Set(
  361. kTopic1.name,
  362. MakeStoredTopicMetadata(&handler, TopicMetadata{kTopic1.is_public}));
  363. sender_id_topics.Set(
  364. kTopic2.name,
  365. MakeStoredTopicMetadata(&handler, TopicMetadata{kTopic2.is_public}));
  366. base::Value::Dict stored_topics;
  367. stored_topics.Set(kSenderId, std::move(sender_id_topics));
  368. pref_service.Set(kTopicsToHandler, base::Value(std::move(stored_topics)));
  369. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  370. &pref_service, kSenderId, /*migrate_old_prefs=*/false);
  371. invalidator->RegisterHandler(&handler);
  372. // Verify that all topics are successfully subscribed but not registered by
  373. // the |handler|.
  374. ASSERT_THAT(invalidator->GetRegisteredTopics(&handler), IsEmpty());
  375. ASSERT_THAT(invalidator->GetAllSubscribedTopics(),
  376. UnorderedElementsAre(
  377. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public}),
  378. Pair(kTopic2.name, TopicMetadata{kTopic2.is_public})));
  379. // Unregister from all topics.
  380. invalidator->RemoveUnregisteredTopics(&handler);
  381. EXPECT_THAT(invalidator->GetAllSubscribedTopics(), IsEmpty());
  382. invalidator->UnregisterHandler(&handler);
  383. }
  384. TEST(InvalidatorRegistrarWithMemoryTest, ShouldRemoveUnregisteredTopics) {
  385. const std::string kSenderId = "sender_id";
  386. const TopicData kTopic1(/*name=*/"topic_1", /*is_public=*/true);
  387. const TopicData kTopic2(/*name=*/"topic_2", /*is_public=*/true);
  388. TestingPrefServiceSimple pref_service;
  389. InvalidatorRegistrarWithMemory::RegisterProfilePrefs(pref_service.registry());
  390. FakeInvalidationHandler handler("handler");
  391. // Set up some previously-registered topics in the pref.
  392. base::Value::Dict sender_id_topics;
  393. sender_id_topics.Set(
  394. kTopic1.name,
  395. MakeStoredTopicMetadata(&handler, TopicMetadata{kTopic1.is_public}));
  396. sender_id_topics.Set(
  397. kTopic2.name,
  398. MakeStoredTopicMetadata(&handler, TopicMetadata{kTopic2.is_public}));
  399. base::Value::Dict stored_topics;
  400. stored_topics.Set(kSenderId, std::move(sender_id_topics));
  401. pref_service.Set(kTopicsToHandler, base::Value(std::move(stored_topics)));
  402. auto invalidator = std::make_unique<InvalidatorRegistrarWithMemory>(
  403. &pref_service, kSenderId, /*migrate_old_prefs=*/false);
  404. invalidator->RegisterHandler(&handler);
  405. // Verify that all topics are successfully subscribed but not registered by
  406. // the |handler|.
  407. ASSERT_THAT(invalidator->GetRegisteredTopics(&handler), IsEmpty());
  408. ASSERT_THAT(invalidator->GetAllSubscribedTopics(),
  409. UnorderedElementsAre(
  410. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public}),
  411. Pair(kTopic2.name, TopicMetadata{kTopic2.is_public})));
  412. // Register to only one topic and unregister from another.
  413. ASSERT_TRUE(invalidator->UpdateRegisteredTopics(&handler, {kTopic1}));
  414. invalidator->RemoveUnregisteredTopics(&handler);
  415. EXPECT_THAT(invalidator->GetAllSubscribedTopics(),
  416. UnorderedElementsAre(
  417. Pair(kTopic1.name, TopicMetadata{kTopic1.is_public})));
  418. invalidator->UnregisterHandler(&handler);
  419. }
  420. } // namespace
  421. } // namespace invalidation