odoo.define('mail.typingThreadWindowTests', function (require) {
"use strict";

var mailTestUtils = require('mail.testUtils');

var testUtils = require('web.test_utils');
var Widget = require('web.Widget');

QUnit.module('mail', {}, function () {
QUnit.module('Thread Window', {}, function () {
QUnit.module('Typing', {
    beforeEach: function () {
        var self = this;

        // define channel to link to chat window
        this.data = {
            'mail.message': {
                fields: {},
                records: [],
            },
            initMessaging: {
                channel_slots: {
                    channel_channel: [{
                        id: 1,
                        channel_type: "channel",
                        name: "general",
                    }],
                },
            },
        };
        this.services = mailTestUtils.getMailServices();
        this.ORIGINAL_THREAD_WINDOW_APPENDTO = this.services.mail_service.prototype.THREAD_WINDOW_APPENDTO;

        /**
         * Simulate that someone typing something (or stops typing)
         *
         * @param {Object} params
         * @param {integer} params.channelID
         * @param {boolean} params.isTyping
         * @param {integer} params.partnerID
         * @param {Widget} params.widget a widget that can call the bus_service
         */
        this.simulateIsTyping = function (params) {
            var typingData = {
                info: 'typing_status',
                partner_id: params.partnerID,
                is_typing: params.isTyping,
            };
            var notification = [[false, 'mail.channel', params.channelID], typingData];
            params.widget.call('bus_service', 'trigger', 'notification', [notification]);
        };

        this.createParent = function (params) {
            var widget = new Widget();

            // in non-debug mode, append thread windows in qunit-fixture
            // note that it does not hide thread window because it uses fixed
            // position, and qunit-fixture uses absolute...
            if (params.debug) {
                self.services.mail_service.prototype.THREAD_WINDOW_APPENDTO = 'body';
            } else {
                self.services.mail_service.prototype.THREAD_WINDOW_APPENDTO = '#qunit-fixture';
            }

            testUtils.mock.addMockEnvironment(widget, params);
            return widget;
        };
    },
    afterEach: function () {
        // reset thread window append to body
        this.services.mail_service.prototype.THREAD_WINDOW_APPENDTO = 'body';
    },
});

QUnit.test('receive typing notification', function (assert) {
    assert.expect(4);

    var parent = this.createParent({
        data: this.data,
        services: this.services,
        mockRPC: function (route, args) {
            // when receiving an 'is typing' notification, fetch the list of
            // members of this channel if we haven't done yet.
            if (args.method === 'channel_fetch_listeners') {
                return $.when([
                    { id: 42, name: "Someone" },
                ]);
            }
            return this._super.apply(this, arguments);
        },
    });

    // detach channel 1, so that it opens corresponding thread window.
    parent.call('mail_service', 'getChannel', 1).detach();

    var $threadWindow = $('.o_thread_window');
    assert.containsNone($threadWindow, '.o_mail_thread_typing_icon',
        "should not display an icon that someone is typing something on this thread");

    this.simulateIsTyping({
        channelID: 1,
        isTyping: true,
        partnerID: 42,
        widget: parent,
    });

    assert.containsOnce($threadWindow, '.o_mail_thread_typing_icon',
        "should display an icon that someone is typing something on this thread");
    assert.hasAttrValue($threadWindow.find('.o_mail_thread_typing_icon'), 'title',
        "Someone is typing...",
        "should display someone is typing something on hover of this icon");

    this.simulateIsTyping({
        channelID: 1,
        isTyping: false,
        partnerID: 42,
        widget: parent,
    });

    assert.containsNone($threadWindow, '.o_mail_thread_typing_icon',
        "should no longer display an icon that someone is typing something on this thread");

    parent.destroy();
});

});
});
});
