FEATURE: Implement edit functionality for post notices (#11140)
All post notice related custom fields were moved to a single one.
This commit is contained in:
parent
84e2915e71
commit
ab314218d3
|
@ -1,63 +0,0 @@
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import Controller from "@ember/controller";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { cookAsync } from "discourse/lib/text";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
post: null,
|
||||
resolve: null,
|
||||
reject: null,
|
||||
|
||||
notice: null,
|
||||
saving: false,
|
||||
|
||||
@discourseComputed("saving", "notice")
|
||||
disabled(saving, notice) {
|
||||
return saving || isEmpty(notice);
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.setProperties({
|
||||
notice: "",
|
||||
saving: false,
|
||||
});
|
||||
},
|
||||
|
||||
onClose() {
|
||||
const reject = this.reject;
|
||||
if (reject) {
|
||||
reject();
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
setNotice() {
|
||||
this.set("saving", true);
|
||||
|
||||
const post = this.post;
|
||||
const resolve = this.resolve;
|
||||
const reject = this.reject;
|
||||
const notice = this.notice;
|
||||
|
||||
// Let `updatePostField` handle state.
|
||||
this.setProperties({ resolve: null, reject: null });
|
||||
|
||||
post
|
||||
.updatePostField("notice", notice)
|
||||
.then(() => cookAsync(notice, { features: { onebox: false } }))
|
||||
.then((cookedNotice) => {
|
||||
post.setProperties({
|
||||
notice_type: "custom",
|
||||
notice_args: cookedNotice.string,
|
||||
});
|
||||
resolve();
|
||||
this.send("closeModal");
|
||||
})
|
||||
.catch(() => {
|
||||
reject();
|
||||
this.send("closeModal");
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,58 @@
|
|||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { cookAsync } from "discourse/lib/text";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
post: null,
|
||||
resolve: null,
|
||||
reject: null,
|
||||
|
||||
notice: null,
|
||||
saving: false,
|
||||
|
||||
@discourseComputed("saving", "notice")
|
||||
disabled(saving, notice) {
|
||||
return saving || isEmpty(notice);
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.setProperties({ notice: "", saving: false });
|
||||
},
|
||||
|
||||
onClose() {
|
||||
if (this.reject) {
|
||||
this.reject();
|
||||
}
|
||||
},
|
||||
|
||||
@action
|
||||
setNotice(notice) {
|
||||
const { resolve, reject } = this;
|
||||
this.setProperties({ saving: true, resolve: null, reject: null });
|
||||
|
||||
this.model
|
||||
.updatePostField("notice", notice)
|
||||
.then(() => {
|
||||
if (notice) {
|
||||
return cookAsync(notice, { features: { onebox: false } });
|
||||
}
|
||||
})
|
||||
.then((cooked) =>
|
||||
this.model.set(
|
||||
"notice",
|
||||
cooked
|
||||
? {
|
||||
type: "custom",
|
||||
raw: notice,
|
||||
cooked: cooked.string,
|
||||
}
|
||||
: null
|
||||
)
|
||||
)
|
||||
.then(resolve, reject)
|
||||
.finally(() => this.send("closeModal"));
|
||||
},
|
||||
});
|
|
@ -857,22 +857,17 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
this.send("showGrantBadgeModal");
|
||||
},
|
||||
|
||||
addNotice(post) {
|
||||
changeNotice(post) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const modal = showModal("add-post-notice");
|
||||
modal.setProperties({ post, resolve, reject });
|
||||
const modal = showModal("change-post-notice", { model: post });
|
||||
modal.setProperties({
|
||||
resolve,
|
||||
reject,
|
||||
notice: post.notice ? post.notice.raw : "",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
removeNotice(post) {
|
||||
return post.updatePostField("notice", null).then(() =>
|
||||
post.setProperties({
|
||||
notice_type: null,
|
||||
notice_args: null,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
toggleParticipant(user) {
|
||||
this.get("model.postStream")
|
||||
.toggleParticipant(user.get("username"))
|
||||
|
|
|
@ -140,12 +140,10 @@ export default function transformPost(
|
|||
postAtts.topicUrl = topic.get("url");
|
||||
postAtts.isSaving = post.isSaving;
|
||||
|
||||
if (post.notice_type) {
|
||||
postAtts.noticeType = post.notice_type;
|
||||
if (postAtts.noticeType === "custom") {
|
||||
postAtts.noticeMessage = post.notice_args;
|
||||
} else if (postAtts.noticeType === "returning_user") {
|
||||
postAtts.noticeTime = new Date(post.notice_args);
|
||||
if (post.notice) {
|
||||
postAtts.notice = post.notice;
|
||||
if (postAtts.notice.type === "returning_user") {
|
||||
postAtts.notice.lastPostedAt = new Date(post.notice.last_posted_at);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
{{#d-modal-body title="post.controls.add_post_notice"}}
|
||||
<form>{{textarea value=notice}}</form>
|
||||
{{/d-modal-body}}
|
||||
|
||||
<div class="modal-footer">
|
||||
{{d-button
|
||||
class="btn-primary"
|
||||
action=(action "setNotice")
|
||||
disabled=disabled
|
||||
label=(if saving "saving" "save")}}
|
||||
{{d-modal-cancel close=(route-action "closeModal")}}
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
{{#d-modal-body title=(if model.notice "post.controls.change_post_notice" "post.controls.add_post_notice")}}
|
||||
<form>{{textarea value=notice}}</form>
|
||||
{{/d-modal-body}}
|
||||
|
||||
<div class="modal-footer">
|
||||
{{d-button class="btn-primary" label=(if saving "saving" "save") action=(action "setNotice" notice) disabled=disabled}}
|
||||
{{#if model.notice}}
|
||||
{{d-button class="btn-danger" label="post.controls.delete_post_notice" action=(action "setNotice") disabled=saving}}
|
||||
{{/if}}
|
||||
{{d-modal-cancel close=(route-action "closeModal")}}
|
||||
</div>
|
|
@ -215,8 +215,7 @@
|
|||
rebakePost=(action "rebakePost")
|
||||
changePostOwner=(action "changePostOwner")
|
||||
grantBadge=(action "grantBadge")
|
||||
addNotice=(action "addNotice")
|
||||
removeNotice=(action "removeNotice")
|
||||
changeNotice=(action "changeNotice")
|
||||
lockPost=(action "lockPost")
|
||||
unlockPost=(action "unlockPost")
|
||||
unhidePost=(action "unhidePost")
|
||||
|
|
|
@ -53,21 +53,16 @@ export function buildManageButtons(attrs, currentUser, siteSettings) {
|
|||
}
|
||||
|
||||
if (attrs.canEditStaffNotes) {
|
||||
if (attrs.noticeType) {
|
||||
contents.push({
|
||||
icon: "user-shield",
|
||||
label: "post.controls.remove_post_notice",
|
||||
action: "removeNotice",
|
||||
className: "popup-menu-button remove-notice",
|
||||
});
|
||||
} else {
|
||||
contents.push({
|
||||
icon: "user-shield",
|
||||
label: "post.controls.add_post_notice",
|
||||
action: "addNotice",
|
||||
className: "popup-menu-button add-notice",
|
||||
});
|
||||
}
|
||||
contents.push({
|
||||
icon: "user-shield",
|
||||
label: attrs.notice
|
||||
? "post.controls.change_post_notice"
|
||||
: "post.controls.add_post_notice",
|
||||
action: "changeNotice",
|
||||
className: attrs.notice
|
||||
? "popup-menu-button change-notice"
|
||||
: "popup-menu-button add-notice",
|
||||
});
|
||||
}
|
||||
|
||||
if (attrs.canManage && attrs.hidden) {
|
||||
|
|
|
@ -471,7 +471,7 @@ createWidget("post-notice", {
|
|||
tagName: "div.post-notice",
|
||||
|
||||
buildClasses(attrs) {
|
||||
const classes = [attrs.noticeType.replace(/_/g, "-")];
|
||||
const classes = [attrs.notice.type.replace(/_/g, "-")];
|
||||
|
||||
if (
|
||||
new Date() - new Date(attrs.created_at) >
|
||||
|
@ -484,30 +484,33 @@ createWidget("post-notice", {
|
|||
},
|
||||
|
||||
html(attrs) {
|
||||
if (attrs.notice.type === "custom") {
|
||||
return [
|
||||
iconNode("user-shield"),
|
||||
new RawHtml({ html: `<div>${attrs.notice.cooked}</div>` }),
|
||||
];
|
||||
}
|
||||
|
||||
const user =
|
||||
this.siteSettings.display_name_on_posts && prioritizeNameInUx(attrs.name)
|
||||
? attrs.name
|
||||
: attrs.username;
|
||||
let text, icon;
|
||||
if (attrs.noticeType === "custom") {
|
||||
icon = "user-shield";
|
||||
text = new RawHtml({ html: `<div>${attrs.noticeMessage}</div>` });
|
||||
} else if (attrs.noticeType === "new_user") {
|
||||
icon = "hands-helping";
|
||||
text = h("p", I18n.t("post.notice.new_user", { user }));
|
||||
} else if (attrs.noticeType === "returning_user") {
|
||||
icon = "far-smile";
|
||||
const distance = (new Date() - new Date(attrs.noticeTime)) / 1000;
|
||||
text = h(
|
||||
"p",
|
||||
I18n.t("post.notice.returning_user", {
|
||||
user,
|
||||
time: relativeAgeMediumSpan(distance, true),
|
||||
})
|
||||
);
|
||||
|
||||
if (attrs.notice.type === "new_user") {
|
||||
return [
|
||||
iconNode("hands-helping"),
|
||||
h("p", I18n.t("post.notice.new_user", { user })),
|
||||
];
|
||||
}
|
||||
|
||||
return [iconNode(icon), text];
|
||||
if (attrs.notice.type === "returning_user") {
|
||||
const timeAgo = (new Date() - new Date(attrs.notice.lastPostedAt)) / 1000;
|
||||
const time = relativeAgeMediumSpan(timeAgo, true);
|
||||
return [
|
||||
iconNode("far-smile"),
|
||||
h("p", I18n.t("post.notice.returning_user", { user, time })),
|
||||
];
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -593,7 +596,7 @@ createWidget("post-article", {
|
|||
);
|
||||
}
|
||||
|
||||
if (attrs.noticeType) {
|
||||
if (!attrs.deleted_at && attrs.notice) {
|
||||
rows.push(h("div.row", [this.attach("post-notice", attrs)]));
|
||||
}
|
||||
|
||||
|
|
|
@ -5174,7 +5174,7 @@ export default {
|
|||
edit_reason: null,
|
||||
can_view_edit_history: true,
|
||||
wiki: false,
|
||||
notice_type: "new-user",
|
||||
notice: { type: "new_user" }
|
||||
},
|
||||
],
|
||||
stream: [25, 26, 27],
|
||||
|
|
|
@ -934,11 +934,13 @@ widgetTest("post notice - with username", {
|
|||
this.siteSettings.prioritize_username_in_ux = true;
|
||||
this.siteSettings.old_post_notice_days = 14;
|
||||
this.set("args", {
|
||||
noticeType: "returning_user",
|
||||
noticeTime: twoDaysAgo,
|
||||
username: "codinghorror",
|
||||
name: "Jeff",
|
||||
created_at: new Date(),
|
||||
notice: {
|
||||
type: "returning_user",
|
||||
lastPostedAt: twoDaysAgo,
|
||||
},
|
||||
});
|
||||
},
|
||||
test(assert) {
|
||||
|
@ -959,10 +961,10 @@ widgetTest("post notice - with name", {
|
|||
this.siteSettings.prioritize_username_in_ux = false;
|
||||
this.siteSettings.old_post_notice_days = 14;
|
||||
this.set("args", {
|
||||
noticeType: "new_user",
|
||||
username: "codinghorror",
|
||||
name: "Jeff",
|
||||
created_at: new Date(2019, 0, 1),
|
||||
notice: { type: "new_user" },
|
||||
});
|
||||
},
|
||||
test(assert) {
|
||||
|
|
|
@ -95,3 +95,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.change-post-notice-modal {
|
||||
.modal-body {
|
||||
min-width: 450px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -477,18 +477,25 @@ class PostsController < ApplicationController
|
|||
post = find_post_from_params
|
||||
raise Discourse::NotFound unless guardian.can_edit_staff_notes?(post.topic)
|
||||
|
||||
previous_notice = post.custom_fields[Post::NOTICE_ARGS]
|
||||
old_notice = post.custom_fields[Post::NOTICE]
|
||||
|
||||
if params[:notice].present?
|
||||
post.custom_fields[Post::NOTICE_TYPE] = Post.notices[:custom]
|
||||
post.custom_fields[Post::NOTICE_ARGS] = PrettyText.cook(params[:notice], features: { onebox: false })
|
||||
post.save_custom_fields
|
||||
post.custom_fields[Post::NOTICE] = {
|
||||
type: Post.notices[:custom],
|
||||
raw: params[:notice],
|
||||
cooked: PrettyText.cook(params[:notice], features: { onebox: false })
|
||||
}
|
||||
else
|
||||
post.delete_post_notices
|
||||
post.custom_fields.delete(Post::NOTICE)
|
||||
end
|
||||
|
||||
details = { new_raw_value: params[:notice], old_value: previous_notice }
|
||||
StaffActionLogger.new(current_user).log_post_staff_note(post, details)
|
||||
post.save_custom_fields
|
||||
|
||||
StaffActionLogger.new(current_user).log_post_staff_note(
|
||||
post,
|
||||
old_value: old_notice&.[]("raw"),
|
||||
new_value: params[:notice]
|
||||
)
|
||||
|
||||
render body: nil
|
||||
end
|
||||
|
|
|
@ -67,8 +67,7 @@ class Post < ActiveRecord::Base
|
|||
DOWNLOADED_IMAGES ||= "downloaded_images"
|
||||
MISSING_UPLOADS ||= "missing uploads"
|
||||
MISSING_UPLOADS_IGNORED ||= "missing uploads ignored"
|
||||
NOTICE_TYPE ||= "notice_type"
|
||||
NOTICE_ARGS ||= "notice_args"
|
||||
NOTICE ||= "notice"
|
||||
|
||||
SHORT_POST_CHARS ||= 1200
|
||||
|
||||
|
@ -79,6 +78,8 @@ class Post < ActiveRecord::Base
|
|||
register_custom_field_type(MISSING_UPLOADS, :json)
|
||||
register_custom_field_type(MISSING_UPLOADS_IGNORED, :boolean)
|
||||
|
||||
register_custom_field_type(NOTICE, :json)
|
||||
|
||||
scope :private_posts_for_user, ->(user) {
|
||||
where("posts.topic_id IN (#{Topic::PRIVATE_MESSAGES_SQL})", user_id: user.id)
|
||||
}
|
||||
|
@ -225,7 +226,7 @@ class Post < ActiveRecord::Base
|
|||
|
||||
def trash!(trashed_by = nil)
|
||||
self.topic_links.each(&:destroy)
|
||||
self.delete_post_notices
|
||||
self.save_custom_fields if self.custom_fields.delete(Post::NOTICE)
|
||||
super(trashed_by)
|
||||
end
|
||||
|
||||
|
@ -428,8 +429,7 @@ class Post < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def delete_post_notices
|
||||
self.custom_fields.delete(Post::NOTICE_TYPE)
|
||||
self.custom_fields.delete(Post::NOTICE_ARGS)
|
||||
self.custom_fields.delete(Post::NOTICE)
|
||||
self.save_custom_fields
|
||||
end
|
||||
|
||||
|
|
|
@ -78,8 +78,7 @@ class PostSerializer < BasicPostSerializer
|
|||
:is_auto_generated,
|
||||
:action_code,
|
||||
:action_code_who,
|
||||
:notice_type,
|
||||
:notice_args,
|
||||
:notice,
|
||||
:last_wiki_edit,
|
||||
:locked,
|
||||
:excerpt,
|
||||
|
@ -438,12 +437,14 @@ class PostSerializer < BasicPostSerializer
|
|||
include_action_code? && action_code_who.present?
|
||||
end
|
||||
|
||||
def notice_type
|
||||
post_custom_fields[Post::NOTICE_TYPE]
|
||||
def notice
|
||||
post_custom_fields[Post::NOTICE]
|
||||
end
|
||||
|
||||
def include_notice_type?
|
||||
case notice_type
|
||||
def include_notice?
|
||||
return false if notice.blank?
|
||||
|
||||
case notice["type"]
|
||||
when Post.notices[:custom]
|
||||
return true
|
||||
when Post.notices[:new_user]
|
||||
|
@ -454,17 +455,7 @@ class PostSerializer < BasicPostSerializer
|
|||
return false
|
||||
end
|
||||
|
||||
scope.user && scope.user.id && object.user &&
|
||||
scope.user.id != object.user_id &&
|
||||
scope.user.has_trust_level?(min_trust_level)
|
||||
end
|
||||
|
||||
def notice_args
|
||||
post_custom_fields[Post::NOTICE_ARGS]
|
||||
end
|
||||
|
||||
def include_notice_args?
|
||||
notice_args.present? && include_notice_type?
|
||||
scope.user && scope.user.id != object.user_id && scope.user.has_trust_level?(min_trust_level)
|
||||
end
|
||||
|
||||
def locked
|
||||
|
|
|
@ -31,8 +31,7 @@ class WebHookPostSerializer < PostSerializer
|
|||
primary_group_flair_url
|
||||
primary_group_flair_bg_color
|
||||
primary_group_flair_color
|
||||
notice_args
|
||||
notice_type
|
||||
notice
|
||||
}.each do |attr|
|
||||
define_method("include_#{attr}?") do
|
||||
false
|
||||
|
|
|
@ -168,10 +168,10 @@ class StaffActionLogger
|
|||
raise Discourse::InvalidParameters.new(:post) unless post && post.is_a?(Post)
|
||||
|
||||
args = params(opts).merge(
|
||||
action: UserHistory.actions[opts[:new_raw_value].present? ? :post_staff_note_create : :post_staff_note_destroy],
|
||||
action: UserHistory.actions[opts[:new_value].present? ? :post_staff_note_create : :post_staff_note_destroy],
|
||||
post_id: post.id
|
||||
)
|
||||
args[:new_value] = opts[:new_raw_value] if opts[:new_raw_value].present?
|
||||
args[:new_value] = opts[:new_value] if opts[:new_value].present?
|
||||
args[:previous_value] = opts[:old_value] if opts[:old_value].present?
|
||||
|
||||
UserHistory.create!(params(opts).merge(args))
|
||||
|
|
|
@ -2823,7 +2823,8 @@ en:
|
|||
delete_topic_error: "An error occurred while deleting this topic"
|
||||
delete_topic: "delete topic"
|
||||
add_post_notice: "Add Staff Notice"
|
||||
remove_post_notice: "Remove Staff Notice"
|
||||
change_post_notice: "Change Staff Notice"
|
||||
delete_post_notice: "Delete Staff Notice"
|
||||
remove_timer: "remove timer"
|
||||
|
||||
actions:
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MovePostNoticesToJson < ActiveRecord::Migration[6.0]
|
||||
def up
|
||||
execute <<~SQL
|
||||
INSERT INTO post_custom_fields(post_id, name, value, created_at, updated_at)
|
||||
SELECT
|
||||
posts.id,
|
||||
'notice',
|
||||
CASE
|
||||
WHEN pcf_type.value = 'custom' THEN json_build_object('type', pcf_type.value, 'raw', pcf_args.value, 'cooked', pcf_args.value)
|
||||
WHEN pcf_type.value = 'new_user' THEN json_build_object('type', pcf_type.value)
|
||||
WHEN pcf_type.value = 'returning_user' THEN json_build_object('type', pcf_type.value, 'last_posted_at', pcf_args.value)
|
||||
END,
|
||||
pcf_type.created_at created_at,
|
||||
pcf_type.updated_at updated_at
|
||||
FROM posts
|
||||
JOIN post_custom_fields pcf_type ON posts.id = pcf_type.post_id AND pcf_type.name = 'notice_type'
|
||||
LEFT JOIN post_custom_fields pcf_args ON posts.id = pcf_args.post_id AND pcf_args.name = 'notice_args'
|
||||
SQL
|
||||
|
||||
execute "DELETE FROM post_custom_fields WHERE name = 'notice_type' OR name = 'notice_args'"
|
||||
|
||||
add_index :post_custom_fields, :post_id, unique: true, name: "index_post_custom_fields_on_notice", where: "name = 'notice'"
|
||||
|
||||
remove_index :post_custom_fields, name: "index_post_custom_fields_on_notice_type"
|
||||
remove_index :post_custom_fields, name: "index_post_custom_fields_on_notice_args"
|
||||
end
|
||||
|
||||
def down
|
||||
execute <<~SQL
|
||||
INSERT INTO post_custom_fields(post_id, name, value, created_at, updated_at)
|
||||
SELECT post_id, 'notice_type', value::json->>'type', created_at, updated_at
|
||||
FROM post_custom_fields
|
||||
WHERE name = 'notice'
|
||||
SQL
|
||||
|
||||
execute <<~SQL
|
||||
INSERT INTO post_custom_fields(post_id, name, value, created_at, updated_at)
|
||||
SELECT post_id, 'notice_args', COALESCE(value::json->>'cooked', value::json->>'last_posted_at'), created_at, updated_at
|
||||
FROM post_custom_fields
|
||||
WHERE name = 'notice'
|
||||
SQL
|
||||
|
||||
execute "DELETE FROM post_custom_fields WHERE name = 'notice'"
|
||||
|
||||
add_index :post_custom_fields, :post_id, unique: true, name: "index_post_custom_fields_on_notice_type", where: "name = 'notice_type'"
|
||||
add_index :post_custom_fields, :post_id, unique: true, name: "index_post_custom_fields_on_notice_args", where: "name = 'notice_args'"
|
||||
|
||||
remove_index :index_post_custom_fields_on_notice
|
||||
end
|
||||
end
|
|
@ -616,10 +616,12 @@ class PostCreator
|
|||
.first
|
||||
|
||||
if !last_post_time
|
||||
@post.custom_fields[Post::NOTICE_TYPE] = Post.notices[:new_user]
|
||||
@post.custom_fields[Post::NOTICE] = { type: Post.notices[:new_user] }
|
||||
elsif SiteSetting.returning_users_days > 0 && last_post_time < SiteSetting.returning_users_days.days.ago
|
||||
@post.custom_fields[Post::NOTICE_TYPE] = Post.notices[:returning_user]
|
||||
@post.custom_fields[Post::NOTICE_ARGS] = last_post_time.iso8601
|
||||
@post.custom_fields[Post::NOTICE] = {
|
||||
type: Post.notices[:returning_user],
|
||||
last_posted_at: last_post_time.iso8601
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class TopicView
|
|||
end
|
||||
|
||||
def self.default_post_custom_fields
|
||||
@default_post_custom_fields ||= [Post::NOTICE_TYPE, Post::NOTICE_ARGS, "action_code_who"]
|
||||
@default_post_custom_fields ||= [Post::NOTICE, "action_code_who"]
|
||||
end
|
||||
|
||||
def self.post_custom_fields_allowlisters
|
||||
|
|
|
@ -1627,10 +1627,10 @@ describe PostCreator do
|
|||
|
||||
it "generates post notices for new users" do
|
||||
post = PostCreator.create!(user, title: "one of my first topics", raw: "one of my first posts")
|
||||
expect(post.custom_fields[Post::NOTICE_TYPE]).to eq(Post.notices[:new_user])
|
||||
expect(post.custom_fields[Post::NOTICE]).to eq("type" => Post.notices[:new_user])
|
||||
|
||||
post = PostCreator.create!(user, title: "another one of my first topics", raw: "another one of my first posts")
|
||||
expect(post.custom_fields[Post::NOTICE_TYPE]).to eq(nil)
|
||||
expect(post.custom_fields[Post::NOTICE]).to eq(nil)
|
||||
end
|
||||
|
||||
it "generates post notices for returning users" do
|
||||
|
@ -1638,12 +1638,10 @@ describe PostCreator do
|
|||
old_post = Fabricate(:post, user: user, created_at: 31.days.ago)
|
||||
|
||||
post = PostCreator.create!(user, title: "this is a returning topic", raw: "this is a post")
|
||||
expect(post.custom_fields[Post::NOTICE_TYPE]).to eq(Post.notices[:returning_user])
|
||||
expect(post.custom_fields[Post::NOTICE_ARGS]).to eq(old_post.created_at.iso8601)
|
||||
expect(post.custom_fields[Post::NOTICE]).to eq("type" => Post.notices[:returning_user], "last_posted_at" => old_post.created_at.iso8601)
|
||||
|
||||
post = PostCreator.create!(user, title: "this is another topic", raw: "this is my another post")
|
||||
expect(post.custom_fields[Post::NOTICE_TYPE]).to eq(nil)
|
||||
expect(post.custom_fields[Post::NOTICE_ARGS]).to eq(nil)
|
||||
expect(post.custom_fields[Post::NOTICE]).to eq(nil)
|
||||
end
|
||||
|
||||
it "does not generate for non-human, staged or anonymous users" do
|
||||
|
@ -1652,8 +1650,7 @@ describe PostCreator do
|
|||
[anonymous, Discourse.system_user, staged].each do |user|
|
||||
expect(user.posts.size).to eq(0)
|
||||
post = PostCreator.create!(user, title: "#{user.username}'s first topic", raw: "#{user.name}'s first post")
|
||||
expect(post.custom_fields[Post::NOTICE_TYPE]).to eq(nil)
|
||||
expect(post.custom_fields[Post::NOTICE_ARGS]).to eq(nil)
|
||||
expect(post.custom_fields[Post::NOTICE]).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -136,24 +136,18 @@ describe Post do
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'a post with notices' do
|
||||
let(:post) {
|
||||
post = Fabricate(:post, post_args)
|
||||
post.custom_fields[Post::NOTICE_TYPE] = Post.notices[:returning_user]
|
||||
post.custom_fields[Post::NOTICE_ARGS] = 1.day.ago
|
||||
post.save_custom_fields
|
||||
post
|
||||
}
|
||||
|
||||
describe 'recovery' do
|
||||
it 'deletes notices' do
|
||||
expect { post.trash! }
|
||||
.to change { post.custom_fields.length }.from(2).to(0)
|
||||
end
|
||||
end
|
||||
context 'a post with notices' do
|
||||
let(:post) do
|
||||
post = Fabricate(:post, post_args)
|
||||
post.upsert_custom_fields(Post::NOTICE => { type: Post.notices[:returning_user], last_posted_at: 1.day.ago })
|
||||
post
|
||||
end
|
||||
|
||||
it 'will have its notice cleared when post is trashed' do
|
||||
expect { post.trash! }.to change { post.custom_fields }.to({})
|
||||
end
|
||||
end
|
||||
|
||||
describe "with_secure_media?" do
|
||||
|
|
|
@ -463,7 +463,7 @@ describe 'posts' do
|
|||
edit_reason: { type: :string, nullable: true },
|
||||
can_view_edit_history: { type: :boolean },
|
||||
wiki: { type: :boolean },
|
||||
notice_type: { type: :string },
|
||||
notice: { type: :object },
|
||||
reviewable_id: { type: :string, nullable: true },
|
||||
reviewable_score_count: { type: :integer },
|
||||
reviewable_score_pending_count: { type: :integer },
|
||||
|
|
|
@ -1914,21 +1914,17 @@ describe PostsController do
|
|||
it 'can create and remove notices as a moderator' do
|
||||
sign_in(moderator)
|
||||
|
||||
put "/posts/#{public_post.id}/notice.json", params: { notice: "Hello *world*!\n\nhttps://github.com/discourse/discourse" }
|
||||
raw_notice = "Hello *world*!\n\nhttps://github.com/discourse/discourse"
|
||||
put "/posts/#{public_post.id}/notice.json", params: { notice: raw_notice }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
public_post.reload
|
||||
expect(public_post.custom_fields[Post::NOTICE_TYPE]).to eq(Post.notices[:custom])
|
||||
expect(public_post.custom_fields[Post::NOTICE_ARGS]).to include('<p>Hello <em>world</em>!</p>')
|
||||
expect(public_post.custom_fields[Post::NOTICE_ARGS]).not_to include('onebox')
|
||||
expect(public_post.reload.custom_fields[Post::NOTICE]).to eq("type" => Post.notices[:custom], "raw" => raw_notice, "cooked" => PrettyText.cook(raw_notice, features: { onebox: false }))
|
||||
expect(UserHistory.where(action: UserHistory.actions[:post_staff_note_create]).count).to eq(1)
|
||||
|
||||
put "/posts/#{public_post.id}/notice.json", params: { notice: nil }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
public_post.reload
|
||||
expect(public_post.custom_fields[Post::NOTICE_TYPE]).to eq(nil)
|
||||
expect(public_post.custom_fields[Post::NOTICE_ARGS]).to eq(nil)
|
||||
expect(public_post.reload.custom_fields[Post::NOTICE]).to eq(nil)
|
||||
expect(UserHistory.where(action: UserHistory.actions[:post_staff_note_destroy]).count).to eq(1)
|
||||
end
|
||||
|
||||
|
@ -1945,20 +1941,16 @@ describe PostsController do
|
|||
end
|
||||
|
||||
it 'can create and remove notices as a group moderator' do
|
||||
put "/posts/#{public_post.id}/notice.json", params: { notice: "Hello *world*!\n\nhttps://github.com/discourse/discourse" }
|
||||
raw_notice = "Hello *world*!\n\nhttps://github.com/discourse/discourse"
|
||||
put "/posts/#{public_post.id}/notice.json", params: { notice: raw_notice }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
public_post.reload
|
||||
expect(public_post.custom_fields[Post::NOTICE_TYPE]).to eq(Post.notices[:custom])
|
||||
expect(public_post.custom_fields[Post::NOTICE_ARGS]).to include('<p>Hello <em>world</em>!</p>')
|
||||
expect(public_post.custom_fields[Post::NOTICE_ARGS]).not_to include('onebox')
|
||||
expect(public_post.reload.custom_fields[Post::NOTICE]).to eq("type" => Post.notices[:custom], "raw" => raw_notice, "cooked" => PrettyText.cook(raw_notice, features: { onebox: false }))
|
||||
|
||||
put "/posts/#{public_post.id}/notice.json", params: { notice: nil }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
public_post.reload
|
||||
expect(public_post.custom_fields[Post::NOTICE_TYPE]).to eq(nil)
|
||||
expect(public_post.custom_fields[Post::NOTICE_ARGS]).to eq(nil)
|
||||
expect(public_post.reload.custom_fields[Post::NOTICE]).to eq(nil)
|
||||
end
|
||||
|
||||
it 'prevents a group moderator from altering notes outside of their category' do
|
||||
|
|
|
@ -201,8 +201,7 @@ describe PostSerializer do
|
|||
|
||||
let(:post) {
|
||||
post = Fabricate(:post, user: user)
|
||||
post.custom_fields[Post::NOTICE_TYPE] = Post.notices[:returning_user]
|
||||
post.custom_fields[Post::NOTICE_ARGS] = 1.day.ago
|
||||
post.custom_fields[Post::NOTICE] = { type: Post.notices[:returning_user], last_posted_at: 1.day.ago }
|
||||
post.save_custom_fields
|
||||
post
|
||||
}
|
||||
|
@ -212,16 +211,16 @@ describe PostSerializer do
|
|||
end
|
||||
|
||||
it "is visible for TL2+ users (except poster)" do
|
||||
expect(json_for_user(nil)[:notice_type]).to eq(nil)
|
||||
expect(json_for_user(user)[:notice_type]).to eq(nil)
|
||||
expect(json_for_user(nil)[:notice]).to eq(nil)
|
||||
expect(json_for_user(user)[:notice]).to eq(nil)
|
||||
|
||||
SiteSetting.returning_user_notice_tl = 2
|
||||
expect(json_for_user(user_tl1)[:notice_type]).to eq(nil)
|
||||
expect(json_for_user(user_tl2)[:notice_type]).to eq(Post.notices[:returning_user])
|
||||
expect(json_for_user(user_tl1)[:notice]).to eq(nil)
|
||||
expect(json_for_user(user_tl2)[:notice][:type]).to eq(Post.notices[:returning_user])
|
||||
|
||||
SiteSetting.returning_user_notice_tl = 1
|
||||
expect(json_for_user(user_tl1)[:notice_type]).to eq(Post.notices[:returning_user])
|
||||
expect(json_for_user(user_tl2)[:notice_type]).to eq(Post.notices[:returning_user])
|
||||
expect(json_for_user(user_tl1)[:notice][:type]).to eq(Post.notices[:returning_user])
|
||||
expect(json_for_user(user_tl2)[:notice][:type]).to eq(Post.notices[:returning_user])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -581,13 +581,13 @@ describe StaffActionLogger do
|
|||
end
|
||||
|
||||
it "creates a new UserHistory record" do
|
||||
expect { logger.log_post_staff_note(post, { new_raw_value: 'my note', old_value: nil }) }.to change { UserHistory.count }.by(1)
|
||||
expect { logger.log_post_staff_note(post, { new_value: 'my note', old_value: nil }) }.to change { UserHistory.count }.by(1)
|
||||
user_history = UserHistory.last
|
||||
expect(user_history.action).to eq(UserHistory.actions[:post_staff_note_create])
|
||||
expect(user_history.new_value).to eq('my note')
|
||||
expect(user_history.previous_value).to eq(nil)
|
||||
|
||||
expect { logger.log_post_staff_note(post, { new_raw_value: '', old_value: 'my note' }) }.to change { UserHistory.count }.by(1)
|
||||
expect { logger.log_post_staff_note(post, { new_value: '', old_value: 'my note' }) }.to change { UserHistory.count }.by(1)
|
||||
user_history = UserHistory.last
|
||||
expect(user_history.action).to eq(UserHistory.actions[:post_staff_note_destroy])
|
||||
expect(user_history.new_value).to eq(nil)
|
||||
|
@ -603,13 +603,13 @@ describe StaffActionLogger do
|
|||
end
|
||||
|
||||
it "creates a new UserHistory record" do
|
||||
expect { logger.log_post_staff_note(post, { new_raw_value: 'my note', old_value: nil }) }.to change { UserHistory.count }.by(1)
|
||||
expect { logger.log_post_staff_note(post, { new_value: 'my note', old_value: nil }) }.to change { UserHistory.count }.by(1)
|
||||
user_history = UserHistory.last
|
||||
expect(user_history.action).to eq(UserHistory.actions[:post_staff_note_create])
|
||||
expect(user_history.new_value).to eq('my note')
|
||||
expect(user_history.previous_value).to eq(nil)
|
||||
|
||||
expect { logger.log_post_staff_note(post, { new_raw_value: nil, old_value: 'my note' }) }.to change { UserHistory.count }.by(1)
|
||||
expect { logger.log_post_staff_note(post, { new_value: nil, old_value: 'my note' }) }.to change { UserHistory.count }.by(1)
|
||||
user_history = UserHistory.last
|
||||
expect(user_history.action).to eq(UserHistory.actions[:post_staff_note_destroy])
|
||||
expect(user_history.new_value).to eq(nil)
|
||||
|
|
Loading…
Reference in New Issue