Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / fileapi / copy_or_move_file_validator_unittest.cc
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 "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/test_file_system_backend.h"
12 #include "content/public/test/test_file_system_context.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
15 #include "webkit/browser/fileapi/external_mount_points.h"
16 #include "webkit/browser/fileapi/file_system_backend.h"
17 #include "webkit/browser/fileapi/file_system_context.h"
18 #include "webkit/browser/fileapi/file_system_url.h"
19 #include "webkit/browser/fileapi/isolated_context.h"
20 #include "webkit/browser/quota/mock_special_storage_policy.h"
21 #include "webkit/common/blob/shareable_file_reference.h"
22 #include "webkit/common/fileapi/file_system_util.h"
23
24 using content::AsyncFileTestHelper;
25 using fileapi::CopyOrMoveFileValidator;
26 using fileapi::CopyOrMoveFileValidatorFactory;
27 using fileapi::FileSystemType;
28 using fileapi::FileSystemURL;
29
30 namespace content {
31
32 namespace {
33
34 const FileSystemType kNoValidatorType = fileapi::kFileSystemTypeTemporary;
35 const FileSystemType kWithValidatorType = fileapi::kFileSystemTypeTest;
36
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);
41 }
42
43 class CopyOrMoveFileValidatorTestHelper {
44  public:
45   CopyOrMoveFileValidatorTestHelper(
46       const GURL& origin,
47       FileSystemType src_type,
48       FileSystemType dest_type)
49       : origin_(origin),
50         src_type_(src_type),
51         dest_type_(dest_type) {}
52
53   ~CopyOrMoveFileValidatorTestHelper() {
54     file_system_context_ = NULL;
55     base::RunLoop().RunUntilIdle();
56   }
57
58   void SetUp() {
59     ASSERT_TRUE(base_.CreateUniqueTempDir());
60     base::FilePath base_dir = base_.path();
61
62     file_system_context_ = CreateFileSystemContextForTesting(NULL, base_dir);
63
64     // Set up TestFileSystemBackend to require CopyOrMoveFileValidator.
65     fileapi::FileSystemBackend* test_file_system_backend =
66         file_system_context_->GetFileSystemBackend(kWithValidatorType);
67     static_cast<TestFileSystemBackend*>(test_file_system_backend)->
68         set_require_copy_or_move_validator(true);
69
70     // Sets up source.
71     fileapi::FileSystemBackend* src_file_system_backend =
72         file_system_context_->GetFileSystemBackend(src_type_);
73     src_file_system_backend->OpenFileSystem(
74         origin_, src_type_,
75         fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
76         base::Bind(&ExpectOk));
77     base::RunLoop().RunUntilIdle();
78     ASSERT_EQ(base::File::FILE_OK, CreateDirectory(SourceURL("")));
79
80     // Sets up dest.
81     DCHECK_EQ(kWithValidatorType, dest_type_);
82     ASSERT_EQ(base::File::FILE_OK, CreateDirectory(DestURL("")));
83
84     copy_src_ = SourceURL("copy_src.jpg");
85     move_src_ = SourceURL("move_src.jpg");
86     copy_dest_ = DestURL("copy_dest.jpg");
87     move_dest_ = DestURL("move_dest.jpg");
88
89     ASSERT_EQ(base::File::FILE_OK, CreateFile(copy_src_, 10));
90     ASSERT_EQ(base::File::FILE_OK, CreateFile(move_src_, 10));
91
92     ASSERT_TRUE(FileExists(copy_src_, 10));
93     ASSERT_TRUE(FileExists(move_src_, 10));
94     ASSERT_FALSE(FileExists(copy_dest_, 10));
95     ASSERT_FALSE(FileExists(move_dest_, 10));
96   }
97
98   void SetMediaCopyOrMoveFileValidatorFactory(
99       scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
100     TestFileSystemBackend* backend = static_cast<TestFileSystemBackend*>(
101         file_system_context_->GetFileSystemBackend(kWithValidatorType));
102     backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
103   }
104
105   void CopyTest(base::File::Error expected) {
106     ASSERT_TRUE(FileExists(copy_src_, 10));
107     ASSERT_FALSE(FileExists(copy_dest_, 10));
108
109     EXPECT_EQ(expected,
110               AsyncFileTestHelper::Copy(
111                   file_system_context_.get(), copy_src_, copy_dest_));
112
113     EXPECT_TRUE(FileExists(copy_src_, 10));
114     if (expected == base::File::FILE_OK)
115       EXPECT_TRUE(FileExists(copy_dest_, 10));
116     else
117       EXPECT_FALSE(FileExists(copy_dest_, 10));
118   };
119
120   void MoveTest(base::File::Error expected) {
121     ASSERT_TRUE(FileExists(move_src_, 10));
122     ASSERT_FALSE(FileExists(move_dest_, 10));
123
124     EXPECT_EQ(expected,
125               AsyncFileTestHelper::Move(
126                   file_system_context_.get(), move_src_, move_dest_));
127
128     if (expected == base::File::FILE_OK) {
129       EXPECT_FALSE(FileExists(move_src_, 10));
130       EXPECT_TRUE(FileExists(move_dest_, 10));
131     } else {
132       EXPECT_TRUE(FileExists(move_src_, 10));
133       EXPECT_FALSE(FileExists(move_dest_, 10));
134     }
135   };
136
137  private:
138   FileSystemURL SourceURL(const std::string& path) {
139     return file_system_context_->CreateCrackedFileSystemURL(
140         origin_, src_type_,
141         base::FilePath().AppendASCII("src").AppendASCII(path));
142   }
143
144   FileSystemURL DestURL(const std::string& path) {
145     return file_system_context_->CreateCrackedFileSystemURL(
146         origin_, dest_type_,
147         base::FilePath().AppendASCII("dest").AppendASCII(path));
148   }
149
150   base::File::Error CreateFile(const FileSystemURL& url, size_t size) {
151     base::File::Error result =
152         AsyncFileTestHelper::CreateFile(file_system_context_.get(), url);
153     if (result != base::File::FILE_OK)
154       return result;
155     return AsyncFileTestHelper::TruncateFile(
156         file_system_context_.get(), url, size);
157   }
158
159   base::File::Error CreateDirectory(const FileSystemURL& url) {
160     return AsyncFileTestHelper::CreateDirectory(file_system_context_.get(),
161                                                 url);
162   }
163
164   bool FileExists(const FileSystemURL& url, int64 expected_size) {
165     return AsyncFileTestHelper::FileExists(
166         file_system_context_.get(), url, expected_size);
167   }
168
169   base::ScopedTempDir base_;
170
171   const GURL origin_;
172
173   const FileSystemType src_type_;
174   const FileSystemType dest_type_;
175   std::string src_fsid_;
176   std::string dest_fsid_;
177
178   base::MessageLoop message_loop_;
179   scoped_refptr<fileapi::FileSystemContext> file_system_context_;
180
181   FileSystemURL copy_src_;
182   FileSystemURL copy_dest_;
183   FileSystemURL move_src_;
184   FileSystemURL move_dest_;
185
186   DISALLOW_COPY_AND_ASSIGN(CopyOrMoveFileValidatorTestHelper);
187 };
188
189 // For TestCopyOrMoveFileValidatorFactory
190 enum Validity {
191   VALID,
192   PRE_WRITE_INVALID,
193   POST_WRITE_INVALID
194 };
195
196 class TestCopyOrMoveFileValidatorFactory
197     : public fileapi::CopyOrMoveFileValidatorFactory {
198  public:
199   // A factory that creates validators that accept everything or nothing.
200   // TODO(gbillock): switch args to enum or something
201   explicit TestCopyOrMoveFileValidatorFactory(Validity validity)
202       : validity_(validity) {}
203   virtual ~TestCopyOrMoveFileValidatorFactory() {}
204
205   virtual fileapi::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
206       const FileSystemURL& /*src_url*/,
207       const base::FilePath& /*platform_path*/) OVERRIDE {
208     return new TestCopyOrMoveFileValidator(validity_);
209   }
210
211  private:
212   class TestCopyOrMoveFileValidator : public CopyOrMoveFileValidator {
213    public:
214     explicit TestCopyOrMoveFileValidator(Validity validity)
215         : result_(validity == VALID || validity == POST_WRITE_INVALID ?
216                   base::File::FILE_OK :
217                   base::File::FILE_ERROR_SECURITY),
218           write_result_(validity == VALID || validity == PRE_WRITE_INVALID ?
219                         base::File::FILE_OK :
220                         base::File::FILE_ERROR_SECURITY) {
221     }
222     virtual ~TestCopyOrMoveFileValidator() {}
223
224     virtual void StartPreWriteValidation(
225         const ResultCallback& result_callback) OVERRIDE {
226       // Post the result since a real validator must do work asynchronously.
227       base::MessageLoop::current()->PostTask(
228           FROM_HERE, base::Bind(result_callback, result_));
229     }
230
231     virtual void StartPostWriteValidation(
232         const base::FilePath& dest_platform_path,
233         const ResultCallback& result_callback) OVERRIDE {
234       // Post the result since a real validator must do work asynchronously.
235       base::MessageLoop::current()->PostTask(
236           FROM_HERE, base::Bind(result_callback, write_result_));
237     }
238
239    private:
240     base::File::Error result_;
241     base::File::Error write_result_;
242
243     DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidator);
244   };
245
246   Validity validity_;
247
248   DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidatorFactory);
249 };
250
251 }  // namespace
252
253 TEST(CopyOrMoveFileValidatorTest, NoValidatorWithinSameFSType) {
254   // Within a file system type, validation is not expected, so it should
255   // work for kWithValidatorType without a validator set.
256   CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
257                                            kWithValidatorType,
258                                            kWithValidatorType);
259   helper.SetUp();
260   helper.CopyTest(base::File::FILE_OK);
261   helper.MoveTest(base::File::FILE_OK);
262 }
263
264 TEST(CopyOrMoveFileValidatorTest, MissingValidator) {
265   // Copying or moving into a kWithValidatorType requires a file
266   // validator.  An error is expected if copy is attempted without a validator.
267   CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
268                                            kNoValidatorType,
269                                            kWithValidatorType);
270   helper.SetUp();
271   helper.CopyTest(base::File::FILE_ERROR_SECURITY);
272   helper.MoveTest(base::File::FILE_ERROR_SECURITY);
273 }
274
275 TEST(CopyOrMoveFileValidatorTest, AcceptAll) {
276   CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
277                                            kNoValidatorType,
278                                            kWithValidatorType);
279   helper.SetUp();
280   scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
281       new TestCopyOrMoveFileValidatorFactory(VALID));
282   helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
283
284   helper.CopyTest(base::File::FILE_OK);
285   helper.MoveTest(base::File::FILE_OK);
286 }
287
288 TEST(CopyOrMoveFileValidatorTest, AcceptNone) {
289   CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
290                                            kNoValidatorType,
291                                            kWithValidatorType);
292   helper.SetUp();
293   scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
294       new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
295   helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
296
297   helper.CopyTest(base::File::FILE_ERROR_SECURITY);
298   helper.MoveTest(base::File::FILE_ERROR_SECURITY);
299 }
300
301 TEST(CopyOrMoveFileValidatorTest, OverrideValidator) {
302   // Once set, you can not override the validator.
303   CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
304                                            kNoValidatorType,
305                                            kWithValidatorType);
306   helper.SetUp();
307   scoped_ptr<CopyOrMoveFileValidatorFactory> reject_factory(
308       new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
309   helper.SetMediaCopyOrMoveFileValidatorFactory(reject_factory.Pass());
310
311   scoped_ptr<CopyOrMoveFileValidatorFactory> accept_factory(
312       new TestCopyOrMoveFileValidatorFactory(VALID));
313   helper.SetMediaCopyOrMoveFileValidatorFactory(accept_factory.Pass());
314
315   helper.CopyTest(base::File::FILE_ERROR_SECURITY);
316   helper.MoveTest(base::File::FILE_ERROR_SECURITY);
317 }
318
319 TEST(CopyOrMoveFileValidatorTest, RejectPostWrite) {
320   CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
321                                            kNoValidatorType,
322                                            kWithValidatorType);
323   helper.SetUp();
324   scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
325       new TestCopyOrMoveFileValidatorFactory(POST_WRITE_INVALID));
326   helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
327
328   helper.CopyTest(base::File::FILE_ERROR_SECURITY);
329   helper.MoveTest(base::File::FILE_ERROR_SECURITY);
330 }
331
332 }  // namespace content