Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / fileapi / copy_or_move_file_validator_unittest.cc
blobea2ba898940a0d75bdf565347174663cc5f10c80
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.
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/run_loop.h"
10 #include "content/public/test/async_file_test_helper.h"
11 #include "content/public/test/mock_special_storage_policy.h"
12 #include "content/public/test/test_file_system_backend.h"
13 #include "content/public/test/test_file_system_context.h"
14 #include "storage/browser/fileapi/copy_or_move_file_validator.h"
15 #include "storage/browser/fileapi/external_mount_points.h"
16 #include "storage/browser/fileapi/file_system_backend.h"
17 #include "storage/browser/fileapi/file_system_context.h"
18 #include "storage/browser/fileapi/file_system_url.h"
19 #include "storage/browser/fileapi/isolated_context.h"
20 #include "storage/common/blob/shareable_file_reference.h"
21 #include "storage/common/fileapi/file_system_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using content::AsyncFileTestHelper;
25 using storage::CopyOrMoveFileValidator;
26 using storage::CopyOrMoveFileValidatorFactory;
27 using storage::FileSystemURL;
29 namespace content {
31 namespace {
33 const storage::FileSystemType kNoValidatorType =
34 storage::kFileSystemTypeTemporary;
35 const storage::FileSystemType kWithValidatorType = storage::kFileSystemTypeTest;
37 void ExpectOk(const GURL& origin_url,
38 const std::string& name,
39 base::File::Error error) {
40 ASSERT_EQ(base::File::FILE_OK, error);
43 class CopyOrMoveFileValidatorTestHelper {
44 public:
45 CopyOrMoveFileValidatorTestHelper(const GURL& origin,
46 storage::FileSystemType src_type,
47 storage::FileSystemType dest_type)
48 : origin_(origin), src_type_(src_type), dest_type_(dest_type) {}
50 ~CopyOrMoveFileValidatorTestHelper() {
51 file_system_context_ = NULL;
52 base::RunLoop().RunUntilIdle();
55 void SetUp() {
56 ASSERT_TRUE(base_.CreateUniqueTempDir());
57 base::FilePath base_dir = base_.path();
59 file_system_context_ = CreateFileSystemContextForTesting(NULL, base_dir);
61 // Set up TestFileSystemBackend to require CopyOrMoveFileValidator.
62 storage::FileSystemBackend* test_file_system_backend =
63 file_system_context_->GetFileSystemBackend(kWithValidatorType);
64 static_cast<TestFileSystemBackend*>(test_file_system_backend)->
65 set_require_copy_or_move_validator(true);
67 // Sets up source.
68 storage::FileSystemBackend* src_file_system_backend =
69 file_system_context_->GetFileSystemBackend(src_type_);
70 src_file_system_backend->ResolveURL(
71 FileSystemURL::CreateForTest(origin_, src_type_, base::FilePath()),
72 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
73 base::Bind(&ExpectOk));
74 base::RunLoop().RunUntilIdle();
75 ASSERT_EQ(base::File::FILE_OK, CreateDirectory(SourceURL("")));
77 // Sets up dest.
78 DCHECK_EQ(kWithValidatorType, dest_type_);
79 ASSERT_EQ(base::File::FILE_OK, CreateDirectory(DestURL("")));
81 copy_src_ = SourceURL("copy_src.jpg");
82 move_src_ = SourceURL("move_src.jpg");
83 copy_dest_ = DestURL("copy_dest.jpg");
84 move_dest_ = DestURL("move_dest.jpg");
86 ASSERT_EQ(base::File::FILE_OK, CreateFile(copy_src_, 10));
87 ASSERT_EQ(base::File::FILE_OK, CreateFile(move_src_, 10));
89 ASSERT_TRUE(FileExists(copy_src_, 10));
90 ASSERT_TRUE(FileExists(move_src_, 10));
91 ASSERT_FALSE(FileExists(copy_dest_, 10));
92 ASSERT_FALSE(FileExists(move_dest_, 10));
95 void SetMediaCopyOrMoveFileValidatorFactory(
96 scoped_ptr<storage::CopyOrMoveFileValidatorFactory> factory) {
97 TestFileSystemBackend* backend = static_cast<TestFileSystemBackend*>(
98 file_system_context_->GetFileSystemBackend(kWithValidatorType));
99 backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
102 void CopyTest(base::File::Error expected) {
103 ASSERT_TRUE(FileExists(copy_src_, 10));
104 ASSERT_FALSE(FileExists(copy_dest_, 10));
106 EXPECT_EQ(expected,
107 AsyncFileTestHelper::Copy(
108 file_system_context_.get(), copy_src_, copy_dest_));
110 EXPECT_TRUE(FileExists(copy_src_, 10));
111 if (expected == base::File::FILE_OK)
112 EXPECT_TRUE(FileExists(copy_dest_, 10));
113 else
114 EXPECT_FALSE(FileExists(copy_dest_, 10));
117 void MoveTest(base::File::Error expected) {
118 ASSERT_TRUE(FileExists(move_src_, 10));
119 ASSERT_FALSE(FileExists(move_dest_, 10));
121 EXPECT_EQ(expected,
122 AsyncFileTestHelper::Move(
123 file_system_context_.get(), move_src_, move_dest_));
125 if (expected == base::File::FILE_OK) {
126 EXPECT_FALSE(FileExists(move_src_, 10));
127 EXPECT_TRUE(FileExists(move_dest_, 10));
128 } else {
129 EXPECT_TRUE(FileExists(move_src_, 10));
130 EXPECT_FALSE(FileExists(move_dest_, 10));
134 private:
135 FileSystemURL SourceURL(const std::string& path) {
136 return file_system_context_->CreateCrackedFileSystemURL(
137 origin_, src_type_,
138 base::FilePath().AppendASCII("src").AppendASCII(path));
141 FileSystemURL DestURL(const std::string& path) {
142 return file_system_context_->CreateCrackedFileSystemURL(
143 origin_, dest_type_,
144 base::FilePath().AppendASCII("dest").AppendASCII(path));
147 base::File::Error CreateFile(const FileSystemURL& url, size_t size) {
148 base::File::Error result =
149 AsyncFileTestHelper::CreateFile(file_system_context_.get(), url);
150 if (result != base::File::FILE_OK)
151 return result;
152 return AsyncFileTestHelper::TruncateFile(
153 file_system_context_.get(), url, size);
156 base::File::Error CreateDirectory(const FileSystemURL& url) {
157 return AsyncFileTestHelper::CreateDirectory(file_system_context_.get(),
158 url);
161 bool FileExists(const FileSystemURL& url, int64 expected_size) {
162 return AsyncFileTestHelper::FileExists(
163 file_system_context_.get(), url, expected_size);
166 base::ScopedTempDir base_;
168 const GURL origin_;
170 const storage::FileSystemType src_type_;
171 const storage::FileSystemType dest_type_;
172 std::string src_fsid_;
173 std::string dest_fsid_;
175 base::MessageLoop message_loop_;
176 scoped_refptr<storage::FileSystemContext> file_system_context_;
178 FileSystemURL copy_src_;
179 FileSystemURL copy_dest_;
180 FileSystemURL move_src_;
181 FileSystemURL move_dest_;
183 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveFileValidatorTestHelper);
186 // For TestCopyOrMoveFileValidatorFactory
187 enum Validity {
188 VALID,
189 PRE_WRITE_INVALID,
190 POST_WRITE_INVALID
193 class TestCopyOrMoveFileValidatorFactory
194 : public storage::CopyOrMoveFileValidatorFactory {
195 public:
196 // A factory that creates validators that accept everything or nothing.
197 // TODO(gbillock): switch args to enum or something
198 explicit TestCopyOrMoveFileValidatorFactory(Validity validity)
199 : validity_(validity) {}
200 ~TestCopyOrMoveFileValidatorFactory() override {}
202 storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
203 const FileSystemURL& /*src_url*/,
204 const base::FilePath& /*platform_path*/) override {
205 return new TestCopyOrMoveFileValidator(validity_);
208 private:
209 class TestCopyOrMoveFileValidator : public CopyOrMoveFileValidator {
210 public:
211 explicit TestCopyOrMoveFileValidator(Validity validity)
212 : result_(validity == VALID || validity == POST_WRITE_INVALID ?
213 base::File::FILE_OK :
214 base::File::FILE_ERROR_SECURITY),
215 write_result_(validity == VALID || validity == PRE_WRITE_INVALID ?
216 base::File::FILE_OK :
217 base::File::FILE_ERROR_SECURITY) {
219 ~TestCopyOrMoveFileValidator() override {}
221 void StartPreWriteValidation(
222 const ResultCallback& result_callback) override {
223 // Post the result since a real validator must do work asynchronously.
224 base::MessageLoop::current()->PostTask(
225 FROM_HERE, base::Bind(result_callback, result_));
228 void StartPostWriteValidation(
229 const base::FilePath& dest_platform_path,
230 const ResultCallback& result_callback) override {
231 // Post the result since a real validator must do work asynchronously.
232 base::MessageLoop::current()->PostTask(
233 FROM_HERE, base::Bind(result_callback, write_result_));
236 private:
237 base::File::Error result_;
238 base::File::Error write_result_;
240 DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidator);
243 Validity validity_;
245 DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidatorFactory);
248 } // namespace
250 TEST(CopyOrMoveFileValidatorTest, NoValidatorWithinSameFSType) {
251 // Within a file system type, validation is not expected, so it should
252 // work for kWithValidatorType without a validator set.
253 CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
254 kWithValidatorType,
255 kWithValidatorType);
256 helper.SetUp();
257 helper.CopyTest(base::File::FILE_OK);
258 helper.MoveTest(base::File::FILE_OK);
261 TEST(CopyOrMoveFileValidatorTest, MissingValidator) {
262 // Copying or moving into a kWithValidatorType requires a file
263 // validator. An error is expected if copy is attempted without a validator.
264 CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
265 kNoValidatorType,
266 kWithValidatorType);
267 helper.SetUp();
268 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
269 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
272 TEST(CopyOrMoveFileValidatorTest, AcceptAll) {
273 CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
274 kNoValidatorType,
275 kWithValidatorType);
276 helper.SetUp();
277 scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
278 new TestCopyOrMoveFileValidatorFactory(VALID));
279 helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
281 helper.CopyTest(base::File::FILE_OK);
282 helper.MoveTest(base::File::FILE_OK);
285 TEST(CopyOrMoveFileValidatorTest, AcceptNone) {
286 CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
287 kNoValidatorType,
288 kWithValidatorType);
289 helper.SetUp();
290 scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
291 new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
292 helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
294 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
295 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
298 TEST(CopyOrMoveFileValidatorTest, OverrideValidator) {
299 // Once set, you can not override the validator.
300 CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
301 kNoValidatorType,
302 kWithValidatorType);
303 helper.SetUp();
304 scoped_ptr<CopyOrMoveFileValidatorFactory> reject_factory(
305 new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
306 helper.SetMediaCopyOrMoveFileValidatorFactory(reject_factory.Pass());
308 scoped_ptr<CopyOrMoveFileValidatorFactory> accept_factory(
309 new TestCopyOrMoveFileValidatorFactory(VALID));
310 helper.SetMediaCopyOrMoveFileValidatorFactory(accept_factory.Pass());
312 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
313 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
316 TEST(CopyOrMoveFileValidatorTest, RejectPostWrite) {
317 CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
318 kNoValidatorType,
319 kWithValidatorType);
320 helper.SetUp();
321 scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
322 new TestCopyOrMoveFileValidatorFactory(POST_WRITE_INVALID));
323 helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
325 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
326 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
329 } // namespace content