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#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_TESTS_EXTENSION_MANIFEST_TEST_H_
6#define CHROME_COMMON_EXTENSIONS_MANIFEST_TESTS_EXTENSION_MANIFEST_TEST_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/values.h"
11#include "chrome/common/extensions/features/feature_channel.h"
12#include "extensions/common/extension.h"
13#include "extensions/common/manifest.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16class ExtensionManifestTest : public testing::Test {
17 public:
18  ExtensionManifestTest();
19
20 protected:
21  // Helper class that simplifies creating methods that take either a filename
22  // to a manifest or the manifest itself.
23  class Manifest {
24   public:
25    explicit Manifest(const char* name);
26    Manifest(base::DictionaryValue* manifest, const char* name);
27    explicit Manifest(scoped_ptr<base::DictionaryValue> manifest);
28    // C++98 requires the copy constructor for a type to be visible if you
29    // take a const-ref of a temporary for that type.  Since Manifest
30    // contains a scoped_ptr, its implicit copy constructor is declared
31    // Manifest(Manifest&) according to spec 12.8.5.  This breaks the first
32    // requirement and thus you cannot use it with LoadAndExpectError() or
33    // LoadAndExpectSuccess() easily.
34    //
35    // To get around this spec pedantry, we declare the copy constructor
36    // explicitly.  It will never get invoked.
37    Manifest(const Manifest& m);
38
39    ~Manifest();
40
41    const std::string& name() const { return name_; };
42
43    base::DictionaryValue* GetManifest(char const* test_data_dir,
44                                       std::string* error) const;
45
46   private:
47    const std::string name_;
48    mutable base::DictionaryValue* manifest_;
49    mutable scoped_ptr<base::DictionaryValue> manifest_holder_;
50  };
51
52  // The subdirectory in which to find test data files.
53  virtual char const* test_data_dir();
54
55  scoped_ptr<base::DictionaryValue> LoadManifest(
56      char const* manifest_name,
57      std::string* error);
58
59  scoped_refptr<extensions::Extension> LoadExtension(
60      const Manifest& manifest,
61      std::string* error,
62      extensions::Manifest::Location location =
63          extensions::Manifest::INTERNAL,
64      int flags = extensions::Extension::NO_FLAGS);
65
66  scoped_refptr<extensions::Extension> LoadAndExpectSuccess(
67      const Manifest& manifest,
68      extensions::Manifest::Location location =
69          extensions::Manifest::INTERNAL,
70      int flags = extensions::Extension::NO_FLAGS);
71
72  scoped_refptr<extensions::Extension> LoadAndExpectSuccess(
73      char const* manifest_name,
74      extensions::Manifest::Location location =
75          extensions::Manifest::INTERNAL,
76      int flags = extensions::Extension::NO_FLAGS);
77
78  // Load and expect success from a manifest provided as a json string. Single
79  // quotes will be replaced with double quotes for test readability.
80  scoped_refptr<extensions::Extension> LoadFromStringAndExpectSuccess(
81      char const* manifest_json);
82
83  scoped_refptr<extensions::Extension> LoadAndExpectWarning(
84      const Manifest& manifest,
85      const std::string& expected_error,
86      extensions::Manifest::Location location =
87          extensions::Manifest::INTERNAL,
88      int flags = extensions::Extension::NO_FLAGS);
89
90  scoped_refptr<extensions::Extension> LoadAndExpectWarning(
91      char const* manifest_name,
92      const std::string& expected_error,
93      extensions::Manifest::Location location =
94          extensions::Manifest::INTERNAL,
95      int flags = extensions::Extension::NO_FLAGS);
96
97  void VerifyExpectedError(extensions::Extension* extension,
98                           const std::string& name,
99                           const std::string& error,
100                           const std::string& expected_error);
101
102  void LoadAndExpectError(char const* manifest_name,
103                          const std::string& expected_error,
104                          extensions::Manifest::Location location =
105                              extensions::Manifest::INTERNAL,
106                          int flags = extensions::Extension::NO_FLAGS);
107
108  void LoadAndExpectError(const Manifest& manifest,
109                          const std::string& expected_error,
110                          extensions::Manifest::Location location =
111                              extensions::Manifest::INTERNAL,
112                          int flags = extensions::Extension::NO_FLAGS);
113
114  // Load and expect an error from a manifest provided as a json string. Single
115  // quotes will be replaced with double quotes for test readability.
116  void LoadFromStringAndExpectError(char const* manifest_json,
117                                    const std::string& expected_error);
118
119  void AddPattern(extensions::URLPatternSet* extent,
120                  const std::string& pattern);
121
122  // used to differentiate between calls to LoadAndExpectError,
123  // LoadAndExpectWarning and LoadAndExpectSuccess via function RunTestcases.
124  enum ExpectType {
125    EXPECT_TYPE_ERROR,
126    EXPECT_TYPE_WARNING,
127    EXPECT_TYPE_SUCCESS
128  };
129
130  struct Testcase {
131    std::string manifest_filename_;
132    std::string expected_error_; // only used for ExpectedError tests
133    extensions::Manifest::Location location_;
134    int flags_;
135
136    Testcase(std::string manifest_filename, std::string expected_error,
137        extensions::Manifest::Location location, int flags);
138
139    Testcase(std::string manifest_filename, std::string expected_error);
140
141    explicit Testcase(std::string manifest_filename);
142
143    Testcase(std::string manifest_filename,
144             extensions::Manifest::Location location,
145             int flags);
146  };
147
148  void RunTestcases(const Testcase* testcases,
149                    size_t num_testcases,
150                    ExpectType type);
151
152  void RunTestcase(const Testcase& testcase, ExpectType type);
153
154  bool enable_apps_;
155
156  // Force the manifest tests to run as though they are on trunk, since several
157  // tests rely on manifest features being available that aren't on
158  // stable/beta.
159  //
160  // These objects nest, so if a test wants to explicitly test the behaviour
161  // on stable or beta, declare it inside that test.
162  extensions::ScopedCurrentChannel current_channel_;
163};
164
165#endif  // CHROME_COMMON_EXTENSIONS_MANIFEST_TESTS_EXTENSION_MANIFEST_TEST_H_
166