1 // Copyright 2013 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 #include "chrome/browser/drive/drive_api_util.h" 6 7 #include "base/files/scoped_temp_dir.h" 8 #include "base/md5.h" 9 #include "google_apis/drive/drive_api_parser.h" 10 #include "google_apis/drive/gdata_wapi_parser.h" 11 #include "google_apis/drive/test_util.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "url/gurl.h" 14 15 namespace drive { 16 namespace util { 17 18 TEST(DriveApiUtilTest, EscapeQueryStringValue) { 19 EXPECT_EQ("abcde", EscapeQueryStringValue("abcde")); 20 EXPECT_EQ("\\'", EscapeQueryStringValue("'")); 21 EXPECT_EQ("\\'abcde\\'", EscapeQueryStringValue("'abcde'")); 22 EXPECT_EQ("\\\\", EscapeQueryStringValue("\\")); 23 EXPECT_EQ("\\\\\\'", EscapeQueryStringValue("\\'")); 24 } 25 26 TEST(DriveApiUtilTest, TranslateQuery) { 27 EXPECT_EQ("", TranslateQuery("")); 28 EXPECT_EQ("fullText contains 'dog'", TranslateQuery("dog")); 29 EXPECT_EQ("fullText contains 'dog' and fullText contains 'cat'", 30 TranslateQuery("dog cat")); 31 EXPECT_EQ("not fullText contains 'cat'", TranslateQuery("-cat")); 32 EXPECT_EQ("fullText contains 'dog cat'", TranslateQuery("\"dog cat\"")); 33 34 // Should handles full-width white space correctly. 35 // Note: \xE3\x80\x80 (\u3000) is Ideographic Space (a.k.a. Japanese 36 // full-width whitespace). 37 EXPECT_EQ("fullText contains 'dog' and fullText contains 'cat'", 38 TranslateQuery("dog" "\xE3\x80\x80" "cat")); 39 40 // If the quoted token is not closed (i.e. the last '"' is missing), 41 // we handle the remaining string is one token, as a fallback. 42 EXPECT_EQ("fullText contains 'dog cat'", TranslateQuery("\"dog cat")); 43 44 // For quoted text with leading '-'. 45 EXPECT_EQ("not fullText contains 'dog cat'", TranslateQuery("-\"dog cat\"")); 46 47 // Empty tokens should be simply ignored. 48 EXPECT_EQ("", TranslateQuery("-")); 49 EXPECT_EQ("", TranslateQuery("\"\"")); 50 EXPECT_EQ("", TranslateQuery("-\"\"")); 51 EXPECT_EQ("", TranslateQuery("\"\"\"\"")); 52 EXPECT_EQ("", TranslateQuery("\"\" \"\"")); 53 EXPECT_EQ("fullText contains 'dog'", TranslateQuery("\"\" dog \"\"")); 54 } 55 56 TEST(FileSystemUtilTest, ExtractResourceIdFromUrl) { 57 EXPECT_EQ("file:2_file_resource_id", ExtractResourceIdFromUrl( 58 GURL("https://file1_link_self/file:2_file_resource_id"))); 59 // %3A should be unescaped. 60 EXPECT_EQ("file:2_file_resource_id", ExtractResourceIdFromUrl( 61 GURL("https://file1_link_self/file%3A2_file_resource_id"))); 62 63 // The resource ID cannot be extracted, hence empty. 64 EXPECT_EQ("", ExtractResourceIdFromUrl(GURL("https://www.example.com/"))); 65 } 66 67 TEST(FileSystemUtilTest, CanonicalizeResourceId) { 68 std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug"); 69 70 // New style ID is unchanged. 71 EXPECT_EQ(resource_id, CanonicalizeResourceId(resource_id)); 72 73 // Drop prefixes from old style IDs. 74 EXPECT_EQ(resource_id, CanonicalizeResourceId("document:" + resource_id)); 75 EXPECT_EQ(resource_id, CanonicalizeResourceId("spreadsheet:" + resource_id)); 76 EXPECT_EQ(resource_id, CanonicalizeResourceId("presentation:" + resource_id)); 77 EXPECT_EQ(resource_id, CanonicalizeResourceId("drawing:" + resource_id)); 78 EXPECT_EQ(resource_id, CanonicalizeResourceId("table:" + resource_id)); 79 EXPECT_EQ(resource_id, CanonicalizeResourceId("externalapp:" + resource_id)); 80 } 81 82 TEST(FileSystemUtilTest, ConvertAccountMetadataToAboutResource) { 83 google_apis::AccountMetadata account_metadata; 84 // Set up AccountMetadata instance. 85 { 86 account_metadata.set_quota_bytes_total(10000); 87 account_metadata.set_quota_bytes_used(1000); 88 account_metadata.set_largest_changestamp(100); 89 } 90 91 scoped_ptr<google_apis::AboutResource> about_resource( 92 ConvertAccountMetadataToAboutResource( 93 account_metadata, "dummy_root_id")); 94 95 EXPECT_EQ(10000, about_resource->quota_bytes_total()); 96 EXPECT_EQ(1000, about_resource->quota_bytes_used()); 97 EXPECT_EQ(100, about_resource->largest_change_id()); 98 EXPECT_EQ("dummy_root_id", about_resource->root_folder_id()); 99 } 100 101 TEST(FileSystemUtilTest, ConvertAccountMetadataToAppList) { 102 google_apis::AccountMetadata account_metadata; 103 // Set up AccountMetadata instance. 104 { 105 ScopedVector<google_apis::InstalledApp> installed_apps; 106 scoped_ptr<google_apis::InstalledApp> installed_app( 107 new google_apis::InstalledApp); 108 installed_app->set_app_id("app_id"); 109 installed_app->set_app_name("name"); 110 installed_app->set_object_type("object_type"); 111 installed_app->set_supports_create(true); 112 113 { 114 ScopedVector<google_apis::Link> links; 115 scoped_ptr<google_apis::Link> link(new google_apis::Link); 116 link->set_type(google_apis::Link::LINK_PRODUCT); 117 link->set_href(GURL("http://product/url")); 118 links.push_back(link.release()); 119 installed_app->set_links(links.Pass()); 120 } 121 { 122 ScopedVector<std::string> primary_mimetypes; 123 primary_mimetypes.push_back(new std::string("primary_mimetype")); 124 installed_app->set_primary_mimetypes(primary_mimetypes.Pass()); 125 } 126 { 127 ScopedVector<std::string> secondary_mimetypes; 128 secondary_mimetypes.push_back(new std::string("secondary_mimetype")); 129 installed_app->set_secondary_mimetypes(secondary_mimetypes.Pass()); 130 } 131 { 132 ScopedVector<std::string> primary_extensions; 133 primary_extensions.push_back(new std::string("primary_extension")); 134 installed_app->set_primary_extensions(primary_extensions.Pass()); 135 } 136 { 137 ScopedVector<std::string> secondary_extensions; 138 secondary_extensions.push_back(new std::string("secondary_extension")); 139 installed_app->set_secondary_extensions(secondary_extensions.Pass()); 140 } 141 { 142 ScopedVector<google_apis::AppIcon> app_icons; 143 scoped_ptr<google_apis::AppIcon> app_icon(new google_apis::AppIcon); 144 app_icon->set_category(google_apis::AppIcon::ICON_DOCUMENT); 145 app_icon->set_icon_side_length(10); 146 { 147 ScopedVector<google_apis::Link> links; 148 scoped_ptr<google_apis::Link> link(new google_apis::Link); 149 link->set_type(google_apis::Link::LINK_ICON); 150 link->set_href(GURL("http://icon/url")); 151 links.push_back(link.release()); 152 app_icon->set_links(links.Pass()); 153 } 154 app_icons.push_back(app_icon.release()); 155 installed_app->set_app_icons(app_icons.Pass()); 156 } 157 158 installed_apps.push_back(installed_app.release()); 159 account_metadata.set_installed_apps(installed_apps.Pass()); 160 } 161 162 scoped_ptr<google_apis::AppList> app_list( 163 ConvertAccountMetadataToAppList(account_metadata)); 164 const ScopedVector<google_apis::AppResource>& items = app_list->items(); 165 ASSERT_EQ(1U, items.size()); 166 167 const google_apis::AppResource& app_resource = *items[0]; 168 EXPECT_EQ("app_id", app_resource.application_id()); 169 EXPECT_EQ("name", app_resource.name()); 170 EXPECT_EQ("object_type", app_resource.object_type()); 171 EXPECT_TRUE(app_resource.supports_create()); 172 EXPECT_EQ("http://product/url", app_resource.product_url().spec()); 173 const ScopedVector<std::string>& primary_mimetypes = 174 app_resource.primary_mimetypes(); 175 ASSERT_EQ(1U, primary_mimetypes.size()); 176 EXPECT_EQ("primary_mimetype", *primary_mimetypes[0]); 177 const ScopedVector<std::string>& secondary_mimetypes = 178 app_resource.secondary_mimetypes(); 179 ASSERT_EQ(1U, secondary_mimetypes.size()); 180 EXPECT_EQ("secondary_mimetype", *secondary_mimetypes[0]); 181 const ScopedVector<std::string>& primary_file_extensions = 182 app_resource.primary_file_extensions(); 183 ASSERT_EQ(1U, primary_file_extensions.size()); 184 EXPECT_EQ("primary_extension", *primary_file_extensions[0]); 185 const ScopedVector<std::string>& secondary_file_extensions = 186 app_resource.secondary_file_extensions(); 187 ASSERT_EQ(1U, secondary_file_extensions.size()); 188 EXPECT_EQ("secondary_extension", *secondary_file_extensions[0]); 189 190 const ScopedVector<google_apis::DriveAppIcon>& icons = app_resource.icons(); 191 ASSERT_EQ(1U, icons.size()); 192 const google_apis::DriveAppIcon& icon = *icons[0]; 193 EXPECT_EQ(google_apis::DriveAppIcon::DOCUMENT, icon.category()); 194 EXPECT_EQ(10, icon.icon_side_length()); 195 EXPECT_EQ("http://icon/url", icon.icon_url().spec()); 196 } 197 198 TEST(FileSystemUtilTest, ConvertFileResourceToResource_Parents) { 199 google_apis::FileResource file_resource; 200 201 std::vector<GURL> expected_links; 202 expected_links.push_back(GURL("http://server/id1")); 203 expected_links.push_back(GURL("http://server/id2")); 204 expected_links.push_back(GURL("http://server/id3")); 205 206 ScopedVector<google_apis::ParentReference> parents; 207 for (size_t i = 0; i < expected_links.size(); ++i) { 208 google_apis::ParentReference* parent = new google_apis::ParentReference; 209 parent->set_parent_link(expected_links[i]); 210 parents.push_back(parent); 211 } 212 file_resource.set_parents(parents.Pass()); 213 214 scoped_ptr<google_apis::ResourceEntry> entry( 215 ConvertFileResourceToResourceEntry(file_resource)); 216 std::vector<GURL> actual_links; 217 for (size_t i = 0; i < entry->links().size(); ++i) { 218 if (entry->links()[i]->type() == google_apis::Link::LINK_PARENT) 219 actual_links.push_back(entry->links()[i]->href()); 220 } 221 222 EXPECT_EQ(expected_links, actual_links); 223 } 224 225 TEST(FileSystemUtilTest, ConvertFileResourceToResourceEntryImageMediaMetadata) { 226 google_apis::FileResource file_resource_all_fields; 227 google_apis::FileResource file_resource_zero_fields; 228 google_apis::FileResource file_resource_no_fields; 229 // Set up FileResource instances; 230 { 231 { 232 google_apis::ImageMediaMetadata* image_media_metadata = 233 file_resource_all_fields.mutable_image_media_metadata(); 234 image_media_metadata->set_width(640); 235 image_media_metadata->set_height(480); 236 image_media_metadata->set_rotation(90); 237 } 238 { 239 google_apis::ImageMediaMetadata* image_media_metadata = 240 file_resource_zero_fields.mutable_image_media_metadata(); 241 image_media_metadata->set_width(0); 242 image_media_metadata->set_height(0); 243 image_media_metadata->set_rotation(0); 244 } 245 } 246 247 // Verify the converted values. 248 { 249 scoped_ptr<google_apis::ResourceEntry> resource_entry( 250 ConvertFileResourceToResourceEntry(file_resource_all_fields)); 251 252 EXPECT_EQ(640, resource_entry->image_width()); 253 EXPECT_EQ(480, resource_entry->image_height()); 254 EXPECT_EQ(90, resource_entry->image_rotation()); 255 } 256 { 257 scoped_ptr<google_apis::ResourceEntry> resource_entry( 258 ConvertFileResourceToResourceEntry(file_resource_zero_fields)); 259 260 EXPECT_EQ(0, resource_entry->image_width()); 261 EXPECT_EQ(0, resource_entry->image_height()); 262 EXPECT_EQ(0, resource_entry->image_rotation()); 263 } 264 { 265 scoped_ptr<google_apis::ResourceEntry> resource_entry( 266 ConvertFileResourceToResourceEntry(file_resource_no_fields)); 267 268 EXPECT_EQ(-1, resource_entry->image_width()); 269 EXPECT_EQ(-1, resource_entry->image_height()); 270 EXPECT_EQ(-1, resource_entry->image_rotation()); 271 } 272 } 273 274 TEST(FileSystemUtilTest, ConvertResourceEntryToFileResourceImageMediaMetadata) { 275 google_apis::ResourceEntry resource_entry_all_fields; 276 google_apis::ResourceEntry resource_entry_zero_fields; 277 google_apis::ResourceEntry resource_entry_no_fields; 278 // Set up FileResource instances; 279 { 280 resource_entry_all_fields.set_image_width(640); 281 resource_entry_all_fields.set_image_height(480); 282 resource_entry_all_fields.set_image_rotation(90); 283 284 resource_entry_zero_fields.set_image_width(0); 285 resource_entry_zero_fields.set_image_height(0); 286 resource_entry_zero_fields.set_image_rotation(0); 287 } 288 289 // Verify the converted values. 290 { 291 scoped_ptr<google_apis::FileResource> file_resource( 292 ConvertResourceEntryToFileResource(resource_entry_all_fields)); 293 const google_apis::ImageMediaMetadata& image_media_metadata = 294 file_resource->image_media_metadata(); 295 EXPECT_EQ(640, image_media_metadata.width()); 296 EXPECT_EQ(480, image_media_metadata.height()); 297 EXPECT_EQ(90, image_media_metadata.rotation()); 298 } 299 { 300 scoped_ptr<google_apis::FileResource> file_resource( 301 ConvertResourceEntryToFileResource(resource_entry_zero_fields)); 302 const google_apis::ImageMediaMetadata& image_media_metadata = 303 file_resource->image_media_metadata(); 304 EXPECT_EQ(0, image_media_metadata.width()); 305 EXPECT_EQ(0, image_media_metadata.height()); 306 EXPECT_EQ(0, image_media_metadata.rotation()); 307 } 308 { 309 scoped_ptr<google_apis::FileResource> file_resource( 310 ConvertResourceEntryToFileResource(resource_entry_no_fields)); 311 const google_apis::ImageMediaMetadata& image_media_metadata = 312 file_resource->image_media_metadata(); 313 EXPECT_EQ(-1, image_media_metadata.width()); 314 EXPECT_EQ(-1, image_media_metadata.height()); 315 EXPECT_EQ(-1, image_media_metadata.rotation()); 316 } 317 } 318 319 TEST(DriveAPIUtilTest, GetMd5Digest) { 320 base::ScopedTempDir temp_dir; 321 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 322 323 base::FilePath path = temp_dir.path().AppendASCII("test.txt"); 324 const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789"; 325 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, kTestData)); 326 327 EXPECT_EQ(base::MD5String(kTestData), GetMd5Digest(path)); 328 } 329 330 } // namespace util 331 } // namespace drive 332