[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / fileapi / copy_or_move_file_validator_unittest.cc
blobc07db9db006b61b72db6afa9879df4a8a3f2ce44
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/location.h"
10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "content/public/test/async_file_test_helper.h"
14 #include "content/public/test/mock_special_storage_policy.h"
15 #include "content/public/test/test_file_system_backend.h"
16 #include "content/public/test/test_file_system_context.h"
17 #include "storage/browser/blob/shareable_file_reference.h"
18 #include "storage/browser/fileapi/copy_or_move_file_validator.h"
19 #include "storage/browser/fileapi/external_mount_points.h"
20 #include "storage/browser/fileapi/file_system_backend.h"
21 #include "storage/browser/fileapi/file_system_context.h"
22 #include "storage/browser/fileapi/file_system_url.h"
23 #include "storage/browser/fileapi/isolated_context.h"
24 #include "storage/common/fileapi/file_system_util.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using content::AsyncFileTestHelper;
28 using storage::CopyOrMoveFileValidator;
29 using storage::CopyOrMoveFileValidatorFactory;
30 using storage::FileSystemURL;
32 namespace content {
34 namespace {
36 const storage::FileSystemType kNoValidatorType =
37 storage::kFileSystemTypeTemporary;
38 const storage::FileSystemType kWithValidatorType = storage::kFileSystemTypeTest;
40 void ExpectOk(const GURL& origin_url,
41 const std::string& name,
42 base::File::Error error) {
43 ASSERT_EQ(base::File::FILE_OK, error);
46 class CopyOrMoveFileValidatorTestHelper {
47 public:
48 CopyOrMoveFileValidatorTestHelper(const GURL& origin,
49 storage::FileSystemType src_type,
50 storage::FileSystemType dest_type)
51 : origin_(origin), src_type_(src_type), dest_type_(dest_type) {}
53 ~CopyOrMoveFileValidatorTestHelper() {
54 file_system_context_ = NULL;
55 base::RunLoop().RunUntilIdle();
58 void SetUp() {
59 ASSERT_TRUE(base_.CreateUniqueTempDir());
60 base::FilePath base_dir = base_.path();
62 file_system_context_ = CreateFileSystemContextForTesting(NULL, base_dir);
64 // Set up TestFileSystemBackend to require CopyOrMoveFileValidator.
65 storage::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);
70 // Sets up source.
71 storage::FileSystemBackend* src_file_system_backend =
72 file_system_context_->GetFileSystemBackend(src_type_);
73 src_file_system_backend->ResolveURL(
74 FileSystemURL::CreateForTest(origin_, src_type_, base::FilePath()),
75 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
76 base::Bind(&ExpectOk));
77 base::RunLoop().RunUntilIdle();
78 ASSERT_EQ(base::File::FILE_OK, CreateDirectory(SourceURL("")));
80 // Sets up dest.
81 DCHECK_EQ(kWithValidatorType, dest_type_);
82 ASSERT_EQ(base::File::FILE_OK, CreateDirectory(DestURL("")));
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");
89 ASSERT_EQ(base::File::FILE_OK, CreateFile(copy_src_, 10));
90 ASSERT_EQ(base::File::FILE_OK, CreateFile(move_src_, 10));
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));
98 void SetMediaCopyOrMoveFileValidatorFactory(
99 scoped_ptr<storage::CopyOrMoveFileValidatorFactory> factory) {
100 TestFileSystemBackend* backend = static_cast<TestFileSystemBackend*>(
101 file_system_context_->GetFileSystemBackend(kWithValidatorType));
102 backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
105 void CopyTest(base::File::Error expected) {
106 ASSERT_TRUE(FileExists(copy_src_, 10));
107 ASSERT_FALSE(FileExists(copy_dest_, 10));
109 EXPECT_EQ(expected,
110 AsyncFileTestHelper::Copy(
111 file_system_context_.get(), copy_src_, copy_dest_));
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));
120 void MoveTest(base::File::Error expected) {
121 ASSERT_TRUE(FileExists(move_src_, 10));
122 ASSERT_FALSE(FileExists(move_dest_, 10));
124 EXPECT_EQ(expected,
125 AsyncFileTestHelper::Move(
126 file_system_context_.get(), move_src_, move_dest_));
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));
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));
144 FileSystemURL DestURL(const std::string& path) {
145 return file_system_context_->CreateCrackedFileSystemURL(
146 origin_, dest_type_,
147 base::FilePath().AppendASCII("dest").AppendASCII(path));
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);
159 base::File::Error CreateDirectory(const FileSystemURL& url) {
160 return AsyncFileTestHelper::CreateDirectory(file_system_context_.get(),
161 url);
164 bool FileExists(const FileSystemURL& url, int64 expected_size) {
165 return AsyncFileTestHelper::FileExists(
166 file_system_context_.get(), url, expected_size);
169 base::ScopedTempDir base_;
171 const GURL origin_;
173 const storage::FileSystemType src_type_;
174 const storage::FileSystemType dest_type_;
175 std::string src_fsid_;
176 std::string dest_fsid_;
178 base::MessageLoop message_loop_;
179 scoped_refptr<storage::FileSystemContext> file_system_context_;
181 FileSystemURL copy_src_;
182 FileSystemURL copy_dest_;
183 FileSystemURL move_src_;
184 FileSystemURL move_dest_;
186 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveFileValidatorTestHelper);
189 // For TestCopyOrMoveFileValidatorFactory
190 enum Validity {
191 VALID,
192 PRE_WRITE_INVALID,
193 POST_WRITE_INVALID
196 class TestCopyOrMoveFileValidatorFactory
197 : public storage::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 ~TestCopyOrMoveFileValidatorFactory() override {}
205 storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
206 const FileSystemURL& /*src_url*/,
207 const base::FilePath& /*platform_path*/) override {
208 return new TestCopyOrMoveFileValidator(validity_);
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) {
222 ~TestCopyOrMoveFileValidator() override {}
224 void StartPreWriteValidation(
225 const ResultCallback& result_callback) override {
226 // Post the result since a real validator must do work asynchronously.
227 base::ThreadTaskRunnerHandle::Get()->PostTask(
228 FROM_HERE, base::Bind(result_callback, result_));
231 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::ThreadTaskRunnerHandle::Get()->PostTask(
236 FROM_HERE, base::Bind(result_callback, write_result_));
239 private:
240 base::File::Error result_;
241 base::File::Error write_result_;
243 DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidator);
246 Validity validity_;
248 DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidatorFactory);
251 } // namespace
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);
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);
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());
284 helper.CopyTest(base::File::FILE_OK);
285 helper.MoveTest(base::File::FILE_OK);
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());
297 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
298 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
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());
311 scoped_ptr<CopyOrMoveFileValidatorFactory> accept_factory(
312 new TestCopyOrMoveFileValidatorFactory(VALID));
313 helper.SetMediaCopyOrMoveFileValidatorFactory(accept_factory.Pass());
315 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
316 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
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());
328 helper.CopyTest(base::File::FILE_ERROR_SECURITY);
329 helper.MoveTest(base::File::FILE_ERROR_SECURITY);
332 } // namespace content