define([
    'aui',
    'jquery',
    'bitbucket/internal/feature/tasks/model/task',
    'bitbucket/internal/feature/tasks/task-view'
], function (
    AJS,
    $,
    Task,
    TaskView
) {

    'use strict';

    module('tasks-view', {
        setup: function () {
            this._expandingTextarea = $.fn.expandingTextarea;
            $.fn.expandingTextarea = function() { return this; };
            this.task = new Task({});
            sinon.stub(this.task, 'save');
            this.task.save.returns($.Deferred().promise());

            this.template = sinon.stub();
            this.template.returns("<div class='task'><textarea class='task-text'></textarea><a href='#' class='task-cancel'>Cancel</a></div>");
            this.view = new TaskView({
                model: this.task,
                mode: TaskView.Mode.EDIT
            });
            this.view.template = this.template;
            $('body').append(this.view.render().$el);
        },
        teardown: function () {
            this.task.save.restore();
            this.view.remove();
            $.fn.expandingTextarea = this._expandingTextarea;
        }
    });

    test('TaskView saves on enter', function () {
        sinon.spy(this.view, 'cancelTaskEdit');
        var keyEvent = $.Event('keydown', {
            keyCode: AJS.keyCode.ENTER
        });
        this.view.$('.task-text')
            .val('task text')
            .trigger(keyEvent);
        ok(this.task.save.calledOnce, "Task was saved");
        ok(this.view.cancelTaskEdit.notCalled, "Cancel edit was not called");
    });

    test("TaskView doesn't save when text is removed", function () {
        this.task.set({
            id: 1,
            text: "Current text"
        });
        this.view.saveTask();
        ok(!this.task.isValid(), "Task is not valid without text");
    });


    test('TaskView cancels on escape', function () {
        sinon.spy(this.view, 'cancelTaskEdit');
        sinon.spy(this.task, 'destroy');
        this.task.set({
            id: 1,
            text: 'Original text'
        });
        // need to force view into edit mode to save original text
        this.view.switchMode(TaskView.Mode.EDIT);
        var keyEvent = $.Event('keydown', {
            keyCode: AJS.keyCode.ESCAPE
        });
        this.view.$('.task-text')
            .html('task text')
            .trigger(keyEvent);
        ok(this.task.save.notCalled, "Task was not saved");
        ok(this.view.cancelTaskEdit.calledOnce, "Cancel edit was called");
        equal(this.task.getText(), "Original text", "Text reverted");
        ok(this.task.destroy.notCalled, "Task was not destroyed");
    });

    test('TaskView destroys model when new task is cancelled', function () {
        sinon.spy(this.view, 'cancelTaskEdit');
        sinon.spy(this.task, 'destroy');
        var keyEvent = $.Event('keydown', {
            keyCode: AJS.keyCode.ESCAPE
        });
        this.view.$('.task-text')
            .trigger(keyEvent);
        ok(this.task.save.notCalled, "Task was not saved");
        ok(this.view.cancelTaskEdit.calledOnce, "Task was cancelled");
        ok(this.task.destroy.calledOnce, "Task was destroyed");
        this.task.destroy.restore();
    });
});
