/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/

/*global exports, cordova, FileTransfer, FileTransferError,
         FileUploadOptions, LocalFileSystem, requestFileSystem, TEMPORARY */

/*global describe, it, expect, beforeEach, afterEach, spyOn,
         jasmine, pending*/

exports.defineAutoTests = function () {

    // constants
    var GRACE_TIME_DELTA = 600; // in milliseconds
    var DEFAULT_FILESYSTEM_SIZE = 1024*50; //filesystem size in bytes
    var UNKNOWN_HOST = "http://foobar.apache.org";
    var HEADERS_ECHO = "http://whatheaders.com"; // NOTE: this site is very useful!
    var DOWNLOAD_TIMEOUT = 2 * 60 * 1000; // download tests sometimes need a higher timeout to complete successfully
    var UPLOAD_TIMEOUT = 2 * 60 * 1000; // upload tests sometimes need a higher timeout to complete successfully
    var ABORT_DELAY = 100; // for abort() tests

    // config for upload test server
    // NOTE:
    //      more info at https://github.com/apache/cordova-labs/tree/cordova-filetransfer
    var SERVER                  = "http://cordova-filetransfer.jitsu.com";
    var SERVER_WITH_CREDENTIALS = "http://cordova_user:cordova_password@cordova-filetransfer.jitsu.com";

    // flags
    var isWindows = cordova.platformId === 'windows8' || cordova.platformId === 'windows';
    var isWP8 = cordova.platformId === 'windowsphone';

    var isBrowser = cordova.platformId === 'browser';
    var isIE = isBrowser && navigator.userAgent.indexOf('Trident') >= 0;

    describe('FileTransferError', function () {

        it('should exist', function () {
            expect(FileTransferError).toBeDefined();
        });

        it('should be constructable', function () {
            var transferError = new FileTransferError();
            expect(transferError).toBeDefined();
        });

        it('filetransfer.spec.3 should expose proper constants', function () {

            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBeDefined();
            expect(FileTransferError.INVALID_URL_ERR).toBeDefined();
            expect(FileTransferError.CONNECTION_ERR).toBeDefined();
            expect(FileTransferError.ABORT_ERR).toBeDefined();
            expect(FileTransferError.NOT_MODIFIED_ERR).toBeDefined();

            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);
            expect(FileTransferError.INVALID_URL_ERR).toBe(2);
            expect(FileTransferError.CONNECTION_ERR).toBe(3);
            expect(FileTransferError.ABORT_ERR).toBe(4);
            expect(FileTransferError.NOT_MODIFIED_ERR).toBe(5);
        });
    });

    describe('FileUploadOptions', function () {

        it('should exist', function () {
            expect(FileUploadOptions).toBeDefined();
        });

        it('should be constructable', function () {
            var transferOptions = new FileUploadOptions();
            expect(transferOptions).toBeDefined();
        });
    });

    describe('FileTransfer', function () {

        var persistentRoot, tempRoot;

        // named callbacks
        var unexpectedCallbacks = {
            httpFail:          function () {},
            httpWin:           function () {},
            fileSystemFail:    function () {},
            fileSystemWin:     function () {},
            fileOperationFail: function () {},
            fileOperationWin:  function () {},
        };

        var expectedCallbacks = {
            unsupportedOperation: function (response) {
                console.log('spec called unsupported functionality; response:', response);
            },
        };

        // helpers
        var deleteFile = function (fileSystem, name, done) {
            fileSystem.getFile(name, null,
                function (fileEntry) {
                    fileEntry.remove(
                        function () {
                            console.log('deleted \'' + name + '\'');
                            done();
                        },
                        function () {
                            throw new Error('failed to delete: \'' + name + '\'');
                        }
                    );
                },
                function () {
                    console.log('no \'' + name + '\' to delete; skipping deletion');
                    done();
                }
            );
        };

        var writeFile = function (fileSystem, name, content, success) {
            fileSystem.getFile(name, { create: true },
                function (fileEntry) {
                    fileEntry.createWriter(function (writer) {

                        writer.onwrite = function () {
                            console.log('created test file \'' + name + '\'');
                            success(fileEntry);
                        };

                        writer.onabort = function (evt) {
                            throw new Error('aborted creating test file \'' + name + '\': ' + evt);
                        };

                        writer.error = function (evt) {
                            throw new Error('aborted creating test file \'' + name + '\': ' + evt);
                        };

                        if (cordova.platformId === 'browser') {
                            // var builder = new BlobBuilder();
                            // builder.append(content + '\n');
                            var blob = new Blob([content + '\n'], { type: 'text/plain' });
                            writer.write(blob);
                        } else {
                            writer.write(content + "\n");
                        }

                    }, unexpectedCallbacks.fileOperationFail);
                },
                function () {
                    throw new Error('could not create test file \'' + name + '\'');
                }
            );
        };

        // according to documentation, wp8 does not support onProgress:
        // https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md#supported-platforms
        var wp8OnProgressHandler = function () {};

        var defaultOnProgressHandler = function (event) {
            if (event.lengthComputable) {
                expect(event.loaded).toBeGreaterThan(1);
                expect(event.total).toBeGreaterThan(0);
                expect(event.total).not.toBeLessThan(event.loaded);
                expect(event.lengthComputable).toBe(true, 'lengthComputable');
            } else {
                // In IE, when lengthComputable === false, event.total somehow is equal to 2^64
                if (isIE) {
                    expect(event.total).toBe(Math.pow(2, 64));
                } else {
                    expect(event.total).toBe(0);
                }
            }
        };

        var getMalformedUrl = function () {
            if (cordova.platformId === 'android' || cordova.platformId === 'amazon-fireos') {
                // bad protocol causes a MalformedUrlException on Android
                return "httpssss://example.com";
            } else {
                // iOS doesn't care about protocol, space in hostname causes error
                return "httpssss://exa mple.com";
            }
        };

        // NOTE:
        //      there are several beforeEach calls, one per async call; since calling done()
        //      signifies a completed async call, each async call needs its own done(), and
        //      therefore its own beforeEach
        beforeEach(function (done) {
            window.requestFileSystem(LocalFileSystem.PERSISTENT, DEFAULT_FILESYSTEM_SIZE,
                function (fileSystem) {
                    persistentRoot = fileSystem.root;
                    done();
                },
                function () {
                    throw new Error('Failed to initialize persistent file system.');
                }
            );
        });

        beforeEach(function (done) {
            window.requestFileSystem(LocalFileSystem.TEMPORARY, DEFAULT_FILESYSTEM_SIZE,
                function (fileSystem) {
                    tempRoot = fileSystem.root;
                    done();
                },
                function () {
                    throw new Error('Failed to initialize temporary file system.');
                }
            );
        });

        // spy on all named callbacks
        beforeEach(function() {

            // ignore the actual implementations of the unexpected callbacks
            for (var callback in unexpectedCallbacks) {
                if (unexpectedCallbacks.hasOwnProperty(callback)) {
                    spyOn(unexpectedCallbacks, callback);
                }
            }

            // but run the implementations of the expected callbacks
            for (callback in expectedCallbacks) { //jshint ignore: line
                if (expectedCallbacks.hasOwnProperty(callback)) {
                    spyOn(expectedCallbacks, callback).and.callThrough();
                }
            }
        });

        // at the end, check that none of the unexpected callbacks got called,
        // and act on the expected callbacks
        afterEach(function() {
            for (var callback in unexpectedCallbacks) {
                if (unexpectedCallbacks.hasOwnProperty(callback)) {
                    expect(unexpectedCallbacks[callback]).not.toHaveBeenCalled();
                }
            }

            if (expectedCallbacks.unsupportedOperation.calls.any()) {
                pending();
            }
        });

        it('should initialise correctly', function() {
            expect(persistentRoot).toBeDefined();
            expect(tempRoot).toBeDefined();
        });

        it('should exist', function () {
            expect(FileTransfer).toBeDefined();
        });

        it('filetransfer.spec.1 should be constructable', function () {
            var transfer = new FileTransfer();
            expect(transfer).toBeDefined();
        });

        it('filetransfer.spec.2 should expose proper functions', function () {

            var transfer = new FileTransfer();

            expect(transfer.upload).toBeDefined();
            expect(transfer.download).toBeDefined();

            expect(transfer.upload).toEqual(jasmine.any(Function));
            expect(transfer.download).toEqual(jasmine.any(Function));
        });

        describe('methods', function() {

            var transfer;

            var root;
            var fileName;
            var localFilePath;

            beforeEach(function() {

                transfer = new FileTransfer();

                // assign onprogress handler
                transfer.onprogress = isWP8 ? wp8OnProgressHandler : defaultOnProgressHandler;

                // spy on the onprogress handler, but still call through to it
                spyOn(transfer, 'onprogress').and.callThrough();

                root          = persistentRoot;
                fileName      = 'testFile.txt';
                localFilePath = root.toURL() + fileName;
            });

            // NOTE:
            //      if download tests are failing, check the
            //      URL white list for the following URLs:
            //         - 'httpssss://example.com'
            //         - 'apache.org', with subdomains="true"
            //         - 'cordova-filetransfer.jitsu.com'
            describe('download', function () {

                // helpers
                var verifyDownload = function (fileEntry) {
                    expect(fileEntry.name).toBe(fileName);
                };

                // delete the downloaded file
                afterEach(function (done) {
                    deleteFile(root, fileName, done);
                });

                it('ensures that test file does not exist', function (done) {
                    deleteFile(root, fileName, done);
                });

                it('filetransfer.spec.4 should download a file', function (done) {

                    var fileURL = SERVER + '/robots.txt';

                    var fileWin = function (blob) {

                        if (transfer.onprogress.calls.any()) {
                            var lastProgressEvent = transfer.onprogress.calls.mostRecent().args[0];
                            expect(lastProgressEvent.loaded).not.toBeGreaterThan(blob.size);
                        } else {
                            console.log('no progress events were emitted');
                        }

                        done();
                    };

                    var downloadWin = function (entry) {

                        verifyDownload(entry);

                        // verify the FileEntry representing this file
                        entry.file(fileWin, unexpectedCallbacks.fileSystemFail);
                    };

                    transfer.download(fileURL, localFilePath, downloadWin, unexpectedCallbacks.httpFail);
                }, DOWNLOAD_TIMEOUT);

                it('filetransfer.spec.5 should download a file using http basic auth', function (done) {

                    var fileURL = SERVER_WITH_CREDENTIALS + '/download_basic_auth';

                    var downloadWin = function (entry) {
                        verifyDownload(entry);
                        done();
                    };

                    transfer.download(fileURL, localFilePath, downloadWin, unexpectedCallbacks.httpFail);
                }, DOWNLOAD_TIMEOUT);

                it('filetransfer.spec.6 should get 401 status on http basic auth failure', function (done) {

                    // NOTE:
                    //      using server without credentials
                    var fileURL = SERVER + '/download_basic_auth';

                    var downloadFail = function (error) {
                        expect(error.http_status).toBe(401);
                        expect(error.http_status).not.toBe(404, "Ensure " + fileURL + " is in the white list");
                        done();
                    };

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail, null,
                        {
                            headers: {
                                'If-Modified-Since': 'Thu, 19 Mar 2015 00:00:00 GMT'
                            }
                        });
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.7 should download a file using file:// (when hosted from file://)", function (done) {

                    // for Windows platform it's ms-appdata:/// by default, not file://
                    if (isWindows) {
                        pending();
                        return;
                    }

                    var fileURL = window.location.protocol + '//' + window.location.pathname.replace(/ /g, '%20');

                    if (!/^file:/.exec(fileURL) && cordova.platformId !== 'blackberry10') {
                        if (cordova.platformId === 'windowsphone')
                            expect(fileURL).toMatch(/^x-wmapp0:/);
                        done();
                        return;
                    }

                    var downloadWin = function (entry) {
                        verifyDownload(entry);
                        done();
                    };

                    transfer.download(fileURL, localFilePath, downloadWin, unexpectedCallbacks.httpFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.8 should download a file using https://", function (done) {

                    var fileURL = "https://www.apache.org/licenses/";

                    var fileWin = function (file) {

                        var reader = new FileReader();

                        reader.onerror = unexpectedCallbacks.fileOperationFail;
                        reader.onload  = function () {
                            expect(reader.result).toMatch(/The Apache Software Foundation/);
                            done();
                        };

                        reader.readAsText(file);
                    };

                    var downloadWin = function (entry) {
                        verifyDownload(entry);
                        entry.file(fileWin, unexpectedCallbacks.fileSystemFail);
                    };

                    transfer.download(fileURL, localFilePath, downloadWin, unexpectedCallbacks.httpFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.11 should call the error callback on abort()", function (done) {

                    var fileURL = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, done);
                    setTimeout(function() {
                        transfer.abort();
                    }, ABORT_DELAY);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.9 should not leave partial file due to abort", function (done) {

                    var fileURL = 'http://cordova.apache.org/downloads/logos_2.zip';

                    var downloadFail = function (error) {

                        expect(error.code).toBe(FileTransferError.ABORT_ERR);
                        expect(transfer.onprogress).toHaveBeenCalled();

                        // check that there is no file
                        root.getFile(localFilePath, null, unexpectedCallbacks.fileSystemWin, done);
                    };

                    // abort at the first onprogress event
                    transfer.onprogress = function (event) {
                        if (event.loaded > 0) {
                            transfer.abort();
                        }
                    };

                    spyOn(transfer, 'onprogress').and.callThrough();

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.10 should be stopped by abort() right away", function (done) {

                    var fileURL = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';

                    expect(transfer.abort).not.toThrow(); // should be a no-op.

                    var startTime = +new Date();

                    var downloadFail = function (error) {

                        expect(error.code).toBe(FileTransferError.ABORT_ERR);
                        expect(new Date() - startTime).toBeLessThan(GRACE_TIME_DELTA);

                        // delay calling done() to wait for the bogus abort()
                        setTimeout(done, GRACE_TIME_DELTA * 2);
                    };

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
                    setTimeout(function() {
                        transfer.abort();
                    }, ABORT_DELAY);

                    // call abort() again, after a time greater than the grace period
                    setTimeout(function () {
                        expect(transfer.abort).not.toThrow();
                    }, GRACE_TIME_DELTA);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.12 should get http status on failure", function (done) {

                    var fileURL = SERVER + "/404";

                    var downloadFail = function (error) {

                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        expect(error.http_status).toBe(404);

                        done();
                    };

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.13 should get http body on failure", function (done) {

                    var fileURL = SERVER + "/404";

                    var downloadFail = function (error) {

                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        expect(error.http_status).toBe(404);

                        expect(error.body).toBeDefined();
                        expect(error.body).toMatch('You requested a 404');

                        done();
                    };

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.14 should handle malformed urls", function (done) {

                    var fileURL = getMalformedUrl();

                    var downloadFail = function (error) {

                        // Note: Android needs the bad protocol to be added to the access list
                        // <access origin=".*"/> won't match because ^https?:// is prepended to the regex
                        // The bad protocol must begin with http to avoid automatic prefix
                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);

                        done();
                    };

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
                });

                it("filetransfer.spec.15 should handle unknown host", function (done) {
                    var fileURL = UNKNOWN_HOST;

                    var downloadFail = function (error) {
                        expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
                        done();
                    };

                    // turn off the onprogress handler
                    transfer.onprogress = function () {};

                    transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
                }, 30000);

                it("filetransfer.spec.16 should handle bad file path", function (done) {
                    var fileURL = SERVER;
                    transfer.download(fileURL, "c:\\54321", unexpectedCallbacks.httpWin, done);
                });

                it("filetransfer.spec.17 progress should work with gzip encoding", function (done) {

                    // lengthComputable false on bb10 when downloading gzip
                    if (cordova.platformId === 'blackberry10') {
                        pending();
                        return;
                    }

                    var fileURL = "http://www.apache.org/";

                    var downloadWin = function (entry) {
                        verifyDownload(entry);
                        done();
                    };

                    transfer.download(fileURL, localFilePath, downloadWin, unexpectedCallbacks.httpFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.30 downloaded file entries should have a toNativeURL method", function (done) {

                    if (cordova.platformId === 'browser') {
                        pending();
                        return;
                    }

                    var fileURL = SERVER + "/robots.txt";

                    var downloadWin = function (entry) {

                        expect(entry.toNativeURL).toBeDefined();
                        expect(entry.toNativeURL).toEqual(jasmine.any(Function));

                        var nativeURL = entry.toNativeURL();

                        expect(nativeURL).toBeTruthy();
                        expect(nativeURL).toEqual(jasmine.any(String));

                        if (isWindows) {
                            expect(nativeURL.substring(0, 14)).toBe('ms-appdata:///');
                        } else if (isWP8) {
                            expect(nativeURL.substring(0, 1)).toBe('/');
                        } else {
                            expect(nativeURL.substring(0, 7)).toBe('file://');
                        }

                        done();
                    };

                    transfer.download(fileURL, localFilePath, downloadWin, unexpectedCallbacks.httpFail);
                }, DOWNLOAD_TIMEOUT);

                it("filetransfer.spec.28 (compatibility) should be able to download a file using local paths", function (done) {

                    var fileURL = SERVER + "/robots.txt";

                    var unsupported = function (response) {
                        expectedCallbacks.unsupportedOperation(response);
                        done();
                    };

                    var downloadWin = function (entry) {
                        verifyDownload(entry);
                        done();
                    };

                    var internalFilePath;
                    if (root.toInternalURL) {
                        internalFilePath = root.toInternalURL() + fileName;
                    } else {
                        internalFilePath = localFilePath;
                    }

                    // This is an undocumented interface to File which exists only for testing
                    // backwards compatibilty. By obtaining the raw filesystem path of the download
                    // location, we can pass that to transfer.download() to make sure that previously-stored
                    // paths are still valid.
                    cordova.exec(function (localPath) {
                        transfer.download(fileURL, localPath, downloadWin, unexpectedCallbacks.httpFail);
                    }, unsupported, 'File', '_getLocalFilesystemPath', [internalFilePath]);
                });
            });

            describe('upload', function() {

                var uploadParams;
                var uploadOptions;

                var fileName;
                var fileContents;
                var localFilePath;

                // helpers
                var verifyUpload = function (uploadResult) {

                    expect(uploadResult.bytesSent).toBeGreaterThan(0);
                    expect(uploadResult.responseCode).toBe(200);

                    var obj = null;
                    try {
                        obj = JSON.parse(uploadResult.response);
                        expect(obj.fields).toBeDefined();
                        expect(obj.fields.value1).toBe("test");
                        expect(obj.fields.value2).toBe("param");
                    } catch (e) {
                        expect(obj).not.toBeNull('returned data from server should be valid json');
                    }

                    expect(transfer.onprogress).toHaveBeenCalled();
                };

                beforeEach(function(done) {

                    fileName      = 'fileToUpload.txt';
                    fileContents  = 'upload test file';

                    uploadParams        = {};
                    uploadParams.value1 = "test";
                    uploadParams.value2 = "param";

                    uploadOptions          = new FileUploadOptions();
                    uploadOptions.fileKey  = "file";
                    uploadOptions.fileName = fileName;
                    uploadOptions.mimeType = "text/plain";
                    uploadOptions.params   = uploadParams;

                    var fileWin = function (entry) {
                        localFilePath = entry.toURL();
                        done();
                    };

                    // create a file to upload
                    writeFile(root, fileName, fileContents, fileWin);
                });

                // delete the uploaded file
                afterEach(function (done) {
                    deleteFile(root, fileName, done);
                });

                it("filetransfer.spec.18 should be able to upload a file", function (done) {

                    var fileURL = SERVER + '/upload';

                    var uploadWin = function (uploadResult) {

                        verifyUpload(uploadResult);

                        if (cordova.platformId === 'ios') {
                            expect(uploadResult.headers).toBeDefined('Expected headers to be defined.');
                            expect(uploadResult.headers['Content-Type']).toBeDefined('Expected content-type header to be defined.');
                        }

                        done();
                    };

                    // NOTE: removing uploadOptions cause Android to timeout
                    transfer.upload(localFilePath, fileURL, uploadWin, unexpectedCallbacks.httpFail, uploadOptions);
                }, UPLOAD_TIMEOUT);

                it("filetransfer.spec.19 should be able to upload a file with http basic auth", function (done) {

                    var fileURL = SERVER_WITH_CREDENTIALS + "/upload_basic_auth";

                    var uploadWin = function (uploadResult) {
                        verifyUpload(uploadResult);
                        done();
                    };

                    // NOTE: removing uploadOptions cause Android to timeout
                    transfer.upload(localFilePath, fileURL, uploadWin, unexpectedCallbacks.httpFail, uploadOptions);
                }, UPLOAD_TIMEOUT);

                it("filetransfer.spec.21 should be stopped by abort() right away", function (done) {

                    var fileURL = SERVER + '/upload';
                    var startTime;

                    var uploadFail = function (e) {
                        expect(e.code).toBe(FileTransferError.ABORT_ERR);
                        expect(new Date() - startTime).toBeLessThan(GRACE_TIME_DELTA);

                        // delay calling done() to wait for the bogus abort()
                        setTimeout(done, GRACE_TIME_DELTA * 2);
                    };

                    var fileWin = function () {

                        startTime = +new Date();

                        expect(transfer.abort).not.toThrow();

                        // NOTE: removing uploadOptions cause Android to timeout
                        transfer.upload(localFilePath, fileURL, unexpectedCallbacks.httpWin, uploadFail, uploadOptions);
                        setTimeout(function() {
                            transfer.abort();
                        }, ABORT_DELAY);

                        setTimeout(function () {
                            expect(transfer.abort).not.toThrow();
                        }, GRACE_TIME_DELTA);
                    };

                    writeFile(root, fileName, new Array(100000).join('aborttest!'), fileWin);
                }, UPLOAD_TIMEOUT);

                it("filetransfer.spec.22 should get http status and body on failure", function (done) {

                    var fileURL = SERVER + '/403';

                    var uploadFail = function (error) {
                        expect(error.http_status).toBe(403);
                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        done();
                    };

                    transfer.upload(localFilePath, fileURL, unexpectedCallbacks.httpWin, uploadFail, uploadOptions);
                }, UPLOAD_TIMEOUT);

                it("filetransfer.spec.24 should handle malformed urls", function (done) {

                    var fileURL = getMalformedUrl();

                    var uploadFail = function (error) {
                        expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        done();
                    };

                    transfer.upload(localFilePath, fileURL, unexpectedCallbacks.httpWin, uploadFail, {});
                });

                it("filetransfer.spec.25 should handle unknown host", function (done) {

                    var fileURL = UNKNOWN_HOST;

                    var uploadFail = function (error) {
                        expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        done();
                    };

                    transfer.upload(localFilePath, fileURL, unexpectedCallbacks.httpWin, uploadFail, {});
                }, 30000); // unknown host may need quite some time on some devices

                it("filetransfer.spec.25 should handle missing file", function (done) {

                    var fileURL = SERVER + "/upload";

                    var uploadFail = function (error) {
                        expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        done();
                    };

                    transfer.upload('does_not_exist.txt', fileURL, unexpectedCallbacks.httpWin, uploadFail);
                }, UPLOAD_TIMEOUT);

                it("filetransfer.spec.26 should handle bad file path", function (done) {

                    var fileURL = SERVER + "/upload";

                    var uploadFail = function (error) {
                        expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                        done();
                    };

                    transfer.upload("c:\\54321", fileURL, unexpectedCallbacks.httpWin, uploadFail);
                });

                it("filetransfer.spec.27 should be able to set custom headers", function (done) {

                    if (cordova.platformId === 'windowsphone') {
                        pending();
                    }

                    var fileURL = HEADERS_ECHO;

                    var uploadWin = function (uploadResult) {

                        expect(uploadResult.bytesSent).toBeGreaterThan(0);
                        expect(uploadResult.responseCode).toBe(200);
                        expect(uploadResult.response).toBeDefined();

                        var responseHtml = decodeURIComponent(uploadResult.response);

                        expect(responseHtml).toMatch(/CustomHeader1[\s\S]*CustomValue1/i);
                        expect(responseHtml).toMatch(/CustomHeader2[\s\S]*CustomValue2[\s\S]*CustomValue3/i, "Should allow array values");

                        done();
                    };

                    uploadOptions.headers = {
                        "CustomHeader1": "CustomValue1",
                        "CustomHeader2": ["CustomValue2", "CustomValue3"],
                    };

                    // NOTE: removing uploadOptions cause Android to timeout
                    transfer.upload(localFilePath, fileURL, uploadWin, unexpectedCallbacks.httpFail, uploadOptions);
                }, UPLOAD_TIMEOUT);

                it("filetransfer.spec.29 (compatibility) should be able to upload a file using local paths", function (done) {

                    var fileURL = SERVER + "/upload";

                    var unsupported = function (response) {
                        expectedCallbacks.unsupportedOperation(response);
                        done();
                    };

                    var uploadWin = function (uploadResult) {
                        verifyUpload(uploadResult);
                        done();
                    };

                    var internalFilePath;
                    if (root.toInternalURL) {
                        internalFilePath = root.toInternalURL() + fileName;
                    } else {
                        internalFilePath = localFilePath;
                    }

                    // This is an undocumented interface to File which exists only for testing
                    // backwards compatibilty. By obtaining the raw filesystem path of the download
                    // location, we can pass that to transfer.download() to make sure that previously-stored
                    // paths are still valid.
                    cordova.exec(function (localPath) {
                        transfer.upload(localPath, fileURL, uploadWin, unexpectedCallbacks.httpFail, uploadOptions);
                    }, unsupported, 'File', '_getLocalFilesystemPath', [internalFilePath]);
                }, UPLOAD_TIMEOUT);
            });
        });
    });
};

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

exports.defineManualTests = function (contentEl, createActionButton) {
    var imageURL = "http://apache.org/images/feather-small.gif";
    var videoURL = "http://techslides.com/demos/sample-videos/small.mp4";

    function clearResults() {
        var results = document.getElementById("info");
        results.innerHTML = '';
    }

    function downloadImg(source, urlFn, element, directory) {
        var filename = source.substring(source.lastIndexOf("/") + 1);
        filename = directory + filename || filename;
        function download(fileSystem) {
            var ft = new FileTransfer();
            console.log("Starting download");
            ft.download(source, fileSystem.root.toURL() + filename, function (entry) {
                console.log("Download complete");
                element.src = urlFn(entry);
                console.log("Src URL is " + element.src);
                console.log("Inserting element");
                document.getElementById("info").appendChild(element);
            }, function (e) { console.log("ERROR: ft.download " + e.code); });
        }
        console.log("Requesting filesystem");
        clearResults();
        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) {
            console.log("Checking for existing file");
            if (directory !== undefined) {
                console.log("Checking for existing directory.");
                fileSystem.root.getDirectory(directory, {}, function (dirEntry) {
                    dirEntry.removeRecursively(function () {
                        download(fileSystem);
                    }, function () { console.log("ERROR: dirEntry.removeRecursively"); });
                }, function () {
                    download(fileSystem);
                });
            } else {
                fileSystem.root.getFile(filename, { create: false }, function (entry) {
                    console.log("Removing existing file");
                    entry.remove(function () {
                        download(fileSystem);
                    }, function () { console.log("ERROR: entry.remove"); });
                }, function () {
                    download(fileSystem);
                });
            }
        }, function () { console.log("ERROR: requestFileSystem"); });
    }

    /******************************************************************************/

    var file_transfer_tests = '<h2>Image File Transfer Tests</h2>' +
        '<h3>The following tests should display an image of the Apache feather in the status box</h3>' +
        '<div id="cdv_image"></div>' +
        '<div id="native_image"></div>' +
        '<div id="non-existent_dir"></div>' +
        '<h2>Video File Transfer Tests</h2>' +
        '<h3>The following tests should display a video in the status box. The video should play when play is pressed</h3>' +
        '<div id="cdv_video"></div>' +
        '<div id="native_video"></div>';

    contentEl.innerHTML = '<div id="info"></div>' +
        file_transfer_tests;

    createActionButton('Download and display img (cdvfile)', function () {
        downloadImg(imageURL, function (entry) { return entry.toURL(); }, new Image());
    }, 'cdv_image');

    createActionButton('Download and display img (native)', function () {
        downloadImg(imageURL, function (entry) { return entry.toNativeURL(); }, new Image());
    }, 'native_image');

    createActionButton('Download to a non-existent dir (should work)', function () {
        downloadImg(imageURL, function (entry) { return entry.toURL(); }, new Image(), '/nonExistentDirTest/');
    }, 'non-existent_dir');

    createActionButton('Download and play video (cdvfile)', function () {
        var videoElement = document.createElement('video');
        videoElement.controls = "controls";
        downloadImg(videoURL, function (entry) { return entry.toURL(); }, videoElement);
    }, 'cdv_video');

    createActionButton('Download and play video (native)', function () {
        var videoElement = document.createElement('video');
        videoElement.controls = "controls";
        downloadImg(videoURL, function (entry) { return entry.toNativeURL(); }, videoElement);
    }, 'native_video');
};
