| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "testing/gtest/include/gtest/gtest.h" | 5 #include "testing/gtest/include/gtest/gtest.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/scoped_temp_dir.h" | 12 #include "base/scoped_temp_dir.h" |
| 13 #include "base/task.h" | 13 #include "base/task.h" |
| 14 #include "chrome/browser/extensions/extension_settings_backend.h" | 14 #include "chrome/browser/extensions/extension_settings_backend.h" |
| 15 #include "chrome/browser/extensions/extension_settings_frontend.h" |
| 15 #include "chrome/browser/extensions/extension_settings_storage_cache.h" | 16 #include "chrome/browser/extensions/extension_settings_storage_cache.h" |
| 16 #include "chrome/browser/extensions/extension_settings_sync_util.h" | 17 #include "chrome/browser/extensions/extension_settings_sync_util.h" |
| 17 #include "chrome/browser/extensions/syncable_extension_settings_storage.h" | 18 #include "chrome/browser/extensions/syncable_extension_settings_storage.h" |
| 18 #include "chrome/browser/sync/api/sync_change_processor.h" | 19 #include "chrome/browser/sync/api/sync_change_processor.h" |
| 20 #include "chrome/test/base/testing_profile.h" |
| 19 #include "content/browser/browser_thread.h" | 21 #include "content/browser/browser_thread.h" |
| 20 | 22 |
| 21 // TODO(kalman): Integration tests for sync. | 23 // TODO(kalman): Integration tests for sync. |
| 22 | 24 |
| 23 namespace { | 25 namespace { |
| 24 | 26 |
| 25 // Gets the pretty-printed JSON for a value. | 27 // Gets the pretty-printed JSON for a value. |
| 26 static std::string GetJson(const Value& value) { | 28 static std::string GetJson(const Value& value) { |
| 27 std::string json; | 29 std::string json; |
| 28 base::JSONWriter::Write(&value, true, &json); | 30 base::JSONWriter::Write(&value, true, &json); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 ExtensionSettingSyncDataList matching_changes; | 98 ExtensionSettingSyncDataList matching_changes; |
| 97 for (ExtensionSettingSyncDataList::iterator it = changes_.begin(); | 99 for (ExtensionSettingSyncDataList::iterator it = changes_.begin(); |
| 98 it != changes_.end(); ++it) { | 100 it != changes_.end(); ++it) { |
| 99 if (it->extension_id() == extension_id && it->key() == key) { | 101 if (it->extension_id() == extension_id && it->key() == key) { |
| 100 matching_changes.push_back(*it); | 102 matching_changes.push_back(*it); |
| 101 } | 103 } |
| 102 } | 104 } |
| 103 if (matching_changes.empty()) { | 105 if (matching_changes.empty()) { |
| 104 ADD_FAILURE() << "No matching changes for " << extension_id << "/" << | 106 ADD_FAILURE() << "No matching changes for " << extension_id << "/" << |
| 105 key << " (out of " << changes_.size() << ")"; | 107 key << " (out of " << changes_.size() << ")"; |
| 106 return ExtensionSettingSyncData(SyncChange::ACTION_INVALID, "", "", NULL); | 108 return ExtensionSettingSyncData( |
| 109 SyncChange::ACTION_INVALID, "", "", new DictionaryValue()); |
| 107 } | 110 } |
| 108 if (matching_changes.size() != 1u) { | 111 if (matching_changes.size() != 1u) { |
| 109 ADD_FAILURE() << matching_changes.size() << " matching changes for " << | 112 ADD_FAILURE() << matching_changes.size() << " matching changes for " << |
| 110 extension_id << "/" << key << " (out of " << changes_.size() << ")"; | 113 extension_id << "/" << key << " (out of " << changes_.size() << ")"; |
| 111 } | 114 } |
| 112 return matching_changes[0]; | 115 return matching_changes[0]; |
| 113 } | 116 } |
| 114 | 117 |
| 115 private: | 118 private: |
| 116 ExtensionSettingSyncDataList changes_; | 119 ExtensionSettingSyncDataList changes_; |
| 117 }; | 120 }; |
| 118 | 121 |
| 122 // To be called as a callback from ExtensionSettingsFrontend::RunWithSettings. |
| 123 void AssignSettings( |
| 124 ExtensionSettingsBackend** dst, ExtensionSettingsBackend* src) { |
| 125 *dst = src; |
| 126 } |
| 127 |
| 119 } // namespace | 128 } // namespace |
| 120 | 129 |
| 121 class ExtensionSettingsSyncTest : public testing::Test { | 130 class ExtensionSettingsSyncTest : public testing::Test { |
| 122 public: | 131 public: |
| 123 ExtensionSettingsSyncTest() | 132 ExtensionSettingsSyncTest() |
| 124 : ui_thread_(BrowserThread::UI, MessageLoop::current()), | 133 : ui_thread_(BrowserThread::UI, MessageLoop::current()), |
| 125 file_thread_(BrowserThread::FILE, MessageLoop::current()) {} | 134 file_thread_(BrowserThread::FILE, MessageLoop::current()), |
| 135 frontend_(&profile_), |
| 136 backend_(NULL) { |
| 137 } |
| 126 | 138 |
| 127 virtual void SetUp() OVERRIDE { | 139 virtual void SetUp() OVERRIDE { |
| 128 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 140 frontend_.RunWithBackend(base::Bind(&AssignSettings, &backend_)); |
| 129 // TODO(kalman): Use ExtensionSettingsFrontend here? It would test more | 141 MessageLoop::current()->RunAllPending(); |
| 130 // code paths. | 142 ASSERT_TRUE(backend_ != NULL); |
| 131 backend_.reset(new ExtensionSettingsBackend(temp_dir_.path())); | |
| 132 } | |
| 133 | |
| 134 virtual void TearDown() OVERRIDE { | |
| 135 // Must do this explicitly here so that it's destroyed before the | |
| 136 // message loops are. | |
| 137 backend_.reset(); | |
| 138 } | 143 } |
| 139 | 144 |
| 140 protected: | 145 protected: |
| 141 // Creates a new extension storage object and adds a record of the extension | 146 // Creates a new extension storage object and adds a record of the extension |
| 142 // to the extension service. | 147 // to the extension service. |
| 143 SyncableExtensionSettingsStorage* GetStorage( | 148 SyncableExtensionSettingsStorage* GetStorage( |
| 144 const std::string& extension_id) { | 149 const std::string& extension_id) { |
| 145 return static_cast<SyncableExtensionSettingsStorage*>( | 150 return static_cast<SyncableExtensionSettingsStorage*>( |
| 146 backend_->GetStorage(extension_id)); | 151 backend_->GetStorage(extension_id)); |
| 147 } | 152 } |
| 148 | 153 |
| 149 MockSyncChangeProcessor sync_; | 154 // Gets all the sync data from |backend_| as a map from extension id to its |
| 150 scoped_ptr<ExtensionSettingsBackend> backend_; | |
| 151 | |
| 152 // Gets all the sync data from backend_ as a map from extension id to its | |
| 153 // sync data. | 155 // sync data. |
| 154 std::map<std::string, ExtensionSettingSyncDataList> GetAllSyncData() { | 156 std::map<std::string, ExtensionSettingSyncDataList> GetAllSyncData() { |
| 155 SyncDataList as_list = | 157 SyncDataList as_list = |
| 156 backend_->GetAllSyncData(syncable::EXTENSION_SETTINGS); | 158 backend_->GetAllSyncData(syncable::EXTENSION_SETTINGS); |
| 157 std::map<std::string, ExtensionSettingSyncDataList> as_map; | 159 std::map<std::string, ExtensionSettingSyncDataList> as_map; |
| 158 for (SyncDataList::iterator it = as_list.begin(); | 160 for (SyncDataList::iterator it = as_list.begin(); |
| 159 it != as_list.end(); ++it) { | 161 it != as_list.end(); ++it) { |
| 160 ExtensionSettingSyncData sync_data(*it); | 162 ExtensionSettingSyncData sync_data(*it); |
| 161 as_map[sync_data.extension_id()].push_back(sync_data); | 163 as_map[sync_data.extension_id()].push_back(sync_data); |
| 162 } | 164 } |
| 163 return as_map; | 165 return as_map; |
| 164 } | 166 } |
| 165 | 167 |
| 166 private: | |
| 167 ScopedTempDir temp_dir_; | |
| 168 | |
| 169 // Need these so that the DCHECKs for running on FILE or UI threads pass. | 168 // Need these so that the DCHECKs for running on FILE or UI threads pass. |
| 170 MessageLoop message_loop_; | 169 MessageLoop message_loop_; |
| 171 BrowserThread ui_thread_; | 170 BrowserThread ui_thread_; |
| 172 BrowserThread file_thread_; | 171 BrowserThread file_thread_; |
| 172 |
| 173 MockSyncChangeProcessor sync_; |
| 174 TestingProfile profile_; |
| 175 ExtensionSettingsFrontend frontend_; |
| 176 |
| 177 // Get from frontend_->RunWithBackend, so weak reference. |
| 178 ExtensionSettingsBackend* backend_; |
| 173 }; | 179 }; |
| 174 | 180 |
| 175 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) { | 181 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) { |
| 176 ASSERT_EQ(0u, GetAllSyncData().size()); | 182 ASSERT_EQ(0u, GetAllSyncData().size()); |
| 177 | 183 |
| 178 // Have one extension created before sync is set up, the other created after. | 184 // Have one extension created before sync is set up, the other created after. |
| 179 GetStorage("s1"); | 185 GetStorage("s1"); |
| 180 ASSERT_EQ(0u, GetAllSyncData().size()); | 186 ASSERT_EQ(0u, GetAllSyncData().size()); |
| 181 | 187 |
| 182 backend_->MergeDataAndStartSyncing( | 188 backend_->MergeDataAndStartSyncing( |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 sync_.GetOnlyChange("s3", "bar").change_type()); | 490 sync_.GetOnlyChange("s3", "bar").change_type()); |
| 485 ASSERT_EQ( | 491 ASSERT_EQ( |
| 486 SyncChange::ACTION_DELETE, | 492 SyncChange::ACTION_DELETE, |
| 487 sync_.GetOnlyChange("s4", "foo").change_type()); | 493 sync_.GetOnlyChange("s4", "foo").change_type()); |
| 488 ASSERT_EQ( | 494 ASSERT_EQ( |
| 489 SyncChange::ACTION_DELETE, | 495 SyncChange::ACTION_DELETE, |
| 490 sync_.GetOnlyChange("s4", "bar").change_type()); | 496 sync_.GetOnlyChange("s4", "bar").change_type()); |
| 491 | 497 |
| 492 backend_->StopSyncing(syncable::EXTENSION_SETTINGS); | 498 backend_->StopSyncing(syncable::EXTENSION_SETTINGS); |
| 493 } | 499 } |
| OLD | NEW |