FEATURE: Let users select flair (#13587)

User flair was given by user's primary group. This PR separates the
two, adds a new field to the user model for flair group ID and users
can select their flair from user preferences now.
This commit is contained in:
Bianca Nenciu 2021-07-08 10:46:21 +03:00 committed by GitHub
parent c6f2459cc4
commit 87c1e98571
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 625 additions and 326 deletions

View File

@ -4,17 +4,17 @@ import { observes } from "discourse-common/utils/decorators";
export default MountWidget.extend({
widget: "avatar-flair",
@observes("flairURL", "flairBgColor", "flairColor")
@observes("flairName", "flairUrl", "flairBgColor", "flairColor")
_rerender() {
this.queueRerender();
},
buildArgs() {
return {
primary_group_flair_url: this.flairURL,
primary_group_flair_bg_color: this.flairBgColor,
primary_group_flair_color: this.flairColor,
primary_group_name: this.groupName,
flair_name: this.flairName,
flair_url: this.flairUrl,
flair_bg_color: this.flairBgColor,
flair_color: this.flairColor,
};
},
});

View File

@ -67,8 +67,8 @@ export default Component.extend({
},
@discourseComputed("model.flair_url")
flairImageUrl(flairURL) {
return flairURL && flairURL.match(/\//) ? flairURL : null;
flairImageUrl(flairUrl) {
return flairUrl && flairUrl.includes("/") ? flairUrl : null;
},
@discourseComputed(
@ -78,7 +78,7 @@ export default Component.extend({
"model.flairHexColor"
)
flairPreviewStyle(
flairURL,
flairUrl,
flairPreviewImage,
flairBackgroundHexColor,
flairHexColor
@ -86,7 +86,7 @@ export default Component.extend({
let style = "";
if (flairPreviewImage) {
style += `background-image: url(${escapeExpression(flairURL)});`;
style += `background-image: url(${escapeExpression(flairUrl)});`;
}
if (flairBackgroundHexColor) {

View File

@ -10,28 +10,23 @@ export default Component.extend({
if (!user) {
return;
}
return this.primaryGroupFlair(user) || this.automaticGroupFlair(user);
},
primaryGroupFlair(user) {
if (user.primary_group_flair_url || user.primary_group_flair_bg_color) {
if (user.flair_url || user.flair_bg_color) {
return {
flairURL: user.primary_group_flair_url,
flairBgColor: user.primary_group_flair_bg_color,
flairColor: user.primary_group_flair_color,
groupName: user.primary_group_name,
flairName: user.flair_name,
flairUrl: user.flair_url,
flairBgColor: user.flair_bg_color,
flairColor: user.flair_color,
};
}
},
automaticGroupFlair(user) {
const autoFlairAttrs = autoGroupFlairForUser(this.site, user);
if (autoFlairAttrs) {
return {
flairURL: autoFlairAttrs.primary_group_flair_url,
flairBgColor: autoFlairAttrs.primary_group_flair_bg_color,
flairColor: autoFlairAttrs.primary_group_flair_color,
groupName: autoFlairAttrs.primary_group_name,
flairName: autoFlairAttrs.flair_name,
flairUrl: autoFlairAttrs.flair_url,
flairBgColor: autoFlairAttrs.flair_bg_color,
flairColor: autoFlairAttrs.flair_color,
};
}
},

View File

@ -101,21 +101,6 @@ export default Controller.extend({
return (fullName || displayName).capitalize();
},
@discourseComputed(
"model.name",
"model.flair_url",
"model.flair_bg_color",
"model.flair_color"
)
avatarFlairAttributes(groupName, flairURL, flairBgColor, flairColor) {
return {
primary_group_flair_url: flairURL,
primary_group_flair_bg_color: flairBgColor,
primary_group_flair_color: flairColor,
primary_group_name: groupName,
};
},
@discourseComputed("model.messageable")
displayGroupMessageButton(messageable) {
return this.currentUser && messageable;

View File

@ -15,7 +15,12 @@ export default Controller.extend(CanCheckEmails, {
init() {
this._super(...arguments);
this.saveAttrNames = ["name", "title", "primary_group_id"];
this.saveAttrNames = [
"name",
"title",
"primary_group_id",
"flair_group_id",
];
this.set("revoking", {});
},
@ -45,6 +50,7 @@ export default Controller.extend(CanCheckEmails, {
},
canSelectTitle: gt("model.availableTitles.length", 0),
canSelectFlair: gt("model.availableFlairs.length", 0),
@discourseComputed("model.filteredGroups")
canSelectPrimaryGroup(primaryGroupOptions) {
@ -132,6 +138,7 @@ export default Controller.extend(CanCheckEmails, {
name: this.newNameInput,
title: this.newTitleInput,
primary_group_id: this.newPrimaryGroupInput,
flair_group_id: this.newFlairGroupId,
});
return this.model

View File

@ -56,10 +56,10 @@ function initializeAutoGroupFlair(site) {
if (group && group.flair_url) {
_noAutoFlair = false;
_autoGroupFlair[groupName] = {
primary_group_flair_url: group.flair_url,
primary_group_flair_bg_color: group.flair_bg_color,
primary_group_flair_color: group.flair_color,
primary_group_name: group.name.replace(/_/g, " "),
flair_name: group.name.replace(/_/g, " "),
flair_url: group.flair_url,
flair_bg_color: group.flair_bg_color,
flair_color: group.flair_color,
};
}
});

View File

@ -21,9 +21,10 @@ export function transformBasicPost(post) {
deletedByAvatarTemplate: null,
deletedByUsername: null,
primary_group_name: post.primary_group_name,
primary_group_flair_url: post.primary_group_flair_url,
primary_group_flair_bg_color: post.primary_group_flair_bg_color,
primary_group_flair_color: post.primary_group_flair_color,
flair_name: post.flair_name,
flair_url: post.flair_url,
flair_bg_color: post.flair_bg_color,
flair_color: post.flair_color,
wiki: post.wiki,
lastWikiEdit: post.last_wiki_edit,
firstPost: post.post_number === 1,

View File

@ -59,6 +59,7 @@ let userFields = [
"watching_first_post_tags",
"date_of_birth",
"primary_group_id",
"flair_group_id",
"user_notification_schedule",
];
@ -863,7 +864,7 @@ const User = RestModel.extend({
@discourseComputed("groups.@each.title", "badges.[]")
availableTitles() {
let titles = [];
const titles = [];
(this.groups || []).forEach((group) => {
if (get(group, "title")) {
@ -888,6 +889,27 @@ const User = RestModel.extend({
});
},
@discourseComputed("groups.[]")
availableFlairs() {
const flairs = [];
if (this.groups) {
this.groups.forEach((group) => {
if (group.flair_url) {
flairs.push({
id: group.id,
name: group.name,
url: group.flair_url,
bgColor: group.flair_bg_color,
color: group.flair_color,
});
}
});
}
return flairs;
},
@discourseComputed("user_option.text_size_seq", "user_option.text_size")
currentTextSize(serverSeq, serverSize) {
if (cookie("text_size")) {

View File

@ -29,6 +29,7 @@ export default RestrictedUserRoute.extend({
newNameInput: user.get("name"),
newTitleInput: user.get("title"),
newPrimaryGroupInput: user.get("primary_group_id"),
newFlairGroupId: user.get("flair_group_id"),
});
},

View File

@ -4,10 +4,10 @@
<div class="group-card-avatar">
<a href={{groupPath}} {{action "showGroup" group}} class="card-huge-avatar">
{{avatar-flair
flairURL=group.flair_url
flairName=group.name
flairUrl=group.flair_url
flairBgColor=group.flair_bg_color
flairColor=group.flair_color
groupName=group.name
}}
</a>
</div>

View File

@ -1,7 +1,8 @@
{{#if flair}}
{{avatar-flair
flairURL=flair.flairURL
flairName=flair.flairName
flairUrl=flair.flairUrl
flairBgColor=flair.flairBgColor
flairColor=flair.flairColor
groupName=flair.groupName}}
}}
{{/if}}

View File

@ -12,10 +12,10 @@
{{#if model.flair_url}}
<div class="group-avatar-flair">
{{avatar-flair
flairURL=model.flair_url
flairName=model.name
flairUrl=model.flair_url
flairBgColor=model.flair_bg_color
flairColor=model.flair_color
groupName=model.name
}}
</div>
{{/if}}

View File

@ -44,10 +44,11 @@
{{#if group.flair_url}}
<span class="group-avatar-flair">
{{avatar-flair
flairURL=group.flair_url
flairBgColor=group.flair_bg_color
flairColor=group.flair_color
groupName=group.name}}
flairName=group.name
flairUrl=group.flair_url
flairBgColor=group.flair_bg_color
flairColor=group.flair_color
}}
</span>
{{/if}}

View File

@ -158,6 +158,26 @@
onChange=(action (mut newTitleInput))
}}
</div>
<div class="instructions">
{{i18n "user.title.instructions"}}
</div>
</div>
{{/if}}
{{#if canSelectFlair}}
<div class="control-group pref-flair">
<label class="control-label">{{i18n "user.flair.title"}}</label>
<div class="controls">
{{flair-chooser
value=newFlairGroupId
content=model.availableFlairs
none="user.flair.none"
onChange=(action (mut newFlairGroupId))
}}
</div>
<div class="instructions">
{{i18n "user.flair.instructions"}}
</div>
</div>
{{/if}}

View File

@ -6,19 +6,16 @@ createWidget("avatar-flair", {
tagName: "div.avatar-flair",
isIcon(attrs) {
return (
attrs.primary_group_flair_url &&
!attrs.primary_group_flair_url.includes("/")
);
return attrs.flair_url && !attrs.flair_url.includes("/");
},
title(attrs) {
return attrs.primary_group_name;
return attrs.flair_name;
},
buildClasses(attrs) {
let defaultClass = `avatar-flair-${attrs.primary_group_name} ${
attrs.primary_group_flair_bg_color ? "rounded" : ""
let defaultClass = `avatar-flair-${attrs.flair_name} ${
attrs.flair_bg_color ? "rounded" : ""
}`;
if (!this.isIcon(attrs)) {
@ -32,26 +29,21 @@ createWidget("avatar-flair", {
let style = "";
if (!this.isIcon(attrs)) {
style +=
"background-image: url(" +
escapeExpression(attrs.primary_group_flair_url) +
"); ";
"background-image: url(" + escapeExpression(attrs.flair_url) + "); ";
}
if (attrs.primary_group_flair_bg_color) {
if (attrs.flair_bg_color) {
style +=
"background-color: #" +
escapeExpression(attrs.primary_group_flair_bg_color) +
"; ";
"background-color: #" + escapeExpression(attrs.flair_bg_color) + "; ";
}
if (attrs.primary_group_flair_color) {
style +=
"color: #" + escapeExpression(attrs.primary_group_flair_color) + "; ";
if (attrs.flair_color) {
style += "color: #" + escapeExpression(attrs.flair_color) + "; ";
}
return { style: style };
return { style };
},
html(attrs) {
if (this.isIcon(attrs)) {
const icon = convertIconClass(attrs.primary_group_flair_url);
const icon = convertIconClass(attrs.flair_url);
return [iconNode(icon)];
} else {
return [];

View File

@ -187,7 +187,7 @@ createWidget("post-avatar", {
const result = [body];
if (attrs.primary_group_flair_url || attrs.primary_group_flair_bg_color) {
if (attrs.flair_url || attrs.flair_bg_color) {
result.push(this.attach("avatar-flair", attrs));
} else {
const autoFlairAttrs = autoGroupFlairForUser(this.site, attrs);

View File

@ -102,10 +102,10 @@ createSearchResult({
let avatarFlair;
if (group.flairUrl) {
avatarFlair = this.attach("avatar-flair", {
primary_group_flair_url: group.flairUrl,
primary_group_flair_bg_color: group.flairBgColor,
primary_group_flair_color: group.flairColor,
primary_group_name: name,
flair_name: name,
flair_url: group.flairUrl,
flair_bg_color: group.flairBgColor,
flair_color: group.flairColor,
});
} else {
avatarFlair = iconNode("users");

View File

@ -79,7 +79,7 @@ createWidget("topic-participant", {
linkContents.push(h("span.post-count", attrs.post_count.toString()));
}
if (attrs.primary_group_flair_url || attrs.primary_group_flair_bg_color) {
if (attrs.flair_url || attrs.flair_bg_color) {
linkContents.push(this.attach("avatar-flair", attrs));
} else {
const autoFlairAttrs = autoGroupFlairForUser(this.site, attrs);

View File

@ -571,9 +571,10 @@ export default {
topic_slug: "14-the-title-must-be-longer-i-guess",
display_username: "",
primary_group_name: "Team",
primary_group_flair_url: null,
primary_group_flair_bg_color: "",
primary_group_flair_color: "",
flair_name: null,
flair_url: null,
flair_bg_color: "",
flair_color: "",
version: 1,
can_edit: false,
can_delete: false,
@ -711,9 +712,10 @@ export default {
avatar_template: "/user_avatar/localhost/markvanlan/{size}/11_2.png",
post_count: 1,
primary_group_name: "Team",
primary_group_flair_url: null,
primary_group_flair_color: "",
primary_group_flair_bg_color: ""
flair_name: null,
flair_url: null,
flair_color: "",
flair_bg_color: ""
}
],
created_by: {

View File

@ -21,9 +21,10 @@ export default {
topic_slug: "test-pm",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,

View File

@ -27,9 +27,10 @@ export default {
topic_slug: "lorem-ipsum-dolor-sit-amet",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -167,9 +168,10 @@ export default {
avatar_template: "/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png",
post_count: 1,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_name: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
],
allowed_users: [
@ -207,6 +209,7 @@ export default {
grant_trust_level: null,
incoming_email: null,
has_messages: true,
flair_name: null,
flair_url: null,
flair_bg_color: "",
flair_color: "",
@ -4217,9 +4220,10 @@ export default {
topic_slug: "pm-for-testing",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -4269,9 +4273,10 @@ export default {
topic_slug: "pm-for-testing",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: true,
@ -4363,6 +4368,7 @@ export default {
grant_trust_level: null,
incoming_email: null,
has_messages: false,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
@ -4384,9 +4390,10 @@ export default {
avatar_template: "/images/avatar.png",
post_count: 2,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_name: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
],
suggested_topics: [
@ -5064,9 +5071,10 @@ export default {
topic_slug: "test-pm",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -5126,9 +5134,10 @@ export default {
topic_slug: "test-pm",
display_username: "Tim Lange",
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: true,
@ -5237,9 +5246,10 @@ export default {
avatar_template: "/images/avatar.png",
post_count: 2,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_name: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
{
id: 2,
@ -5248,9 +5258,10 @@ export default {
avatar_template: "/images/avatar.png",
post_count: 1,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_name: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
],
notification_level: 3,
@ -5317,9 +5328,10 @@ export default {
topic_slug: "a-topic-with-group-category-moderators",
display_username: "",
primary_group_name: "group_moderators",
primary_group_flair_url: "cheese",
primary_group_flair_bg_color: "ff0",
primary_group_flair_color: "",
flair_name: "group_moderators",
flair_url: "cheese",
flair_bg_color: "ff0",
flair_color: "",
version: 1,
can_edit: true,
can_delete: false,
@ -5385,9 +5397,10 @@ export default {
topic_slug: "a-topic-with-group-category-moderators",
display_username: "",
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: false,
can_delete: false,
@ -5459,9 +5472,9 @@ export default {
topic_slug: "a-topic-with-group-category-moderators",
display_username: "",
primary_group_name: "group_moderators",
primary_group_flair_url: "cheese",
primary_group_flair_bg_color: "ff0",
primary_group_flair_color: "",
flair_url: "cheese",
flair_bg_color: "ff0",
flair_color: "",
version: 1,
can_edit: true,
can_delete: true,
@ -5596,9 +5609,10 @@ export default {
avatar_template: "/images/avatar.png",
post_count: 2,
primary_group_name: "group_moderators",
primary_group_flair_url: "cheese",
primary_group_flair_color: "",
primary_group_flair_bg_color: "ff0",
flar_name: "group_moderators",
flair_url: "cheese",
flair_color: "",
flair_bg_color: "ff0",
},
{
id: 2,
@ -5607,9 +5621,10 @@ export default {
avatar_template: "/images/avatar.png",
post_count: 1,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_name: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
],
created_by: {

View File

@ -2508,9 +2508,10 @@ export default {
time_read: 0,
recent_time_read: 0,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
staged: false,
second_factor_enabled: false,
post_count: 0,
@ -2755,9 +2756,10 @@ export default {
time_read: 0,
recent_time_read: 0,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
staged: false,
featured_user_badge_ids: [17],
},
@ -2870,9 +2872,10 @@ export default {
time_read: 0,
recent_time_read: 0,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_name: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
second_factor_enabled: false,
second_factor_backup_enabled: false,
associated_accounts: [],

View File

@ -175,9 +175,10 @@ discourseModule(
admin: false,
moderator: false,
trust_level: 3,
primary_group_flair_url: "fa-times",
primary_group_flair_bg_color: "123456",
primary_group_flair_color: "B0B0B0",
flair_name: "Band Geeks",
flair_url: "fa-times",
flair_bg_color: "123456",
flair_color: "B0B0B0",
primary_group_name: "Band Geeks",
});
setupSiteGroups(this);

View File

@ -17,9 +17,9 @@ discourseModule(
template: hbs`{{mount-widget widget="avatar-flair" args=args}}`,
beforeEach() {
this.set("args", {
primary_group_flair_url: "fa-bars",
primary_group_flair_bg_color: "CC0000",
primary_group_flair_color: "FFFFFF",
flair_url: "fa-bars",
flair_bg_color: "CC0000",
flair_color: "FFFFFF",
});
},
test(assert) {
@ -37,7 +37,7 @@ discourseModule(
template: hbs`{{mount-widget widget="avatar-flair" args=args}}`,
beforeEach() {
this.set("args", {
primary_group_flair_url: "/images/avatar.png",
flair_url: "/images/avatar.png",
});
},
test(assert) {

View File

@ -39,8 +39,9 @@ discourseModule(
avatar_template: "/images/avatar.png",
post_count: 5,
primary_group_name: "devs",
primary_group_flair_url: "/images/d-logo-sketch-small.png",
primary_group_flair_bg_color: "222",
flair_name: "devs",
flair_url: "/images/d-logo-sketch-small.png",
flair_bg_color: "222",
});
},

View File

@ -0,0 +1,14 @@
import ComboBoxComponent from "select-kit/components/combo-box";
export default ComboBoxComponent.extend({
pluginApiIdentifiers: ["flair-chooser"],
classNames: ["flair-chooser"],
selectKitOptions: {
selectedNameComponent: "selected-flair",
},
modifyComponentForRow() {
return "flair-row";
},
});

View File

@ -0,0 +1,7 @@
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
import layout from "select-kit/templates/components/flair-row";
export default SelectKitRowComponent.extend({
layout,
classNames: ["flair-row"],
});

View File

@ -0,0 +1,7 @@
import SelectedNameComponent from "select-kit/components/selected-name";
import layout from "select-kit/templates/components/flair-row";
export default SelectedNameComponent.extend({
layout,
tagName: "",
});

View File

@ -0,0 +1,10 @@
{{#if item.url}}
{{avatar-flair
flairName=item.name
flairUrl=item.url
flairBgColor=item.bgColor
flairColor=item.color
}}
{{/if}}
<span>{{label}}</span>

View File

@ -8,6 +8,7 @@
@import "composer-actions";
@import "dropdown-select-box";
@import "email-group-user-chooser";
@import "flair-row";
@import "future-date-input-selector";
@import "icon-picker";
@import "list-setting";

View File

@ -0,0 +1,29 @@
.flair-chooser .select-kit-header,
.select-kit .flair-row {
.avatar-flair {
align-items: center;
background-position: center;
background-repeat: no-repeat;
background-size: 30px 30px;
display: flex;
justify-content: center;
margin-right: 5px;
height: 30px;
width: 30px;
&.rounded {
background-size: (30px / 1.4) (30px / 1.4);
border-radius: 50%;
}
.d-icon {
display: block;
height: (30px / 1.8);
width: (30px / 1.8);
}
}
}
.select-kit.flair-chooser .select-kit-header {
padding: 2px 4px;
}

View File

@ -61,7 +61,7 @@ class PostsController < ApplicationController
.where('posts.id <= ?', last_post_id)
.where('posts.id > ?', last_post_id - 50)
.includes(topic: :category)
.includes(user: :primary_group)
.includes(user: [:primary_group, :flair_group])
.includes(:reply_to_user)
.limit(50)
rss_description = I18n.t("rss_description.private_posts")
@ -71,7 +71,7 @@ class PostsController < ApplicationController
.where('posts.id <= ?', last_post_id)
.where('posts.id > ?', last_post_id - 50)
.includes(topic: :category)
.includes(user: :primary_group)
.includes(user: [:primary_group, :flair_group])
.includes(:reply_to_user)
.limit(50)
rss_description = I18n.t("rss_description.posts")

View File

@ -10,7 +10,7 @@ class UserBadgesController < ApplicationController
badge = fetch_badge_from_params
user_badges = badge.user_badges.order('granted_at DESC, id DESC').limit(MAX_BADGES)
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type, post: :topic, user: :primary_group)
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type, post: :topic, user: [:primary_group, :flair_group])
grant_count = nil

View File

@ -112,6 +112,7 @@ class UsersController < ApplicationController
:user_profile,
:card_background_upload,
:primary_group,
:flair_group,
:primary_email
)
@ -1632,6 +1633,7 @@ class UsersController < ApplicationController
:profile_background_upload_url,
:card_background_upload_url,
:primary_group_id,
:flair_group_id,
:featured_topic_id
]

View File

@ -33,6 +33,7 @@ class TopicPostersSummary
topic_poster.user = user
topic_poster.description = descriptions_for(user)
topic_poster.primary_group = user_lookup.primary_groups[user.id]
topic_poster.flair_group = user_lookup.flair_groups[user.id]
if topic.last_post_user_id == user.id
topic_poster.extras = +'latest'
topic_poster.extras << ' single' if user_ids.uniq.size == 1

View File

@ -95,6 +95,7 @@ class User < ActiveRecord::Base
has_one :card_background_upload, through: :user_profile
belongs_to :approved_by, class_name: 'User'
belongs_to :primary_group, class_name: 'Group'
belongs_to :flair_group, class_name: 'Group'
has_many :muted_users, through: :muted_user_records
has_many :ignored_users, through: :ignored_user_records
@ -133,7 +134,7 @@ class User < ActiveRecord::Base
before_save :update_usernames
before_save :ensure_password_is_hashed
before_save :match_title_to_primary_group_changes
before_save :match_primary_group_changes
before_save :check_if_title_is_badged_granted
after_save :expire_tokens_if_password_changed
@ -1619,12 +1620,16 @@ class User < ActiveRecord::Base
end
end
def match_title_to_primary_group_changes
def match_primary_group_changes
return unless primary_group_id_changed?
if title == Group.where(id: primary_group_id_was).pluck_first(:title)
self.title = primary_group&.title
end
if flair_group_id == primary_group_id_was
self.flair_group_id = primary_group&.id
end
end
private
@ -1745,6 +1750,7 @@ end
# group_locked_trust_level :integer
# manual_locked_trust_level :integer
# secure_identifier :string
# flair_group_id :integer
#
# Indexes
#

View File

@ -198,9 +198,14 @@ protected
if lookup_hash.present?
primary_group = lookup.primary_groups[user_id]
flair_group = lookup.flair_groups[user_id]
UserWithCount.new(
lookup_hash.attributes.merge(count: user_hash[user_id], primary_group: primary_group)
lookup_hash.attributes.merge(
count: user_hash[user_id],
primary_group: primary_group,
flair_group: flair_group
)
)
end
end.compact.sort_by { |u| -u[:count] }

View File

@ -4,9 +4,10 @@ module UserPrimaryGroupMixin
def self.included(klass)
klass.attributes :primary_group_name,
:primary_group_flair_url,
:primary_group_flair_bg_color,
:primary_group_flair_color,
:flair_name,
:flair_url,
:flair_bg_color,
:flair_color,
:admin,
:moderator,
:trust_level
@ -20,28 +21,36 @@ module UserPrimaryGroupMixin
object&.primary_group.present?
end
def primary_group_flair_url
object&.primary_group&.flair_url
def flair_name
object&.flair_group&.name
end
def include_primary_group_flair_url?
object&.primary_group&.flair_url.present?
def include_flair_group_name?
object&.flair_group.present?
end
def primary_group_flair_bg_color
object&.primary_group&.flair_bg_color
def flair_url
object&.flair_group&.flair_url
end
def include_primary_group_flair_bg_color?
object&.primary_group&.flair_bg_color.present?
def include_flair_url?
object&.flair_group&.flair_url.present?
end
def primary_group_flair_color
object&.primary_group&.flair_color
def flair_bg_color
object&.flair_group&.flair_bg_color
end
def include_primary_group_flair_color?
object&.primary_group&.flair_color.present?
def include_flair_bg_color?
object&.flair_group&.flair_bg_color.present?
end
def flair_color
object&.flair_group&.flair_color
end
def include_flair_color?
object&.flair_group&.flair_color.present?
end
def include_admin?

View File

@ -48,6 +48,7 @@ class CurrentUserSerializer < BasicUserSerializer
:previous_visit_at,
:seen_notification_id,
:primary_group_id,
:flair_group_id,
:can_create_topic,
:can_create_group,
:link_posting_access,

View File

@ -0,0 +1,5 @@
# frozen_string_literal: true
class FlairGroupSerializer < ApplicationSerializer
attributes :id, :name, :flair_url, :flair_bg_color, :flair_color
end

View File

@ -36,9 +36,10 @@ class PostSerializer < BasicPostSerializer
:category_id,
:display_username,
:primary_group_name,
:primary_group_flair_url,
:primary_group_flair_bg_color,
:primary_group_flair_color,
:flair_name,
:flair_url,
:flair_bg_color,
:flair_color,
:version,
:can_edit,
:can_delete,
@ -188,16 +189,20 @@ class PostSerializer < BasicPostSerializer
end
end
def primary_group_flair_url
object.user&.primary_group&.flair_url
def flair_name
object.user&.flair_group&.name
end
def primary_group_flair_bg_color
object.user&.primary_group&.flair_bg_color
def flair_url
object.user&.flair_group&.flair_url
end
def primary_group_flair_color
object.user&.primary_group&.flair_color
def flair_bg_color
object.user&.flair_group&.flair_bg_color
end
def flair_color
object.user&.flair_group&.flair_color
end
def link_counts

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true
class PrimaryGroupSerializer < ApplicationSerializer
attributes :id, :name, :flair_url, :flair_bg_color, :flair_color
attributes :id, :name
end

View File

@ -3,7 +3,7 @@
class TopicPostCountSerializer < BasicUserSerializer
attributes :post_count, :primary_group_name,
:primary_group_flair_url, :primary_group_flair_color, :primary_group_flair_bg_color,
:flair_name, :flair_url, :flair_color, :flair_bg_color,
:admin, :moderator, :trust_level,
def id
@ -23,16 +23,20 @@ class TopicPostCountSerializer < BasicUserSerializer
object[:user]&.primary_group&.name
end
def primary_group_flair_url
object[:user]&.primary_group&.flair_url
def flair_name
object[:user]&.flair_group&.name
end
def primary_group_flair_bg_color
object[:user]&.primary_group&.flair_bg_color
def flair_url
object[:user]&.flair_group&.flair_url
end
def primary_group_flair_color
object[:user]&.primary_group&.flair_color
def flair_bg_color
object[:user]&.flair_group&.flair_bg_color
end
def flair_color
object[:user]&.flair_group&.flair_color
end
def include_admin?

View File

@ -5,4 +5,5 @@ class TopicPosterSerializer < ApplicationSerializer
has_one :user, serializer: PosterSerializer
has_one :primary_group, serializer: PrimaryGroupSerializer
has_one :flair_group, serializer: FlairGroupSerializer
end

View File

@ -59,9 +59,10 @@ class UserCardSerializer < BasicUserSerializer
:recent_time_read,
:primary_group_id,
:primary_group_name,
:primary_group_flair_url,
:primary_group_flair_bg_color,
:primary_group_flair_color,
:flair_name,
:flair_url,
:flair_bg_color,
:flair_color,
:featured_topic,
:timezone
@ -181,19 +182,23 @@ class UserCardSerializer < BasicUserSerializer
end
def primary_group_name
object.primary_group.try(:name)
object.primary_group&.name
end
def primary_group_flair_url
object.try(:primary_group).try(:flair_url)
def flair_name
object.flair_group&.name
end
def primary_group_flair_bg_color
object.try(:primary_group).try(:flair_bg_color)
def flair_url
object.flair_group&.flair_url
end
def primary_group_flair_color
object.try(:primary_group).try(:flair_color)
def flair_bg_color
object.flair_group&.flair_bg_color
end
def flair_color
object.flair_group&.flair_color
end
def featured_topic

View File

@ -29,9 +29,10 @@ class UserSummarySerializer < ApplicationSerializer
:admin,
:moderator,
:trust_level,
:primary_group_flair_url,
:primary_group_flair_bg_color,
:primary_group_flair_color,
:flair_name,
:flair_url,
:flair_bg_color,
:flair_color,
:primary_group_name
def include_name?
@ -42,16 +43,20 @@ class UserSummarySerializer < ApplicationSerializer
User.avatar_template(object[:username], object[:uploaded_avatar_id])
end
def primary_group_flair_url
object.primary_group&.flair_url
def flair_name
object.flair_group&.name
end
def primary_group_flair_bg_color
object.primary_group&.flair_bg_color
def flair_url
object.flair_group&.flair_url
end
def primary_group_flair_color
object.primary_group&.flair_color
def flair_bg_color
object.flair_group&.flair_bg_color
end
def flair_color
object.flair_group&.flair_color
end
def primary_group_name

View File

@ -28,9 +28,9 @@ class WebHookPostSerializer < PostSerializer
actions_summary
can_view_edit_history
yours
primary_group_flair_url
primary_group_flair_bg_color
primary_group_flair_color
flair_url
flair_bg_color
flair_color
notice
}.each do |attr|
define_method("include_#{attr}?") do

View File

@ -121,6 +121,13 @@ class UserUpdater
user.primary_group_id = nil
end
if attributes[:flair_group_id] &&
attributes[:flair_group_id] != user.flair_group_id &&
guardian.can_use_primary_group?(user, attributes[:flair_group_id])
user.flair_group_id = attributes[:flair_group_id]
end
CATEGORY_IDS.each do |attribute, level|
if ids = attributes[attribute]
CategoryUser.batch_set(user, level, ids)

View File

@ -1646,6 +1646,11 @@ en:
title:
title: "Title"
none: "(none)"
instructions: "appears after your username"
flair:
title: "Flair"
none: "(none)"
instructions: "icon displayed next to your profile picture"
primary_group:
title: "Primary Group"
none: "(none)"

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddFlairGroupIdToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :flair_group_id, :integer, null: true
end
end

View File

@ -12,13 +12,33 @@ class UserLookup
end
def primary_groups
@groups ||= group_lookup_hash
@primary_groups ||= begin
hash = {}
users.values.each do |u|
if u.primary_group_id
hash[u.id] = groups[u.primary_group_id]
end
end
hash
end
end
def flair_groups
@flair_groups ||= begin
hash = {}
users.values.each do |u|
if u.flair_group_id
hash[u.id] = groups[u.flair_group_id]
end
end
hash
end
end
private
def self.lookup_columns
@user_lookup_columns ||= %i{id username name uploaded_avatar_id primary_group_id admin moderator trust_level}
@user_lookup_columns ||= %i{id username name uploaded_avatar_id primary_group_id flair_group_id admin moderator trust_level}
end
def self.group_lookup_columns
@ -37,23 +57,21 @@ class UserLookup
hash
end
def group_lookup_hash
users_with_primary_group = users.values.reject { |u| u.primary_group_id.nil? }
def groups
@group_lookup = begin
group_ids = users.values.map { |u| [u.primary_group_id, u.flair_group_id] }
group_ids.flatten!
group_ids.uniq!
group_ids.compact!
group_lookup = {}
group_ids = users_with_primary_group.map { |u| u.primary_group_id }
group_ids.uniq!
hash = {}
Group.includes(:flair_upload)
.where(id: group_ids)
.select(self.class.group_lookup_columns)
.each { |g| group_lookup[g.id] = g }
Group.includes(:flair_upload)
.where(id: group_ids)
.select(self.class.group_lookup_columns)
.each { |g| hash[g.id] = g }
hash = {}
users_with_primary_group.each do |u|
hash[u.id] = group_lookup[u.primary_group_id]
hash
end
hash
end
end

View File

@ -38,9 +38,9 @@ acceptance("Poll in a post reply history", function (needs) {
topic_slug: "topic-with-a-poll-in-a-post-reply-history",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: true,
@ -337,9 +337,9 @@ acceptance("Poll in a post reply history", function (needs) {
"/letter_avatar_proxy/v4/letter/a/bbce88/{size}.png",
post_count: 4,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
],
created_by: {
@ -385,9 +385,9 @@ acceptance("Poll in a post reply history", function (needs) {
topic_slug: "topic-with-a-poll-in-a-post-reply-history",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: false,
can_delete: false,

View File

@ -35,9 +35,9 @@ acceptance("Poll quote", function (needs) {
topic_slug: "topic-with-two-polls",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -154,9 +154,9 @@ acceptance("Poll quote", function (needs) {
topic_slug: "topic-with-two-quoted-polls",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -399,9 +399,9 @@ acceptance("Poll quote", function (needs) {
"/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png",
post_count: 1,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
},
],
created_by: {

View File

@ -38,9 +38,9 @@ acceptance("Poll results", function (needs) {
topic_slug: "load-more-poll-voters",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -143,9 +143,9 @@ acceptance("Poll results", function (needs) {
topic_slug: "load-more-poll-voters",
display_username: null,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_bg_color: null,
primary_group_flair_color: null,
flair_url: null,
flair_bg_color: null,
flair_color: null,
version: 1,
can_edit: true,
can_delete: false,
@ -499,9 +499,9 @@ acceptance("Poll results", function (needs) {
"/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png",
post_count: 1,
primary_group_name: null,
primary_group_flair_url: null,
primary_group_flair_color: null,
primary_group_flair_bg_color: null,
flair_url: null,
flair_color: null,
flair_bg_color: null,
admin: true,
trust_level: 0,
},

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2142,16 +2142,24 @@ describe User do
end
describe '#match_title_to_primary_group_changes' do
let(:primary_group_a) { Fabricate(:group, title: 'A', users: [user]) }
let(:primary_group_b) { Fabricate(:group, title: 'B', users: [user]) }
describe '#match_primary_group_changes' do
let(:group_a) { Fabricate(:group, title: 'A', users: [user]) }
let(:group_b) { Fabricate(:group, title: 'B', users: [user]) }
it "updates user's title only when it is blank or matches the previous primary group" do
expect { user.update(primary_group: primary_group_a) }.to change { user.reload.title }.from(nil).to('A')
expect { user.update(primary_group: primary_group_b) }.to change { user.reload.title }.from('A').to('B')
expect { user.update(primary_group: group_a) }.to change { user.reload.title }.from(nil).to('A')
expect { user.update(primary_group: group_b) }.to change { user.reload.title }.from('A').to('B')
user.update(title: 'Different')
expect { user.update(primary_group: primary_group_a) }.to_not change { user.reload.title }
expect { user.update(primary_group: group_a) }.to_not change { user.reload.title }
end
it "updates user's title only when it is blank or matches the previous primary group" do
expect { user.update(primary_group: group_a) }.to change { user.reload.flair_group }.from(nil).to(group_a)
expect { user.update(primary_group: group_b) }.to change { user.reload.flair_group }.from(group_a).to(group_b)
user.update(flair_group: group_a)
expect { user.update(primary_group: group_a) }.to_not change { user.reload.flair_group }
end
end

View File

@ -51,9 +51,10 @@ describe 'posts' do
category_id: { type: :integer },
display_username: { type: :string },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_name: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
@ -149,9 +150,10 @@ describe 'posts' do
topic_slug: { type: :string },
display_username: { type: :string, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_name: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
@ -237,9 +239,9 @@ describe 'posts' do
topic_slug: { type: :string },
display_username: { type: :string, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
@ -359,9 +361,10 @@ describe 'posts' do
topic_slug: { type: :string },
display_username: { type: :string },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_name: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },

View File

@ -79,19 +79,25 @@
"null"
]
},
"primary_group_flair_url": {
"flair_name": {
"type": [
"string",
"null"
]
},
"primary_group_flair_bg_color": {
"flair_url": {
"type": [
"string",
"null"
]
},
"primary_group_flair_color": {
"flair_bg_color": {
"type": [
"string",
"null"
]
},
"flair_color": {
"type": [
"string",
"null"
@ -219,9 +225,10 @@
"topic_slug",
"display_username",
"primary_group_name",
"primary_group_flair_url",
"primary_group_flair_bg_color",
"primary_group_flair_color",
"flair_name",
"flair_url",
"flair_bg_color",
"flair_color",
"version",
"can_edit",
"can_delete",

View File

@ -53,9 +53,10 @@ describe 'topics' do
topic_slug: { type: :string },
display_username: { type: :string, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_name: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
@ -144,9 +145,10 @@ describe 'topics' do
topic_slug: { type: :string },
display_username: { type: :string },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_name: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
@ -337,9 +339,10 @@ describe 'topics' do
avatar_template: { type: :string },
post_count: { type: :integer },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
flair_name: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
}
},
},

View File

@ -3098,32 +3098,32 @@ describe UsersController do
expect(json["user_summary"]["most_liked_by_users"][0]["trust_level"]).to eq(1)
end
it "returns data for primary group flair when an icon is used for flair" do
it "returns data for flair when an icon is used" do
group = Fabricate(:group, name: "Groupie", flair_bg_color: "#111111", flair_color: "#999999", flair_icon: "icon")
liker = Fabricate(:user, primary_group: group)
liker = Fabricate(:user, flair_group: group)
create_and_like_post(user, liker)
get "/u/#{user.username_lower}/summary.json"
json = response.parsed_body
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_url"]).to eq("icon")
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_name"]).to eq("Groupie")
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_bg_color"]).to eq("#111111")
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_color"]).to eq("#999999")
expect(json["user_summary"]["most_liked_by_users"][0]["flair_name"]).to eq("Groupie")
expect(json["user_summary"]["most_liked_by_users"][0]["flair_url"]).to eq("icon")
expect(json["user_summary"]["most_liked_by_users"][0]["flair_bg_color"]).to eq("#111111")
expect(json["user_summary"]["most_liked_by_users"][0]["flair_color"]).to eq("#999999")
end
it "returns data for primary group flair when an image is used for flair" do
it "returns data for flair when an image is used" do
upload = Fabricate(:upload)
group = Fabricate(:group, name: "Groupie", flair_bg_color: "#111111", flair_upload: upload)
liker = Fabricate(:user, primary_group: group)
liker = Fabricate(:user, flair_group: group)
create_and_like_post(user, liker)
get "/u/#{user.username_lower}/summary.json"
json = response.parsed_body
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_url"]).to eq(upload.url)
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_name"]).to eq("Groupie")
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_bg_color"]).to eq("#111111")
expect(json["user_summary"]["most_liked_by_users"][0]["flair_name"]).to eq("Groupie")
expect(json["user_summary"]["most_liked_by_users"][0]["flair_url"]).to eq(upload.url)
expect(json["user_summary"]["most_liked_by_users"][0]["flair_bg_color"]).to eq("#111111")
end
def create_and_like_post(likee, liker)

View File

@ -11,20 +11,51 @@ RSpec.describe WebHookPostSerializer do
end
it 'should only include the required keys' do
count = serialized_for_user(admin).keys.count
difference = count - 42
expect(difference).to eq(0), lambda {
message = +""
if difference < 0
message << "#{difference * -1} key(s) have been removed from this serializer."
else
message << "#{difference} key(s) have been added to this serializer."
end
message << "\nPlease verify if those key(s) are required as part of the web hook's payload."
}
expect(serialized_for_user(admin).keys).to contain_exactly(
:id,
:name,
:username,
:avatar_template,
:created_at,
:cooked,
:post_number,
:post_type,
:updated_at,
:reply_count,
:reply_to_post_number,
:quote_count,
:incoming_link_count,
:reads,
:score,
:topic_id,
:topic_slug,
:topic_title,
:category_id,
:display_username,
:primary_group_name,
:flair_name,
:version,
:user_title,
:bookmarked,
:raw,
:moderator,
:admin,
:staff,
:user_id,
:hidden,
:trust_level,
:deleted_at,
:user_deleted,
:edit_reason,
:wiki,
:reviewable_id,
:reviewable_score_count,
:reviewable_score_pending_count,
:topic_posts_count,
:topic_filtered_posts_count,
:topic_archetype,
:category_slug
)
end
it "includes category_id" do

View File

@ -22,14 +22,59 @@ RSpec.describe WebHookUserSerializer do
end
it 'should only include the required keys' do
count = serializer.as_json.keys.count
difference = count - 51
expect(difference).to eq(0), lambda {
message = (difference < 0 ?
"#{difference * -1} key(s) have been removed from this serializer." :
"#{difference} key(s) have been added to this serializer.") +
"\nPlease verify if those key(s) are required as part of the web hook's payload."
}
expect(serializer.as_json.keys).to contain_exactly(
:id,
:username,
:name,
:avatar_template,
:email,
:secondary_emails,
:last_posted_at,
:last_seen_at,
:created_at,
:muted,
:trust_level,
:moderator,
:admin,
:title,
:badge_count,
:time_read,
:recent_time_read,
:primary_group_id,
:primary_group_name,
:flair_name,
:flair_url,
:flair_bg_color,
:flair_color,
:featured_topic,
:staged,
:pending_count,
:profile_view_count,
:second_factor_enabled,
:can_upload_profile_header,
:can_upload_user_card_background,
:post_count,
:locale,
:muted_category_ids,
:regular_category_ids,
:watched_tags,
:watching_first_post_tags,
:tracked_tags,
:muted_tags,
:tracked_category_ids,
:watched_category_ids,
:watched_first_post_category_ids,
:system_avatar_template,
:muted_usernames,
:ignored_usernames,
:allowed_pm_usernames,
:mailing_list_posts_per_day,
:user_notification_schedule,
:external_id,
:featured_user_badge_ids,
:invited_by,
:groups,
:user_option
)
end
end

View File

@ -153,9 +153,9 @@ RSpec.configure do |config|
recent_time_read: { type: :integer },
primary_group_id: { type: :string, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
featured_topic: { type: :string, nullable: true },
staged: { type: :boolean },
can_edit: { type: :boolean },