This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/tests/unit/controllers/topic-test.js
Josh Soref 59097b207f
DEV: Correct typos and spelling mistakes (#12812)
Over the years we accrued many spelling mistakes in the code base. 

This PR attempts to fix spelling mistakes and typos in all areas of the code that are extremely safe to change 

- comments
- test descriptions
- other low risk areas
2021-05-21 11:43:47 +10:00

578 lines
16 KiB
JavaScript

import EmberObject from "@ember/object";
import { Placeholder } from "discourse/lib/posts-with-placeholders";
import { Promise } from "rsvp";
import Topic from "discourse/models/topic";
import User from "discourse/models/user";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { next } from "@ember/runloop";
import pretender from "discourse/tests/helpers/create-pretender";
import { settled } from "@ember/test-helpers";
import { test } from "qunit";
function topicWithStream(streamDetails) {
let topic = Topic.create();
topic.get("postStream").setProperties(streamDetails);
return topic;
}
discourseModule("Unit | Controller | topic", function (hooks) {
hooks.beforeEach(function () {
this.registry.register("service:screen-track", {}, { instantiate: false });
this.registry.injection("controller", "appEvents", "service:app-events");
});
hooks.afterEach(function () {
this.registry.unregister("service:screen-track");
this.registry.unregister("current-user:main");
let topic = this.container.lookup("controller:topic");
topic.setProperties({
selectedPostIds: [],
selectedPostUsername: null,
currentUser: null,
});
});
test("editTopic", function (assert) {
const model = Topic.create();
const controller = this.getController("topic", { model });
assert.not(controller.get("editingTopic"), "we are not editing by default");
controller.set("model.details.can_edit", false);
controller.send("editTopic");
assert.not(
controller.get("editingTopic"),
"calling editTopic doesn't enable editing unless the user can edit"
);
controller.set("model.details.can_edit", true);
controller.send("editTopic");
assert.ok(
controller.get("editingTopic"),
"calling editTopic enables editing if the user can edit"
);
assert.equal(controller.get("buffered.title"), model.get("title"));
assert.equal(
controller.get("buffered.category_id"),
model.get("category_id")
);
controller.send("cancelEditingTopic");
assert.not(
controller.get("editingTopic"),
"cancelling edit mode reverts the property value"
);
});
test("deleteTopic", function (assert) {
const model = Topic.create();
let destroyed = false;
let modalDisplayed = false;
model.destroy = () => {
destroyed = true;
return Promise.resolve();
};
const controller = this.getController("topic", {
model,
siteSettings: {
min_topic_views_for_delete_confirm: 5,
},
deleteTopicModal: () => {
modalDisplayed = true;
},
});
model.set("views", 10000);
controller.send("deleteTopic");
assert.not(destroyed, "don't destroy popular topic");
assert.ok(modalDisplayed, "display confirmation modal for popular topic");
model.set("views", 3);
controller.send("deleteTopic");
assert.ok(destroyed, "destroy not popular topic");
});
test("toggleMultiSelect", async function (assert) {
const model = Topic.create();
const controller = this.getController("topic", { model });
assert.not(
controller.get("multiSelect"),
"multi selection mode is disabled by default"
);
controller.get("selectedPostIds").pushObject(1);
assert.equal(controller.get("selectedPostIds.length"), 1);
controller.send("toggleMultiSelect");
await settled();
assert.ok(
controller.get("multiSelect"),
"calling 'toggleMultiSelect' once enables multi selection mode"
);
assert.equal(
controller.get("selectedPostIds.length"),
0,
"toggling 'multiSelect' clears 'selectedPostIds'"
);
controller.get("selectedPostIds").pushObject(2);
assert.equal(controller.get("selectedPostIds.length"), 1);
controller.send("toggleMultiSelect");
await settled();
assert.not(
controller.get("multiSelect"),
"calling 'toggleMultiSelect' twice disables multi selection mode"
);
assert.equal(
controller.get("selectedPostIds.length"),
0,
"toggling 'multiSelect' clears 'selectedPostIds'"
);
});
test("selectedPosts", function (assert) {
let model = topicWithStream({ posts: [{ id: 1 }, { id: 2 }, { id: 3 }] });
const controller = this.getController("topic", { model });
controller.set("selectedPostIds", [1, 2, 42]);
assert.equal(
controller.get("selectedPosts.length"),
2,
"selectedPosts only contains already loaded posts"
);
assert.not(
controller.get("selectedPosts").some((p) => p === undefined),
"selectedPosts only contains valid post objects"
);
});
test("selectedAllPosts", function (assert) {
let model = topicWithStream({ stream: [1, 2, 3] });
const controller = this.getController("topic", { model });
controller.set("selectedPostIds", [1, 2]);
assert.not(
controller.get("selectedAllPosts"),
"not all posts are selected"
);
controller.get("selectedPostIds").pushObject(3);
assert.ok(controller.get("selectedAllPosts"), "all posts are selected");
controller.get("selectedPostIds").pushObject(42);
assert.ok(
controller.get("selectedAllPosts"),
"all posts (including filtered posts) are selected"
);
model.setProperties({
"postStream.isMegaTopic": true,
posts_count: 1,
});
assert.ok(
controller.get("selectedAllPosts"),
"it uses the topic's post count for megatopics"
);
});
test("selectedPostsUsername", function (assert) {
let model = topicWithStream({
posts: [
{ id: 1, username: "gary" },
{ id: 2, username: "gary" },
{ id: 3, username: "lili" },
],
stream: [1, 2, 3],
});
const controller = this.getController("topic", { model });
const selectedPostIds = controller.get("selectedPostIds");
assert.equal(
controller.get("selectedPostsUsername"),
undefined,
"no username when no selected posts"
);
selectedPostIds.pushObject(1);
assert.equal(
controller.get("selectedPostsUsername"),
"gary",
"username of the selected posts"
);
selectedPostIds.pushObject(2);
assert.equal(
controller.get("selectedPostsUsername"),
"gary",
"username of all the selected posts when same user"
);
selectedPostIds.pushObject(3);
assert.equal(
controller.get("selectedPostsUsername"),
undefined,
"no username when more than 1 user"
);
selectedPostIds.replace(2, 1, [42]);
assert.equal(
controller.get("selectedPostsUsername"),
undefined,
"no username when not already loaded posts are selected"
);
});
test("showSelectedPostsAtBottom", function (assert) {
const site = EmberObject.create({ mobileView: false });
const model = Topic.create({ posts_count: 3 });
const controller = this.getController("topic", { model, site });
assert.not(controller.get("showSelectedPostsAtBottom"), "false on desktop");
site.set("mobileView", true);
assert.not(
controller.get("showSelectedPostsAtBottom"),
"requires at least 3 posts on mobile"
);
model.set("posts_count", 4);
assert.ok(
controller.get("showSelectedPostsAtBottom"),
"true when mobile and more than 3 posts"
);
});
test("canDeleteSelected", function (assert) {
const currentUser = User.create({ admin: false });
this.registry.register("current-user:main", currentUser, {
instantiate: false,
});
this.registry.injection("controller", "currentUser", "current-user:main");
let model = topicWithStream({
posts: [
{ id: 1, can_delete: false },
{ id: 2, can_delete: true },
{ id: 3, can_delete: true },
],
stream: [1, 2, 3],
});
const controller = this.getController("topic", {
model,
currentUser,
});
const selectedPostIds = controller.get("selectedPostIds");
assert.not(
controller.get("canDeleteSelected"),
"false when no posts are selected"
);
selectedPostIds.pushObject(1);
assert.not(
controller.get("canDeleteSelected"),
"false when can't delete one of the selected posts"
);
selectedPostIds.replace(0, 1, [2, 3]);
assert.ok(
controller.get("canDeleteSelected"),
"true when all selected posts can be deleted"
);
selectedPostIds.pushObject(1);
assert.not(
controller.get("canDeleteSelected"),
"false when all posts are selected and user is staff"
);
currentUser.set("admin", true);
assert.ok(
controller.get("canDeleteSelected"),
"true when all posts are selected and user is staff"
);
});
test("Can split/merge topic", function (assert) {
let model = topicWithStream({
posts: [
{ id: 1, post_number: 1, post_type: 1 },
{ id: 2, post_number: 2, post_type: 4 },
{ id: 3, post_number: 3, post_type: 1 },
],
stream: [1, 2, 3],
});
model.set("details.can_move_posts", false);
const controller = this.getController("topic", { model });
const selectedPostIds = controller.get("selectedPostIds");
assert.not(
controller.get("canMergeTopic"),
"can't merge topic when no posts are selected"
);
selectedPostIds.pushObject(1);
assert.not(
controller.get("canMergeTopic"),
"can't merge topic when can't move posts"
);
model.set("details.can_move_posts", true);
assert.ok(controller.get("canMergeTopic"), "can merge topic");
selectedPostIds.removeObject(1);
selectedPostIds.pushObject(2);
assert.ok(
controller.get("canMergeTopic"),
"can merge topic when 1st post is not a regular post"
);
selectedPostIds.pushObject(3);
assert.ok(
controller.get("canMergeTopic"),
"can merge topic when all posts are selected"
);
});
test("canChangeOwner", function (assert) {
const currentUser = User.create({ admin: false });
this.registry.register("current-user:main", currentUser, {
instantiate: false,
});
this.registry.injection("controller", "currentUser", "current-user:main");
let model = topicWithStream({
posts: [
{ id: 1, username: "gary" },
{ id: 2, username: "lili" },
],
stream: [1, 2],
});
model.set("currentUser", { admin: false });
const controller = this.getController("topic", {
model,
currentUser,
});
const selectedPostIds = controller.get("selectedPostIds");
assert.not(
controller.get("canChangeOwner"),
"false when no posts are selected"
);
selectedPostIds.pushObject(1);
assert.not(controller.get("canChangeOwner"), "false when not admin");
currentUser.set("admin", true);
assert.ok(
controller.get("canChangeOwner"),
"true when admin and one post is selected"
);
selectedPostIds.pushObject(2);
assert.not(
controller.get("canChangeOwner"),
"false when admin but more than 1 user"
);
});
test("canMergePosts", function (assert) {
let model = topicWithStream({
posts: [
{ id: 1, username: "gary", can_delete: true },
{ id: 2, username: "lili", can_delete: true },
{ id: 3, username: "gary", can_delete: false },
{ id: 4, username: "gary", can_delete: true },
],
stream: [1, 2, 3],
});
const controller = this.getController("topic", {
model,
});
const selectedPostIds = controller.get("selectedPostIds");
assert.not(
controller.get("canMergePosts"),
"false when no posts are selected"
);
selectedPostIds.pushObject(1);
assert.not(
controller.get("canMergePosts"),
"false when only one post is selected"
);
selectedPostIds.pushObject(2);
assert.not(
controller.get("canMergePosts"),
"false when selected posts are from different users"
);
selectedPostIds.replace(1, 1, [3]);
assert.not(
controller.get("canMergePosts"),
"false when selected posts can't be deleted"
);
selectedPostIds.replace(1, 1, [4]);
assert.ok(
controller.get("canMergePosts"),
"true when all selected posts are deletable and by the same user"
);
});
test("Select/deselect all", function (assert) {
let model = topicWithStream({ stream: [1, 2, 3] });
const controller = this.getController("topic", { model });
assert.equal(
controller.get("selectedPostsCount"),
0,
"no posts selected by default"
);
controller.send("selectAll");
assert.equal(
controller.get("selectedPostsCount"),
3,
"calling 'selectAll' selects all posts"
);
controller.send("deselectAll");
assert.equal(
controller.get("selectedPostsCount"),
0,
"calling 'deselectAll' deselects all posts"
);
});
test("togglePostSelection", function (assert) {
const controller = this.getController("topic");
const selectedPostIds = controller.get("selectedPostIds");
assert.equal(selectedPostIds[0], undefined, "no posts selected by default");
controller.send("togglePostSelection", { id: 1 });
assert.equal(
selectedPostIds[0],
1,
"adds the selected post id if not already selected"
);
controller.send("togglePostSelection", { id: 1 });
assert.equal(
selectedPostIds[0],
undefined,
"removes the selected post id if already selected"
);
});
test("selectBelow", function (assert) {
const site = EmberObject.create({
post_types: { small_action: 3, whisper: 4 },
});
let model = topicWithStream({
stream: [1, 2, 3, 4, 5, 6, 7, 8],
posts: [
{ id: 5, cooked: "whisper post", post_type: 4 },
{ id: 6, cooked: "a small action", post_type: 3 },
{ id: 7, cooked: "", post_type: 4 },
],
});
const controller = this.getController("topic", { site, model });
let selectedPostIds = controller.get("selectedPostIds");
assert.equal(selectedPostIds[0], undefined, "no posts selected by default");
controller.send("selectBelow", { id: 3 });
assert.equal(selectedPostIds[0], 3, "selected post #3");
assert.equal(selectedPostIds[1], 4, "also selected 1st post below post #3");
assert.equal(selectedPostIds[2], 5, "also selected 2nd post below post #3");
assert.equal(selectedPostIds[3], 8, "also selected 3rd post below post #3");
});
test("topVisibleChanged", function (assert) {
let model = topicWithStream({
posts: [{ id: 1 }],
});
const controller = this.getController("topic", { model });
const placeholder = new Placeholder("post-placeholder");
assert.equal(
controller.send("topVisibleChanged", {
post: placeholder,
}),
null,
"it should work with a post-placeholder"
);
});
test("deletePost - no modal is shown if post does not have replies", function (assert) {
pretender.get("/posts/2/reply-ids.json", () => {
return [200, { "Content-Type": "application/json" }, []];
});
let destroyed;
const post = EmberObject.create({
id: 2,
post_number: 2,
can_delete: true,
reply_count: 3,
destroy: () => {
destroyed = true;
return Promise.resolve();
},
});
const currentUser = EmberObject.create({ moderator: true });
let model = topicWithStream({
stream: [2, 3, 4],
posts: [post, { id: 3 }, { id: 4 }],
});
const controller = this.getController("topic", { model, currentUser });
const done = assert.async();
controller.send("deletePost", post);
next(() => {
assert.ok(destroyed, "post was destroyed");
done();
});
});
});