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 virtual 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
91 const GURL
& path
, 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 virtual void DoCancel() OVERRIDE
{
126 received_cancel_
= true;
130 class FileWriterTest
: public testing::Test
,
131 public blink::WebFileWriterClient
{
137 blink::WebFileWriter
* writer() {
138 return testable_writer_
.get();
141 // WebFileWriterClient overrides
142 virtual void didWrite(long long bytes
, bool complete
) {
143 EXPECT_FALSE(received_did_write_complete_
);
144 ++received_did_write_count_
;
145 received_did_write_bytes_total_
+= bytes
;
147 received_did_write_complete_
= true;
149 if (delete_in_client_callback_
)
150 testable_writer_
.reset(NULL
);
153 virtual void didTruncate() {
154 EXPECT_FALSE(received_did_truncate_
);
155 received_did_truncate_
= true;
156 if (delete_in_client_callback_
)
157 testable_writer_
.reset(NULL
);
160 virtual void didFail(blink::WebFileError error
) {
161 EXPECT_FALSE(received_did_fail_
);
162 received_did_fail_
= true;
163 fail_error_received_
= error
;
164 if (delete_in_client_callback_
)
165 testable_writer_
.reset(NULL
);
170 testable_writer_
.reset(new TestableFileWriter(this));
171 delete_in_client_callback_
= false;
172 received_did_write_count_
= 0;
173 received_did_write_bytes_total_
= 0;
174 received_did_write_complete_
= false;
175 received_did_truncate_
= false;
176 received_did_fail_
= false;
177 fail_error_received_
= static_cast<blink::WebFileError
>(0);
180 scoped_ptr
<TestableFileWriter
> testable_writer_
;
181 bool delete_in_client_callback_
;
183 // Observed WebFileWriterClient artifacts.
184 int received_did_write_count_
;
185 long long received_did_write_bytes_total_
;
186 bool received_did_write_complete_
;
187 bool received_did_truncate_
;
188 bool received_did_fail_
;
189 blink::WebFileError fail_error_received_
;
191 DISALLOW_COPY_AND_ASSIGN(FileWriterTest
);
194 TEST_F(FileWriterTest
, BasicFileWrite
) {
195 // Call the webkit facing api.
196 const std::string
kBlobId("1234");
197 writer()->write(kBasicFileWrite_Offset
,
198 blink::WebString::fromUTF8(kBlobId
));
200 // Check that the derived class gets called correctly.
201 EXPECT_TRUE(testable_writer_
->received_write_
);
202 EXPECT_EQ(testable_writer_
->received_write_path_
,
203 mock_path_as_gurl());
204 EXPECT_EQ(kBasicFileWrite_Offset
,
205 testable_writer_
->received_write_offset_
);
206 EXPECT_EQ(kBlobId
, testable_writer_
->received_write_blob_uuid_
);
207 EXPECT_FALSE(testable_writer_
->received_truncate_
);
208 EXPECT_FALSE(testable_writer_
->received_cancel_
);
210 // Check that the client gets called correctly.
211 EXPECT_EQ(1, received_did_write_count_
);
212 EXPECT_TRUE(received_did_write_complete_
);
213 EXPECT_EQ(1, received_did_write_bytes_total_
);
214 EXPECT_FALSE(received_did_truncate_
);
215 EXPECT_FALSE(received_did_fail_
);
218 TEST_F(FileWriterTest
, BasicFileTruncate
) {
219 // Call the webkit facing api.
220 writer()->truncate(kBasicFileTruncate_Offset
);
222 // Check that the derived class gets called correctly.
223 EXPECT_TRUE(testable_writer_
->received_truncate_
);
224 EXPECT_EQ(mock_path_as_gurl(),
225 testable_writer_
->received_truncate_path_
);
226 EXPECT_EQ(kBasicFileTruncate_Offset
,
227 testable_writer_
->received_truncate_offset_
);
228 EXPECT_FALSE(testable_writer_
->received_write_
);
229 EXPECT_FALSE(testable_writer_
->received_cancel_
);
231 // Check that the client gets called correctly.
232 EXPECT_TRUE(received_did_truncate_
);
233 EXPECT_EQ(0, received_did_write_count_
);
234 EXPECT_FALSE(received_did_fail_
);
237 TEST_F(FileWriterTest
, ErrorFileWrite
) {
238 // Call the webkit facing api.
239 const std::string
kBlobId("1234");
240 writer()->write(kErrorFileWrite_Offset
,
241 blink::WebString::fromUTF8(kBlobId
));
243 // Check that the derived class gets called correctly.
244 EXPECT_TRUE(testable_writer_
->received_write_
);
245 EXPECT_EQ(testable_writer_
->received_write_path_
,
246 mock_path_as_gurl());
247 EXPECT_EQ(kErrorFileWrite_Offset
,
248 testable_writer_
->received_write_offset_
);
249 EXPECT_EQ(kBlobId
, testable_writer_
->received_write_blob_uuid_
);
250 EXPECT_FALSE(testable_writer_
->received_truncate_
);
251 EXPECT_FALSE(testable_writer_
->received_cancel_
);
253 // Check that the client gets called correctly.
254 EXPECT_TRUE(received_did_fail_
);
255 EXPECT_EQ(blink::WebFileErrorNotFound
, fail_error_received_
);
256 EXPECT_EQ(0, received_did_write_count_
);
257 EXPECT_FALSE(received_did_truncate_
);
260 TEST_F(FileWriterTest
, ErrorFileTruncate
) {
261 // Call the webkit facing api.
262 writer()->truncate(kErrorFileTruncate_Offset
);
264 // Check that the derived class gets called correctly.
265 EXPECT_TRUE(testable_writer_
->received_truncate_
);
266 EXPECT_EQ(mock_path_as_gurl(),
267 testable_writer_
->received_truncate_path_
);
268 EXPECT_EQ(kErrorFileTruncate_Offset
,
269 testable_writer_
->received_truncate_offset_
);
270 EXPECT_FALSE(testable_writer_
->received_write_
);
271 EXPECT_FALSE(testable_writer_
->received_cancel_
);
273 // Check that the client gets called correctly.
274 EXPECT_TRUE(received_did_fail_
);
275 EXPECT_EQ(blink::WebFileErrorNotFound
, fail_error_received_
);
276 EXPECT_FALSE(received_did_truncate_
);
277 EXPECT_EQ(0, received_did_write_count_
);
280 TEST_F(FileWriterTest
, MultiFileWrite
) {
281 // Call the webkit facing api.
282 const std::string
kBlobId("1234");
283 writer()->write(kMultiFileWrite_Offset
,
284 blink::WebString::fromUTF8(kBlobId
));
286 // Check that the derived class gets called correctly.
287 EXPECT_TRUE(testable_writer_
->received_write_
);
288 EXPECT_EQ(testable_writer_
->received_write_path_
,
289 mock_path_as_gurl());
290 EXPECT_EQ(kMultiFileWrite_Offset
,
291 testable_writer_
->received_write_offset_
);
292 EXPECT_EQ(kBlobId
, testable_writer_
->received_write_blob_uuid_
);
293 EXPECT_FALSE(testable_writer_
->received_truncate_
);
294 EXPECT_FALSE(testable_writer_
->received_cancel_
);
296 // Check that the client gets called correctly.
297 EXPECT_EQ(3, received_did_write_count_
);
298 EXPECT_TRUE(received_did_write_complete_
);
299 EXPECT_EQ(3, received_did_write_bytes_total_
);
300 EXPECT_FALSE(received_did_truncate_
);
301 EXPECT_FALSE(received_did_fail_
);
304 TEST_F(FileWriterTest
, CancelFileWriteBeforeCompletion
) {
305 // Call the webkit facing api.
306 const std::string
kBlobId("1234");
307 writer()->write(kCancelFileWriteBeforeCompletion_Offset
,
308 blink::WebString::fromUTF8(kBlobId
));
310 // Check that the derived class gets called correctly.
311 EXPECT_TRUE(testable_writer_
->received_write_
);
312 EXPECT_EQ(testable_writer_
->received_write_path_
,
313 mock_path_as_gurl());
314 EXPECT_EQ(kCancelFileWriteBeforeCompletion_Offset
,
315 testable_writer_
->received_write_offset_
);
316 EXPECT_EQ(kBlobId
, testable_writer_
->received_write_blob_uuid_
);
317 EXPECT_TRUE(testable_writer_
->received_cancel_
);
318 EXPECT_FALSE(testable_writer_
->received_truncate_
);
320 // Check that the client gets called correctly.
321 EXPECT_TRUE(received_did_fail_
);
322 EXPECT_EQ(blink::WebFileErrorAbort
, fail_error_received_
);
323 EXPECT_EQ(1, received_did_write_count_
);
324 EXPECT_FALSE(received_did_write_complete_
);
325 EXPECT_EQ(1, received_did_write_bytes_total_
);
326 EXPECT_FALSE(received_did_truncate_
);
329 TEST_F(FileWriterTest
, CancelFileWriteAfterCompletion
) {
330 // Call the webkit facing api.
331 const std::string
kBlobId("1234");
332 writer()->write(kCancelFileWriteAfterCompletion_Offset
,
333 blink::WebString::fromUTF8(kBlobId
));
335 // Check that the derived class gets called correctly.
336 EXPECT_TRUE(testable_writer_
->received_write_
);
337 EXPECT_EQ(testable_writer_
->received_write_path_
,
338 mock_path_as_gurl());
339 EXPECT_EQ(kCancelFileWriteAfterCompletion_Offset
,
340 testable_writer_
->received_write_offset_
);
341 EXPECT_EQ(kBlobId
, testable_writer_
->received_write_blob_uuid_
);
342 EXPECT_TRUE(testable_writer_
->received_cancel_
);
343 EXPECT_FALSE(testable_writer_
->received_truncate_
);
345 // Check that the client gets called correctly.
346 EXPECT_TRUE(received_did_fail_
);
347 EXPECT_EQ(blink::WebFileErrorAbort
, fail_error_received_
);
348 EXPECT_EQ(1, received_did_write_count_
);
349 EXPECT_FALSE(received_did_write_complete_
);
350 EXPECT_EQ(1, received_did_write_bytes_total_
);
351 EXPECT_FALSE(received_did_truncate_
);
354 TEST_F(FileWriterTest
, CancelFileTruncate
) {
355 // Call the webkit facing api.
356 writer()->truncate(kCancelFileTruncate_Offset
);
358 // Check that the derived class gets called correctly.
359 EXPECT_TRUE(testable_writer_
->received_truncate_
);
360 EXPECT_EQ(mock_path_as_gurl(),
361 testable_writer_
->received_truncate_path_
);
362 EXPECT_EQ(kCancelFileTruncate_Offset
,
363 testable_writer_
->received_truncate_offset_
);
364 EXPECT_TRUE(testable_writer_
->received_cancel_
);
365 EXPECT_FALSE(testable_writer_
->received_write_
);
367 // Check that the client gets called correctly.
368 EXPECT_TRUE(received_did_fail_
);
369 EXPECT_EQ(blink::WebFileErrorAbort
, fail_error_received_
);
370 EXPECT_FALSE(received_did_truncate_
);
371 EXPECT_EQ(0, received_did_write_count_
);
374 TEST_F(FileWriterTest
, CancelFailedTruncate
) {
375 // Call the webkit facing api.
376 writer()->truncate(kCancelFailedTruncate_Offset
);
378 // Check that the derived class gets called correctly.
379 EXPECT_TRUE(testable_writer_
->received_truncate_
);
380 EXPECT_EQ(mock_path_as_gurl(),
381 testable_writer_
->received_truncate_path_
);
382 EXPECT_EQ(kCancelFailedTruncate_Offset
,
383 testable_writer_
->received_truncate_offset_
);
384 EXPECT_TRUE(testable_writer_
->received_cancel_
);
385 EXPECT_FALSE(testable_writer_
->received_write_
);
387 // Check that the client gets called correctly.
388 EXPECT_TRUE(received_did_fail_
);
389 EXPECT_EQ(blink::WebFileErrorAbort
, fail_error_received_
);
390 EXPECT_FALSE(received_did_truncate_
);
391 EXPECT_EQ(0, received_did_write_count_
);
394 TEST_F(FileWriterTest
, DeleteInCompletionCallbacks
) {
395 const std::string
kBlobId("1234");
396 delete_in_client_callback_
= true;
397 writer()->write(kBasicFileWrite_Offset
,
398 blink::WebString::fromUTF8(kBlobId
));
399 EXPECT_FALSE(testable_writer_
.get());
402 delete_in_client_callback_
= true;
403 writer()->truncate(kBasicFileTruncate_Offset
);
404 EXPECT_FALSE(testable_writer_
.get());
407 delete_in_client_callback_
= true;
408 writer()->write(kErrorFileWrite_Offset
,
409 blink::WebString::fromUTF8(kBlobId
));
410 EXPECT_FALSE(testable_writer_
.get());
413 delete_in_client_callback_
= true;
414 writer()->truncate(kErrorFileTruncate_Offset
);
415 EXPECT_FALSE(testable_writer_
.get());
417 // Not crashing counts as passing.
420 } // namespace content