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

const {
    afterEach,
    afterNextRender,
    beforeEach,
    start,
} = require('mail/static/src/utils/test_utils.js');
var ActivityMenu = require('mail.systray.ActivityMenu');

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

QUnit.module('mail', {}, function () {
QUnit.module('ActivityMenu', {
    beforeEach() {
        beforeEach(this);

        Object.assign(this.data, {
            'mail.activity.menu': {
                fields: {
                    name: { type: "char" },
                    model: { type: "char" },
                    type: { type: "char" },
                    planned_count: { type: "integer" },
                    today_count: { type: "integer" },
                    overdue_count: { type: "integer" },
                    total_count: { type: "integer" },
                    actions: [{
                        icon: { type: "char" },
                        name: { type: "char" },
                        action_xmlid: { type: "char" },
                    }],
                },
                records: [{
                        name: "Contact",
                        model: "res.partner",
                        type: "activity",
                        planned_count: 0,
                        today_count: 1,
                        overdue_count: 0,
                        total_count: 1,
                    },
                    {
                        name: "Task",
                        type: "activity",
                        model: "project.task",
                        planned_count: 1,
                        today_count: 0,
                        overdue_count: 0,
                        total_count: 1,
                    },
                    {
                        name: "Issue",
                        type: "activity",
                        model: "project.issue",
                        planned_count: 1,
                        today_count: 1,
                        overdue_count: 1,
                        total_count: 3,
                        actions: [{
                            icon: "fa-clock-o",
                            name: "summary",
                        }],
                    },
                    {
                        name: "Note",
                        type: "activity",
                        model: "partner",
                        planned_count: 1,
                        today_count: 1,
                        overdue_count: 1,
                        total_count: 3,
                        actions: [{
                            icon: "fa-clock-o",
                            name: "summary",
                            action_xmlid: "mail.mail_activity_type_view_tree",
                        }],
                    }
                ],
            },
        });
        this.session = {
            uid: 10,
        };
    },
    afterEach() {
        afterEach(this);
    },
});

QUnit.test('activity menu widget: menu with no records', async function (assert) {
    assert.expect(1);

    const { widget } = await start({
        data: this.data,
        mockRPC: function (route, args) {
            if (args.method === 'systray_get_activities') {
                return Promise.resolve([]);
            }
            return this._super(route, args);
        },
    });
    const activityMenu = new ActivityMenu(widget);
    await activityMenu.appendTo($('#qunit-fixture'));
    await testUtils.nextTick();
    assert.containsOnce(activityMenu, '.o_no_activity');
    widget.destroy();
});

QUnit.test('activity menu widget: activity menu with 3 records', async function (assert) {
    assert.expect(10);
    var self = this;

    const { widget } = await start({
        data: this.data,
        mockRPC: function (route, args) {
            if (args.method === 'systray_get_activities') {
                return Promise.resolve(self.data['mail.activity.menu']['records']);
            }
            return this._super(route, args);
        },
    });
    var activityMenu = new ActivityMenu(widget);
    await activityMenu.appendTo($('#qunit-fixture'));
    await testUtils.nextTick();
    assert.hasClass(activityMenu.$el, 'o_mail_systray_item', 'should be the instance of widget');
    // the assertion below has not been replace because there are includes of ActivityMenu that modify the length.
    assert.ok(activityMenu.$('.o_mail_preview').length);
    assert.containsOnce(activityMenu.$el, '.o_notification_counter', "widget should have notification counter");
    assert.strictEqual(parseInt(activityMenu.el.innerText), 8, "widget should have 8 notification counter");

    var context = {};
    testUtils.mock.intercept(activityMenu, 'do_action', function (event) {
        assert.deepEqual(event.data.action.context, context, "wrong context value");
    }, true);

    // case 1: click on "late"
    context = {
        force_search_count: 1,
        search_default_activities_overdue: 1,
    };
    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    assert.hasClass(activityMenu.$el, 'show', 'ActivityMenu should be open');
    await testUtils.dom.click(activityMenu.$(".o_activity_filter_button[data-model_name='Issue'][data-filter='overdue']"));
    assert.doesNotHaveClass(activityMenu.$el, 'show', 'ActivityMenu should be closed');
    // case 2: click on "today"
    context = {
        force_search_count: 1,
        search_default_activities_today: 1,
    };
    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    await testUtils.dom.click(activityMenu.$(".o_activity_filter_button[data-model_name='Issue'][data-filter='today']"));
    // case 3: click on "future"
    context = {
        force_search_count: 1,
        search_default_activities_upcoming_all: 1,
    };
    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    await testUtils.dom.click(activityMenu.$(".o_activity_filter_button[data-model_name='Issue'][data-filter='upcoming_all']"));
    // case 4: click anywere else
    context = {
        force_search_count: 1,
        search_default_activities_overdue: 1,
        search_default_activities_today: 1,
    };
    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    await testUtils.dom.click(activityMenu.$(".o_mail_systray_dropdown_items > div[data-model_name='Issue']"));

    widget.destroy();
});

QUnit.test('activity menu widget: activity view icon', async function (assert) {
    assert.expect(12);
    var self = this;

    const { widget } = await start({
        data: this.data,
        mockRPC: function (route, args) {
            if (args.method === 'systray_get_activities') {
                return Promise.resolve(self.data['mail.activity.menu'].records);
            }
            return this._super(route, args);
        },
        session: this.session,
    });
    var activityMenu = new ActivityMenu(widget);
    await activityMenu.appendTo($('#qunit-fixture'));
    await testUtils.nextTick();
    assert.containsN(activityMenu, '.o_mail_activity_action', 2,
                       "widget should have 2 activity view icons");

    var $first = activityMenu.$('.o_mail_activity_action').eq(0);
    var $second = activityMenu.$('.o_mail_activity_action').eq(1);
    assert.strictEqual($first.data('model_name'), "Issue",
                       "first activity action should link to 'Issue'");
    assert.hasClass($first, 'fa-clock-o', "should display the activity action icon");

    assert.strictEqual($second.data('model_name'), "Note",
                       "Second activity action should link to 'Note'");
    assert.hasClass($second, 'fa-clock-o', "should display the activity action icon");

    testUtils.mock.intercept(activityMenu, 'do_action', function (ev) {
        if (ev.data.action.name) {
            assert.ok(ev.data.action.domain, "should define a domain on the action");
            assert.deepEqual(ev.data.action.domain, [["activity_ids.user_id", "=", 10]],
                "should set domain to user's activity only");
            assert.step('do_action:' + ev.data.action.name);
        } else {
            assert.step('do_action:' + ev.data.action);
        }
    }, true);

    // click on the "Issue" activity icon
    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    assert.hasClass(activityMenu.$('.dropdown-menu'), 'show',
        "dropdown should be expanded");

    await testUtils.dom.click(activityMenu.$(".o_mail_activity_action[data-model_name='Issue']"));
    assert.doesNotHaveClass(activityMenu.$('.dropdown-menu'), 'show',
        "dropdown should be collapsed");

    // click on the "Note" activity icon
    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    await testUtils.dom.click(activityMenu.$(".o_mail_activity_action[data-model_name='Note']"));

    assert.verifySteps([
        'do_action:Issue',
        'do_action:mail.mail_activity_type_view_tree'
    ]);

    widget.destroy();
});

QUnit.test('activity menu widget: close on messaging menu click', async function (assert) {
    assert.expect(2);

    const { widget } = await start({
        data: this.data,
        hasMessagingMenu: true,
        async mockRPC(route, args) {
            if (args.method === 'message_fetch') {
                return [];
            }
            if (args.method === 'systray_get_activities') {
                return [];
            }
            return this._super(route, args);
        },
    });
    const activityMenu = new ActivityMenu(widget);
    await activityMenu.appendTo($('#qunit-fixture'));
    await testUtils.nextTick();

    await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
    assert.hasClass(
        activityMenu.el.querySelector('.o_mail_systray_dropdown'),
        'show',
        "activity menu should be shown after click on itself"
    );

    await afterNextRender(() =>
        document.querySelector(`.o_MessagingMenu_toggler`).click()
    );
    assert.doesNotHaveClass(
        activityMenu.el.querySelector('.o_mail_systray_dropdown'),
        'show',
        "activity menu should be hidden after click on messaging menu"
    );

    widget.destroy();
});

});

});
