17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension_builder.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/value_builder.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = extensions::manifest_errors;
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::DictionaryBuilder;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Extension;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ExtensionBuilder;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ListBuilder;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass FileBrowserHandlerManifestTest : public ChromeManifestTest {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FileBrowserHandlerManifestTest, InvalidFileBrowserHandlers) {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Testcase testcases[] = {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_access_permission.json",
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             extensions::ErrorUtils::FormatErrorMessage(
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 errors::kInvalidFileAccessValue, base::IntToString(1))),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_access_permission_list.json",
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidFileAccessList),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_empty_access_permission_list.json",
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidFileAccessList),
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_actions_1.json",
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidFileBrowserHandler),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_actions_2.json",
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidFileBrowserHandler),
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_action_id.json",
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidPageActionId),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_action_title.json",
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidPageActionDefaultTitle),
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_file_filters_1.json",
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             errors::kInvalidFileFiltersList),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_file_filters_2.json",
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             extensions::ErrorUtils::FormatErrorMessage(
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                errors::kInvalidFileFilterValue, base::IntToString(0))),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Testcase("filebrowser_invalid_file_filters_url.json",
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             extensions::ErrorUtils::FormatErrorMessage(
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                errors::kInvalidURLPatternError, "http:*.html"))
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunTestcases(testcases, arraysize(testcases), EXPECT_TYPE_ERROR);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandler) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<const Extension> extension =
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ExtensionBuilder()
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .SetManifest(DictionaryBuilder()
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("name", "file browser handler test")
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("version", "1.0.0")
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("manifest_version", 2)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("file_browser_handlers", ListBuilder()
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       .Append(DictionaryBuilder()
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("id", "ExtremelyCoolAction")
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("default_title", "Be Amazed")
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("default_icon", "icon.png")
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("file_filters", ListBuilder()
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               .Append("filesystem:*.txt")))))
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Build();
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(extension.get());
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileBrowserHandler::List* handlers =
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileBrowserHandler::GetHandlers(extension.get());
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(handlers != NULL);
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(1U, handlers->size());
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileBrowserHandler* action = handlers->at(0).get();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("ExtremelyCoolAction", action->id());
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("Be Amazed", action->title());
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("icon.png", action->icon_path());
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const extensions::URLPatternSet& patterns = action->file_url_patterns();
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(1U, patterns.patterns().size());
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(action->MatchesURL(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL("filesystem:chrome-extension://foo/local/test.txt")));
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(action->HasCreateAccessPermission());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(action->CanRead());
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(action->CanWrite());
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandlerMIMETypes) {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<const Extension> extension =
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ExtensionBuilder()
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .SetID(extension_misc::kQuickOfficeExtensionId)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .SetManifest(DictionaryBuilder()
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("name", "file browser handler test")
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("version", "1.0.0")
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("manifest_version", 2)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("file_browser_handlers", ListBuilder()
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       .Append(DictionaryBuilder()
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("id", "ID")
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("default_title", "Default title")
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("default_icon", "icon.png")
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("file_filters", ListBuilder()
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               .Append("filesystem:*.txt")))))
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Build();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(extension.get());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileBrowserHandler::List* handlers =
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileBrowserHandler::GetHandlers(extension.get());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(handlers != NULL);
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(1U, handlers->size());
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileBrowserHandler* action = handlers->at(0).get();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const extensions::URLPatternSet& patterns = action->file_url_patterns();
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(1U, patterns.patterns().size());
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(action->MatchesURL(
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL("filesystem:chrome-extension://foo/local/test.txt")));
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandlerWithCreate) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<const Extension> extension =
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ExtensionBuilder()
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .SetManifest(DictionaryBuilder()
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("name", "file browser handler test create")
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("version", "1.0.0")
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("manifest_version", 2)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   .Set("file_browser_handlers", ListBuilder()
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       .Append(DictionaryBuilder()
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("id", "ID")
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("default_title", "Default title")
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("default_icon", "icon.png")
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("file_filters", ListBuilder()
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               .Append("filesystem:*.txt"))
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           .Set("file_access", ListBuilder()
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               .Append("create")))))
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Build();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(extension.get());
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileBrowserHandler::List* handlers =
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileBrowserHandler::GetHandlers(extension.get());
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(handlers != NULL);
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(1U, handlers->size());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileBrowserHandler* action = handlers->at(0).get();
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const extensions::URLPatternSet& patterns = action->file_url_patterns();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(0U, patterns.patterns().size());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(action->HasCreateAccessPermission());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(action->CanRead());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(action->CanWrite());
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
154