1 // Copyright (c) 2011 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 "webkit/fileapi/webfilewriter_base.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/utf_string_conversions.h"
11 #include "googleurl/src/gurl.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileError.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileWriterClient.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(WebKit::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_url_
= GURL();
55 received_cancel_
= false;
58 bool received_truncate_
;
59 GURL received_truncate_path_
;
60 int64 received_truncate_offset_
;
62 GURL received_write_path_
;
63 GURL received_write_blob_url_
;
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::PLATFORM_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::PLATFORM_FILE_ERROR_NOT_FOUND
); // truncate completion
84 DidSucceed(); // cancel completion
90 virtual void DoWrite(const GURL
& path
, const GURL
& blob_url
,
91 int64 offset
) OVERRIDE
{
92 received_write_
= true;
93 received_write_path_
= path
;
94 received_write_offset_
= offset
;
95 received_write_blob_url_
= blob_url
;
97 if (offset
== kBasicFileWrite_Offset
) {
99 } else if (offset
== kErrorFileWrite_Offset
) {
100 DidFail(base::PLATFORM_FILE_ERROR_NOT_FOUND
);
101 } else if (offset
== kMultiFileWrite_Offset
) {
105 } else if (offset
== kCancelFileWriteBeforeCompletion_Offset
) {
110 DidFail(base::PLATFORM_FILE_ERROR_FAILED
); // write completion
111 DidSucceed(); // cancel completion
112 } else if (offset
== kCancelFileWriteAfterCompletion_Offset
) {
117 DidWrite(1, true); // write completion
118 DidFail(base::PLATFORM_FILE_ERROR_FAILED
); // cancel completion
124 virtual void DoCancel() OVERRIDE
{
125 received_cancel_
= true;
129 class FileWriterTest
: public testing::Test
,
130 public WebKit::WebFileWriterClient
{
136 WebKit::WebFileWriter
* writer() {
137 return testable_writer_
.get();
140 // WebFileWriterClient overrides
141 virtual void didWrite(long long bytes
, bool complete
) {
142 EXPECT_FALSE(received_did_write_complete_
);
143 ++received_did_write_count_
;
144 received_did_write_bytes_total_
+= bytes
;
146 received_did_write_complete_
= true;
148 if (delete_in_client_callback_
)
149 testable_writer_
.reset(NULL
);
152 virtual void didTruncate() {
153 EXPECT_FALSE(received_did_truncate_
);
154 received_did_truncate_
= true;
155 if (delete_in_client_callback_
)
156 testable_writer_
.reset(NULL
);
159 virtual void didFail(WebKit::WebFileError error
) {
160 EXPECT_FALSE(received_did_fail_
);
161 received_did_fail_
= true;
162 fail_error_received_
= error
;
163 if (delete_in_client_callback_
)
164 testable_writer_
.reset(NULL
);
169 testable_writer_
.reset(new TestableFileWriter(this));
170 delete_in_client_callback_
= false;
171 received_did_write_count_
= 0;
172 received_did_write_bytes_total_
= 0;
173 received_did_write_complete_
= false;
174 received_did_truncate_
= false;
175 received_did_fail_
= false;
176 fail_error_received_
= static_cast<WebKit::WebFileError
>(0);
179 scoped_ptr
<TestableFileWriter
> testable_writer_
;
180 bool delete_in_client_callback_
;
182 // Observed WebFileWriterClient artifacts.
183 int received_did_write_count_
;
184 long long received_did_write_bytes_total_
;
185 bool received_did_write_complete_
;
186 bool received_did_truncate_
;
187 bool received_did_fail_
;
188 WebKit::WebFileError fail_error_received_
;
190 DISALLOW_COPY_AND_ASSIGN(FileWriterTest
);
193 TEST_F(FileWriterTest
, BasicFileWrite
) {
194 // Call the webkit facing api.
195 const GURL
kBlobUrl("blob://bloburl/");
196 writer()->write(kBasicFileWrite_Offset
, kBlobUrl
);
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(kBlobUrl
, testable_writer_
->received_write_blob_url_
);
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 GURL
kBlobUrl("blob://bloburl/");
238 writer()->write(kErrorFileWrite_Offset
, kBlobUrl
);
240 // Check that the derived class gets called correctly.
241 EXPECT_TRUE(testable_writer_
->received_write_
);
242 EXPECT_EQ(testable_writer_
->received_write_path_
,
243 mock_path_as_gurl());
244 EXPECT_EQ(kErrorFileWrite_Offset
,
245 testable_writer_
->received_write_offset_
);
246 EXPECT_EQ(kBlobUrl
, testable_writer_
->received_write_blob_url_
);
247 EXPECT_FALSE(testable_writer_
->received_truncate_
);
248 EXPECT_FALSE(testable_writer_
->received_cancel_
);
250 // Check that the client gets called correctly.
251 EXPECT_TRUE(received_did_fail_
);
252 EXPECT_EQ(WebKit::WebFileErrorNotFound
, fail_error_received_
);
253 EXPECT_EQ(0, received_did_write_count_
);
254 EXPECT_FALSE(received_did_truncate_
);
257 TEST_F(FileWriterTest
, ErrorFileTruncate
) {
258 // Call the webkit facing api.
259 writer()->truncate(kErrorFileTruncate_Offset
);
261 // Check that the derived class gets called correctly.
262 EXPECT_TRUE(testable_writer_
->received_truncate_
);
263 EXPECT_EQ(mock_path_as_gurl(),
264 testable_writer_
->received_truncate_path_
);
265 EXPECT_EQ(kErrorFileTruncate_Offset
,
266 testable_writer_
->received_truncate_offset_
);
267 EXPECT_FALSE(testable_writer_
->received_write_
);
268 EXPECT_FALSE(testable_writer_
->received_cancel_
);
270 // Check that the client gets called correctly.
271 EXPECT_TRUE(received_did_fail_
);
272 EXPECT_EQ(WebKit::WebFileErrorNotFound
, fail_error_received_
);
273 EXPECT_FALSE(received_did_truncate_
);
274 EXPECT_EQ(0, received_did_write_count_
);
277 TEST_F(FileWriterTest
, MultiFileWrite
) {
278 // Call the webkit facing api.
279 const GURL
kBlobUrl("blob://bloburl/");
280 writer()->write(kMultiFileWrite_Offset
, kBlobUrl
);
282 // Check that the derived class gets called correctly.
283 EXPECT_TRUE(testable_writer_
->received_write_
);
284 EXPECT_EQ(testable_writer_
->received_write_path_
,
285 mock_path_as_gurl());
286 EXPECT_EQ(kMultiFileWrite_Offset
,
287 testable_writer_
->received_write_offset_
);
288 EXPECT_EQ(kBlobUrl
, testable_writer_
->received_write_blob_url_
);
289 EXPECT_FALSE(testable_writer_
->received_truncate_
);
290 EXPECT_FALSE(testable_writer_
->received_cancel_
);
292 // Check that the client gets called correctly.
293 EXPECT_EQ(3, received_did_write_count_
);
294 EXPECT_TRUE(received_did_write_complete_
);
295 EXPECT_EQ(3, received_did_write_bytes_total_
);
296 EXPECT_FALSE(received_did_truncate_
);
297 EXPECT_FALSE(received_did_fail_
);
300 TEST_F(FileWriterTest
, CancelFileWriteBeforeCompletion
) {
301 // Call the webkit facing api.
302 const GURL
kBlobUrl("blob://bloburl/");
303 writer()->write(kCancelFileWriteBeforeCompletion_Offset
, kBlobUrl
);
305 // Check that the derived class gets called correctly.
306 EXPECT_TRUE(testable_writer_
->received_write_
);
307 EXPECT_EQ(testable_writer_
->received_write_path_
,
308 mock_path_as_gurl());
309 EXPECT_EQ(kCancelFileWriteBeforeCompletion_Offset
,
310 testable_writer_
->received_write_offset_
);
311 EXPECT_EQ(kBlobUrl
, testable_writer_
->received_write_blob_url_
);
312 EXPECT_TRUE(testable_writer_
->received_cancel_
);
313 EXPECT_FALSE(testable_writer_
->received_truncate_
);
315 // Check that the client gets called correctly.
316 EXPECT_TRUE(received_did_fail_
);
317 EXPECT_EQ(WebKit::WebFileErrorAbort
, fail_error_received_
);
318 EXPECT_EQ(1, received_did_write_count_
);
319 EXPECT_FALSE(received_did_write_complete_
);
320 EXPECT_EQ(1, received_did_write_bytes_total_
);
321 EXPECT_FALSE(received_did_truncate_
);
324 TEST_F(FileWriterTest
, CancelFileWriteAfterCompletion
) {
325 // Call the webkit facing api.
326 const GURL
kBlobUrl("blob://bloburl/");
327 writer()->write(kCancelFileWriteAfterCompletion_Offset
, kBlobUrl
);
329 // Check that the derived class gets called correctly.
330 EXPECT_TRUE(testable_writer_
->received_write_
);
331 EXPECT_EQ(testable_writer_
->received_write_path_
,
332 mock_path_as_gurl());
333 EXPECT_EQ(kCancelFileWriteAfterCompletion_Offset
,
334 testable_writer_
->received_write_offset_
);
335 EXPECT_EQ(kBlobUrl
, testable_writer_
->received_write_blob_url_
);
336 EXPECT_TRUE(testable_writer_
->received_cancel_
);
337 EXPECT_FALSE(testable_writer_
->received_truncate_
);
339 // Check that the client gets called correctly.
340 EXPECT_TRUE(received_did_fail_
);
341 EXPECT_EQ(WebKit::WebFileErrorAbort
, fail_error_received_
);
342 EXPECT_EQ(1, received_did_write_count_
);
343 EXPECT_FALSE(received_did_write_complete_
);
344 EXPECT_EQ(1, received_did_write_bytes_total_
);
345 EXPECT_FALSE(received_did_truncate_
);
348 TEST_F(FileWriterTest
, CancelFileTruncate
) {
349 // Call the webkit facing api.
350 writer()->truncate(kCancelFileTruncate_Offset
);
352 // Check that the derived class gets called correctly.
353 EXPECT_TRUE(testable_writer_
->received_truncate_
);
354 EXPECT_EQ(mock_path_as_gurl(),
355 testable_writer_
->received_truncate_path_
);
356 EXPECT_EQ(kCancelFileTruncate_Offset
,
357 testable_writer_
->received_truncate_offset_
);
358 EXPECT_TRUE(testable_writer_
->received_cancel_
);
359 EXPECT_FALSE(testable_writer_
->received_write_
);
361 // Check that the client gets called correctly.
362 EXPECT_TRUE(received_did_fail_
);
363 EXPECT_EQ(WebKit::WebFileErrorAbort
, fail_error_received_
);
364 EXPECT_FALSE(received_did_truncate_
);
365 EXPECT_EQ(0, received_did_write_count_
);
368 TEST_F(FileWriterTest
, CancelFailedTruncate
) {
369 // Call the webkit facing api.
370 writer()->truncate(kCancelFailedTruncate_Offset
);
372 // Check that the derived class gets called correctly.
373 EXPECT_TRUE(testable_writer_
->received_truncate_
);
374 EXPECT_EQ(mock_path_as_gurl(),
375 testable_writer_
->received_truncate_path_
);
376 EXPECT_EQ(kCancelFailedTruncate_Offset
,
377 testable_writer_
->received_truncate_offset_
);
378 EXPECT_TRUE(testable_writer_
->received_cancel_
);
379 EXPECT_FALSE(testable_writer_
->received_write_
);
381 // Check that the client gets called correctly.
382 EXPECT_TRUE(received_did_fail_
);
383 EXPECT_EQ(WebKit::WebFileErrorAbort
, fail_error_received_
);
384 EXPECT_FALSE(received_did_truncate_
);
385 EXPECT_EQ(0, received_did_write_count_
);
388 TEST_F(FileWriterTest
, DeleteInCompletionCallbacks
) {
389 delete_in_client_callback_
= true;
390 writer()->write(kBasicFileWrite_Offset
, GURL("blob://bloburl/"));
391 EXPECT_FALSE(testable_writer_
.get());
394 delete_in_client_callback_
= true;
395 writer()->truncate(kBasicFileTruncate_Offset
);
396 EXPECT_FALSE(testable_writer_
.get());
399 delete_in_client_callback_
= true;
400 writer()->write(kErrorFileWrite_Offset
, GURL("blob://bloburl/"));
401 EXPECT_FALSE(testable_writer_
.get());
404 delete_in_client_callback_
= true;
405 writer()->truncate(kErrorFileTruncate_Offset
);
406 EXPECT_FALSE(testable_writer_
.get());
408 // Not crashing counts as passing.
411 } // namespace fileapi