2020-08-01 03:43:15 +02:00
|
|
|
"use strict";
|
|
|
|
|
2020-11-30 23:46:45 +01:00
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
const {mock_esm, zrequire} = require("./lib/namespace");
|
|
|
|
const {run_test} = require("./lib/test");
|
2024-02-13 02:08:24 +01:00
|
|
|
const {current_user, realm} = require("./lib/zpage_params");
|
2020-12-01 00:02:16 +01:00
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_move_messages_within_stream_limit_seconds = 259200;
|
2016-12-29 23:50:24 +01:00
|
|
|
|
2021-02-10 04:53:22 +01:00
|
|
|
const message_edit = zrequire("message_edit");
|
2023-06-14 19:40:41 +02:00
|
|
|
const people = zrequire("people");
|
2016-12-29 23:50:24 +01:00
|
|
|
|
2022-12-12 15:37:14 +01:00
|
|
|
const is_content_editable = message_edit.is_content_editable;
|
2016-12-29 23:50:24 +01:00
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
const settings_data = mock_esm("../src/settings_data");
|
2021-05-26 21:20:11 +02:00
|
|
|
|
2022-12-12 15:37:14 +01:00
|
|
|
run_test("is_content_editable", () => {
|
2016-12-29 23:50:24 +01:00
|
|
|
// You can't edit a null message
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(null), false);
|
2016-12-29 23:50:24 +01:00
|
|
|
// You can't edit a message you didn't send
|
2020-07-15 00:34:28 +02:00
|
|
|
assert.equal(
|
2022-12-12 15:37:14 +01:00
|
|
|
is_content_editable({
|
2020-07-15 00:34:28 +02:00
|
|
|
sent_by_me: false,
|
|
|
|
}),
|
2022-12-12 15:37:14 +01:00
|
|
|
false,
|
2020-07-15 00:34:28 +02:00
|
|
|
);
|
2016-12-29 23:50:24 +01:00
|
|
|
|
2017-07-18 14:44:29 +02:00
|
|
|
// Failed request are currently not editable (though we want to
|
|
|
|
// change this back).
|
2020-07-15 00:34:28 +02:00
|
|
|
assert.equal(
|
2022-12-12 15:37:14 +01:00
|
|
|
is_content_editable({
|
2020-07-15 00:34:28 +02:00
|
|
|
sent_by_me: true,
|
|
|
|
failed_request: true,
|
|
|
|
}),
|
2022-12-12 15:37:14 +01:00
|
|
|
false,
|
2020-07-15 00:34:28 +02:00
|
|
|
);
|
2016-12-29 23:50:24 +01:00
|
|
|
|
|
|
|
// Locally echoed messages are not editable, since the message hasn't
|
|
|
|
// finished being sent yet.
|
2020-07-15 00:34:28 +02:00
|
|
|
assert.equal(
|
2022-12-12 15:37:14 +01:00
|
|
|
is_content_editable({
|
2020-07-15 00:34:28 +02:00
|
|
|
sent_by_me: true,
|
2022-08-02 19:00:11 +02:00
|
|
|
locally_echoed: true,
|
2020-07-15 00:34:28 +02:00
|
|
|
}),
|
2022-12-12 15:37:14 +01:00
|
|
|
false,
|
2020-07-15 00:34:28 +02:00
|
|
|
);
|
2016-12-29 23:50:24 +01:00
|
|
|
|
|
|
|
// For the rest of these tests, we only consider messages sent by the
|
|
|
|
// user, and that were successfully sent (i.e. no failed_request or local_id)
|
2022-12-12 15:37:14 +01:00
|
|
|
const message = {
|
2017-01-12 00:17:43 +01:00
|
|
|
sent_by_me: true,
|
2016-12-29 23:50:24 +01:00
|
|
|
};
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_allow_message_editing = false;
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message), false);
|
2016-12-29 23:50:24 +01:00
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_allow_message_editing = true;
|
2021-03-25 22:35:45 +01:00
|
|
|
// Limit of 0 means no time limit on editing messages
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_message_content_edit_limit_seconds = null;
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message), true);
|
2016-12-29 23:50:24 +01:00
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_message_content_edit_limit_seconds = 10;
|
2019-11-02 00:06:25 +01:00
|
|
|
const now = new Date();
|
|
|
|
const current_timestamp = now / 1000;
|
2016-12-29 23:50:24 +01:00
|
|
|
message.timestamp = current_timestamp - 60;
|
|
|
|
// Have 55+10 > 60 seconds from message.timestamp to edit the message; we're good!
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message, 55), true);
|
2016-12-29 23:50:24 +01:00
|
|
|
// It's been 60 > 45+10 since message.timestamp. When realm_allow_message_editing
|
|
|
|
// is true, we can edit the topic if there is one.
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message, 45), false);
|
2021-01-31 18:23:48 +01:00
|
|
|
// Right now, we prevent users from editing widgets.
|
|
|
|
message.submessages = ["/poll"];
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message, 55), false);
|
2021-01-31 18:23:48 +01:00
|
|
|
delete message.submessages;
|
2020-07-15 01:29:15 +02:00
|
|
|
message.type = "private";
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message, 45), false);
|
2022-10-08 16:23:58 +02:00
|
|
|
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message, 55), true);
|
2016-12-29 23:50:24 +01:00
|
|
|
// If we don't pass a second argument, treat it as 0
|
2022-12-12 15:37:14 +01:00
|
|
|
assert.equal(is_content_editable(message), false);
|
2022-10-20 16:45:51 +02:00
|
|
|
});
|
2018-04-25 23:15:04 +02:00
|
|
|
|
2022-10-20 16:45:51 +02:00
|
|
|
run_test("is_topic_editable", ({override}) => {
|
|
|
|
const now = new Date();
|
|
|
|
const current_timestamp = now / 1000;
|
2018-04-25 23:15:04 +02:00
|
|
|
|
2022-10-20 16:45:51 +02:00
|
|
|
const message = {
|
|
|
|
sent_by_me: true,
|
2022-10-20 16:29:57 +02:00
|
|
|
locally_echoed: true,
|
2022-10-08 16:23:58 +02:00
|
|
|
type: "stream",
|
2022-10-20 16:45:51 +02:00
|
|
|
};
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_allow_message_editing = true;
|
2022-10-18 13:48:30 +02:00
|
|
|
override(settings_data, "user_can_move_messages_to_another_topic", () => true);
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_admin = true;
|
2022-10-20 16:29:57 +02:00
|
|
|
|
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
|
|
|
|
|
|
|
message.locally_echoed = false;
|
|
|
|
message.failed_request = true;
|
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
|
|
|
|
|
|
|
message.failed_request = false;
|
2018-04-25 23:15:04 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), true);
|
|
|
|
|
2023-12-31 00:00:18 +01:00
|
|
|
message.sent_by_me = false;
|
2022-10-08 16:23:58 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), true);
|
|
|
|
|
2022-10-18 13:48:30 +02:00
|
|
|
override(settings_data, "user_can_move_messages_to_another_topic", () => false);
|
2022-09-28 16:30:10 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
2018-10-09 09:54:57 +02:00
|
|
|
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_admin = false;
|
2022-09-28 16:30:10 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
|
|
|
|
2022-10-17 12:38:24 +02:00
|
|
|
message.topic = "translated: (no topic)";
|
2023-03-16 13:32:30 +01:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
2022-10-17 12:38:24 +02:00
|
|
|
|
|
|
|
message.topic = "test topic";
|
2022-10-18 13:48:30 +02:00
|
|
|
override(settings_data, "user_can_move_messages_to_another_topic", () => false);
|
2022-10-20 16:45:51 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_move_messages_within_stream_limit_seconds = 259200;
|
2022-10-20 16:45:51 +02:00
|
|
|
message.timestamp = current_timestamp - 60;
|
|
|
|
|
2022-10-18 13:48:30 +02:00
|
|
|
override(settings_data, "user_can_move_messages_to_another_topic", () => true);
|
2021-05-26 21:20:11 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), true);
|
|
|
|
|
|
|
|
message.timestamp = current_timestamp - 600000;
|
|
|
|
assert.equal(message_edit.is_topic_editable(message), false);
|
|
|
|
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_moderator = true;
|
2021-05-26 21:20:11 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), true);
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_allow_message_editing = false;
|
2022-08-26 09:17:01 +02:00
|
|
|
assert.equal(message_edit.is_topic_editable(message), true);
|
2018-05-15 12:40:07 +02:00
|
|
|
});
|
2018-05-02 14:01:18 +02:00
|
|
|
|
2022-12-22 11:12:31 +01:00
|
|
|
run_test("is_stream_editable", ({override}) => {
|
|
|
|
const now = new Date();
|
|
|
|
const current_timestamp = now / 1000;
|
|
|
|
|
|
|
|
const message = {
|
|
|
|
sent_by_me: true,
|
|
|
|
locally_echoed: true,
|
|
|
|
type: "stream",
|
|
|
|
};
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_allow_message_editing = true;
|
2022-12-22 11:12:31 +01:00
|
|
|
override(settings_data, "user_can_move_messages_between_streams", () => true);
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_admin = true;
|
2022-12-22 11:12:31 +01:00
|
|
|
|
|
|
|
assert.equal(message_edit.is_stream_editable(message), false);
|
|
|
|
|
|
|
|
message.locally_echoed = false;
|
|
|
|
message.failed_request = true;
|
|
|
|
assert.equal(message_edit.is_stream_editable(message), false);
|
|
|
|
|
|
|
|
message.failed_request = false;
|
|
|
|
assert.equal(message_edit.is_stream_editable(message), true);
|
|
|
|
|
2023-12-31 00:00:18 +01:00
|
|
|
message.sent_by_me = false;
|
2022-12-22 11:12:31 +01:00
|
|
|
assert.equal(message_edit.is_stream_editable(message), true);
|
|
|
|
|
|
|
|
override(settings_data, "user_can_move_messages_between_streams", () => false);
|
|
|
|
assert.equal(message_edit.is_stream_editable(message), false);
|
|
|
|
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_admin = false;
|
2022-12-22 11:12:31 +01:00
|
|
|
assert.equal(message_edit.is_stream_editable(message), false);
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_move_messages_between_streams_limit_seconds = 259200;
|
2022-12-22 11:12:31 +01:00
|
|
|
message.timestamp = current_timestamp - 60;
|
|
|
|
|
|
|
|
override(settings_data, "user_can_move_messages_between_streams", () => true);
|
|
|
|
assert.equal(message_edit.is_stream_editable(message), true);
|
|
|
|
|
|
|
|
message.timestamp = current_timestamp - 600000;
|
|
|
|
assert.equal(message_edit.is_stream_editable(message), false);
|
|
|
|
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_moderator = true;
|
2022-12-22 11:12:31 +01:00
|
|
|
assert.equal(message_edit.is_stream_editable(message), true);
|
|
|
|
});
|
|
|
|
|
2021-06-23 12:53:38 +02:00
|
|
|
run_test("get_deletability", ({override}) => {
|
2024-02-13 02:08:16 +01:00
|
|
|
current_user.is_admin = true;
|
2024-08-15 07:29:15 +02:00
|
|
|
override(settings_data, "user_can_delete_any_message", () => true);
|
2021-06-23 12:53:38 +02:00
|
|
|
override(settings_data, "user_can_delete_own_message", () => false);
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_message_content_delete_limit_seconds = null;
|
2023-06-14 19:40:41 +02:00
|
|
|
const test_user = {
|
|
|
|
user_id: 1,
|
|
|
|
full_name: "Test user",
|
|
|
|
email: "test@zulip.com",
|
|
|
|
};
|
|
|
|
people.add_active_user(test_user);
|
|
|
|
|
|
|
|
const bot_user = {
|
|
|
|
user_id: 2,
|
2024-06-26 22:36:33 +02:00
|
|
|
is_bot: true,
|
2023-06-14 19:40:41 +02:00
|
|
|
full_name: "Test bot user",
|
|
|
|
email: "test-bot@zulip.com",
|
|
|
|
bot_owner_id: 1,
|
|
|
|
};
|
|
|
|
people.add_active_user(bot_user);
|
|
|
|
|
2018-05-02 14:01:18 +02:00
|
|
|
const message = {
|
|
|
|
sent_by_me: false,
|
|
|
|
locally_echoed: true,
|
2023-06-14 19:40:41 +02:00
|
|
|
sender_id: 1,
|
2018-05-02 14:01:18 +02:00
|
|
|
};
|
|
|
|
|
2024-08-15 07:29:15 +02:00
|
|
|
// User can delete any message
|
2018-05-02 14:01:18 +02:00
|
|
|
assert.equal(message_edit.get_deletability(message), true);
|
|
|
|
|
2024-08-15 07:29:15 +02:00
|
|
|
override(settings_data, "user_can_delete_any_message", () => false);
|
|
|
|
// User can't delete message sent by others
|
2018-05-02 14:01:18 +02:00
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
|
|
|
|
|
|
|
// Locally echoed messages are not deletable
|
|
|
|
message.sent_by_me = true;
|
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
|
|
|
|
|
|
|
message.locally_echoed = false;
|
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
|
|
|
|
2021-06-23 12:53:38 +02:00
|
|
|
override(settings_data, "user_can_delete_own_message", () => true);
|
2018-05-02 14:01:18 +02:00
|
|
|
assert.equal(message_edit.get_deletability(message), true);
|
|
|
|
|
2023-06-14 19:40:41 +02:00
|
|
|
message.sent_by_me = false;
|
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
|
|
|
message.sent_by_me = true;
|
|
|
|
|
|
|
|
let now = new Date();
|
|
|
|
let current_timestamp = now / 1000;
|
2018-05-02 14:01:18 +02:00
|
|
|
message.timestamp = current_timestamp - 5;
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_message_content_delete_limit_seconds = 10;
|
2018-05-02 14:01:18 +02:00
|
|
|
assert.equal(message_edit.get_deletability(message), true);
|
|
|
|
|
|
|
|
message.timestamp = current_timestamp - 60;
|
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
2023-06-14 19:40:41 +02:00
|
|
|
|
|
|
|
message.sender_id = 2;
|
|
|
|
message.sent_by_me = false;
|
|
|
|
people.initialize_current_user(test_user.user_id);
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_message_content_delete_limit_seconds = null;
|
2023-06-14 19:40:41 +02:00
|
|
|
|
|
|
|
override(settings_data, "user_can_delete_own_message", () => true);
|
|
|
|
assert.equal(message_edit.get_deletability(message), true);
|
|
|
|
|
|
|
|
override(settings_data, "user_can_delete_own_message", () => false);
|
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
|
|
|
|
|
|
|
now = new Date();
|
|
|
|
current_timestamp = now / 1000;
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_message_content_delete_limit_seconds = 10;
|
2023-06-14 19:40:41 +02:00
|
|
|
message.timestamp = current_timestamp - 60;
|
|
|
|
override(settings_data, "user_can_delete_own_message", () => true);
|
|
|
|
assert.equal(message_edit.get_deletability(message), false);
|
2018-05-02 14:01:18 +02:00
|
|
|
});
|
2022-03-17 16:58:10 +01:00
|
|
|
|
|
|
|
run_test("stream_and_topic_exist_in_edit_history", () => {
|
|
|
|
// A message with no edit history should always return false;
|
|
|
|
// the message's current stream_id and topic are not compared
|
|
|
|
// to the stream_id and topic parameters.
|
|
|
|
const message_no_edits = {
|
|
|
|
stream_id: 1,
|
2024-06-26 22:36:33 +02:00
|
|
|
type: "stream",
|
2022-03-17 16:58:10 +01:00
|
|
|
topic: "topic match",
|
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_no_edits, 2, "no match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_no_edits, 1, "topic match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
|
|
|
|
// A non-stream message (object has no stream_id or topic)
|
|
|
|
// with content edit history, should return false.
|
|
|
|
const private_message = {
|
2023-06-16 17:37:19 +02:00
|
|
|
edit_history: [{prev_content: "content edit to direct message"}],
|
2022-03-17 16:58:10 +01:00
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(private_message, 1, "topic match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
|
|
|
|
// A stream message with only content edits should return false,
|
|
|
|
// even if the message's current stream_id and topic are a match.
|
|
|
|
const message_content_edit = {
|
|
|
|
stream_id: 1,
|
2024-06-26 22:36:33 +02:00
|
|
|
type: "stream",
|
2022-03-17 16:58:10 +01:00
|
|
|
topic: "topic match",
|
|
|
|
edit_history: [{prev_content: "content edit"}],
|
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_content_edit, 1, "topic match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
|
|
|
|
const message_stream_edit = {
|
|
|
|
stream_id: 6,
|
2024-06-26 22:36:33 +02:00
|
|
|
type: "stream",
|
2022-03-17 16:58:10 +01:00
|
|
|
topic: "topic match",
|
|
|
|
edit_history: [{stream: 6, prev_stream: 1}],
|
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_stream_edit, 2, "topic match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_stream_edit, 1, "topic match"),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
const message_topic_edit = {
|
|
|
|
stream_id: 1,
|
2024-06-26 22:36:33 +02:00
|
|
|
type: "stream",
|
2022-03-17 16:58:10 +01:00
|
|
|
topic: "final topic",
|
|
|
|
edit_history: [{topic: "final topic", prev_topic: "topic match"}],
|
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_topic_edit, 1, "no match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_topic_edit, 1, "topic match"),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
const message_many_edits = {
|
|
|
|
stream_id: 6,
|
2024-06-26 22:36:33 +02:00
|
|
|
type: "stream",
|
2022-03-17 16:58:10 +01:00
|
|
|
topic: "final topic",
|
|
|
|
edit_history: [
|
|
|
|
{stream: 6, prev_stream: 5},
|
|
|
|
{prev_content: "content only edit"},
|
|
|
|
{topic: "final topic", prev_topic: "topic match"},
|
|
|
|
{stream: 5, prev_stream: 1},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_many_edits, 1, "no match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_many_edits, 2, "topic match"),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(message_many_edits, 1, "topic match"),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
// When the topic and stream_id exist in the message's edit history
|
|
|
|
// individually, but not together in a historical state, it should return false.
|
|
|
|
const message_no_historical_match = {
|
|
|
|
stream_id: 6,
|
2024-06-26 22:36:33 +02:00
|
|
|
type: "stream",
|
2022-03-17 16:58:10 +01:00
|
|
|
topic: "final topic",
|
|
|
|
edit_history: [
|
|
|
|
{stream: 6, prev_stream: 1}, // stream matches, topic does not
|
|
|
|
{stream: 1, prev_stream: 5}, // neither match
|
|
|
|
{topic: "final topic", prev_topic: "topic match"}, // topic matches, stream does not
|
|
|
|
],
|
|
|
|
};
|
|
|
|
assert.equal(
|
|
|
|
message_edit.stream_and_topic_exist_in_edit_history(
|
|
|
|
message_no_historical_match,
|
|
|
|
1,
|
|
|
|
"topic match",
|
|
|
|
),
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
});
|