import { module, test } from "qunit"; import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { exists, query, queryAll } from "discourse/tests/helpers/qunit-helpers"; import { click, render, settled } from "@ember/test-helpers"; import { NOTIFICATION_TYPES } from "discourse/tests/fixtures/concerns/notification-types"; import { hbs } from "ember-cli-htmlbars"; import pretender from "discourse/tests/helpers/create-pretender"; module("Integration | Component | user-menu", function (hooks) { setupRenderingTest(hooks); const template = hbs``; test("default tab is all notifications", async function (assert) { await render(template); const activeTab = query(".top-tabs.tabs-list .btn.active"); assert.strictEqual(activeTab.id, "user-menu-button-all-notifications"); const notifications = queryAll("#quick-access-all-notifications ul li"); assert.ok(notifications[0].classList.contains("edited")); assert.ok(notifications[1].classList.contains("replied")); assert.ok(notifications[2].classList.contains("liked-consolidated")); }); test("active tab has a11y attributes that indicate it's active", async function (assert) { await render(template); const activeTab = query(".top-tabs.tabs-list .btn.active"); assert.strictEqual(activeTab.getAttribute("tabindex"), "0"); assert.strictEqual(activeTab.getAttribute("aria-selected"), "true"); }); test("inactive tab has a11y attributes that indicate it's inactive", async function (assert) { await render(template); const inactiveTab = query(".top-tabs.tabs-list .btn:not(.active)"); assert.strictEqual(inactiveTab.getAttribute("tabindex"), "-1"); assert.strictEqual(inactiveTab.getAttribute("aria-selected"), "false"); }); test("the menu has a group of tabs at the top", async function (assert) { this.currentUser.set("can_send_private_messages", true); await render(template); const tabs = queryAll(".top-tabs.tabs-list .btn"); assert.strictEqual(tabs.length, 6); ["all-notifications", "replies", "likes", "messages", "bookmarks"].forEach( (tab, index) => { assert.strictEqual(tabs[index].id, `user-menu-button-${tab}`); assert.strictEqual(tabs[index].dataset.tabNumber, index.toString()); assert.strictEqual( tabs[index].getAttribute("aria-controls"), `quick-access-${tab}` ); } ); }); test("the menu has a group of tabs at the bottom", async function (assert) { this.currentUser.set("can_send_private_messages", true); await render(template); const tabs = queryAll(".bottom-tabs.tabs-list .btn"); assert.strictEqual(tabs.length, 1); const profileTab = tabs[0]; assert.strictEqual(profileTab.id, "user-menu-button-profile"); assert.strictEqual(profileTab.dataset.tabNumber, "6"); assert.strictEqual(profileTab.getAttribute("tabindex"), "-1"); }); test("likes tab is hidden if current user's like notifications frequency is 'never'", async function (assert) { this.currentUser.set("likes_notifications_disabled", true); this.currentUser.set("can_send_private_messages", true); await render(template); assert.ok(!exists("#user-menu-button-likes")); const tabs = Array.from(queryAll(".tabs-list .btn")); // top and bottom tabs assert.strictEqual(tabs.length, 6); assert.deepEqual( tabs.map((t) => t.dataset.tabNumber), ["0", "1", "2", "3", "4", "5"], "data-tab-number of the tabs has no gaps when the likes tab is hidden" ); }); test("reviewables tab is shown if current user can review and there are pending reviewables", async function (assert) { this.currentUser.set("can_review", true); this.currentUser.set("reviewable_count", 1); this.currentUser.set("can_send_private_messages", true); await render(template); const tab = query("#user-menu-button-review-queue"); assert.strictEqual(tab.dataset.tabNumber, "5"); const tabs = Array.from(queryAll(".tabs-list .btn")); // top and bottom tabs assert.strictEqual(tabs.length, 8); assert.deepEqual( tabs.map((t) => t.dataset.tabNumber), ["0", "1", "2", "3", "4", "5", "6", "7"], "data-tab-number of the tabs has no gaps when the reviewables tab is show" ); }); test("reviewables tab is not shown if current user can review but there are no pending reviewables", async function (assert) { this.currentUser.set("can_review", true); this.currentUser.set("reviewable_count", 0); await render(template); assert.notOk(exists("#user-menu-button-review-queue")); }); test("messages tab isn't shown if current user does not have can_send_private_messages permission", async function (assert) { this.currentUser.set("moderator", false); this.currentUser.set("admin", false); this.currentUser.set("groups", []); this.currentUser.set("can_send_private_messages", false); await render(template); assert.ok(!exists("#user-menu-button-messages")); const tabs = Array.from(queryAll(".tabs-list .btn")); // top and bottom tabs assert.strictEqual(tabs.length, 6); assert.deepEqual( tabs.map((t) => t.dataset.tabNumber), ["0", "1", "2", "3", "4", "5"], "data-tab-number of the tabs has no gaps when the messages tab is hidden" ); }); test("messages tab is shown if user has can_send_private_messages permission", async function (assert) { this.currentUser.set("moderator", true); this.currentUser.set("admin", false); this.currentUser.set("groups", []); this.currentUser.set("can_send_private_messages", true); await render(template); assert.ok(exists("#user-menu-button-messages")); }); test("reviewables count is shown on the reviewables tab", async function (assert) { this.currentUser.set("can_review", true); this.currentUser.set("reviewable_count", 4); await render(template); const countBadge = query( "#user-menu-button-review-queue .badge-notification" ); assert.strictEqual(countBadge.textContent, "4"); this.currentUser.set("reviewable_count", 0); await settled(); assert.ok(!exists("#user-menu-button-review-queue .badge-notification")); }); test("changing tabs", async function (assert) { this.currentUser.set("can_review", true); this.currentUser.set("reviewable_count", 1); await render(template); let queryParams; pretender.get("/notifications", (request) => { queryParams = request.queryParams; let data; if (queryParams.filter_by_types === "liked,liked_consolidated,reaction") { data = [ { id: 60, user_id: 1, notification_type: NOTIFICATION_TYPES.liked, read: true, high_priority: false, created_at: "2021-11-25T19:31:13.241Z", post_number: 6, topic_id: 10, fancy_title: "Greetings!", slug: "greetings", data: { topic_title: "Greetings!", original_post_id: 20, original_post_type: 1, original_username: "discobot", revision_number: null, display_username: "discobot", }, }, { id: 63, user_id: 1, notification_type: NOTIFICATION_TYPES.liked, read: true, high_priority: false, created_at: "2021-11-25T19:31:13.241Z", post_number: 6, topic_id: 10, fancy_title: "Greetings!", slug: "greetings", data: { topic_title: "Greetings!", original_post_id: 20, original_post_type: 1, original_username: "discobot", revision_number: null, display_username: "discobot", }, }, { id: 20, user_id: 1, notification_type: NOTIFICATION_TYPES.liked_consolidated, read: true, high_priority: false, created_at: "2021-11-25T19:31:13.241Z", post_number: 6, topic_id: 10, fancy_title: "Greetings 123!", slug: "greetings 123", data: { topic_title: "Greetings 123!", original_post_id: 20, original_post_type: 1, original_username: "discobot", revision_number: null, display_username: "discobot", }, }, ]; } else if ( queryParams.filter_by_types === "mentioned,posted,quoted,replied,watching_first_post" ) { data = [ { id: 6, user_id: 1, notification_type: NOTIFICATION_TYPES.mentioned, read: true, high_priority: false, created_at: "2021-11-25T19:31:13.241Z", post_number: 6, topic_id: 10, fancy_title: "Greetings!", slug: "greetings", data: { topic_title: "Greetings!", original_post_id: 20, original_post_type: 1, original_username: "discobot", revision_number: null, display_username: "discobot", }, }, ]; } else { throw new Error( `unexpected notification type ${queryParams.filter_by_types}` ); } return [ 200, { "Content-Type": "application/json" }, { notifications: data }, ]; }); await click("#user-menu-button-likes"); assert.ok(exists("#quick-access-likes.quick-access-panel")); assert.strictEqual( queryParams.filter_by_types, "liked,liked_consolidated,reaction", "request params has filter_by_types set to `liked`, `liked_consolidated` and `reaction`" ); assert.strictEqual(queryParams.silent, "true"); let activeTabs = queryAll(".top-tabs .btn.active"); assert.strictEqual(activeTabs.length, 1); assert.strictEqual( activeTabs[0].id, "user-menu-button-likes", "active tab is now the likes tab" ); assert.strictEqual(queryAll("#quick-access-likes ul li").length, 3); await click("#user-menu-button-replies"); assert.ok(exists("#quick-access-replies.quick-access-panel")); assert.strictEqual( queryParams.filter_by_types, "mentioned,posted,quoted,replied,watching_first_post", "request params has filter_by_types set to `mentioned`, `posted`, `quoted`, `replied` and `watching_first_post`" ); assert.strictEqual(queryParams.silent, "true"); activeTabs = queryAll(".top-tabs .btn.active"); assert.strictEqual(activeTabs.length, 1); assert.strictEqual( activeTabs[0].id, "user-menu-button-replies", "active tab is now the replies tab" ); await click("#user-menu-button-review-queue"); assert.ok(exists("#quick-access-review-queue.quick-access-panel")); activeTabs = queryAll(".top-tabs .btn.active"); assert.strictEqual(activeTabs.length, 1); assert.strictEqual( activeTabs[0].id, "user-menu-button-review-queue", "active tab is now the reviewables tab" ); assert.strictEqual(queryAll("#quick-access-review-queue ul li").length, 8); }); });