Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / child / fileapi / webfilewriter_base_unittest.cc
blob68f58ff9f883635b74358a3b5e4c8782625eca76
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 "content/child/fileapi/webfilewriter_base.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/WebKit/public/platform/WebFileError.h"
13 #include "third_party/WebKit/public/platform/WebFileWriterClient.h"
14 #include "third_party/WebKit/public/platform/WebURL.h"
15 #include "url/gurl.h"
17 namespace content {
19 namespace {
21 // We use particular offsets to trigger particular behaviors
22 // in the TestableFileWriter.
23 const int kNoOffset = -1;
24 const int kBasicFileTruncate_Offset = 1;
25 const int kErrorFileTruncate_Offset = 2;
26 const int kCancelFileTruncate_Offset = 3;
27 const int kCancelFailedTruncate_Offset = 4;
28 const int kBasicFileWrite_Offset = 1;
29 const int kErrorFileWrite_Offset = 2;
30 const int kMultiFileWrite_Offset = 3;
31 const int kCancelFileWriteBeforeCompletion_Offset = 4;
32 const int kCancelFileWriteAfterCompletion_Offset = 5;
34 GURL mock_path_as_gurl() {
35 return GURL("MockPath");
38 } // namespace
40 class TestableFileWriter : public WebFileWriterBase {
41 public:
42 explicit TestableFileWriter(blink::WebFileWriterClient* client)
43 : WebFileWriterBase(mock_path_as_gurl(), client) {
44 reset();
47 void reset() {
48 received_truncate_ = false;
49 received_truncate_path_ = GURL();
50 received_truncate_offset_ = kNoOffset;
51 received_write_ = false;
52 received_write_path_ = GURL();
53 received_write_offset_ = kNoOffset;
54 received_write_blob_uuid_ = std::string();
55 received_cancel_ = false;
58 bool received_truncate_;
59 GURL received_truncate_path_;
60 int64 received_truncate_offset_;
61 bool received_write_;
62 GURL received_write_path_;
63 std::string received_write_blob_uuid_;
64 int64 received_write_offset_;
65 bool received_cancel_;
67 protected:
68 void DoTruncate(const GURL& path, int64 offset) override {
69 received_truncate_ = true;
70 received_truncate_path_ = path;
71 received_truncate_offset_ = offset;
73 if (offset == kBasicFileTruncate_Offset) {
74 DidSucceed();
75 } else if (offset == kErrorFileTruncate_Offset) {
76 DidFail(base::File::FILE_ERROR_NOT_FOUND);
77 } else if (offset == kCancelFileTruncate_Offset) {
78 cancel();
79 DidSucceed(); // truncate completion
80 DidSucceed(); // cancel completion
81 } else if (offset == kCancelFailedTruncate_Offset) {
82 cancel();
83 DidFail(base::File::FILE_ERROR_NOT_FOUND); // truncate completion
84 DidSucceed(); // cancel completion
85 } else {
86 FAIL();
90 void DoWrite(const GURL& path,
91 const std::string& blob_uuid,
92 int64 offset) override {
93 received_write_ = true;
94 received_write_path_ = path;
95 received_write_offset_ = offset;
96 received_write_blob_uuid_ = blob_uuid;
98 if (offset == kBasicFileWrite_Offset) {
99 DidWrite(1, true);
100 } else if (offset == kErrorFileWrite_Offset) {
101 DidFail(base::File::FILE_ERROR_NOT_FOUND);
102 } else if (offset == kMultiFileWrite_Offset) {
103 DidWrite(1, false);
104 DidWrite(1, false);
105 DidWrite(1, true);
106 } else if (offset == kCancelFileWriteBeforeCompletion_Offset) {
107 DidWrite(1, false);
108 cancel();
109 DidWrite(1, false);
110 DidWrite(1, false);
111 DidFail(base::File::FILE_ERROR_FAILED); // write completion
112 DidSucceed(); // cancel completion
113 } else if (offset == kCancelFileWriteAfterCompletion_Offset) {
114 DidWrite(1, false);
115 cancel();
116 DidWrite(1, false);
117 DidWrite(1, false);
118 DidWrite(1, true); // write completion
119 DidFail(base::File::FILE_ERROR_FAILED); // cancel completion
120 } else {
121 FAIL();
125 void DoCancel() override { received_cancel_ = true; }
128 class FileWriterTest : public testing::Test,
129 public blink::WebFileWriterClient {
130 public:
131 FileWriterTest() {
132 reset();
135 blink::WebFileWriter* writer() {
136 return testable_writer_.get();
139 // WebFileWriterClient overrides
140 virtual void didWrite(long long bytes, bool complete) {
141 EXPECT_FALSE(received_did_write_complete_);
142 ++received_did_write_count_;
143 received_did_write_bytes_total_ += bytes;
144 if (complete)
145 received_did_write_complete_ = true;
147 if (delete_in_client_callback_)
148 testable_writer_.reset(NULL);
151 virtual void didTruncate() {
152 EXPECT_FALSE(received_did_truncate_);
153 received_did_truncate_ = true;
154 if (delete_in_client_callback_)
155 testable_writer_.reset(NULL);
158 virtual void didFail(blink::WebFileError error) {
159 EXPECT_FALSE(received_did_fail_);
160 received_did_fail_ = true;
161 fail_error_received_ = error;
162 if (delete_in_client_callback_)
163 testable_writer_.reset(NULL);
166 protected:
167 void reset() {
168 testable_writer_.reset(new TestableFileWriter(this));
169 delete_in_client_callback_ = false;
170 received_did_write_count_ = 0;
171 received_did_write_bytes_total_ = 0;
172 received_did_write_complete_ = false;
173 received_did_truncate_ = false;
174 received_did_fail_ = false;
175 fail_error_received_ = static_cast<blink::WebFileError>(0);
178 scoped_ptr<TestableFileWriter> testable_writer_;
179 bool delete_in_client_callback_;
181 // Observed WebFileWriterClient artifacts.
182 int received_did_write_count_;
183 long long received_did_write_bytes_total_;
184 bool received_did_write_complete_;
185 bool received_did_truncate_;
186 bool received_did_fail_;
187 blink::WebFileError fail_error_received_;
189 DISALLOW_COPY_AND_ASSIGN(FileWriterTest);
192 TEST_F(FileWriterTest, BasicFileWrite) {
193 // Call the webkit facing api.
194 const std::string kBlobId("1234");
195 writer()->write(kBasicFileWrite_Offset,
196 blink::WebString::fromUTF8(kBlobId));
198 // Check that the derived class gets called correctly.
199 EXPECT_TRUE(testable_writer_->received_write_);
200 EXPECT_EQ(testable_writer_->received_write_path_,
201 mock_path_as_gurl());
202 EXPECT_EQ(kBasicFileWrite_Offset,
203 testable_writer_->received_write_offset_);
204 EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
205 EXPECT_FALSE(testable_writer_->received_truncate_);
206 EXPECT_FALSE(testable_writer_->received_cancel_);
208 // Check that the client gets called correctly.
209 EXPECT_EQ(1, received_did_write_count_);
210 EXPECT_TRUE(received_did_write_complete_);
211 EXPECT_EQ(1, received_did_write_bytes_total_);
212 EXPECT_FALSE(received_did_truncate_);
213 EXPECT_FALSE(received_did_fail_);
216 TEST_F(FileWriterTest, BasicFileTruncate) {
217 // Call the webkit facing api.
218 writer()->truncate(kBasicFileTruncate_Offset);
220 // Check that the derived class gets called correctly.
221 EXPECT_TRUE(testable_writer_->received_truncate_);
222 EXPECT_EQ(mock_path_as_gurl(),
223 testable_writer_->received_truncate_path_);
224 EXPECT_EQ(kBasicFileTruncate_Offset,
225 testable_writer_->received_truncate_offset_);
226 EXPECT_FALSE(testable_writer_->received_write_);
227 EXPECT_FALSE(testable_writer_->received_cancel_);
229 // Check that the client gets called correctly.
230 EXPECT_TRUE(received_did_truncate_);
231 EXPECT_EQ(0, received_did_write_count_);
232 EXPECT_FALSE(received_did_fail_);
235 TEST_F(FileWriterTest, ErrorFileWrite) {
236 // Call the webkit facing api.
237 const std::string kBlobId("1234");
238 writer()->write(kErrorFileWrite_Offset,
239 blink::WebString::fromUTF8(kBlobId));
241 // Check that the derived class gets called correctly.
242 EXPECT_TRUE(testable_writer_->received_write_);
243 EXPECT_EQ(testable_writer_->received_write_path_,
244 mock_path_as_gurl());
245 EXPECT_EQ(kErrorFileWrite_Offset,
246 testable_writer_->received_write_offset_);
247 EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
248 EXPECT_FALSE(testable_writer_->received_truncate_);
249 EXPECT_FALSE(testable_writer_->received_cancel_);
251 // Check that the client gets called correctly.
252 EXPECT_TRUE(received_did_fail_);
253 EXPECT_EQ(blink::WebFileErrorNotFound, fail_error_received_);
254 EXPECT_EQ(0, received_did_write_count_);
255 EXPECT_FALSE(received_did_truncate_);
258 TEST_F(FileWriterTest, ErrorFileTruncate) {
259 // Call the webkit facing api.
260 writer()->truncate(kErrorFileTruncate_Offset);
262 // Check that the derived class gets called correctly.
263 EXPECT_TRUE(testable_writer_->received_truncate_);
264 EXPECT_EQ(mock_path_as_gurl(),
265 testable_writer_->received_truncate_path_);
266 EXPECT_EQ(kErrorFileTruncate_Offset,
267 testable_writer_->received_truncate_offset_);
268 EXPECT_FALSE(testable_writer_->received_write_);
269 EXPECT_FALSE(testable_writer_->received_cancel_);
271 // Check that the client gets called correctly.
272 EXPECT_TRUE(received_did_fail_);
273 EXPECT_EQ(blink::WebFileErrorNotFound, fail_error_received_);
274 EXPECT_FALSE(received_did_truncate_);
275 EXPECT_EQ(0, received_did_write_count_);
278 TEST_F(FileWriterTest, MultiFileWrite) {
279 // Call the webkit facing api.
280 const std::string kBlobId("1234");
281 writer()->write(kMultiFileWrite_Offset,
282 blink::WebString::fromUTF8(kBlobId));
284 // Check that the derived class gets called correctly.
285 EXPECT_TRUE(testable_writer_->received_write_);
286 EXPECT_EQ(testable_writer_->received_write_path_,
287 mock_path_as_gurl());
288 EXPECT_EQ(kMultiFileWrite_Offset,
289 testable_writer_->received_write_offset_);
290 EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
291 EXPECT_FALSE(testable_writer_->received_truncate_);
292 EXPECT_FALSE(testable_writer_->received_cancel_);
294 // Check that the client gets called correctly.
295 EXPECT_EQ(3, received_did_write_count_);
296 EXPECT_TRUE(received_did_write_complete_);
297 EXPECT_EQ(3, received_did_write_bytes_total_);
298 EXPECT_FALSE(received_did_truncate_);
299 EXPECT_FALSE(received_did_fail_);
302 TEST_F(FileWriterTest, CancelFileWriteBeforeCompletion) {
303 // Call the webkit facing api.
304 const std::string kBlobId("1234");
305 writer()->write(kCancelFileWriteBeforeCompletion_Offset,
306 blink::WebString::fromUTF8(kBlobId));
308 // Check that the derived class gets called correctly.
309 EXPECT_TRUE(testable_writer_->received_write_);
310 EXPECT_EQ(testable_writer_->received_write_path_,
311 mock_path_as_gurl());
312 EXPECT_EQ(kCancelFileWriteBeforeCompletion_Offset,
313 testable_writer_->received_write_offset_);
314 EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
315 EXPECT_TRUE(testable_writer_->received_cancel_);
316 EXPECT_FALSE(testable_writer_->received_truncate_);
318 // Check that the client gets called correctly.
319 EXPECT_TRUE(received_did_fail_);
320 EXPECT_EQ(blink::WebFileErrorAbort, fail_error_received_);
321 EXPECT_EQ(1, received_did_write_count_);
322 EXPECT_FALSE(received_did_write_complete_);
323 EXPECT_EQ(1, received_did_write_bytes_total_);
324 EXPECT_FALSE(received_did_truncate_);
327 TEST_F(FileWriterTest, CancelFileWriteAfterCompletion) {
328 // Call the webkit facing api.
329 const std::string kBlobId("1234");
330 writer()->write(kCancelFileWriteAfterCompletion_Offset,
331 blink::WebString::fromUTF8(kBlobId));
333 // Check that the derived class gets called correctly.
334 EXPECT_TRUE(testable_writer_->received_write_);
335 EXPECT_EQ(testable_writer_->received_write_path_,
336 mock_path_as_gurl());
337 EXPECT_EQ(kCancelFileWriteAfterCompletion_Offset,
338 testable_writer_->received_write_offset_);
339 EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
340 EXPECT_TRUE(testable_writer_->received_cancel_);
341 EXPECT_FALSE(testable_writer_->received_truncate_);
343 // Check that the client gets called correctly.
344 EXPECT_TRUE(received_did_fail_);
345 EXPECT_EQ(blink::WebFileErrorAbort, fail_error_received_);
346 EXPECT_EQ(1, received_did_write_count_);
347 EXPECT_FALSE(received_did_write_complete_);
348 EXPECT_EQ(1, received_did_write_bytes_total_);
349 EXPECT_FALSE(received_did_truncate_);
352 TEST_F(FileWriterTest, CancelFileTruncate) {
353 // Call the webkit facing api.
354 writer()->truncate(kCancelFileTruncate_Offset);
356 // Check that the derived class gets called correctly.
357 EXPECT_TRUE(testable_writer_->received_truncate_);
358 EXPECT_EQ(mock_path_as_gurl(),
359 testable_writer_->received_truncate_path_);
360 EXPECT_EQ(kCancelFileTruncate_Offset,
361 testable_writer_->received_truncate_offset_);
362 EXPECT_TRUE(testable_writer_->received_cancel_);
363 EXPECT_FALSE(testable_writer_->received_write_);
365 // Check that the client gets called correctly.
366 EXPECT_TRUE(received_did_fail_);
367 EXPECT_EQ(blink::WebFileErrorAbort, fail_error_received_);
368 EXPECT_FALSE(received_did_truncate_);
369 EXPECT_EQ(0, received_did_write_count_);
372 TEST_F(FileWriterTest, CancelFailedTruncate) {
373 // Call the webkit facing api.
374 writer()->truncate(kCancelFailedTruncate_Offset);
376 // Check that the derived class gets called correctly.
377 EXPECT_TRUE(testable_writer_->received_truncate_);
378 EXPECT_EQ(mock_path_as_gurl(),
379 testable_writer_->received_truncate_path_);
380 EXPECT_EQ(kCancelFailedTruncate_Offset,
381 testable_writer_->received_truncate_offset_);
382 EXPECT_TRUE(testable_writer_->received_cancel_);
383 EXPECT_FALSE(testable_writer_->received_write_);
385 // Check that the client gets called correctly.
386 EXPECT_TRUE(received_did_fail_);
387 EXPECT_EQ(blink::WebFileErrorAbort, fail_error_received_);
388 EXPECT_FALSE(received_did_truncate_);
389 EXPECT_EQ(0, received_did_write_count_);
392 TEST_F(FileWriterTest, DeleteInCompletionCallbacks) {
393 const std::string kBlobId("1234");
394 delete_in_client_callback_ = true;
395 writer()->write(kBasicFileWrite_Offset,
396 blink::WebString::fromUTF8(kBlobId));
397 EXPECT_FALSE(testable_writer_.get());
399 reset();
400 delete_in_client_callback_ = true;
401 writer()->truncate(kBasicFileTruncate_Offset);
402 EXPECT_FALSE(testable_writer_.get());
404 reset();
405 delete_in_client_callback_ = true;
406 writer()->write(kErrorFileWrite_Offset,
407 blink::WebString::fromUTF8(kBlobId));
408 EXPECT_FALSE(testable_writer_.get());
410 reset();
411 delete_in_client_callback_ = true;
412 writer()->truncate(kErrorFileTruncate_Offset);
413 EXPECT_FALSE(testable_writer_.get());
415 // Not crashing counts as passing.
418 } // namespace content