Home | History | Annotate | Download | only in drive
      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