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"
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");
40 class TestableFileWriter
: public WebFileWriterBase
{
42 explicit TestableFileWriter(blink::WebFileWriterClient
* client
)
43 : WebFileWriterBase(mock_path_as_gurl(), client
) {
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_
;
62 GURL received_write_path_
;
63 std::string received_write_blob_uuid_
;
64 int64 received_write_offset_
;
65 bool received_cancel_
;
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
) {
75 } else if (offset
== kErrorFileTruncate_Offset
) {
76 DidFail(base::File::FILE_ERROR_NOT_FOUND
);
77 } else if (offset
== kCancelFileTruncate_Offset
) {
79 DidSucceed(); // truncate completion
80 DidSucceed(); // cancel completion
81 } else if (offset
== kCancelFailedTruncate_Offset
) {
83 DidFail(base::File::FILE_ERROR_NOT_FOUND
); // truncate completion
84 DidSucceed(); // cancel completion
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
) {
100 } else if (offset
== kErrorFileWrite_Offset
) {
101 DidFail(base::File::FILE_ERROR_NOT_FOUND
);
102 } else if (offset
== kMultiFileWrite_Offset
) {
106 } else if (offset
== kCancelFileWriteBeforeCompletion_Offset
) {
111 DidFail(base::File::FILE_ERROR_FAILED
); // write completion
112 DidSucceed(); // cancel completion
113 } else if (offset
== kCancelFileWriteAfterCompletion_Offset
) {
118 DidWrite(1, true); // write completion
119 DidFail(base::File::FILE_ERROR_FAILED
); // cancel completion
125 void DoCancel() override
{ received_cancel_
= true; }
128 class FileWriterTest
: public testing::Test
,
129 public blink::WebFileWriterClient
{
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
;
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
);
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());
400 delete_in_client_callback_
= true;
401 writer()->truncate(kBasicFileTruncate_Offset
);
402 EXPECT_FALSE(testable_writer_
.get());
405 delete_in_client_callback_
= true;
406 writer()->write(kErrorFileWrite_Offset
,
407 blink::WebString::fromUTF8(kBlobId
));
408 EXPECT_FALSE(testable_writer_
.get());
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