1 // Copyright (c) 2012 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.
5 #include "chrome/browser/extensions/extension_sync_data.h"
7 #include "base/files/file_path.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/version.h"
10 #include "extensions/common/extension.h"
11 #include "sync/api/string_ordinal.h"
12 #include "sync/protocol/app_specifics.pb.h"
13 #include "sync/protocol/extension_specifics.pb.h"
14 #include "sync/protocol/sync.pb.h"
15 #include "testing/gtest/include/gtest/gtest.h"
18 namespace extensions
{
22 const char kValidId
[] = "abcdefghijklmnopabcdefghijklmnop";
23 const char kVersion
[] = "1.0.0.1";
24 const char kValidUpdateUrl
[] =
25 "https://clients2.google.com/service/update2/crx";
26 const int kValidDisableReasons
= Extension::DISABLE_USER_ACTION
;
27 const char kName
[] = "MyExtension";
29 // Serializes a protobuf structure (entity specifics) into an ExtensionSyncData
30 // and back again, and confirms that the input is the same as the output.
31 void ProtobufToSyncDataEqual(const sync_pb::EntitySpecifics
& entity
) {
32 syncer::SyncData sync_data
=
33 syncer::SyncData::CreateLocalData("sync_tag", "non_unique_title", entity
);
34 scoped_ptr
<ExtensionSyncData
> extension_sync_data
=
35 ExtensionSyncData::CreateFromSyncData(sync_data
);
36 ASSERT_TRUE(extension_sync_data
.get());
37 syncer::SyncData output_sync_data
= extension_sync_data
->GetSyncData();
38 const sync_pb::ExtensionSpecifics
& output
=
39 output_sync_data
.GetSpecifics().extension();
40 const sync_pb::ExtensionSpecifics
& input
= entity
.extension();
42 // Check for field-by-field quality. It'd be nice if we could use
43 // AssertionResults here (instead of EXPECT_EQ) so that we could get valid
44 // line numbers, but it's not worth the ugliness of the verbose comparison.
45 EXPECT_EQ(input
.id(), output
.id());
46 EXPECT_EQ(input
.name(), output
.name());
47 EXPECT_EQ(input
.version(), output
.version());
48 EXPECT_EQ(input
.update_url(), output
.update_url());
49 EXPECT_EQ(input
.enabled(), output
.enabled());
50 EXPECT_EQ(input
.incognito_enabled(), output
.incognito_enabled());
51 EXPECT_EQ(input
.remote_install(), output
.remote_install());
52 EXPECT_EQ(input
.installed_by_custodian(), output
.installed_by_custodian());
53 EXPECT_EQ(input
.has_all_urls_enabled(), output
.has_all_urls_enabled());
54 if (input
.has_all_urls_enabled())
55 EXPECT_EQ(input
.all_urls_enabled(), output
.all_urls_enabled());
58 // Serializes an ExtensionSyncData into a protobuf structure and back again, and
59 // confirms that the input is the same as the output.
60 void SyncDataToProtobufEqual(const ExtensionSyncData
& input
) {
61 syncer::SyncData sync_data
= input
.GetSyncData();
62 scoped_ptr
<ExtensionSyncData
> output
=
63 ExtensionSyncData::CreateFromSyncData(sync_data
);
64 ASSERT_TRUE(output
.get());
66 EXPECT_EQ(input
.id(), output
->id());
67 EXPECT_EQ(input
.uninstalled(), output
->uninstalled());
68 EXPECT_EQ(input
.enabled(), output
->enabled());
69 EXPECT_EQ(input
.incognito_enabled(), output
->incognito_enabled());
70 EXPECT_EQ(input
.remote_install(), output
->remote_install());
71 EXPECT_EQ(input
.installed_by_custodian(), output
->installed_by_custodian());
72 EXPECT_EQ(input
.all_urls_enabled(), output
->all_urls_enabled());
73 EXPECT_TRUE(input
.version().Equals(output
->version()));
74 EXPECT_EQ(input
.update_url(), output
->update_url());
75 EXPECT_EQ(input
.name(), output
->name());
80 class ExtensionSyncDataTest
: public testing::Test
{
83 // Tests the conversion process from a protobuf to an ExtensionSyncData and vice
85 TEST_F(ExtensionSyncDataTest
, ExtensionSyncDataForExtension
) {
86 sync_pb::EntitySpecifics entity
;
87 sync_pb::ExtensionSpecifics
* extension_specifics
= entity
.mutable_extension();
88 extension_specifics
->set_id(kValidId
);
89 extension_specifics
->set_update_url(kValidUpdateUrl
);
90 extension_specifics
->set_enabled(false);
91 extension_specifics
->set_incognito_enabled(true);
92 extension_specifics
->set_remote_install(false);
93 extension_specifics
->set_installed_by_custodian(false);
94 extension_specifics
->set_all_urls_enabled(true);
95 extension_specifics
->set_version(kVersion
);
96 extension_specifics
->set_name(kName
);
98 // Check the serialize-deserialize process for proto to ExtensionSyncData.
99 ProtobufToSyncDataEqual(entity
);
101 // Explicitly test that conversion to an ExtensionSyncData gets the correct
102 // result (otherwise we just know that conversion to/from a proto gives us
103 // the same result, but don't know that it's right).
104 ExtensionSyncData extension_sync_data
;
105 extension_sync_data
.PopulateFromExtensionSpecifics(*extension_specifics
);
106 EXPECT_EQ(kValidId
, extension_sync_data
.id());
107 EXPECT_EQ(GURL(kValidUpdateUrl
), extension_sync_data
.update_url());
108 EXPECT_FALSE(extension_sync_data
.enabled());
109 EXPECT_EQ(true, extension_sync_data
.incognito_enabled());
110 EXPECT_FALSE(extension_sync_data
.remote_install());
111 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE
,
112 extension_sync_data
.all_urls_enabled());
113 EXPECT_TRUE(Version(kVersion
).Equals(extension_sync_data
.version()));
114 EXPECT_EQ(std::string(kName
), extension_sync_data
.name());
116 // Check the serialize-deserialize process for ExtensionSyncData to proto.
117 SyncDataToProtobufEqual(extension_sync_data
);
119 // The most important thing to test is the "all urls" bit, since it is a
120 // tri-state boolean (and thus has more logic). Also flip another bit for a
122 extension_specifics
->set_all_urls_enabled(false);
123 extension_specifics
->set_incognito_enabled(false);
124 ProtobufToSyncDataEqual(entity
);
126 extension_sync_data
.PopulateFromExtensionSpecifics(*extension_specifics
);
127 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE
,
128 extension_sync_data
.all_urls_enabled());
129 EXPECT_FALSE(extension_sync_data
.incognito_enabled());
131 SyncDataToProtobufEqual(extension_sync_data
);
133 extension_specifics
->clear_all_urls_enabled();
134 ProtobufToSyncDataEqual(entity
);
136 extension_sync_data
.PopulateFromExtensionSpecifics(*extension_specifics
);
137 EXPECT_FALSE(extension_specifics
->has_all_urls_enabled());
138 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET
,
139 extension_sync_data
.all_urls_enabled());
141 SyncDataToProtobufEqual(extension_sync_data
);
144 class AppSyncDataTest
: public testing::Test
{
147 ~AppSyncDataTest() override
{}
149 void SetRequiredExtensionValues(
150 sync_pb::ExtensionSpecifics
* extension_specifics
) {
151 extension_specifics
->set_id(kValidId
);
152 extension_specifics
->set_update_url(kValidUpdateUrl
);
153 extension_specifics
->set_version(kVersion
);
154 extension_specifics
->set_enabled(false);
155 extension_specifics
->set_disable_reasons(kValidDisableReasons
);
156 extension_specifics
->set_incognito_enabled(true);
157 extension_specifics
->set_remote_install(false);
158 extension_specifics
->set_all_urls_enabled(true);
159 extension_specifics
->set_installed_by_custodian(false);
160 extension_specifics
->set_name(kName
);
164 TEST_F(AppSyncDataTest
, SyncDataToExtensionSyncDataForApp
) {
165 sync_pb::EntitySpecifics entity
;
166 sync_pb::AppSpecifics
* app_specifics
= entity
.mutable_app();
167 app_specifics
->set_app_launch_ordinal(
168 syncer::StringOrdinal::CreateInitialOrdinal().ToInternalValue());
169 app_specifics
->set_page_ordinal(
170 syncer::StringOrdinal::CreateInitialOrdinal().ToInternalValue());
172 SetRequiredExtensionValues(app_specifics
->mutable_extension());
174 syncer::SyncData sync_data
=
175 syncer::SyncData::CreateLocalData("sync_tag", "non_unique_title", entity
);
177 scoped_ptr
<ExtensionSyncData
> app_sync_data
=
178 ExtensionSyncData::CreateFromSyncData(sync_data
);
179 ASSERT_TRUE(app_sync_data
.get());
180 EXPECT_EQ(app_specifics
->app_launch_ordinal(),
181 app_sync_data
->app_launch_ordinal().ToInternalValue());
182 EXPECT_EQ(app_specifics
->page_ordinal(),
183 app_sync_data
->page_ordinal().ToInternalValue());
186 TEST_F(AppSyncDataTest
, ExtensionSyncDataToSyncDataForApp
) {
187 sync_pb::EntitySpecifics entity
;
188 sync_pb::AppSpecifics
* input_specifics
= entity
.mutable_app();
189 input_specifics
->set_app_launch_ordinal(
190 syncer::StringOrdinal::CreateInitialOrdinal().ToInternalValue());
191 input_specifics
->set_page_ordinal(
192 syncer::StringOrdinal::CreateInitialOrdinal().ToInternalValue());
194 SetRequiredExtensionValues(input_specifics
->mutable_extension());
196 syncer::SyncData sync_data
=
197 syncer::SyncData::CreateLocalData("sync_tag", "non_unique_title", entity
);
198 scoped_ptr
<ExtensionSyncData
> app_sync_data
=
199 ExtensionSyncData::CreateFromSyncData(sync_data
);
200 ASSERT_TRUE(app_sync_data
.get());
202 syncer::SyncData output_sync_data
= app_sync_data
->GetSyncData();
203 EXPECT_TRUE(sync_data
.GetSpecifics().has_app());
204 const sync_pb::AppSpecifics
& output_specifics
=
205 output_sync_data
.GetSpecifics().app();
206 EXPECT_EQ(input_specifics
->SerializeAsString(),
207 output_specifics
.SerializeAsString());
210 // Ensures that invalid StringOrdinals don't break ExtensionSyncData.
211 TEST_F(AppSyncDataTest
, ExtensionSyncDataInvalidOrdinal
) {
212 sync_pb::EntitySpecifics entity
;
213 sync_pb::AppSpecifics
* app_specifics
= entity
.mutable_app();
214 // Set the ordinals as invalid.
215 app_specifics
->set_app_launch_ordinal("");
216 app_specifics
->set_page_ordinal("");
218 SetRequiredExtensionValues(app_specifics
->mutable_extension());
220 syncer::SyncData sync_data
=
221 syncer::SyncData::CreateLocalData("sync_tag", "non_unique_title", entity
);
223 // There should be no issue loading the sync data.
224 scoped_ptr
<ExtensionSyncData
> app_sync_data
=
225 ExtensionSyncData::CreateFromSyncData(sync_data
);
226 ASSERT_TRUE(app_sync_data
.get());
227 app_sync_data
->GetSyncData();
230 } // namespace extensions