define([
    'backbone',
    'jquery',
    'Squire',
    'test-helper',
    'bitbucket/internal/util/function'
], function (
    Backbone,
    $,
    Squire,
    testHelper,
    fn
) {

    'use strict';

    var injector = new Squire();

    testHelper.setTemplates({
        'bitbucket.internal.widget.errorContent': 'Error'
    });

    var self;

    QUnit.module('tasks-comment-task-list-view', {
        beforeEach: function (assert) {
            var done = assert.async();
            self = this;

            injector.mock('bitbucket/util/state', testHelper.mockPageState());

            // This is required to ensure that the same object we modify in setup is injected
            injector.mock('jquery', $);
            injector.mock('backbone', Backbone);
            injector.setDefaultDeps([
                'bitbucket/internal/feature/tasks/task-view',
                'bitbucket/internal/feature/tasks/model/task-collection',
                'bitbucket/internal/feature/tasks/task-list/comment-task-list-view',
                'bitbucket/internal/feature/tasks/task-list/task-list-row-view'
            ]);

            injector.injectedCall(function (TaskView, TaskCollection, CommentTaskListView, TaskListRowView) {
                this.collection = new TaskCollection();
                this._expandingTextarea = $.fn.expandingTextarea;
                $.fn.expandingTextarea = function() { return this; };
                sinon.stub(Backbone, 'sync');
                this.saveDeferred = $.Deferred();
                Backbone.sync.returns(this.saveDeferred.promise());
                TaskListRowView.prototype.template = sinon.spy();
                TaskView.prototype.template = $.noop;
                this.commentTaskListView = new CommentTaskListView({
                    collection: this.collection,
                    comment: {
                        id: 1
                    }
                });
                done();
            }, this);
        },
        afterEach: function () {
            Backbone.sync.restore();
            $.fn.expandingTextarea = this._expandingTextarea;
        }
    });

    injector.test('CommentTaskListView can removes task on save failure', function (assert) {
        var task = this.commentTaskListView.createTask();
        assert.ok(task, 'Got back a task');
        assert.ok(Backbone.sync.notCalled, 'Task was not saved');
        assert.equal(this.commentTaskListView.taskRowViews.length, 1, 'A task view was created');
        assert.equal(this.commentTaskListView.taskRowViews[0].taskView.options.mode, 'edit', 'Task was in edit mode');
    });

    injector.test('CommentTaskListView can removes task on save failure', function (assert) {
        var task = this.commentTaskListView.createTask('');
        assert.ok(task, 'Got back a task');
        assert.ok(Backbone.sync.notCalled, 'Task was not saved');
        assert.equal(this.commentTaskListView.taskRowViews.length, 1, 'A task view was created');
        assert.equal(this.commentTaskListView.taskRowViews[0].taskView.options.mode, 'edit', 'Task was in edit mode');
    });

    injector.test('CommentTaskListView can removes task on save failure', function (assert) {
        var task = this.commentTaskListView.createTask('new task');

        this.saveDeferred.resolve();
        assert.ok(task, 'Got back a task');
        assert.ok(Backbone.sync.called, 'Task was saved');
        assert.equal(this.commentTaskListView.taskRowViews.length, 1, 'A task view was created');
        assert.equal(this.commentTaskListView.taskRowViews[0].taskView.options.mode, 'view', 'Task was in view mode');
    });

    injector.test('CommentTaskListView can removes task on save failure', function (assert) {
        var task = this.commentTaskListView.createTask('new task');
        this.saveDeferred.reject();
        assert.ok(task, 'Got back a task');
        assert.ok(Backbone.sync.called, 'Task attempted to be saved');
        assert.equal(this.commentTaskListView.taskRowViews.length, 0, 'A task view was NOT created');
    });
});