Home | History | Annotate | Download | only in file_system
      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.
      4 
      5 #include "base/files/file_path.h"
      6 #include "base/strings/string_split.h"
      7 #include "base/strings/string_util.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "ui/shell_dialogs/select_file_dialog.h"
     12 
     13 using extensions::FileSystemChooseEntryFunction;
     14 using extensions::api::file_system::AcceptOption;
     15 
     16 namespace {
     17 
     18 void CheckExtensions(const std::vector<base::FilePath::StringType>& expected,
     19                      const std::vector<base::FilePath::StringType>& actual) {
     20   EXPECT_EQ(expected.size(), actual.size());
     21   if (expected.size() != actual.size())
     22     return;
     23 
     24   for (size_t i = 0; i < expected.size(); ++i) {
     25     EXPECT_EQ(expected[i], actual[i]);
     26   }
     27 }
     28 
     29 AcceptOption* BuildAcceptOption(const std::string& description,
     30                                 const std::string& mime_types,
     31                                 const std::string& extensions) {
     32   AcceptOption* option = new AcceptOption();
     33 
     34   if (!description.empty())
     35     option->description.reset(new std::string(description));
     36 
     37   if (!mime_types.empty()) {
     38     option->mime_types.reset(new std::vector<std::string>());
     39     base::SplitString(mime_types, ',', option->mime_types.get());
     40   }
     41 
     42   if (!extensions.empty()) {
     43     option->extensions.reset(new std::vector<std::string>());
     44     base::SplitString(extensions, ',', option->extensions.get());
     45   }
     46 
     47   return option;
     48 }
     49 
     50 #if defined(OS_WIN)
     51 #define ToStringType base::UTF8ToWide
     52 #else
     53 #define ToStringType
     54 #endif
     55 
     56 }  // namespace
     57 
     58 class FileSystemApiUnitTest : public testing::Test {
     59 };
     60 
     61 TEST_F(FileSystemApiUnitTest, FileSystemChooseEntryFunctionFileTypeInfoTest) {
     62   // AcceptsAllTypes is ignored when no other extensions are available.
     63   ui::SelectFileDialog::FileTypeInfo file_type_info;
     64   bool acceptsAllTypes = false;
     65   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
     66       base::FilePath::StringType(), NULL, &acceptsAllTypes);
     67   EXPECT_TRUE(file_type_info.include_all_files);
     68   EXPECT_TRUE(file_type_info.extensions.empty());
     69 
     70   // Test grouping of multiple types.
     71   file_type_info = ui::SelectFileDialog::FileTypeInfo();
     72   std::vector<linked_ptr<AcceptOption> > options;
     73   options.push_back(linked_ptr<AcceptOption>(BuildAcceptOption(
     74       std::string(), "application/x-chrome-extension", "jso")));
     75   acceptsAllTypes = false;
     76   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
     77       base::FilePath::StringType(), &options, &acceptsAllTypes);
     78   EXPECT_FALSE(file_type_info.include_all_files);
     79   ASSERT_EQ(file_type_info.extensions.size(), (size_t) 1);
     80   EXPECT_TRUE(file_type_info.extension_description_overrides[0].empty()) <<
     81       "No override must be specified for boring accept types";
     82   // Note here (and below) that the expectedTypes are sorted, because we use a
     83   // set internally to generate the output: thus, the output is sorted.
     84   std::vector<base::FilePath::StringType> expectedTypes;
     85   expectedTypes.push_back(ToStringType("crx"));
     86   expectedTypes.push_back(ToStringType("jso"));
     87   CheckExtensions(expectedTypes, file_type_info.extensions[0]);
     88 
     89   // Test that not satisfying the extension will force all types.
     90   file_type_info = ui::SelectFileDialog::FileTypeInfo();
     91   options.clear();
     92   options.push_back(linked_ptr<AcceptOption>(BuildAcceptOption(
     93       std::string(), std::string(), "unrelated")));
     94   acceptsAllTypes = false;
     95   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
     96       ToStringType(".jso"), &options, &acceptsAllTypes);
     97   EXPECT_TRUE(file_type_info.include_all_files);
     98 
     99   // Test multiple list entries, all containing their own types.
    100   file_type_info = ui::SelectFileDialog::FileTypeInfo();
    101   options.clear();
    102   options.push_back(linked_ptr<AcceptOption>(
    103       BuildAcceptOption(std::string(), std::string(), "jso,js")));
    104   options.push_back(linked_ptr<AcceptOption>(
    105       BuildAcceptOption(std::string(), std::string(), "cpp,cc")));
    106   acceptsAllTypes = false;
    107   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
    108       base::FilePath::StringType(), &options, &acceptsAllTypes);
    109   ASSERT_EQ(file_type_info.extensions.size(), options.size());
    110 
    111   expectedTypes.clear();
    112   expectedTypes.push_back(ToStringType("js"));
    113   expectedTypes.push_back(ToStringType("jso"));
    114   CheckExtensions(expectedTypes, file_type_info.extensions[0]);
    115 
    116   expectedTypes.clear();
    117   expectedTypes.push_back(ToStringType("cc"));
    118   expectedTypes.push_back(ToStringType("cpp"));
    119   CheckExtensions(expectedTypes, file_type_info.extensions[1]);
    120 
    121   // Test accept type that causes description override.
    122   file_type_info = ui::SelectFileDialog::FileTypeInfo();
    123   options.clear();
    124   options.push_back(linked_ptr<AcceptOption>(
    125       BuildAcceptOption(std::string(), "image/*", "html")));
    126   acceptsAllTypes = false;
    127   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
    128       base::FilePath::StringType(), &options, &acceptsAllTypes);
    129   ASSERT_EQ(file_type_info.extension_description_overrides.size(), (size_t) 1);
    130   EXPECT_FALSE(file_type_info.extension_description_overrides[0].empty()) <<
    131       "Accept type \"image/*\" must generate description override";
    132 
    133   // Test multiple accept types that cause description override causes us to
    134   // still present the default.
    135   file_type_info = ui::SelectFileDialog::FileTypeInfo();
    136   options.clear();
    137   options.push_back(linked_ptr<AcceptOption>(BuildAcceptOption(
    138       std::string(), "image/*,audio/*,video/*", std::string())));
    139   acceptsAllTypes = false;
    140   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
    141       base::FilePath::StringType(), &options, &acceptsAllTypes);
    142   ASSERT_EQ(file_type_info.extension_description_overrides.size(), (size_t) 1);
    143   EXPECT_TRUE(file_type_info.extension_description_overrides[0].empty());
    144 
    145   // Test explicit description override.
    146   file_type_info = ui::SelectFileDialog::FileTypeInfo();
    147   options.clear();
    148   options.push_back(linked_ptr<AcceptOption>(
    149       BuildAcceptOption("File Types 101", "image/jpeg", std::string())));
    150   acceptsAllTypes = false;
    151   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
    152       base::FilePath::StringType(), &options, &acceptsAllTypes);
    153   EXPECT_EQ(file_type_info.extension_description_overrides[0],
    154       base::UTF8ToUTF16("File Types 101"));
    155 }
    156 
    157 TEST_F(FileSystemApiUnitTest, FileSystemChooseEntryFunctionSuggestionTest) {
    158   std::string opt_name;
    159   base::FilePath suggested_name;
    160   base::FilePath::StringType suggested_extension;
    161 
    162   opt_name = std::string("normal_path.txt");
    163   FileSystemChooseEntryFunction::BuildSuggestion(&opt_name, &suggested_name,
    164       &suggested_extension);
    165   EXPECT_FALSE(suggested_name.IsAbsolute());
    166   EXPECT_EQ(suggested_name.MaybeAsASCII(), "normal_path.txt");
    167   EXPECT_EQ(suggested_extension, ToStringType("txt"));
    168 
    169   // We should provide just the basename, i.e., "path".
    170   opt_name = std::string("/a/bad/path");
    171   FileSystemChooseEntryFunction::BuildSuggestion(&opt_name, &suggested_name,
    172       &suggested_extension);
    173   EXPECT_FALSE(suggested_name.IsAbsolute());
    174   EXPECT_EQ(suggested_name.MaybeAsASCII(), "path");
    175   EXPECT_TRUE(suggested_extension.empty());
    176 
    177 #if !defined(OS_WIN)
    178   // TODO(thorogood): Fix this test on Windows.
    179   // Filter out absolute paths with no basename.
    180   opt_name = std::string("/");
    181   FileSystemChooseEntryFunction::BuildSuggestion(&opt_name, &suggested_name,
    182       &suggested_extension);
    183   EXPECT_FALSE(suggested_name.IsAbsolute());
    184   EXPECT_TRUE(suggested_name.MaybeAsASCII().empty());
    185   EXPECT_TRUE(suggested_extension.empty());
    186 #endif
    187 }
    188