snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
795
web/tests/upload.test.cjs
Normal file
795
web/tests/upload.test.cjs
Normal file
@@ -0,0 +1,795 @@
|
||||
"use strict";
|
||||
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const {mock_banners} = require("./lib/compose_banner.cjs");
|
||||
const {make_realm} = require("./lib/example_realm.cjs");
|
||||
const {mock_esm, set_global, zrequire} = require("./lib/namespace.cjs");
|
||||
const {run_test, noop} = require("./lib/test.cjs");
|
||||
const {$} = require("./lib/zjquery.cjs");
|
||||
|
||||
class ClipboardEvent {
|
||||
constructor({clipboardData}) {
|
||||
this.clipboardData = clipboardData;
|
||||
}
|
||||
}
|
||||
set_global("ClipboardEvent", ClipboardEvent);
|
||||
|
||||
set_global("navigator", {
|
||||
userAgent: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
|
||||
});
|
||||
|
||||
let uppy_stub;
|
||||
mock_esm("@uppy/core", {
|
||||
Uppy: function Uppy(options) {
|
||||
return uppy_stub.call(this, options);
|
||||
},
|
||||
});
|
||||
mock_esm("@uppy/tus", {default: class Tus {}});
|
||||
|
||||
const compose_actions = mock_esm("../src/compose_actions");
|
||||
const compose_reply = mock_esm("../src/compose_reply");
|
||||
const compose_state = mock_esm("../src/compose_state");
|
||||
const rows = mock_esm("../src/rows");
|
||||
|
||||
const compose_ui = zrequire("compose_ui");
|
||||
const upload = zrequire("upload");
|
||||
const message_lists = mock_esm("../src/message_lists");
|
||||
const {set_realm} = zrequire("state_data");
|
||||
const compose_validate = zrequire("compose_validate");
|
||||
|
||||
const realm = make_realm();
|
||||
set_realm(realm);
|
||||
|
||||
message_lists.current = {
|
||||
id: "1",
|
||||
};
|
||||
function test(label, f) {
|
||||
run_test(label, (helpers) => {
|
||||
helpers.override(realm, "max_file_upload_size_mib", 25);
|
||||
return f(helpers);
|
||||
});
|
||||
}
|
||||
|
||||
test("feature_check", ({override}) => {
|
||||
assert.ok(!upload.feature_check());
|
||||
|
||||
override(window, "XMLHttpRequest", () => ({upload: true}));
|
||||
assert.ok(upload.feature_check());
|
||||
});
|
||||
|
||||
test("config", () => {
|
||||
assert.equal(upload.compose_config.textarea()[0], $("textarea#compose-textarea")[0]);
|
||||
assert.equal(
|
||||
upload.compose_config.upload_banner_message("id_1")[0],
|
||||
$("#compose_banners .upload_banner.file_id_1 .upload_msg")[0],
|
||||
);
|
||||
assert.equal(
|
||||
upload.compose_config.upload_banner_cancel_button("id_2")[0],
|
||||
$("#compose_banners .upload_banner.file_id_2 .upload_banner_cancel_button")[0],
|
||||
);
|
||||
assert.equal(
|
||||
upload.compose_config.upload_banner_hide_button("id_2")[0],
|
||||
$("#compose_banners .upload_banner.file_id_2 .main-view-banner-close-button")[0],
|
||||
);
|
||||
assert.equal(upload.compose_config.file_input_identifier(), "#compose input.file_input");
|
||||
assert.equal(upload.compose_config.source(), "compose-file-input");
|
||||
assert.equal(upload.compose_config.drag_drop_container()[0], $("#compose")[0]);
|
||||
assert.equal(
|
||||
upload.compose_config.markdown_preview_hide_button()[0],
|
||||
$("#compose .undo_markdown_preview")[0],
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
upload.edit_config(1).textarea()[0],
|
||||
$(`#edit_form_${CSS.escape(1)} textarea.message_edit_content`)[0],
|
||||
);
|
||||
|
||||
$(`#edit_form_${CSS.escape(2)}`).set_find_results(
|
||||
".message_edit_save",
|
||||
$(".message_edit_save"),
|
||||
);
|
||||
assert.equal(upload.edit_config(2).send_button()[0], $(".message_edit_save")[0]);
|
||||
|
||||
assert.equal(
|
||||
upload.edit_config(11).upload_banner_identifier("id_3"),
|
||||
`#edit_form_${CSS.escape(11)} .upload_banner.file_id_3`,
|
||||
);
|
||||
assert.equal(
|
||||
upload.edit_config(75).upload_banner("id_60")[0],
|
||||
$(`#edit_form_${CSS.escape(75)} .upload_banner.file_id_60`)[0],
|
||||
);
|
||||
|
||||
$(`#edit_form_${CSS.escape(2)} .upload_banner`).set_find_results(
|
||||
".upload_banner_cancel_button",
|
||||
$(".upload_banner_cancel_button"),
|
||||
);
|
||||
assert.equal(
|
||||
upload.edit_config(2).upload_banner_cancel_button("id_34")[0],
|
||||
$(`#edit_form_${CSS.escape(2)} .upload_banner.file_id_34 .upload_banner_cancel_button`)[0],
|
||||
);
|
||||
|
||||
$(`#edit_form_${CSS.escape(2)} .upload_banner`).set_find_results(
|
||||
".main-view-banner-close-button",
|
||||
$(".main-view-banner-close-button"),
|
||||
);
|
||||
assert.equal(
|
||||
upload.edit_config(2).upload_banner_hide_button("id_34")[0],
|
||||
$(
|
||||
`#edit_form_${CSS.escape(2)} .upload_banner.file_id_34 .main-view-banner-close-button`,
|
||||
)[0],
|
||||
);
|
||||
|
||||
$(`#edit_form_${CSS.escape(22)} .upload_banner.file_id_234`).set_find_results(
|
||||
".upload_msg",
|
||||
$(".upload_msg"),
|
||||
);
|
||||
assert.equal(
|
||||
upload.edit_config(22).upload_banner_message("id_234")[0],
|
||||
$(`#edit_form_${CSS.escape(22)} .upload_banner.file_id_234 .upload_msg`)[0],
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
upload.edit_config(123).file_input_identifier(),
|
||||
`#edit_form_${CSS.escape(123)} input.file_input`,
|
||||
);
|
||||
assert.equal(upload.edit_config(123).source(), "message-edit-file-input");
|
||||
assert.equal(
|
||||
upload.edit_config(1).drag_drop_container()[0],
|
||||
$(`#message-row-1-${CSS.escape(1)} .message_edit_form`)[0],
|
||||
);
|
||||
assert.equal(
|
||||
upload.edit_config(65).markdown_preview_hide_button()[0],
|
||||
$(`#edit_form_${CSS.escape(65)} .undo_markdown_preview`)[0],
|
||||
);
|
||||
});
|
||||
|
||||
test("show_error_message", ({mock_template}) => {
|
||||
mock_banners();
|
||||
|
||||
let banner_shown = false;
|
||||
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||
assert.equal(data.banner_type, "error");
|
||||
assert.equal(data.banner_text, "Error message");
|
||||
banner_shown = true;
|
||||
return "<banner-stub>";
|
||||
});
|
||||
|
||||
upload.show_error_message(upload.compose_config, "Error message");
|
||||
assert.ok(!$("#compose-send-button").hasClass("disabled-message-send-controls"));
|
||||
assert.ok(banner_shown);
|
||||
|
||||
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||
assert.equal(data.banner_type, "error");
|
||||
assert.equal(data.banner_text, "translated: An unknown error occurred.");
|
||||
banner_shown = true;
|
||||
return "<banner-stub>";
|
||||
});
|
||||
upload.show_error_message(upload.compose_config);
|
||||
});
|
||||
|
||||
test("upload_files", async ({mock_template, override, override_rewire}) => {
|
||||
mock_banners();
|
||||
|
||||
let files = [
|
||||
{
|
||||
name: "budapest.png",
|
||||
type: "image/png",
|
||||
},
|
||||
];
|
||||
let uppy_add_file_called = false;
|
||||
let remove_file_called = false;
|
||||
const uppy = {
|
||||
addFile(params) {
|
||||
uppy_add_file_called = true;
|
||||
assert.equal(params.source, "compose-file-input");
|
||||
assert.equal(params.name, "budapest.png");
|
||||
assert.equal(params.type, "image/png");
|
||||
assert.equal(params.data, files[0]);
|
||||
return "id_123";
|
||||
},
|
||||
removeFile() {
|
||||
remove_file_called = true;
|
||||
},
|
||||
};
|
||||
let hide_upload_banner_called;
|
||||
override_rewire(upload, "hide_upload_banner", (_uppy, config) => {
|
||||
hide_upload_banner_called = true;
|
||||
assert.equal(config.mode, "compose");
|
||||
});
|
||||
const config = upload.compose_config;
|
||||
$("#compose-send-button").removeClass("disabled-message-send-controls");
|
||||
await upload.upload_files(uppy, config, []);
|
||||
assert.ok(!$("#compose-send-button").hasClass("disabled-message-send-controls"));
|
||||
|
||||
let banner_shown = false;
|
||||
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||
assert.equal(data.banner_type, "error");
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
"translated: File and image uploads have been disabled for this organization.",
|
||||
);
|
||||
banner_shown = true;
|
||||
return "<banner-stub>";
|
||||
});
|
||||
override(realm, "max_file_upload_size_mib", 0);
|
||||
await upload.upload_files(uppy, config, files);
|
||||
assert.ok(banner_shown);
|
||||
|
||||
override(realm, "max_file_upload_size_mib", 25);
|
||||
let compose_ui_insert_syntax_and_focus_called = false;
|
||||
override_rewire(compose_ui, "insert_syntax_and_focus", () => {
|
||||
compose_ui_insert_syntax_and_focus_called = true;
|
||||
});
|
||||
let compose_ui_autosize_textarea_called = false;
|
||||
override_rewire(compose_ui, "autosize_textarea", () => {
|
||||
compose_ui_autosize_textarea_called = true;
|
||||
});
|
||||
let markdown_preview_hide_button_clicked = false;
|
||||
$("#compose .undo_markdown_preview").on("click", () => {
|
||||
markdown_preview_hide_button_clicked = true;
|
||||
});
|
||||
$("#compose-send-button").removeClass("disabled-message-send-controls");
|
||||
|
||||
banner_shown = false;
|
||||
mock_template("compose_banner/upload_banner.hbs", false, () => {
|
||||
banner_shown = true;
|
||||
return "<banner-stub>";
|
||||
});
|
||||
override_rewire(compose_validate, "validate", () => false);
|
||||
await upload.upload_files(uppy, config, files);
|
||||
assert.ok($("#compose-send-button").hasClass("disabled-message-send-controls"));
|
||||
assert.ok(banner_shown);
|
||||
assert.ok(compose_ui_insert_syntax_and_focus_called);
|
||||
assert.ok(compose_ui_autosize_textarea_called);
|
||||
assert.ok(markdown_preview_hide_button_clicked);
|
||||
assert.ok(uppy_add_file_called);
|
||||
|
||||
banner_shown = false;
|
||||
files = [
|
||||
{
|
||||
name: "budapest.png",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
name: "prague.png",
|
||||
type: "image/png",
|
||||
},
|
||||
];
|
||||
let add_file_counter = 0;
|
||||
uppy.addFile = (file) => {
|
||||
add_file_counter += 1;
|
||||
if (file.name === "budapest.png") {
|
||||
throw new Error("some error");
|
||||
}
|
||||
return `id_${add_file_counter}`;
|
||||
};
|
||||
await upload.upload_files(uppy, config, files);
|
||||
assert.ok(banner_shown);
|
||||
assert.equal(add_file_counter, 2);
|
||||
|
||||
hide_upload_banner_called = false;
|
||||
let compose_ui_replace_syntax_called = false;
|
||||
|
||||
override_rewire(compose_ui, "replace_syntax", (old_syntax, new_syntax, $textarea) => {
|
||||
compose_ui_replace_syntax_called = true;
|
||||
assert.equal(old_syntax, "[translated: Uploading budapest.png…]()");
|
||||
assert.equal(new_syntax, "");
|
||||
assert.equal($textarea[0], $("textarea#compose-textarea")[0]);
|
||||
});
|
||||
$("#compose_banners .upload_banner.file_id_123 .upload_banner_cancel_button").trigger("click");
|
||||
assert.ok(remove_file_called);
|
||||
assert.ok(hide_upload_banner_called);
|
||||
assert.ok(compose_ui_autosize_textarea_called);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
hide_upload_banner_called = false;
|
||||
compose_ui_replace_syntax_called = false;
|
||||
remove_file_called = false;
|
||||
$("textarea#compose-textarea").val("user modified text");
|
||||
|
||||
$("#compose_banners .upload_banner.file_id_123 .upload_banner_cancel_button").trigger("click");
|
||||
assert.ok(remove_file_called);
|
||||
assert.ok(hide_upload_banner_called);
|
||||
assert.ok(compose_ui_autosize_textarea_called);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
assert.equal($("textarea#compose-textarea").val(), "user modified text");
|
||||
});
|
||||
|
||||
test("uppy_config", () => {
|
||||
let uppy_stub_called = false;
|
||||
let uppy_used_tusupload = false;
|
||||
|
||||
uppy_stub = function (config) {
|
||||
uppy_stub_called = true;
|
||||
assert.equal(config.debug, false);
|
||||
assert.equal(config.autoProceed, true);
|
||||
assert.equal(config.restrictions.maxFileSize, 25 * 1024 * 1024);
|
||||
assert.equal(Object.keys(config.locale.strings).length, 2);
|
||||
assert.ok("exceedsSize" in config.locale.strings);
|
||||
|
||||
return {
|
||||
use(func, params) {
|
||||
const func_name = func.name;
|
||||
if (func_name === "Tus") {
|
||||
uppy_used_tusupload = true;
|
||||
assert.equal(params.endpoint, "/api/v1/tus/");
|
||||
assert.equal(params.limit, 5);
|
||||
} else {
|
||||
/* istanbul ignore next */
|
||||
assert.fail(`Missing tests for ${func_name}`);
|
||||
}
|
||||
},
|
||||
on() {},
|
||||
};
|
||||
};
|
||||
upload.setup_upload(upload.compose_config);
|
||||
|
||||
assert.equal(uppy_stub_called, true);
|
||||
assert.equal(uppy_used_tusupload, true);
|
||||
});
|
||||
|
||||
test("file_input", ({override_rewire}) => {
|
||||
upload.setup_upload(upload.compose_config);
|
||||
|
||||
const change_handler = $("#compose input.file_input").get_on_handler("change");
|
||||
const files = ["file1", "file2"];
|
||||
const event = {
|
||||
target: {
|
||||
files,
|
||||
value: "C:\\fakepath\\portland.png",
|
||||
},
|
||||
};
|
||||
let upload_files_called = false;
|
||||
override_rewire(upload, "upload_files", (_uppy, config, files) => {
|
||||
assert.equal(config.mode, "compose");
|
||||
assert.equal(files, files);
|
||||
upload_files_called = true;
|
||||
});
|
||||
change_handler(event);
|
||||
assert.ok(upload_files_called);
|
||||
});
|
||||
|
||||
test("file_drop", ({override, override_rewire}) => {
|
||||
override(compose_state, "composing", () => false);
|
||||
upload.setup_upload(upload.compose_config);
|
||||
|
||||
let prevent_default_counter = 0;
|
||||
const drag_event = {
|
||||
preventDefault() {
|
||||
prevent_default_counter += 1;
|
||||
},
|
||||
};
|
||||
const dragover_handler = $("#compose").get_on_handler("dragover");
|
||||
dragover_handler(drag_event);
|
||||
assert.equal(prevent_default_counter, 1);
|
||||
|
||||
const dragenter_handler = $("#compose").get_on_handler("dragenter");
|
||||
dragenter_handler(drag_event);
|
||||
assert.equal(prevent_default_counter, 2);
|
||||
|
||||
let stop_propagation_counter = 0;
|
||||
const files = ["file1", "file2"];
|
||||
const drop_event = {
|
||||
preventDefault() {
|
||||
prevent_default_counter += 1;
|
||||
},
|
||||
stopPropagation() {
|
||||
stop_propagation_counter += 1;
|
||||
},
|
||||
originalEvent: {
|
||||
dataTransfer: {
|
||||
files,
|
||||
},
|
||||
},
|
||||
};
|
||||
const drop_handler = $("#compose").get_on_handler("drop");
|
||||
let upload_files_called = false;
|
||||
override_rewire(upload, "upload_files", () => {
|
||||
upload_files_called = true;
|
||||
});
|
||||
let compose_actions_start_called = false;
|
||||
override(compose_reply, "respond_to_message", () => {
|
||||
compose_actions_start_called = true;
|
||||
});
|
||||
drop_handler(drop_event);
|
||||
assert.ok(compose_actions_start_called);
|
||||
assert.equal(prevent_default_counter, 3);
|
||||
assert.equal(stop_propagation_counter, 1);
|
||||
assert.equal(upload_files_called, true);
|
||||
});
|
||||
|
||||
test("copy_paste", ({override, override_rewire}) => {
|
||||
override(compose_state, "composing", () => false);
|
||||
upload.setup_upload(upload.compose_config);
|
||||
|
||||
const paste_handler = $("#compose").get_on_handler("paste");
|
||||
let get_as_file_called = false;
|
||||
let event = {
|
||||
originalEvent: new ClipboardEvent({
|
||||
clipboardData: {
|
||||
items: [
|
||||
{
|
||||
kind: "file",
|
||||
getAsFile() {
|
||||
get_as_file_called = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "notfile",
|
||||
getAsFile: () => null,
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
preventDefault() {},
|
||||
};
|
||||
let upload_files_called = false;
|
||||
override_rewire(upload, "upload_files", () => {
|
||||
upload_files_called = true;
|
||||
});
|
||||
let compose_actions_start_called = false;
|
||||
override(compose_reply, "respond_to_message", () => {
|
||||
compose_actions_start_called = true;
|
||||
});
|
||||
|
||||
paste_handler(event);
|
||||
assert.ok(get_as_file_called);
|
||||
assert.ok(upload_files_called);
|
||||
assert.ok(compose_actions_start_called);
|
||||
upload_files_called = false;
|
||||
event = {
|
||||
originalEvent: new ClipboardEvent({}),
|
||||
};
|
||||
paste_handler(event);
|
||||
assert.equal(upload_files_called, false);
|
||||
});
|
||||
|
||||
test("uppy_events", ({override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
override_rewire(compose_ui, "smart_insert_inline", noop);
|
||||
override_rewire(compose_validate, "validate_and_update_send_button_status", noop);
|
||||
|
||||
const callbacks = {};
|
||||
let state = {};
|
||||
let tus_options;
|
||||
const file = {
|
||||
id: "uppy-copenhagen.png",
|
||||
name: "copenhagen.png",
|
||||
type: "image/png",
|
||||
meta: {
|
||||
name: "copenhagen.png",
|
||||
},
|
||||
};
|
||||
|
||||
uppy_stub = function () {
|
||||
return {
|
||||
setMeta() {},
|
||||
use(_plugin, options) {
|
||||
tus_options = options;
|
||||
},
|
||||
on(event_name, callback) {
|
||||
callbacks[event_name] = callback;
|
||||
},
|
||||
removeFile() {},
|
||||
getFiles() {
|
||||
return [];
|
||||
},
|
||||
getState: () => ({
|
||||
info: [
|
||||
{
|
||||
type: state.type,
|
||||
details: state.details,
|
||||
message: state.message,
|
||||
},
|
||||
],
|
||||
}),
|
||||
};
|
||||
};
|
||||
upload.setup_upload(upload.compose_config);
|
||||
assert.equal(Object.keys(callbacks).length, 6);
|
||||
|
||||
// Simulate tus-js-client having recorded this upload in our
|
||||
// InMemoryUrlStorage, which it does while uploading -- keyed by its
|
||||
// `/api/v1/tus/...` upload URL. That URL is what upload-success uses
|
||||
// to find the entry and store/recover the result.
|
||||
const tus_upload_url = "/api/v1/tus/rue1c-MlMUjDAUdkRrEM4BTJ";
|
||||
tus_options.urlStorage.urlStorage.set("fingerprint::1", {
|
||||
uploadUrl: tus_upload_url,
|
||||
metadata: {},
|
||||
size: null,
|
||||
creationTime: "",
|
||||
urlStorageKey: "fingerprint::1",
|
||||
parallelUploadUrls: null,
|
||||
});
|
||||
|
||||
const on_upload_success_callback = callbacks["upload-success"];
|
||||
let response = {
|
||||
status: 200,
|
||||
uploadURL: tus_upload_url,
|
||||
body: {
|
||||
xhr: {
|
||||
responseText: JSON.stringify({
|
||||
url: "/user_uploads/4/cb/rue1c-MlMUjDAUdkRrEM4BTJ/copenhagen.png",
|
||||
filename: "modified-name-copenhagen.png",
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let compose_ui_replace_syntax_called = false;
|
||||
override_rewire(compose_ui, "replace_syntax", (old_syntax, new_syntax, $textarea) => {
|
||||
compose_ui_replace_syntax_called = true;
|
||||
assert.equal(old_syntax, "[translated: Uploading copenhagen.png…]()");
|
||||
assert.equal(
|
||||
new_syntax,
|
||||
"",
|
||||
);
|
||||
assert.equal($textarea[0], $("textarea#compose-textarea")[0]);
|
||||
});
|
||||
let compose_ui_autosize_textarea_called = false;
|
||||
override_rewire(compose_ui, "autosize_textarea", () => {
|
||||
compose_ui_autosize_textarea_called = true;
|
||||
});
|
||||
on_upload_success_callback(file, response);
|
||||
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
assert.ok(compose_ui_autosize_textarea_called);
|
||||
|
||||
// Re-uploading the same file makes tus-js-client short-circuit to a
|
||||
// HEAD request that returns no response body. We must still recover
|
||||
// the URL and filename stored from the first upload above and insert
|
||||
// the same syntax, rather than stalling on the placeholder. The
|
||||
// replace_syntax override below continues to assert the same syntax.
|
||||
compose_ui_replace_syntax_called = false;
|
||||
const reupload_response = {
|
||||
status: 200,
|
||||
uploadURL: tus_upload_url,
|
||||
body: {
|
||||
xhr: {
|
||||
responseText: "",
|
||||
},
|
||||
},
|
||||
};
|
||||
on_upload_success_callback(file, reupload_response);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
|
||||
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||
assert.equal(data.banner_type, "error");
|
||||
assert.equal(data.banner_text, "Some error message");
|
||||
return "<banner-stub>";
|
||||
});
|
||||
state = {
|
||||
type: "error",
|
||||
details: "Some error",
|
||||
message: "Some error message",
|
||||
};
|
||||
const on_info_visible_callback = callbacks["info-visible"];
|
||||
compose_ui_replace_syntax_called = false;
|
||||
const on_restriction_failed_callback = callbacks["restriction-failed"];
|
||||
on_info_visible_callback();
|
||||
override_rewire(compose_ui, "replace_syntax", (old_syntax, new_syntax, $textarea) => {
|
||||
compose_ui_replace_syntax_called = true;
|
||||
assert.equal(old_syntax, "[translated: Uploading copenhagen.png…]()");
|
||||
assert.equal(new_syntax, "");
|
||||
assert.equal($textarea[0], $("textarea#compose-textarea")[0]);
|
||||
});
|
||||
on_restriction_failed_callback(file, null, null);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
compose_ui_replace_syntax_called = false;
|
||||
$("textarea#compose-textarea").val("user modified text");
|
||||
on_restriction_failed_callback(file, null, null);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
assert.equal($("textarea#compose-textarea").val(), "user modified text");
|
||||
|
||||
state = {
|
||||
type: "error",
|
||||
message: "No Internet connection",
|
||||
};
|
||||
on_info_visible_callback();
|
||||
|
||||
state = {
|
||||
type: "error",
|
||||
details: "Upload Error",
|
||||
};
|
||||
on_info_visible_callback();
|
||||
|
||||
let hide_upload_banner_called = false;
|
||||
override_rewire(upload, "hide_upload_banner", (_uppy, config) => {
|
||||
hide_upload_banner_called = true;
|
||||
assert.equal(config.mode, "compose");
|
||||
});
|
||||
|
||||
const on_upload_error_callback = callbacks["upload-error"];
|
||||
const $error_msg = upload.compose_config.upload_banner_message(file.id);
|
||||
compose_ui_replace_syntax_called = false;
|
||||
response = {
|
||||
body: {
|
||||
msg: "Response message",
|
||||
},
|
||||
};
|
||||
on_upload_error_callback(file, null, response);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
assert.equal($error_msg.text(), "Response message");
|
||||
|
||||
// With no response body, we fall back to a generic error message.
|
||||
compose_ui_replace_syntax_called = false;
|
||||
on_upload_error_callback(file, null, undefined);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
assert.equal($error_msg.text(), "translated: An unknown error occurred.");
|
||||
|
||||
assert.ok(hide_upload_banner_called);
|
||||
$("textarea#compose-textarea").val("user modified text");
|
||||
on_upload_error_callback(file, null);
|
||||
assert.ok(compose_ui_replace_syntax_called);
|
||||
assert.equal($("textarea#compose-textarea").val(), "user modified text");
|
||||
});
|
||||
|
||||
test("main_file_drop_compose_mode", ({override, override_rewire}) => {
|
||||
uppy_stub = function () {
|
||||
return {
|
||||
setMeta() {},
|
||||
use() {},
|
||||
cancelAll() {},
|
||||
on() {},
|
||||
getFiles() {},
|
||||
removeFile() {},
|
||||
};
|
||||
};
|
||||
upload.initialize();
|
||||
|
||||
let prevent_default_counter = 0;
|
||||
const drag_event = {
|
||||
preventDefault() {
|
||||
prevent_default_counter += 1;
|
||||
},
|
||||
};
|
||||
|
||||
// dragover event test
|
||||
const dragover_handler = $(".app, #navbar-fixed-container").get_on_handler("dragover");
|
||||
dragover_handler(drag_event);
|
||||
assert.equal(prevent_default_counter, 1);
|
||||
|
||||
// dragenter event test
|
||||
const dragenter_handler = $(".app, #navbar-fixed-container").get_on_handler("dragenter");
|
||||
dragenter_handler(drag_event);
|
||||
assert.equal(prevent_default_counter, 2);
|
||||
|
||||
const files = ["file1", "file2"];
|
||||
const drop_event = {
|
||||
target: "target",
|
||||
preventDefault() {
|
||||
prevent_default_counter += 1;
|
||||
},
|
||||
originalEvent: {
|
||||
dataTransfer: {
|
||||
files,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
$.set_results(".message_edit_form form", []);
|
||||
|
||||
const drop_handler = $(".app, #navbar-fixed-container").get_on_handler("drop");
|
||||
|
||||
// Test drop on compose box
|
||||
let upload_files_called = false;
|
||||
override_rewire(upload, "upload_files", () => {
|
||||
upload_files_called = true;
|
||||
});
|
||||
override(compose_state, "composing", () => true);
|
||||
drop_handler(drop_event);
|
||||
assert.equal(upload_files_called, true);
|
||||
assert.equal(prevent_default_counter, 3);
|
||||
|
||||
// Test reply to message if no edit and compose box open
|
||||
upload_files_called = false;
|
||||
override(compose_state, "composing", () => false);
|
||||
const msg = {
|
||||
type: "stream",
|
||||
stream: "Denmark",
|
||||
topic: "python",
|
||||
sender_full_name: "Bob Roberts",
|
||||
sender_id: 40,
|
||||
};
|
||||
let compose_actions_start_called = false;
|
||||
let compose_actions_respond_to_message_called = false;
|
||||
override(message_lists, "current", {
|
||||
selected_message() {
|
||||
return msg;
|
||||
},
|
||||
});
|
||||
compose_actions.start = () => {
|
||||
compose_actions_start_called = true;
|
||||
};
|
||||
compose_reply.respond_to_message = () => {
|
||||
compose_actions_respond_to_message_called = true;
|
||||
};
|
||||
drop_handler(drop_event);
|
||||
assert.equal(upload_files_called, true);
|
||||
assert.equal(compose_actions_start_called, false);
|
||||
assert.equal(compose_actions_respond_to_message_called, true);
|
||||
|
||||
// Test drop on Recent Conversations view
|
||||
compose_actions_respond_to_message_called = false;
|
||||
override(message_lists, "current", {
|
||||
selected_message() {
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
upload_files_called = false;
|
||||
drop_handler(drop_event);
|
||||
assert.equal(upload_files_called, true);
|
||||
assert.equal(compose_actions_start_called, true);
|
||||
assert.equal(compose_actions_respond_to_message_called, false);
|
||||
});
|
||||
|
||||
test("main_file_drop_edit_mode", ({override, override_rewire}) => {
|
||||
uppy_stub = function () {
|
||||
return {
|
||||
setMeta() {},
|
||||
use() {},
|
||||
cancelAll() {},
|
||||
on() {},
|
||||
getFiles() {},
|
||||
removeFile() {},
|
||||
};
|
||||
};
|
||||
|
||||
upload.setup_upload(upload.edit_config(40));
|
||||
upload.initialize();
|
||||
override(compose_state, "composing", () => false);
|
||||
let prevent_default_counter = 0;
|
||||
const drag_event = {
|
||||
preventDefault() {
|
||||
prevent_default_counter += 1;
|
||||
},
|
||||
};
|
||||
const $drag_drop_container = $(`#message-row-1-${CSS.escape(40)} .message_edit_form`);
|
||||
|
||||
// Dragover event test
|
||||
const dragover_handler = $(".app, #navbar-fixed-container").get_on_handler("dragover");
|
||||
dragover_handler(drag_event);
|
||||
assert.equal(prevent_default_counter, 1);
|
||||
// Dragenter event test
|
||||
const dragenter_handler = $(".app, #navbar-fixed-container").get_on_handler("dragenter");
|
||||
dragenter_handler(drag_event);
|
||||
assert.equal(prevent_default_counter, 2);
|
||||
|
||||
const files = ["file1", "file2"];
|
||||
const drop_event = {
|
||||
target: "target",
|
||||
preventDefault() {
|
||||
prevent_default_counter += 1;
|
||||
},
|
||||
originalEvent: {
|
||||
dataTransfer: {
|
||||
files,
|
||||
},
|
||||
},
|
||||
};
|
||||
const drop_handler = $(".app, #navbar-fixed-container").get_on_handler("drop");
|
||||
let upload_files_called = false;
|
||||
let dropped_row_id = -1;
|
||||
override_rewire(upload, "upload_files", (_, config) => {
|
||||
dropped_row_id = config.row;
|
||||
upload_files_called = true;
|
||||
});
|
||||
override(rows, "get_message_id", () => 40);
|
||||
|
||||
// Edit box which registered the event handler no longer exists.
|
||||
$drag_drop_container.set_closest_results("html", []);
|
||||
|
||||
drop_handler(drop_event);
|
||||
assert.equal(upload_files_called, false);
|
||||
|
||||
$drag_drop_container.set_closest_results("html", $.create("html"));
|
||||
|
||||
// Drag and dropped in one of the edit boxes. The event would be taken care of by
|
||||
// drag_drop_container event handlers.
|
||||
|
||||
override(rows, "get_message_id", () => 40);
|
||||
// Edit box open
|
||||
drop_handler(drop_event);
|
||||
assert.equal(upload_files_called, true);
|
||||
assert.equal(dropped_row_id, 40);
|
||||
});
|
||||
Reference in New Issue
Block a user