mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 23:42:44 +08:00
FEATURE: Dismiss new and unread for PM inboxes.
This commit is contained in:
parent
d3779d4cf7
commit
2c046cc670
|
@ -44,7 +44,7 @@ export default Controller.extend({
|
|||
|
||||
@discourseComputed("pmView")
|
||||
isPersonalInbox(pmView) {
|
||||
return pmView && pmView.startsWith("personal");
|
||||
return pmView && pmView.startsWith("user");
|
||||
},
|
||||
|
||||
@discourseComputed("isPersonalInbox", "group.name")
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import discourseComputed, {
|
||||
observes,
|
||||
on,
|
||||
} from "discourse-common/utils/decorators";
|
||||
import BulkTopicSelection from "discourse/mixins/bulk-topic-selection";
|
||||
import { action } from "@ember/object";
|
||||
import Topic from "discourse/models/topic";
|
||||
|
||||
import {
|
||||
NEW_FILTER,
|
||||
UNREAD_FILTER,
|
||||
} from "discourse/routes/build-private-messages-route";
|
||||
|
||||
// Lists of topics on a user's page.
|
||||
export default Controller.extend(BulkTopicSelection, {
|
||||
|
@ -12,18 +22,17 @@ export default Controller.extend(BulkTopicSelection, {
|
|||
channel: null,
|
||||
tagsForUser: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
@on("init")
|
||||
_initialize() {
|
||||
this.newIncoming = [];
|
||||
},
|
||||
|
||||
saveScrollPosition: function () {
|
||||
saveScrollPosition() {
|
||||
this.session.set("topicListScrollPosition", $(window).scrollTop());
|
||||
},
|
||||
|
||||
@observes("model.canLoadMore")
|
||||
_showFooter: function () {
|
||||
_showFooter() {
|
||||
this.set("application.showFooter", !this.get("model.canLoadMore"));
|
||||
},
|
||||
|
||||
|
@ -32,6 +41,16 @@ export default Controller.extend(BulkTopicSelection, {
|
|||
return incomingCount > 0;
|
||||
},
|
||||
|
||||
@discourseComputed("filter", "model.topics.length")
|
||||
showResetNew(filter, hasTopics) {
|
||||
return filter === NEW_FILTER && hasTopics;
|
||||
},
|
||||
|
||||
@discourseComputed("filter", "model.topics.length")
|
||||
showDismissRead(filter, hasTopics) {
|
||||
return filter === UNREAD_FILTER && hasTopics;
|
||||
},
|
||||
|
||||
subscribe(channel) {
|
||||
this.set("channel", channel);
|
||||
|
||||
|
@ -59,15 +78,35 @@ export default Controller.extend(BulkTopicSelection, {
|
|||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
loadMore: function () {
|
||||
this.model.loadMore();
|
||||
},
|
||||
@action
|
||||
resetNew() {
|
||||
const topicIds = this.selected
|
||||
? this.selected.map((topic) => topic.id)
|
||||
: null;
|
||||
|
||||
showInserted() {
|
||||
this.model.loadBefore(this.newIncoming);
|
||||
this._resetTracking();
|
||||
return false;
|
||||
},
|
||||
const opts = {
|
||||
inbox: this.inbox,
|
||||
topicIds: topicIds,
|
||||
};
|
||||
|
||||
if (this.group) {
|
||||
opts.groupName = this.group.name;
|
||||
}
|
||||
|
||||
Topic.pmResetNew(opts).then(() => {
|
||||
this.send("refresh");
|
||||
});
|
||||
},
|
||||
|
||||
@action
|
||||
loadMore() {
|
||||
this.model.loadMore();
|
||||
},
|
||||
|
||||
@action
|
||||
showInserted() {
|
||||
this.model.loadBefore(this.newIncoming);
|
||||
this._resetTracking();
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -747,6 +747,14 @@ Topic.reopenClass({
|
|||
if (options.tagName) {
|
||||
data.tag_name = options.tagName;
|
||||
}
|
||||
|
||||
if (options.private_message_inbox) {
|
||||
data.private_message_inbox = options.private_message_inbox;
|
||||
|
||||
if (options.group_name) {
|
||||
data.group_name = options.group_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/bulk", {
|
||||
|
@ -778,6 +786,24 @@ Topic.reopenClass({
|
|||
return ajax("/topics/reset-new", { type: "PUT", data });
|
||||
},
|
||||
|
||||
pmResetNew(opts = {}) {
|
||||
const data = {};
|
||||
|
||||
if (opts.topicIds) {
|
||||
data.topic_ids = opts.topicIds;
|
||||
}
|
||||
|
||||
if (opts.inbox) {
|
||||
data.inbox = opts.inbox;
|
||||
|
||||
if (opts.groupName) {
|
||||
data.group_name = opts.groupName;
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/pm-reset-new", { type: "PUT", data });
|
||||
},
|
||||
|
||||
idForSlug(slug) {
|
||||
return ajax(`/t/id_for/${slug}`);
|
||||
},
|
||||
|
|
|
@ -2,8 +2,8 @@ import I18n from "I18n";
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||
|
||||
export default (viewName, channel) => {
|
||||
return createPMRoute("groups", "private-messages-groups").extend({
|
||||
export default (inboxType, filter) => {
|
||||
return createPMRoute(inboxType, "private-messages-groups", filter).extend({
|
||||
groupName: null,
|
||||
|
||||
titleToken() {
|
||||
|
@ -12,8 +12,8 @@ export default (viewName, channel) => {
|
|||
if (groupName) {
|
||||
let title = groupName.capitalize();
|
||||
|
||||
if (viewName !== "index") {
|
||||
title = `${title} ${I18n.t("user.messages." + viewName)}`;
|
||||
if (filter !== "inbox") {
|
||||
title = `${title} ${I18n.t("user.messages." + filter)}`;
|
||||
}
|
||||
|
||||
return [title, I18n.t(`user.private_messages`)];
|
||||
|
@ -22,24 +22,27 @@ export default (viewName, channel) => {
|
|||
|
||||
model(params) {
|
||||
const username = this.modelFor("user").get("username_lower");
|
||||
let filter = `topics/private-messages-group/${username}/${params.name}`;
|
||||
let topicListFilter = `topics/private-messages-group/${username}/${params.name}`;
|
||||
|
||||
if (viewName !== "index") {
|
||||
filter = `${filter}/${viewName}`;
|
||||
if (filter !== "inbox") {
|
||||
topicListFilter = `${topicListFilter}/${filter}`;
|
||||
}
|
||||
|
||||
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
|
||||
const lastTopicList = findOrResetCachedTopicList(
|
||||
this.session,
|
||||
topicListFilter
|
||||
);
|
||||
|
||||
return lastTopicList
|
||||
? lastTopicList
|
||||
: this.store.findFiltered("topicList", { filter });
|
||||
: this.store.findFiltered("topicList", { filter: topicListFilter });
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
const filters = model.get("filter").split("/");
|
||||
let groupName;
|
||||
|
||||
if (viewName !== "index") {
|
||||
if (filter !== "inbox") {
|
||||
groupName = filters[filters.length - 2];
|
||||
} else {
|
||||
groupName = filters.pop();
|
||||
|
@ -55,14 +58,21 @@ export default (viewName, channel) => {
|
|||
setupController() {
|
||||
this._super.apply(this, arguments);
|
||||
this.controllerFor("user-private-messages").set("group", this.group);
|
||||
this.controllerFor("user-topics-list").set("group", this.group);
|
||||
|
||||
if (channel) {
|
||||
if (filter) {
|
||||
this.controllerFor("user-topics-list").subscribe(
|
||||
`/private-messages/group/${this.get(
|
||||
"groupName"
|
||||
).toLowerCase()}/${channel}`
|
||||
).toLowerCase()}/${filter}`
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
dismissReadOptions() {
|
||||
return {
|
||||
group_name: this.get("groupName"),
|
||||
};
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -2,41 +2,49 @@ import I18n from "I18n";
|
|||
import UserAction from "discourse/models/user-action";
|
||||
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
||||
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export const NEW_FILTER = "new";
|
||||
export const UNREAD_FILTER = "unread";
|
||||
|
||||
// A helper to build a user topic list route
|
||||
export default (viewName, path, channel) => {
|
||||
export default (inboxType, path, filter) => {
|
||||
return UserTopicListRoute.extend({
|
||||
userActionType: UserAction.TYPES.messages_received,
|
||||
|
||||
titleToken() {
|
||||
const key = viewName === "index" ? "inbox" : viewName;
|
||||
return [I18n.t(`user.messages.${key}`), I18n.t("user.private_messages")];
|
||||
return [
|
||||
I18n.t(`user.messages.${filter}`),
|
||||
I18n.t("user.private_messages"),
|
||||
];
|
||||
},
|
||||
|
||||
actions: {
|
||||
didTransition() {
|
||||
this.controllerFor("user-topics-list")._showFooter();
|
||||
return true;
|
||||
},
|
||||
@action
|
||||
didTransition() {
|
||||
this.controllerFor("user-topics-list")._showFooter();
|
||||
return true;
|
||||
},
|
||||
|
||||
model() {
|
||||
const filter =
|
||||
const topicListFilter =
|
||||
"topics/" + path + "/" + this.modelFor("user").get("username_lower");
|
||||
|
||||
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
|
||||
const lastTopicList = findOrResetCachedTopicList(
|
||||
this.session,
|
||||
topicListFilter
|
||||
);
|
||||
|
||||
return lastTopicList
|
||||
? lastTopicList
|
||||
: this.store.findFiltered("topicList", { filter });
|
||||
: this.store.findFiltered("topicList", { filter: topicListFilter });
|
||||
},
|
||||
|
||||
setupController() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
if (channel) {
|
||||
if (filter) {
|
||||
this.controllerFor("user-topics-list").subscribe(
|
||||
`/private-messages/${channel}`
|
||||
`/private-messages/${filter}`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -46,11 +54,14 @@ export default (viewName, path, channel) => {
|
|||
tagsForUser: this.modelFor("user").get("username_lower"),
|
||||
selected: [],
|
||||
showToggleBulkSelect: true,
|
||||
filter: filter,
|
||||
group: null,
|
||||
inbox: inboxType,
|
||||
});
|
||||
|
||||
this.controllerFor("user-private-messages").setProperties({
|
||||
archive: false,
|
||||
pmView: viewName,
|
||||
pmView: inboxType,
|
||||
group: null,
|
||||
});
|
||||
|
||||
|
@ -65,5 +76,20 @@ export default (viewName, path, channel) => {
|
|||
this.controllerFor("user").get("model.searchContext")
|
||||
);
|
||||
},
|
||||
|
||||
dismissReadOptions() {
|
||||
return {};
|
||||
},
|
||||
|
||||
@action
|
||||
dismissReadTopics(dismissTopics) {
|
||||
const operationType = dismissTopics ? "topics" : "posts";
|
||||
const controller = this.controllerFor("user-topics-list");
|
||||
|
||||
controller.send("dismissRead", operationType, {
|
||||
private_message_inbox: inboxType,
|
||||
...this.dismissReadOptions(),
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
|
||||
export default createPMRoute("archive", "archive");
|
||||
export default createPMRoute("group", "archive");
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
import { NEW_FILTER } from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("new", null /* no message bus notifications */);
|
||||
export default createPMRoute("group", NEW_FILTER);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
import { UNREAD_FILTER } from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("unread", null /* no message bus notifications */);
|
||||
export default createPMRoute("group", UNREAD_FILTER);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
|
||||
export default createPMRoute("index", "inbox");
|
||||
export default createPMRoute("group", "inbox");
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("index", "private-messages-all", "inbox");
|
||||
export default createPMRoute("all", "private-messages-all", "inbox");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import {
|
||||
NEW_FILTER,
|
||||
default as createPMRoute,
|
||||
} from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"new",
|
||||
"private-messages-all-new",
|
||||
null /* no message bus notifications */
|
||||
);
|
||||
export default createPMRoute("all", "private-messages-all-new", NEW_FILTER);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("personal", "private-messages-archive", "archive");
|
||||
export default createPMRoute("user", "private-messages-archive", "archive");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import {
|
||||
NEW_FILTER,
|
||||
default as createPMRoute,
|
||||
} from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"personal",
|
||||
"private-messages-new",
|
||||
null /* no message bus notifications */
|
||||
);
|
||||
export default createPMRoute("user", "private-messages-new", NEW_FILTER);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("personal", "private-messages-sent", "sent");
|
||||
export default createPMRoute("user", "private-messages-sent", "sent");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import {
|
||||
UNREAD_FILTER,
|
||||
default as createPMRoute,
|
||||
} from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"personal",
|
||||
"private-messages-unread",
|
||||
null /* no message bus notifications */
|
||||
);
|
||||
export default createPMRoute("user", "private-messages-unread", UNREAD_FILTER);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("personal", "private-messages", "inbox");
|
||||
export default createPMRoute("user", "private-messages", "inbox");
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"sent",
|
||||
"private-messages-all-sent",
|
||||
null /* no message bus notifications */
|
||||
);
|
||||
export default createPMRoute("all", "private-messages-all-sent", "sent");
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import {
|
||||
UNREAD_FILTER,
|
||||
default as createPMRoute,
|
||||
} from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"unread",
|
||||
"all",
|
||||
"private-messages-all-unread",
|
||||
null /* no message bus notifications */
|
||||
UNREAD_FILTER
|
||||
);
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
{{#conditional-loading-spinner condition=loading}}
|
||||
{{#if hasIncoming}}
|
||||
<div class="show-mores">
|
||||
<a tabindex="0" href {{action showInserted}} class="alert alert-info clickable">
|
||||
{{count-i18n key="topic_count_" suffix="latest" count=incomingCount}}
|
||||
</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if topics}}
|
||||
{{topic-list
|
||||
showPosters=showPosters
|
||||
|
|
|
@ -5,14 +5,27 @@
|
|||
{{/unless}}
|
||||
|
||||
{{#load-more class="paginated-topics-list" selector=".paginated-topics-list .topic-list tr" action=(action "loadMore")}}
|
||||
{{topic-dismiss-buttons
|
||||
position="top"
|
||||
selectedTopics=selected
|
||||
model=model
|
||||
showResetNew=showResetNew
|
||||
showDismissRead=showDismissRead
|
||||
resetNew=(action "resetNew")}}
|
||||
|
||||
{{#if hasIncoming}}
|
||||
<div class="show-mores">
|
||||
<a tabindex="0" href {{action "showInserted"}} class="alert alert-info clickable">
|
||||
{{count-i18n key="topic_count_" suffix="latest" count=incomingCount}}
|
||||
</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{basic-topic-list topicList=model
|
||||
hideCategory=hideCategory
|
||||
showPosters=showPosters
|
||||
bulkSelectEnabled=bulkSelectEnabled
|
||||
selected=selected
|
||||
hasIncoming=hasIncoming
|
||||
incomingCount=incomingCount
|
||||
showInserted=(action "showInserted")
|
||||
tagsForUser=tagsForUser
|
||||
onScroll=saveScrollPosition
|
||||
canBulkSelect=canBulkSelect
|
||||
|
@ -20,5 +33,13 @@
|
|||
toggleBulkSelect=(action "toggleBulkSelect")
|
||||
updateAutoAddTopicsToBulkSelect=(action "updateAutoAddTopicsToBulkSelect")}}
|
||||
|
||||
{{topic-dismiss-buttons
|
||||
position="bottom"
|
||||
selectedTopics=selected
|
||||
model=model
|
||||
showResetNew=showResetNew
|
||||
showDismissRead=showDismissRead
|
||||
resetNew=(action "resetNew")}}
|
||||
|
||||
{{conditional-loading-spinner condition=model.loadingMore}}
|
||||
{{/load-more}}
|
||||
|
|
|
@ -40,12 +40,22 @@ acceptance(
|
|||
acceptance(
|
||||
"User Private Messages - user with group messages",
|
||||
function (needs) {
|
||||
let fetchedNew;
|
||||
let fetchUserNew;
|
||||
let fetchedGroupNew;
|
||||
|
||||
needs.user();
|
||||
|
||||
needs.site({
|
||||
can_tag_pms: true,
|
||||
});
|
||||
|
||||
needs.hooks.afterEach(() => {
|
||||
fetchedNew = false;
|
||||
fetchedGroupNew = false;
|
||||
fetchUserNew = false;
|
||||
});
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/topics/private-messages-all/:username.json", () => {
|
||||
return helper.response({
|
||||
|
@ -59,6 +69,35 @@ acceptance(
|
|||
});
|
||||
});
|
||||
|
||||
[
|
||||
"/topics/private-messages-all-new/:username.json",
|
||||
"/topics/private-messages-all-unread/:username.json",
|
||||
"/topics/private-messages-new/:username.json",
|
||||
"/topics/private-messages-unread/:username.json",
|
||||
"/topics/private-messages-group/:username/:group_name/new.json",
|
||||
"/topics/private-messages-group/:username/:group_name/unread.json",
|
||||
].forEach((url) => {
|
||||
server.get(url, () => {
|
||||
let topics;
|
||||
|
||||
if (fetchedNew || fetchedGroupNew || fetchUserNew) {
|
||||
topics = [];
|
||||
} else {
|
||||
topics = [
|
||||
{ id: 1, posters: [] },
|
||||
{ id: 2, posters: [] },
|
||||
{ id: 3, posters: [] },
|
||||
];
|
||||
}
|
||||
|
||||
return helper.response({
|
||||
topic_list: {
|
||||
topics: topics,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
server.get(
|
||||
"/topics/private-messages-group/:username/:group_name.json",
|
||||
() => {
|
||||
|
@ -72,6 +111,157 @@ acceptance(
|
|||
});
|
||||
}
|
||||
);
|
||||
|
||||
server.put("/topics/pm-reset-new", (request) => {
|
||||
const requestBody = request.requestBody;
|
||||
// No easy way to do this https://github.com/pretenderjs/pretender/issues/159
|
||||
if (requestBody === "inbox=group&group_name=awesome_group") {
|
||||
fetchedGroupNew = true;
|
||||
}
|
||||
|
||||
if (requestBody === "inbox=user") {
|
||||
fetchUserNew = true;
|
||||
}
|
||||
|
||||
if (requestBody === "inbox=all") {
|
||||
fetchedNew = true;
|
||||
}
|
||||
|
||||
return helper.response({});
|
||||
});
|
||||
|
||||
server.put("/topics/bulk", (request) => {
|
||||
const requestBody = request.requestBody;
|
||||
|
||||
if (requestBody.includes("private_message_inbox=all")) {
|
||||
fetchedNew = true;
|
||||
}
|
||||
|
||||
if (
|
||||
requestBody.includes(
|
||||
"private_message_inbox=group&group_name=awesome_group"
|
||||
)
|
||||
) {
|
||||
fetchedGroupNew = true;
|
||||
}
|
||||
|
||||
if (requestBody.includes("private_message_inbox=user")) {
|
||||
fetchUserNew = true;
|
||||
}
|
||||
|
||||
return helper.response({});
|
||||
});
|
||||
});
|
||||
|
||||
test("dismissing all unread messages", async function (assert) {
|
||||
await visit("/u/charlie/messages/unread");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
await click(".btn.dismiss-read");
|
||||
await click("#dismiss-read-confirm");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
0,
|
||||
"displays the right topic list"
|
||||
);
|
||||
});
|
||||
|
||||
test("dismissing personal unread messages", async function (assert) {
|
||||
await visit("/u/charlie/messages/personal/unread");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
await click(".btn.dismiss-read");
|
||||
await click("#dismiss-read-confirm");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
0,
|
||||
"displays the right topic list"
|
||||
);
|
||||
});
|
||||
|
||||
test("dismissing group unread messages", async function (assert) {
|
||||
await visit("/u/charlie/messages/group/awesome_group/unread");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
await click(".btn.dismiss-read");
|
||||
await click("#dismiss-read-confirm");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
0,
|
||||
"displays the right topic list"
|
||||
);
|
||||
});
|
||||
|
||||
test("dismissing all new messages", async function (assert) {
|
||||
await visit("/u/charlie/messages/new");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
await click(".btn.dismiss-read");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
0,
|
||||
"displays the right topic list"
|
||||
);
|
||||
});
|
||||
|
||||
test("dismissing personal new messages", async function (assert) {
|
||||
await visit("/u/charlie/messages/personal/new");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
await click(".btn.dismiss-read");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
0,
|
||||
"displays the right topic list"
|
||||
);
|
||||
});
|
||||
|
||||
test("dismissing new group messages", async function (assert) {
|
||||
await visit("/u/charlie/messages/group/awesome_group/new");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
await click(".btn.dismiss-read");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
0,
|
||||
"displays the right topic list"
|
||||
);
|
||||
});
|
||||
|
||||
test("viewing messages", async function (assert) {
|
||||
|
|
|
@ -925,26 +925,7 @@ class TopicsController < ApplicationController
|
|||
end
|
||||
topic_ids = params[:topic_ids].map { |t| t.to_i }
|
||||
elsif params[:filter] == 'unread'
|
||||
tq = TopicQuery.new(current_user)
|
||||
topics = TopicQuery.unread_filter(tq.joined_topic_user, staff: guardian.is_staff?).listable_topics
|
||||
topics = TopicQuery.tracked_filter(topics, current_user.id) if params[:tracked].to_s == "true"
|
||||
|
||||
if params[:category_id]
|
||||
if params[:include_subcategories]
|
||||
topics = topics.where(<<~SQL, category_id: params[:category_id])
|
||||
category_id in (select id FROM categories WHERE parent_category_id = :category_id) OR
|
||||
category_id = :category_id
|
||||
SQL
|
||||
else
|
||||
topics = topics.where('category_id = ?', params[:category_id])
|
||||
end
|
||||
end
|
||||
|
||||
if params[:tag_name].present?
|
||||
topics = topics.joins(:tags).where("tags.name": params[:tag_name])
|
||||
end
|
||||
|
||||
topic_ids = topics.pluck(:id)
|
||||
topic_ids = bulk_unread_topic_ids
|
||||
else
|
||||
raise ActionController::ParameterMissing.new(:topic_ids)
|
||||
end
|
||||
|
@ -960,6 +941,35 @@ class TopicsController < ApplicationController
|
|||
render_json_dump topic_ids: changed_topic_ids
|
||||
end
|
||||
|
||||
def private_message_reset_new
|
||||
topic_query = TopicQuery.new(current_user)
|
||||
|
||||
if params[:topic_ids].present?
|
||||
unless Array === params[:topic_ids]
|
||||
raise Discourse::InvalidParameters.new(
|
||||
"Expecting topic_ids to contain a list of topic ids"
|
||||
)
|
||||
end
|
||||
|
||||
topic_scope = topic_query
|
||||
.private_messages_for(current_user, :all)
|
||||
.where("topics.id IN (?)", params[:topic_ids].map(&:to_i))
|
||||
else
|
||||
params.require(:inbox)
|
||||
inbox = params[:inbox].to_s
|
||||
filter = private_message_filter(topic_query, inbox)
|
||||
topic_scope = topic_query.filter_private_message_new(current_user, filter)
|
||||
end
|
||||
|
||||
TopicsBulkAction.new(
|
||||
current_user,
|
||||
topic_scope.pluck(:id),
|
||||
type: "dismiss_topics"
|
||||
).perform!
|
||||
|
||||
render json: success_json
|
||||
end
|
||||
|
||||
def reset_new
|
||||
topic_scope =
|
||||
if params[:category_id].present?
|
||||
|
@ -993,7 +1003,7 @@ class TopicsController < ApplicationController
|
|||
topic_scope = topic_scope.where(id: topic_ids)
|
||||
end
|
||||
|
||||
dismissed_topic_ids = TopicsBulkAction.new(current_user, [topic_scope.pluck(:id)], type: "dismiss_topics").perform!
|
||||
dismissed_topic_ids = TopicsBulkAction.new(current_user, topic_scope.pluck(:id), type: "dismiss_topics").perform!
|
||||
TopicTrackingState.publish_dismiss_new(current_user.id, topic_ids: dismissed_topic_ids)
|
||||
|
||||
render body: nil
|
||||
|
@ -1217,4 +1227,49 @@ class TopicsController < ApplicationController
|
|||
def pm_has_slots?(pm)
|
||||
guardian.is_staff? || !pm.reached_recipients_limit?
|
||||
end
|
||||
|
||||
def bulk_unread_topic_ids
|
||||
topic_query = TopicQuery.new(current_user)
|
||||
|
||||
if inbox = params[:private_message_inbox]
|
||||
filter = private_message_filter(topic_query, inbox)
|
||||
topics = topic_query.filter_private_messages_unread(current_user, filter)
|
||||
else
|
||||
topics = TopicQuery.unread_filter(topic_query.joined_topic_user, staff: guardian.is_staff?).listable_topics
|
||||
topics = TopicQuery.tracked_filter(topics, current_user.id) if params[:tracked].to_s == "true"
|
||||
|
||||
if params[:category_id]
|
||||
if params[:include_subcategories]
|
||||
topics = topics.where(<<~SQL, category_id: params[:category_id])
|
||||
category_id in (select id FROM categories WHERE parent_category_id = :category_id) OR
|
||||
category_id = :category_id
|
||||
SQL
|
||||
else
|
||||
topics = topics.where('category_id = ?', params[:category_id])
|
||||
end
|
||||
end
|
||||
|
||||
if params[:tag_name].present?
|
||||
topics = topics.joins(:tags).where("tags.name": params[:tag_name])
|
||||
end
|
||||
end
|
||||
|
||||
topics.pluck(:id)
|
||||
end
|
||||
|
||||
def private_message_filter(topic_query, inbox)
|
||||
case inbox
|
||||
when "group"
|
||||
group_name = params[:group_name]
|
||||
group = Group.find_by("lower(name) = ?", group_name)
|
||||
raise Discourse::NotFound if !group
|
||||
raise Discourse::NotFound if !guardian.can_see_group_messages?(group)
|
||||
topic_query.options[:group_name] = group_name
|
||||
:group
|
||||
when "user"
|
||||
:user
|
||||
else
|
||||
:all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -758,6 +758,7 @@ Discourse::Application.routes.draw do
|
|||
put "t/:id/reset-bump-date" => "topics#reset_bump_date"
|
||||
put "topics/bulk"
|
||||
put "topics/reset-new" => 'topics#reset_new'
|
||||
put "topics/pm-reset-new" => 'topics#private_message_reset_new'
|
||||
post "topics/timings"
|
||||
|
||||
get 'topics/similar_to' => 'similar_topics#index'
|
||||
|
|
|
@ -806,7 +806,6 @@ class TopicQuery
|
|||
list = list
|
||||
.references("cu")
|
||||
.joins("LEFT JOIN category_users ON category_users.category_id = topics.category_id AND category_users.user_id = #{user.id}")
|
||||
.joins("LEFT JOIN dismissed_topic_users ON dismissed_topic_users.topic_id = topics.id AND dismissed_topic_users.user_id = #{user.id}")
|
||||
.where("topics.category_id = :category_id
|
||||
OR COALESCE(category_users.notification_level, :default) <> :muted
|
||||
OR tu.notification_level > :regular",
|
||||
|
@ -877,10 +876,16 @@ class TopicQuery
|
|||
|
||||
def remove_dismissed(list, user)
|
||||
if user
|
||||
list = list.where("dismissed_topic_users.id IS NULL")
|
||||
list
|
||||
.joins(<<~SQL)
|
||||
LEFT JOIN dismissed_topic_users
|
||||
ON dismissed_topic_users.topic_id = topics.id
|
||||
AND dismissed_topic_users.user_id = #{user.id.to_i}
|
||||
SQL
|
||||
.where("dismissed_topic_users.id IS NULL")
|
||||
else
|
||||
list
|
||||
end
|
||||
|
||||
list
|
||||
end
|
||||
|
||||
def new_messages(params)
|
||||
|
|
|
@ -63,30 +63,15 @@ class TopicQuery
|
|||
end
|
||||
|
||||
def list_private_messages_new(user, type = :user)
|
||||
list = TopicQuery.new_filter(
|
||||
private_messages_for(user, type),
|
||||
treat_as_new_topic_start_date: user.user_option.treat_as_new_topic_start_date
|
||||
)
|
||||
|
||||
list = filter_private_message_new(user, type)
|
||||
list = remove_muted_tags(list, user)
|
||||
list = remove_dismissed(list, user)
|
||||
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_unread(user, type = :user)
|
||||
list = TopicQuery.unread_filter(
|
||||
private_messages_for(user, type),
|
||||
staff: user.staff?
|
||||
)
|
||||
|
||||
first_unread_pm_at = UserStat
|
||||
.where(user_id: user.id)
|
||||
.pluck_first(:first_unread_pm_at)
|
||||
|
||||
if first_unread_pm_at
|
||||
list = list.where("topics.updated_at >= ?", first_unread_pm_at)
|
||||
end
|
||||
|
||||
list = filter_private_messages_unread(user, type)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
|
@ -118,30 +103,14 @@ class TopicQuery
|
|||
end
|
||||
|
||||
def list_private_messages_group_new(user)
|
||||
list = TopicQuery.new_filter(
|
||||
private_messages_for(user, :group),
|
||||
treat_as_new_topic_start_date: user.user_option.treat_as_new_topic_start_date
|
||||
)
|
||||
|
||||
list = filter_private_message_new(user, :group)
|
||||
publish_read_state = !!group.publish_read_state
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group_unread(user)
|
||||
list = TopicQuery.unread_filter(
|
||||
private_messages_for(user, :group),
|
||||
staff: user.staff?
|
||||
)
|
||||
|
||||
first_unread_pm_at = UserStat
|
||||
.where(user_id: user.id)
|
||||
.pluck_first(:first_unread_pm_at)
|
||||
|
||||
if first_unread_pm_at
|
||||
list = list.where("topics.updated_at >= ?", first_unread_pm_at)
|
||||
end
|
||||
|
||||
list = filter_private_messages_unread(user, :group)
|
||||
publish_read_state = !!group.publish_read_state
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
|
@ -206,6 +175,30 @@ class TopicQuery
|
|||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def filter_private_messages_unread(user, type)
|
||||
list = TopicQuery.unread_filter(
|
||||
private_messages_for(user, type),
|
||||
staff: user.staff?
|
||||
)
|
||||
|
||||
first_unread_pm_at = UserStat
|
||||
.where(user_id: user.id)
|
||||
.pluck_first(:first_unread_pm_at)
|
||||
|
||||
if first_unread_pm_at
|
||||
list = list.where("topics.updated_at >= ?", first_unread_pm_at)
|
||||
end
|
||||
|
||||
list
|
||||
end
|
||||
|
||||
def filter_private_message_new(user, type)
|
||||
TopicQuery.new_filter(
|
||||
private_messages_for(user, type),
|
||||
treat_as_new_topic_start_date: user.user_option.treat_as_new_topic_start_date
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def append_read_state(list, group)
|
||||
|
|
|
@ -86,7 +86,6 @@ class TopicsBulkAction
|
|||
.joins("LEFT JOIN topic_users ON topic_users.topic_id = topics.id AND topic_users.user_id = #{@user.id}")
|
||||
.where("topics.created_at >= ?", dismiss_topics_since_date)
|
||||
.where("topic_users.last_read_post_number IS NULL")
|
||||
.where("topics.archetype <> ?", Archetype.private_message)
|
||||
.order("topics.created_at DESC")
|
||||
.limit(SiteSetting.max_new_topics).map do |topic|
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rails_helper'
|
|||
describe TopicsBulkAction do
|
||||
fab!(:topic) { Fabricate(:topic) }
|
||||
|
||||
describe type: "dismiss_topics" do
|
||||
describe "#dismiss_topics" do
|
||||
fab!(:user) { Fabricate(:user, created_at: 1.days.ago) }
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
fab!(:topic2) { Fabricate(:topic, category: category, created_at: 60.minutes.ago) }
|
||||
|
@ -15,6 +15,14 @@ describe TopicsBulkAction do
|
|||
topic.destroy!
|
||||
end
|
||||
|
||||
it 'dismisses private messages' do
|
||||
pm = Fabricate(:private_message_topic)
|
||||
|
||||
TopicsBulkAction.new(user, [pm.id], type: "dismiss_topics").perform!
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: pm)).to eq(true)
|
||||
end
|
||||
|
||||
it 'dismisses two topics' do
|
||||
expect { TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform! }.to change { DismissedTopicUser.count }.by(2)
|
||||
end
|
||||
|
|
|
@ -282,9 +282,17 @@ describe TopicQuery::PrivateMessageLists do
|
|||
).topic
|
||||
end
|
||||
|
||||
fab!(:pm_2) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
it 'returns a list of new private messages' do
|
||||
expect(TopicQuery.new(user_2).list_private_messages_new(user_2).topics)
|
||||
.to contain_exactly(pm)
|
||||
.to contain_exactly(pm, pm_2)
|
||||
end
|
||||
|
||||
it 'returns a list of new private messages accounting for muted tags' do
|
||||
|
@ -299,7 +307,14 @@ describe TopicQuery::PrivateMessageLists do
|
|||
)
|
||||
|
||||
expect(TopicQuery.new(user_2).list_private_messages_new(user_2).topics)
|
||||
.to eq([])
|
||||
.to contain_exactly(pm_2)
|
||||
end
|
||||
|
||||
it 'returns a list of new private messages accounting for dismissed topics' do
|
||||
Fabricate(:dismissed_topic_user, topic: pm, user: user_2)
|
||||
|
||||
expect(TopicQuery.new(user_2).list_private_messages_new(user_2).topics)
|
||||
.to contain_exactly(pm_2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2838,6 +2838,116 @@ RSpec.describe TopicsController do
|
|||
expect(TopicUser.get(post1.topic, post1.user).last_read_post_number).to eq(2)
|
||||
end
|
||||
|
||||
context "private message" do
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
|
||||
fab!(:group) do
|
||||
Fabricate(:group, messageable_level: Group::ALIAS_LEVELS[:everyone]).tap do |g|
|
||||
g.add(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
fab!(:group_message) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_group_names: [group.name],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
fab!(:private_message) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
fab!(:group_pm_topic_user) do
|
||||
TopicUser.find_by(user: user_2, topic: group_message).tap do |tu|
|
||||
tu.update!(last_read_post_number: 1)
|
||||
end
|
||||
end
|
||||
|
||||
fab!(:regular_pm_topic_user) do
|
||||
TopicUser.find_by(user: user_2, topic: private_message).tap do |tu|
|
||||
tu.update!(last_read_post_number: 1)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
create_post(user: user, topic: group_message)
|
||||
create_post(user: user, topic: private_message)
|
||||
sign_in(user_2)
|
||||
end
|
||||
|
||||
it "can dismiss all user and group private message topics" do
|
||||
expect do
|
||||
put "/topics/bulk.json", params: {
|
||||
filter: "unread",
|
||||
operation: { type: 'dismiss_posts' },
|
||||
private_message_inbox: "all"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end.to change { group_pm_topic_user.reload.last_read_post_number }.from(1).to(2)
|
||||
.and change { regular_pm_topic_user.reload.last_read_post_number }.from(1).to(2)
|
||||
end
|
||||
|
||||
it "can dismiss all user unread private message topics" do
|
||||
expect do
|
||||
put "/topics/bulk.json", params: {
|
||||
filter: "unread",
|
||||
operation: { type: 'dismiss_posts' },
|
||||
private_message_inbox: "user"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end.to change { regular_pm_topic_user.reload.last_read_post_number }.from(1).to(2)
|
||||
|
||||
expect(group_pm_topic_user.reload.last_read_post_number).to eq(1)
|
||||
end
|
||||
|
||||
it "returns the right response when trying to dismiss private messages of an invalid group" do
|
||||
put "/topics/bulk.json", params: {
|
||||
filter: "unread",
|
||||
operation: { type: 'dismiss_posts' },
|
||||
private_message_inbox: "group",
|
||||
group_name: 'randomgroup'
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "returns the right response when trying to dismiss private messages of a restricted group" do
|
||||
sign_in(user)
|
||||
|
||||
put "/topics/bulk.json", params: {
|
||||
filter: "unread",
|
||||
operation: { type: 'dismiss_posts' },
|
||||
private_message_inbox: "group",
|
||||
group_name: group.name
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "can dismiss all group unread private message topics" do
|
||||
expect do
|
||||
put "/topics/bulk.json", params: {
|
||||
filter: "unread",
|
||||
operation: { type: 'dismiss_posts' },
|
||||
private_message_inbox: "group",
|
||||
group_name: group.name
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end.to change { group_pm_topic_user.reload.last_read_post_number }.from(1).to(2)
|
||||
|
||||
expect(regular_pm_topic_user.reload.last_read_post_number).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
it "can find unread" do
|
||||
# mark all unread muted
|
||||
put "/topics/bulk.json", params: {
|
||||
|
@ -4081,4 +4191,133 @@ RSpec.describe TopicsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#private_message_reset_new' do
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
|
||||
fab!(:group) do
|
||||
Fabricate(:group, messageable_level: Group::ALIAS_LEVELS[:everyone]).tap do |g|
|
||||
g.add(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
fab!(:group_message) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_group_names: [group.name],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
fab!(:private_message) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
before do
|
||||
sign_in(user_2)
|
||||
end
|
||||
|
||||
it 'returns the right response when inbox param is missing' do
|
||||
put "/topics/pm-reset-new.json"
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
it "returns the right response when trying to reset new private messages of an invalid group" do
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
inbox: "group",
|
||||
group_name: "randomgroup"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "returns the right response when trying to reset new private messages of a restricted group" do
|
||||
sign_in(user)
|
||||
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
inbox: "group",
|
||||
group_name: group.name
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "can reset all new group private messages" do
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
inbox: "group",
|
||||
group_name: group.name
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(DismissedTopicUser.count).to eq(1)
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: group_message, user: user_2))
|
||||
.to eq(true)
|
||||
end
|
||||
|
||||
it "can reset new personal private messages" do
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
inbox: "user",
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(DismissedTopicUser.count).to eq(1)
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: private_message, user: user_2))
|
||||
.to eq(true)
|
||||
end
|
||||
|
||||
it 'can reset new personal and group private messages' do
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
inbox: "all",
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(DismissedTopicUser.count).to eq(2)
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: private_message, user: user_2))
|
||||
.to eq(true)
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: group_message, user: user_2))
|
||||
.to eq(true)
|
||||
end
|
||||
|
||||
it 'returns the right response is topic_ids params is not valid' do
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
topic_ids: '1'
|
||||
}
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
it 'can reset new private messages from given topic ids' do
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
topic_ids: [group_message.id, '12345']
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(DismissedTopicUser.count).to eq(1)
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: group_message, user: user_2))
|
||||
.to eq(true)
|
||||
|
||||
put "/topics/pm-reset-new.json", params: {
|
||||
topic_ids: [private_message.id, '12345']
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(DismissedTopicUser.exists?(topic: private_message, user: user_2))
|
||||
.to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user