OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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 |
| 5 #import "ios/chrome/test/app/sync_test_util.h" |
| 6 |
| 7 #include <set> |
| 8 #include <string> |
| 9 |
| 10 #include "base/logging.h" |
| 11 #include "base/mac/bind_objc_block.h" |
| 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/strings/sys_string_conversions.h" |
| 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/test/ios/wait_util.h" |
| 16 #include "components/autofill/core/browser/personal_data_manager.h" |
| 17 #include "components/browser_sync/profile_sync_service.h" |
| 18 #include "components/history/core/browser/history_service.h" |
| 19 #include "components/keyed_service/core/service_access_type.h" |
| 20 #include "components/sync/engine/net/http_bridge_network_resources.h" |
| 21 #include "components/sync/test/fake_server/entity_builder_factory.h" |
| 22 #include "components/sync/test/fake_server/fake_server.h" |
| 23 #include "components/sync/test/fake_server/fake_server_network_resources.h" |
| 24 #include "components/sync/test/fake_server/fake_server_verifier.h" |
| 25 #include "components/sync/test/fake_server/sessions_hierarchy.h" |
| 26 #include "components/sync/test/fake_server/tombstone_entity.h" |
| 27 #include "components/sync/test/fake_server/unique_client_entity.h" |
| 28 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" |
| 29 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| 30 #include "ios/chrome/browser/history/history_service_factory.h" |
| 31 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" |
| 32 #include "ios/chrome/browser/sync/sync_setup_service.h" |
| 33 #include "ios/chrome/browser/sync/sync_setup_service_factory.h" |
| 34 #import "ios/chrome/test/app/chrome_test_util.h" |
| 35 #include "testing/gtest/include/gtest/gtest.h" |
| 36 |
| 37 namespace { |
| 38 |
| 39 fake_server::FakeServer* gSyncFakeServer = nullptr; |
| 40 |
| 41 NSString* const kSyncTestErrorDomain = @"SyncTestDomain"; |
| 42 |
| 43 // Overrides the network resources of the current ProfileSyncService with |
| 44 // |resources|. |
| 45 void OverrideSyncNetworkResources( |
| 46 std::unique_ptr<syncer::NetworkResources> resources) { |
| 47 ios::ChromeBrowserState* browser_state = |
| 48 chrome_test_util::GetOriginalBrowserState(); |
| 49 DCHECK(browser_state); |
| 50 browser_sync::ProfileSyncService* service = |
| 51 IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state); |
| 52 service->OverrideNetworkResourcesForTest(std::move(resources)); |
| 53 } |
| 54 |
| 55 } // namespace |
| 56 |
| 57 namespace chrome_test_util { |
| 58 |
| 59 void SetUpFakeSyncServer() { |
| 60 DCHECK(!gSyncFakeServer); |
| 61 gSyncFakeServer = new fake_server::FakeServer(); |
| 62 OverrideSyncNetworkResources(base::WrapUnique<syncer::NetworkResources>( |
| 63 new fake_server::FakeServerNetworkResources( |
| 64 gSyncFakeServer->AsWeakPtr()))); |
| 65 } |
| 66 |
| 67 void TearDownFakeSyncServer() { |
| 68 DCHECK(gSyncFakeServer); |
| 69 delete gSyncFakeServer; |
| 70 gSyncFakeServer = nullptr; |
| 71 OverrideSyncNetworkResources(base::WrapUnique<syncer::NetworkResources>( |
| 72 new syncer::HttpBridgeNetworkResources())); |
| 73 } |
| 74 |
| 75 void StartSync() { |
| 76 DCHECK(!IsSyncInitialized()); |
| 77 ios::ChromeBrowserState* browser_state = |
| 78 chrome_test_util::GetOriginalBrowserState(); |
| 79 SyncSetupService* sync_setup_service = |
| 80 SyncSetupServiceFactory::GetForBrowserState(browser_state); |
| 81 sync_setup_service->SetSyncEnabled(true); |
| 82 } |
| 83 |
| 84 void StopSync() { |
| 85 DCHECK(IsSyncInitialized()); |
| 86 ios::ChromeBrowserState* browser_state = |
| 87 chrome_test_util::GetOriginalBrowserState(); |
| 88 SyncSetupService* sync_setup_service = |
| 89 SyncSetupServiceFactory::GetForBrowserState(browser_state); |
| 90 sync_setup_service->SetSyncEnabled(false); |
| 91 } |
| 92 |
| 93 void TriggerSyncCycle(syncer::ModelType type) { |
| 94 ios::ChromeBrowserState* browser_state = |
| 95 chrome_test_util::GetOriginalBrowserState(); |
| 96 browser_sync::ProfileSyncService* profile_sync_service = |
| 97 IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state); |
| 98 const syncer::ModelTypeSet types(type); |
| 99 profile_sync_service->RefreshTypesForTest(types); |
| 100 } |
| 101 |
| 102 void ClearSyncServerData() { |
| 103 DCHECK(gSyncFakeServer); |
| 104 gSyncFakeServer->ClearServerData(); |
| 105 } |
| 106 |
| 107 int GetNumberOfSyncEntities(syncer::ModelType type) { |
| 108 DCHECK(gSyncFakeServer); |
| 109 std::unique_ptr<base::DictionaryValue> entities = |
| 110 gSyncFakeServer->GetEntitiesAsDictionaryValue(); |
| 111 |
| 112 std::string model_type_string = ModelTypeToString(type); |
| 113 base::ListValue* entity_list = NULL; |
| 114 if (!entities->GetList(model_type_string, &entity_list)) { |
| 115 return 0; |
| 116 } |
| 117 return entity_list->GetSize(); |
| 118 } |
| 119 |
| 120 BOOL VerifyNumberOfSyncEntitiesWithName(syncer::ModelType type, |
| 121 std::string name, |
| 122 size_t count, |
| 123 NSError** error) { |
| 124 DCHECK(gSyncFakeServer); |
| 125 fake_server::FakeServerVerifier verifier(gSyncFakeServer); |
| 126 testing::AssertionResult result = |
| 127 verifier.VerifyEntityCountByTypeAndName(count, type, name); |
| 128 if (result != testing::AssertionSuccess() && error != nil) { |
| 129 NSDictionary* errorInfo = @{ |
| 130 NSLocalizedDescriptionKey : base::SysUTF8ToNSString(result.message()) |
| 131 }; |
| 132 *error = [NSError errorWithDomain:kSyncTestErrorDomain |
| 133 code:0 |
| 134 userInfo:errorInfo]; |
| 135 return NO; |
| 136 } |
| 137 return result == testing::AssertionSuccess(); |
| 138 } |
| 139 |
| 140 void InjectBookmarkOnFakeSyncServer(std::string url, std::string title) { |
| 141 DCHECK(gSyncFakeServer); |
| 142 fake_server::EntityBuilderFactory entity_builder_factory; |
| 143 fake_server::BookmarkEntityBuilder bookmark_builder = |
| 144 entity_builder_factory.NewBookmarkEntityBuilder(title); |
| 145 gSyncFakeServer->InjectEntity(bookmark_builder.BuildBookmark(GURL(url))); |
| 146 } |
| 147 |
| 148 bool IsSyncInitialized() { |
| 149 ios::ChromeBrowserState* browser_state = |
| 150 chrome_test_util::GetOriginalBrowserState(); |
| 151 DCHECK(browser_state); |
| 152 syncer::SyncService* syncService = |
| 153 IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state); |
| 154 return syncService->IsEngineInitialized(); |
| 155 } |
| 156 |
| 157 std::string GetSyncCacheGuid() { |
| 158 DCHECK(IsSyncInitialized()); |
| 159 ios::ChromeBrowserState* browser_state = |
| 160 chrome_test_util::GetOriginalBrowserState(); |
| 161 browser_sync::ProfileSyncService* profile_sync_service = |
| 162 IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state); |
| 163 syncer::LocalDeviceInfoProvider* info_provider = |
| 164 profile_sync_service->GetLocalDeviceInfoProvider(); |
| 165 return info_provider->GetLocalSyncCacheGUID(); |
| 166 } |
| 167 |
| 168 void InjectAutofillProfileOnFakeSyncServer(std::string guid, |
| 169 std::string full_name) { |
| 170 DCHECK(gSyncFakeServer); |
| 171 sync_pb::EntitySpecifics entity_specifics; |
| 172 sync_pb::AutofillProfileSpecifics* autofill_profile = |
| 173 entity_specifics.mutable_autofill_profile(); |
| 174 autofill_profile->add_name_full(full_name); |
| 175 autofill_profile->set_guid(guid); |
| 176 |
| 177 std::unique_ptr<fake_server::FakeServerEntity> entity = |
| 178 fake_server::UniqueClientEntity::CreateForInjection(guid, |
| 179 entity_specifics); |
| 180 gSyncFakeServer->InjectEntity(std::move(entity)); |
| 181 } |
| 182 |
| 183 void DeleteAutofillProfileOnFakeSyncServer(std::string guid) { |
| 184 DCHECK(gSyncFakeServer); |
| 185 std::vector<sync_pb::SyncEntity> autofill_profiles = |
| 186 gSyncFakeServer->GetSyncEntitiesByModelType(syncer::AUTOFILL_PROFILE); |
| 187 std::string entity_id; |
| 188 for (const sync_pb::SyncEntity& autofill_profile : autofill_profiles) { |
| 189 if (autofill_profile.specifics().autofill_profile().guid() == guid) { |
| 190 entity_id = autofill_profile.id_string(); |
| 191 break; |
| 192 } |
| 193 } |
| 194 // Delete the entity if it exists. |
| 195 if (!entity_id.empty()) { |
| 196 std::unique_ptr<fake_server::FakeServerEntity> entity; |
| 197 entity = fake_server::TombstoneEntity::Create(entity_id, std::string()); |
| 198 gSyncFakeServer->InjectEntity(std::move(entity)); |
| 199 } |
| 200 } |
| 201 |
| 202 bool IsAutofillProfilePresent(std::string guid, std::string full_name) { |
| 203 ios::ChromeBrowserState* browser_state = |
| 204 chrome_test_util::GetOriginalBrowserState(); |
| 205 autofill::PersonalDataManager* personal_data_manager = |
| 206 autofill::PersonalDataManagerFactory::GetForBrowserState(browser_state); |
| 207 autofill::AutofillProfile* autofill_profile = |
| 208 personal_data_manager->GetProfileByGUID(guid); |
| 209 |
| 210 if (autofill_profile) { |
| 211 std::string actual_full_name = |
| 212 base::UTF16ToUTF8(autofill_profile->GetRawInfo(autofill::NAME_FULL)); |
| 213 return actual_full_name == full_name; |
| 214 } |
| 215 return false; |
| 216 } |
| 217 |
| 218 void ClearAutofillProfile(std::string guid) { |
| 219 ios::ChromeBrowserState* browser_state = |
| 220 chrome_test_util::GetOriginalBrowserState(); |
| 221 autofill::PersonalDataManager* personal_data_manager = |
| 222 autofill::PersonalDataManagerFactory::GetForBrowserState(browser_state); |
| 223 personal_data_manager->RemoveByGUID(guid); |
| 224 } |
| 225 |
| 226 BOOL VerifySessionsOnSyncServer(const std::multiset<std::string>& expected_urls, |
| 227 NSError** error) { |
| 228 DCHECK(gSyncFakeServer); |
| 229 fake_server::SessionsHierarchy expected_sessions; |
| 230 expected_sessions.AddWindow(expected_urls); |
| 231 fake_server::FakeServerVerifier verifier(gSyncFakeServer); |
| 232 testing::AssertionResult result = verifier.VerifySessions(expected_sessions); |
| 233 if (result != testing::AssertionSuccess() && error != nil) { |
| 234 NSDictionary* errorInfo = @{ |
| 235 NSLocalizedDescriptionKey : base::SysUTF8ToNSString(result.message()) |
| 236 }; |
| 237 *error = [NSError errorWithDomain:kSyncTestErrorDomain |
| 238 code:0 |
| 239 userInfo:errorInfo]; |
| 240 return NO; |
| 241 } |
| 242 return result == testing::AssertionSuccess(); |
| 243 } |
| 244 |
| 245 void AddTypedURLOnClient(const GURL& url) { |
| 246 ios::ChromeBrowserState* browser_state = |
| 247 chrome_test_util::GetOriginalBrowserState(); |
| 248 history::HistoryService* historyService = |
| 249 ios::HistoryServiceFactory::GetForBrowserState( |
| 250 browser_state, ServiceAccessType::EXPLICIT_ACCESS); |
| 251 |
| 252 historyService->AddPage(url, base::Time::UnixEpoch(), nullptr, 1, GURL(), |
| 253 history::RedirectList(), ui::PAGE_TRANSITION_TYPED, |
| 254 history::SOURCE_BROWSED, false); |
| 255 } |
| 256 |
| 257 void InjectTypedURLOnFakeSyncServer(const std::string& url) { |
| 258 DCHECK(gSyncFakeServer); |
| 259 sync_pb::EntitySpecifics entitySpecifics; |
| 260 sync_pb::TypedUrlSpecifics* typedUrl = entitySpecifics.mutable_typed_url(); |
| 261 typedUrl->set_url(url); |
| 262 typedUrl->set_title(url); |
| 263 typedUrl->add_visits(base::Time::Max().ToInternalValue()); |
| 264 typedUrl->add_visit_transitions(sync_pb::SyncEnums::TYPED); |
| 265 |
| 266 std::unique_ptr<fake_server::FakeServerEntity> entity = |
| 267 fake_server::UniqueClientEntity::CreateForInjection(url, entitySpecifics); |
| 268 gSyncFakeServer->InjectEntity(std::move(entity)); |
| 269 } |
| 270 |
| 271 BOOL IsTypedUrlPresentOnClient(const GURL& url, |
| 272 BOOL expect_present, |
| 273 NSError** error) { |
| 274 // Call the history service. |
| 275 ios::ChromeBrowserState* browser_state = |
| 276 chrome_test_util::GetOriginalBrowserState(); |
| 277 history::HistoryService* history_service = |
| 278 ios::HistoryServiceFactory::GetForBrowserState( |
| 279 browser_state, ServiceAccessType::EXPLICIT_ACCESS); |
| 280 |
| 281 const GURL block_safe_url(url); |
| 282 std::set<GURL> origins; |
| 283 origins.insert(block_safe_url); |
| 284 |
| 285 __block bool history_service_callback_called = false; |
| 286 __block int count = 0; |
| 287 using history::OriginCountAndLastVisitMap; |
| 288 history_service->GetCountsAndLastVisitForOrigins( |
| 289 origins, base::BindBlock(^(const OriginCountAndLastVisitMap& result) { |
| 290 auto iter = result.find(block_safe_url); |
| 291 if (iter != result.end()) |
| 292 count = iter->second.first; |
| 293 history_service_callback_called = true; |
| 294 })); |
| 295 |
| 296 NSDate* deadline = [NSDate dateWithTimeIntervalSinceNow:4.0]; |
| 297 while (!history_service_callback_called && |
| 298 [[NSDate date] compare:deadline] != NSOrderedDescending) { |
| 299 base::test::ios::SpinRunLoopWithMaxDelay( |
| 300 base::TimeDelta::FromSecondsD(0.1)); |
| 301 } |
| 302 |
| 303 NSString* error_message = nil; |
| 304 if (!history_service_callback_called) { |
| 305 error_message = @"History::GetCountsAndLastVisitForOrigins callback never " |
| 306 "called, app will probably crash later."; |
| 307 } else if (count == 0 && expect_present) { |
| 308 error_message = @"Typed URL isn't found in HistoryService."; |
| 309 } else if (count > 0 && !expect_present) { |
| 310 error_message = @"Typed URL isn't supposed to be in HistoryService."; |
| 311 } |
| 312 |
| 313 if (error_message != nil && error != nil) { |
| 314 NSDictionary* error_info = @{NSLocalizedDescriptionKey : error_message}; |
| 315 *error = [NSError errorWithDomain:kSyncTestErrorDomain |
| 316 code:0 |
| 317 userInfo:error_info]; |
| 318 return NO; |
| 319 } |
| 320 return error_message == nil; |
| 321 } |
| 322 |
| 323 void DeleteTypedUrlFromClient(const GURL& url) { |
| 324 ios::ChromeBrowserState* browser_state = |
| 325 chrome_test_util::GetOriginalBrowserState(); |
| 326 history::HistoryService* history_service = |
| 327 ios::HistoryServiceFactory::GetForBrowserState( |
| 328 browser_state, ServiceAccessType::EXPLICIT_ACCESS); |
| 329 |
| 330 history_service->DeleteURL(url); |
| 331 } |
| 332 |
| 333 void DeleteTypedUrlFromFakeSyncServer(std::string url) { |
| 334 DCHECK(gSyncFakeServer); |
| 335 std::vector<sync_pb::SyncEntity> typed_urls = |
| 336 gSyncFakeServer->GetSyncEntitiesByModelType(syncer::TYPED_URLS); |
| 337 std::string entity_id; |
| 338 for (const sync_pb::SyncEntity& typed_url : typed_urls) { |
| 339 if (typed_url.specifics().typed_url().url() == url) { |
| 340 entity_id = typed_url.id_string(); |
| 341 break; |
| 342 } |
| 343 } |
| 344 if (!entity_id.empty()) { |
| 345 std::unique_ptr<fake_server::FakeServerEntity> entity; |
| 346 entity = fake_server::TombstoneEntity::Create(entity_id, std::string()); |
| 347 gSyncFakeServer->InjectEntity(std::move(entity)); |
| 348 } |
| 349 } |
| 350 |
| 351 } // namespace chrome_test_util |
OLD | NEW |