FEATURE: Site setting to display user avatars in user menu (#24514)
This commit is contained in:
parent
e4c373194d
commit
ee05f57e2d
|
@ -73,7 +73,11 @@ export default class UserMenuBookmarksList extends UserMenuNotificationsList {
|
|||
await Bookmark.applyTransformations(bookmarks);
|
||||
content.push(
|
||||
...bookmarks.map((bookmark) => {
|
||||
return new UserMenuBookmarkItem({ bookmark });
|
||||
return new UserMenuBookmarkItem({
|
||||
bookmark,
|
||||
siteSettings: this.siteSettings,
|
||||
site: this.site,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import Component from "@glimmer/component";
|
||||
import avatar from "discourse/helpers/bound-avatar-template";
|
||||
import dIcon from "discourse-common/helpers/d-icon";
|
||||
|
||||
export default class IconAvatar extends Component {
|
||||
<template>
|
||||
<div class="icon-avatar">
|
||||
{{avatar @data.avatarTemplate "small"}}
|
||||
{{dIcon @data.icon}}
|
||||
</div>
|
||||
</template>
|
||||
}
|
|
@ -4,7 +4,11 @@
|
|||
title={{this.linkTitle}}
|
||||
{{on "click" this.onClick}}
|
||||
>
|
||||
{{d-icon this.icon}}
|
||||
{{#if this.iconComponent}}
|
||||
<this.iconComponent @data={{this.iconComponentArgs}} />
|
||||
{{else}}
|
||||
{{d-icon this.icon}}
|
||||
{{/if}}
|
||||
<div>
|
||||
{{#if this.label}}
|
||||
<span class={{concat "item-label " this.labelClass}}>
|
||||
|
|
|
@ -49,6 +49,14 @@ export default class UserMenuItem extends Component {
|
|||
return this.#item.topicId;
|
||||
}
|
||||
|
||||
get iconComponent() {
|
||||
return this.#item.iconComponent;
|
||||
}
|
||||
|
||||
get iconComponentArgs() {
|
||||
return this.#item.iconComponentArgs;
|
||||
}
|
||||
|
||||
get #item() {
|
||||
return this.args.item;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div
|
||||
class="user-menu revamped menu-panel drop-down"
|
||||
class={{this.classNames}}
|
||||
data-max-width="320"
|
||||
{{did-insert this.triggerRenderedAppEvent}}
|
||||
>
|
||||
|
|
|
@ -196,6 +196,14 @@ export default class UserMenu extends Component {
|
|||
@tracked currentPanelComponent = DEFAULT_PANEL_COMPONENT;
|
||||
@tracked currentNotificationTypes;
|
||||
|
||||
get classNames() {
|
||||
let classes = ["user-menu", "revamped", "menu-panel", "drop-down"];
|
||||
if (this.siteSettings.show_user_menu_avatars) {
|
||||
classes.push("show-avatars");
|
||||
}
|
||||
return classes.join(" ");
|
||||
}
|
||||
|
||||
@cached
|
||||
get topTabs() {
|
||||
const tabs = [];
|
||||
|
|
|
@ -77,6 +77,16 @@ export default class UserMenuMessagesList extends UserMenuNotificationsList {
|
|||
const topics = data.topics.map((t) => this.store.createRecord("topic", t));
|
||||
await Topic.applyTransformations(topics);
|
||||
|
||||
if (this.siteSettings.show_user_menu_avatars) {
|
||||
// Populate avatar_template for lastPoster
|
||||
const usersById = new Map(data.users.map((u) => [u.id, u]));
|
||||
topics.forEach((t) => {
|
||||
t.last_poster_avatar_template = usersById.get(
|
||||
t.lastPoster.user_id
|
||||
).avatar_template;
|
||||
});
|
||||
}
|
||||
|
||||
const readNotifications = await Notification.initializeNotifications(
|
||||
data.read_notifications
|
||||
);
|
||||
|
@ -96,7 +106,13 @@ export default class UserMenuMessagesList extends UserMenuNotificationsList {
|
|||
})
|
||||
);
|
||||
} else {
|
||||
content.push(new UserMenuMessageItem({ message: item }));
|
||||
content.push(
|
||||
new UserMenuMessageItem({
|
||||
message: item,
|
||||
siteSettings: this.siteSettings,
|
||||
site: this.site,
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import UserMenuIconAvatar from "discourse/components/user-menu/icon-avatar";
|
||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
|
||||
export default class UserMenuBaseItem {
|
||||
constructor({ siteSettings, site }) {
|
||||
this.site = site;
|
||||
this.siteSettings = siteSettings;
|
||||
}
|
||||
get className() {}
|
||||
|
||||
get linkHref() {
|
||||
|
@ -30,6 +35,20 @@ export default class UserMenuBaseItem {
|
|||
|
||||
get topicId() {}
|
||||
|
||||
get avatarTemplate() {}
|
||||
|
||||
get iconComponent() {
|
||||
return this.siteSettings.show_user_menu_avatars ? UserMenuIconAvatar : null;
|
||||
}
|
||||
|
||||
get iconComponentArgs() {
|
||||
return {
|
||||
avatarTemplate:
|
||||
this.avatarTemplate || this.site.system_user_avatar_template,
|
||||
icon: this.icon,
|
||||
};
|
||||
}
|
||||
|
||||
onClick({ event, closeUserMenu }) {
|
||||
if (wantsNewWindow(event)) {
|
||||
return;
|
||||
|
|
|
@ -34,4 +34,8 @@ export default class UserMenuBookmarkItem extends UserMenuBaseItem {
|
|||
get topicId() {
|
||||
return this.bookmark.topic_id;
|
||||
}
|
||||
|
||||
get avatarTemplate() {
|
||||
return this.bookmark.user.avatar_template;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,4 +41,8 @@ export default class UserMenuMessageItem extends UserMenuBaseItem {
|
|||
get topicId() {
|
||||
return this.message.id;
|
||||
}
|
||||
|
||||
get avatarTemplate() {
|
||||
return this.message.last_poster_avatar_template;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,10 @@ export default class UserMenuNotificationItem extends UserMenuBaseItem {
|
|||
return this.notification.topic_id;
|
||||
}
|
||||
|
||||
get avatarTemplate() {
|
||||
return this.notification.acting_user_avatar_template;
|
||||
}
|
||||
|
||||
get #notificationName() {
|
||||
return this.site.notificationLookup[this.notification.notification_type];
|
||||
}
|
||||
|
|
|
@ -1101,3 +1101,36 @@ acceptance("User menu - Dismiss button", function (needs) {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("User menu - avatars", function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.settings({
|
||||
show_user_menu_avatars: true,
|
||||
});
|
||||
|
||||
test("It shows user avatars for various notifications on all notifications pane", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".d-header-icons .current-user");
|
||||
assert.ok(exists("li.notification.edited .icon-avatar"));
|
||||
assert.ok(exists("li.notification.replied .icon-avatar"));
|
||||
});
|
||||
|
||||
test("It shows user avatars for messages", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".d-header-icons .current-user");
|
||||
await click("#user-menu-button-messages");
|
||||
|
||||
assert.ok(exists("li.notification.private-message .icon-avatar"));
|
||||
assert.ok(exists("li.message .icon-avatar"));
|
||||
});
|
||||
|
||||
test("It shows user avatars for bookmark items and bookmark reminder notification items", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".d-header-icons .current-user");
|
||||
await click("#user-menu-button-bookmarks");
|
||||
|
||||
assert.ok(exists("li.notification.bookmark-reminder .icon-avatar"));
|
||||
assert.ok(exists("li.bookmark .icon-avatar"));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ export default {
|
|||
{
|
||||
id: 5340,
|
||||
notification_type: NOTIFICATION_TYPES.edited,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
post_number: 1,
|
||||
topic_id: 130,
|
||||
|
@ -23,6 +24,7 @@ export default {
|
|||
{
|
||||
id: 123,
|
||||
notification_type: NOTIFICATION_TYPES.replied,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
post_number: 1,
|
||||
topic_id: 1234,
|
||||
|
@ -33,12 +35,14 @@ export default {
|
|||
{
|
||||
id: 456,
|
||||
notification_type: NOTIFICATION_TYPES.liked_consolidated,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
data: { display_username: "aquaman", count: "5" },
|
||||
},
|
||||
{
|
||||
id: 789,
|
||||
notification_type: NOTIFICATION_TYPES.group_message_summary,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
post_number: null,
|
||||
topic_id: null,
|
||||
|
@ -53,6 +57,7 @@ export default {
|
|||
{
|
||||
id: 1234,
|
||||
notification_type: NOTIFICATION_TYPES.invitee_accepted,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
post_number: null,
|
||||
topic_id: null,
|
||||
|
@ -62,6 +67,7 @@ export default {
|
|||
{
|
||||
id: 5678,
|
||||
notification_type: NOTIFICATION_TYPES.membership_request_accepted,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
post_number: null,
|
||||
topic_id: null,
|
||||
|
|
|
@ -5,6 +5,7 @@ export default {
|
|||
id: 1713,
|
||||
user_id: 1,
|
||||
notification_type: 24,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
high_priority: true,
|
||||
created_at: "2022-08-05T17:27:24.873Z",
|
||||
|
@ -69,6 +70,7 @@ export default {
|
|||
id: 8315,
|
||||
user_id: 1,
|
||||
notification_type: 6,
|
||||
acting_user_avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png",
|
||||
read: false,
|
||||
high_priority: true,
|
||||
created_at: "2022-08-05T17:27:24.873Z",
|
||||
|
@ -139,5 +141,9 @@ export default {
|
|||
}
|
||||
],
|
||||
read_notifications: [],
|
||||
users: [{id: 13,
|
||||
username: "mixtape",
|
||||
avatar_template: "/letter_avatar_proxy/v4/letter/o/f05b48/{size}.png"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ module(
|
|||
}
|
||||
);
|
||||
|
||||
function getMessage(overrides = {}) {
|
||||
function getMessage(overrides = {}, siteSettings, site) {
|
||||
const message = deepMerge(
|
||||
cloneJSON(
|
||||
PrivateMessagesFixture["/topics/private-messages/eviltrout.json"]
|
||||
|
@ -409,7 +409,7 @@ function getMessage(overrides = {}) {
|
|||
overrides
|
||||
);
|
||||
|
||||
return new UserMenuMessageItem({ message });
|
||||
return new UserMenuMessageItem({ message, siteSettings, site });
|
||||
}
|
||||
|
||||
module(
|
||||
|
@ -422,7 +422,11 @@ module(
|
|||
test("item description is the fancy title of the message", async function (assert) {
|
||||
this.set(
|
||||
"item",
|
||||
getMessage({ fancy_title: "This is a <b>safe</b> title!" })
|
||||
getMessage(
|
||||
{ fancy_title: "This is a <b>safe</b> title!" },
|
||||
this.siteSettings,
|
||||
this.site
|
||||
)
|
||||
);
|
||||
await render(template);
|
||||
assert.strictEqual(
|
||||
|
@ -438,7 +442,7 @@ module(
|
|||
}
|
||||
);
|
||||
|
||||
function getBookmark(overrides = {}) {
|
||||
function getBookmark(overrides = {}, siteSettings, site) {
|
||||
const bookmark = deepMerge(
|
||||
{
|
||||
id: 6,
|
||||
|
@ -480,7 +484,7 @@ function getBookmark(overrides = {}) {
|
|||
overrides
|
||||
);
|
||||
|
||||
return new UserMenuBookmarkItem({ bookmark });
|
||||
return new UserMenuBookmarkItem({ bookmark, siteSettings, site });
|
||||
}
|
||||
|
||||
module(
|
||||
|
@ -491,7 +495,7 @@ module(
|
|||
const template = hbs`<UserMenu::MenuItem @item={{this.item}}/>`;
|
||||
|
||||
test("uses bookmarkable_url for the href", async function (assert) {
|
||||
this.set("item", getBookmark());
|
||||
this.set("item", getBookmark({}, this.siteSettings, this.site));
|
||||
await render(template);
|
||||
assert.ok(
|
||||
query("li.bookmark a").href.endsWith("/t/this-bookmarkable-url/227/1")
|
||||
|
@ -501,7 +505,11 @@ module(
|
|||
test("item label is the bookmarked post author", async function (assert) {
|
||||
this.set(
|
||||
"item",
|
||||
getBookmark({ user: { username: "bookmarkPostAuthor" } })
|
||||
getBookmark(
|
||||
{ user: { username: "bookmarkPostAuthor" } },
|
||||
this.siteSettings,
|
||||
this.site
|
||||
)
|
||||
);
|
||||
await render(template);
|
||||
assert.strictEqual(
|
||||
|
@ -511,7 +519,14 @@ module(
|
|||
});
|
||||
|
||||
test("item description is the bookmark title", async function (assert) {
|
||||
this.set("item", getBookmark({ title: "Custom bookmark title" }));
|
||||
this.set(
|
||||
"item",
|
||||
getBookmark(
|
||||
{ title: "Custom bookmark title" },
|
||||
this.siteSettings,
|
||||
this.site
|
||||
)
|
||||
);
|
||||
await render(template);
|
||||
assert.strictEqual(
|
||||
query("li.bookmark .item-description").textContent.trim(),
|
||||
|
|
|
@ -514,6 +514,7 @@
|
|||
padding: 0;
|
||||
align-self: flex-start;
|
||||
width: 100%;
|
||||
|
||||
.d-icon {
|
||||
padding-top: 0.2em;
|
||||
margin-right: 0.5em;
|
||||
|
@ -557,6 +558,42 @@
|
|||
}
|
||||
}
|
||||
|
||||
.user-menu.show-avatars {
|
||||
li {
|
||||
a {
|
||||
.icon-avatar {
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
margin-right: 0.5em;
|
||||
flex-shrink: 0;
|
||||
width: 2.25em;
|
||||
height: 2.25em;
|
||||
padding: 0.125em 0;
|
||||
|
||||
.avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.d-icon {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: -0.675em;
|
||||
bottom: -0.125em;
|
||||
background: var(--secondary);
|
||||
color: var(--primary-very-high);
|
||||
padding: 0.25em;
|
||||
border-radius: 100%;
|
||||
font-size: var(--font-down-1);
|
||||
}
|
||||
}
|
||||
& + div {
|
||||
padding: 0.25em 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hamburger-panel .menu-panel.slide-in {
|
||||
left: 0;
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ class NotificationsController < ApplicationController
|
|||
|
||||
notifications =
|
||||
Notification.filter_inaccessible_topic_notifications(current_user.guardian, notifications)
|
||||
notifications =
|
||||
Notification.populate_acting_user(notifications) if SiteSetting.show_user_menu_avatars
|
||||
|
||||
json = {
|
||||
notifications: serialize_data(notifications, NotificationSerializer),
|
||||
|
@ -86,6 +88,8 @@ class NotificationsController < ApplicationController
|
|||
notifications = notifications.offset(offset).limit(limit)
|
||||
notifications =
|
||||
Notification.filter_inaccessible_topic_notifications(current_user.guardian, notifications)
|
||||
notifications =
|
||||
Notification.populate_acting_user(notifications) if SiteSetting.show_user_menu_avatars
|
||||
render_json_dump(
|
||||
notifications: serialize_data(notifications, NotificationSerializer),
|
||||
total_rows_notifications: total_rows,
|
||||
|
|
|
@ -1897,6 +1897,9 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
if reminder_notifications.present?
|
||||
if SiteSetting.show_user_menu_avatars
|
||||
Notification.populate_acting_user(reminder_notifications)
|
||||
end
|
||||
serialized_notifications =
|
||||
ActiveModel::ArraySerializer.new(
|
||||
reminder_notifications,
|
||||
|
@ -1967,6 +1970,7 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
if unread_notifications.present?
|
||||
Notification.populate_acting_user(unread_notifications) if SiteSetting.show_user_menu_avatars
|
||||
serialized_unread_notifications =
|
||||
ActiveModel::ArraySerializer.new(
|
||||
unread_notifications,
|
||||
|
@ -1978,9 +1982,17 @@ class UsersController < ApplicationController
|
|||
if messages_list
|
||||
serialized_messages =
|
||||
serialize_data(messages_list, TopicListSerializer, scope: guardian, root: false)[:topics]
|
||||
serialized_users =
|
||||
if SiteSetting.show_user_menu_avatars
|
||||
users = messages_list.topics.map { |t| t.posters.last.user }.flatten.compact.uniq(&:id)
|
||||
serialize_data(users, BasicUserSerializer, scope: guardian, root: false)
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
if read_notifications.present?
|
||||
Notification.populate_acting_user(read_notifications) if SiteSetting.show_user_menu_avatars
|
||||
serialized_read_notifications =
|
||||
ActiveModel::ArraySerializer.new(
|
||||
read_notifications,
|
||||
|
@ -1993,6 +2005,7 @@ class UsersController < ApplicationController
|
|||
unread_notifications: serialized_unread_notifications || [],
|
||||
read_notifications: serialized_read_notifications || [],
|
||||
topics: serialized_messages || [],
|
||||
users: serialized_users || [],
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Notification < ActiveRecord::Base
|
||||
attr_accessor :acting_user
|
||||
attr_accessor :acting_username
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :topic
|
||||
|
||||
|
@ -349,6 +352,25 @@ class Notification < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.populate_acting_user(notifications)
|
||||
usernames =
|
||||
notifications.map do |notification|
|
||||
notification.acting_username =
|
||||
(
|
||||
notification.data_hash[:username] || notification.data_hash[:display_username] ||
|
||||
notification.data_hash[:mentioned_by_username] ||
|
||||
notification.data_hash[:invited_by_username]
|
||||
)&.downcase
|
||||
end
|
||||
|
||||
users = User.where(username_lower: usernames.uniq).index_by(&:username_lower)
|
||||
notifications.each do |notification|
|
||||
notification.acting_user = users[notification.acting_username]
|
||||
end
|
||||
|
||||
notifications
|
||||
end
|
||||
|
||||
def unread_high_priority?
|
||||
self.high_priority? && !read
|
||||
end
|
||||
|
|
|
@ -13,7 +13,8 @@ class NotificationSerializer < ApplicationSerializer
|
|||
:fancy_title,
|
||||
:slug,
|
||||
:data,
|
||||
:is_warning
|
||||
:is_warning,
|
||||
:acting_user_avatar_template
|
||||
|
||||
def slug
|
||||
Slug.for(object.topic.title) if object.topic.present?
|
||||
|
@ -46,4 +47,12 @@ class NotificationSerializer < ApplicationSerializer
|
|||
def include_external_id?
|
||||
SiteSetting.enable_discourse_connect
|
||||
end
|
||||
|
||||
def acting_user_avatar_template
|
||||
object.acting_user.avatar_template_url
|
||||
end
|
||||
|
||||
def include_acting_user_avatar_template?
|
||||
object.acting_user.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,6 +46,7 @@ class SiteSerializer < ApplicationSerializer
|
|||
:denied_emojis,
|
||||
:tos_url,
|
||||
:privacy_policy_url,
|
||||
:system_user_avatar_template,
|
||||
)
|
||||
|
||||
has_many :archetypes, embed: :objects, serializer: ArchetypeSerializer
|
||||
|
@ -332,6 +333,14 @@ class SiteSerializer < ApplicationSerializer
|
|||
privacy_policy_url.present?
|
||||
end
|
||||
|
||||
def system_user_avatar_template
|
||||
Discourse.system_user.avatar_template
|
||||
end
|
||||
|
||||
def include_system_user_avatar_template?
|
||||
SiteSetting.show_user_menu_avatars
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ordered_flags(flags)
|
||||
|
|
|
@ -2484,6 +2484,7 @@ en:
|
|||
experimental_form_templates: "EXPERIMENTAL: Enable the form templates feature. <b>After enabled,</b> manage the templates at <a href='%{base_path}/admin/customize/form-templates'>Customize / Templates</a>."
|
||||
|
||||
page_loading_indicator: "Configure the loading indicator which appears during page navigations within Discourse. 'Spinner' is a full page indicator. 'Slider' shows a narrow bar at the top of the screen."
|
||||
show_user_menu_avatars: "Show user avatars in the user menu"
|
||||
|
||||
errors:
|
||||
invalid_css_color: "Invalid color. Enter a color name or hex value."
|
||||
|
|
|
@ -395,7 +395,9 @@ basic:
|
|||
choices:
|
||||
- spinner
|
||||
- slider
|
||||
|
||||
show_user_menu_avatars:
|
||||
client: true
|
||||
default: false
|
||||
login:
|
||||
invite_only:
|
||||
refresh: true
|
||||
|
|
|
@ -806,4 +806,34 @@ RSpec.describe Notification do
|
|||
expect(notification.shelved_notification).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe ".populate_acting_user" do
|
||||
fab!(:user1) { Fabricate(:user) }
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
fab!(:user3) { Fabricate(:user) }
|
||||
fab!(:user4) { Fabricate(:user) }
|
||||
fab!(:notification1) do
|
||||
Fabricate(:notification, user: user, data: { username: user1.username }.to_json)
|
||||
end
|
||||
fab!(:notification2) do
|
||||
Fabricate(:notification, user: user, data: { display_username: user2.username }.to_json)
|
||||
end
|
||||
fab!(:notification3) do
|
||||
Fabricate(:notification, user: user, data: { mentioned_by_username: user3.username }.to_json)
|
||||
end
|
||||
fab!(:notification4) do
|
||||
Fabricate(:notification, user: user, data: { invited_by_username: user4.username }.to_json)
|
||||
end
|
||||
|
||||
it "Sets the acting_user correctly for each notification" do
|
||||
Notification.populate_acting_user(
|
||||
[notification1, notification2, notification3, notification4],
|
||||
)
|
||||
|
||||
expect(notification1.acting_user).to eq(user1)
|
||||
expect(notification2.acting_user).to eq(user2)
|
||||
expect(notification3.acting_user).to eq(user3)
|
||||
expect(notification4.acting_user).to eq(user4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,7 +32,10 @@ RSpec.describe NotificationsController do
|
|||
context "when logged in" do
|
||||
context "as normal user" do
|
||||
fab!(:user) { sign_in(Fabricate(:user)) }
|
||||
fab!(:notification) { Fabricate(:notification, user: user) }
|
||||
fab!(:acting_user) { Fabricate(:user) }
|
||||
fab!(:notification) do
|
||||
Fabricate(:notification, user: user, data: { username: acting_user.username }.to_json)
|
||||
end
|
||||
|
||||
describe "#index" do
|
||||
it "should succeed for recent" do
|
||||
|
@ -424,6 +427,20 @@ RSpec.describe NotificationsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with `show_user_menu_avatars` setting enabled" do
|
||||
before { SiteSetting.show_user_menu_avatars = true }
|
||||
|
||||
it "serializes acting_user_avatar_template into notifications" do
|
||||
get "/notifications.json"
|
||||
|
||||
notifications = response.parsed_body["notifications"]
|
||||
expect(notifications).not_to be_empty
|
||||
notifications.each do |notification|
|
||||
expect(notification["acting_user_avatar_template"]).to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "should succeed" do
|
||||
|
|
|
@ -7051,6 +7051,18 @@ RSpec.describe UsersController do
|
|||
expect(notifications.size).to eq(1)
|
||||
expect(notifications.first["data"]["bookmark_id"]).to eq(bookmark_with_reminder.id)
|
||||
end
|
||||
|
||||
context "with `show_user_menu_avatars` setting enabled" do
|
||||
before { SiteSetting.show_user_menu_avatars = true }
|
||||
|
||||
it "serializes acting_user_avatar into notifications" do
|
||||
get "/u/#{user.username}/user-menu-bookmarks"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
first_notification = response.parsed_body["notifications"].first
|
||||
expect(first_notification["acting_user_avatar_template"]).to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue