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:
199
web/tests/zjquery.test.cjs
Normal file
199
web/tests/zjquery.test.cjs
Normal file
@@ -0,0 +1,199 @@
|
||||
"use strict";
|
||||
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const {run_test} = require("./lib/test.cjs");
|
||||
const {$} = require("./lib/zjquery.cjs");
|
||||
|
||||
/*
|
||||
|
||||
This test module actually tests our test code, particularly zjquery, and
|
||||
it is intended to demonstrate how to use zjquery (as well as, of course, verify
|
||||
that it works as advertised). This test module is a good place to learn how to
|
||||
stub out functions from jQuery.
|
||||
|
||||
What is zjquery?
|
||||
|
||||
The zjquery test module behaves like jQuery at a very surface level, and it
|
||||
allows you to test code that uses actual jQuery without pulling in all the
|
||||
complexity of jQuery. It also allows you to mostly simulate DOM for the
|
||||
purposes of unit testing, so that your tests focus on component interactions
|
||||
that aren't super tightly coupled to building the DOM. The tests also run
|
||||
faster! In order to keep zjquery light, it only has stubs for the most commonly
|
||||
used functions of jQuery. This means that it is possible that you may need to
|
||||
stub out additional functions manually in the relevant test module.
|
||||
|
||||
The code we are testing lives here:
|
||||
|
||||
https://github.com/zulip/zulip/blob/main/web/tests/lib/zjquery.cjs
|
||||
|
||||
*/
|
||||
|
||||
run_test("basics", () => {
|
||||
// Let's create a sample piece of code to test:
|
||||
|
||||
function show_my_form() {
|
||||
$("#my-form").show();
|
||||
}
|
||||
|
||||
// Before we call show_my_form, we can assert that my-form is hidden:
|
||||
assert.ok(!$("#my-form").visible());
|
||||
|
||||
// Then calling show_my_form() should make it visible.
|
||||
show_my_form();
|
||||
assert.ok($("#my-form").visible());
|
||||
|
||||
// Next, look at how several functions correctly simulate setting
|
||||
// and getting for you.
|
||||
const $widget = $("#my-widget");
|
||||
|
||||
$widget.attr("data-employee-id", 42);
|
||||
assert.equal($widget.attr("data-employee-id"), "42");
|
||||
assert.equal($widget.data("employee-id"), 42);
|
||||
|
||||
$widget.data("department-id", 77);
|
||||
assert.equal($widget.attr("data-department-id"), undefined);
|
||||
assert.equal($widget.data("department-id"), 77);
|
||||
|
||||
$widget.data("department-name", "hr");
|
||||
assert.equal($widget.attr("data-department-name"), undefined);
|
||||
assert.equal($widget.data("department-name"), "hr");
|
||||
|
||||
$widget.html("<b>hello</b>"); // eslint-disable-line no-jquery/no-parse-html-literal
|
||||
assert.equal($widget.html(), "<b>hello</b>");
|
||||
|
||||
$widget.prop("title", "My widget");
|
||||
assert.equal($widget.prop("title"), "My widget");
|
||||
|
||||
$widget.val("42");
|
||||
assert.equal($widget.val(), "42");
|
||||
});
|
||||
|
||||
run_test("finding_related_objects", () => {
|
||||
// Let's say you have a function like the following:
|
||||
function update_message_emoji(emoji_src) {
|
||||
$("#my-message").find(".emoji").attr("src", emoji_src);
|
||||
}
|
||||
|
||||
// This would explode:
|
||||
// update_message_emoji('foo.png');
|
||||
|
||||
// The error would be:
|
||||
// Error: Cannot find .emoji in #my-message
|
||||
|
||||
// But you can set up your tests to simulate DOM relationships.
|
||||
//
|
||||
// We will use set_find_results(), which is a special zjquery helper.
|
||||
const $emoji = $("<emoji-stub>");
|
||||
$("#my-message").set_find_results(".emoji", $emoji);
|
||||
|
||||
// And then calling the function produces the desired effect:
|
||||
update_message_emoji("foo.png");
|
||||
assert.equal($emoji.attr("src"), "foo.png");
|
||||
|
||||
// Sometimes you want to deliberately test paths that do not find an
|
||||
// element. You can pass [] as the result for those cases.
|
||||
$emoji.set_find_results(".random", []);
|
||||
assert.equal($emoji.find(".random").length, 0);
|
||||
/*
|
||||
An important thing to understand is that zjquery doesn't truly
|
||||
simulate DOM. The way you make relationships work in zjquery
|
||||
is that you explicitly set up what your functions want to return.
|
||||
|
||||
Here is another example.
|
||||
*/
|
||||
|
||||
const $my_parents = $("#folder1,#folder4");
|
||||
const $elem = $("#folder555");
|
||||
|
||||
$elem.set_parents_result(".folder", $my_parents);
|
||||
$elem.parents(".folder").addClass("active");
|
||||
assert.ok($my_parents.hasClass("active"));
|
||||
});
|
||||
|
||||
run_test("clicks", () => {
|
||||
// We can support basic handlers like click and keydown.
|
||||
|
||||
const state = {};
|
||||
|
||||
function set_up_click_handlers() {
|
||||
$("#widget1").on("click", () => {
|
||||
state.clicked = true;
|
||||
});
|
||||
|
||||
$(".some-class").on("keydown", () => {
|
||||
state.keydown = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Setting up the click handlers doesn't change state right away.
|
||||
set_up_click_handlers();
|
||||
assert.ok(!state.clicked);
|
||||
assert.ok(!state.keydown);
|
||||
|
||||
// But we can simulate clicks.
|
||||
$("#widget1").trigger("click");
|
||||
assert.equal(state.clicked, true);
|
||||
|
||||
// and keydown
|
||||
$(".some-class").trigger("keydown");
|
||||
assert.equal(state.keydown, true);
|
||||
});
|
||||
|
||||
run_test("events", () => {
|
||||
// Zulip's codebase uses jQuery's event API heavily with anonymous
|
||||
// functions that are hard for naive test code to cover. zjquery
|
||||
// will come to our rescue.
|
||||
|
||||
let value;
|
||||
|
||||
function initialize_handler() {
|
||||
$("#my-parent").on("click", ".button-red", (e) => {
|
||||
value = "red"; // just a dummy side effect
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$("#my-parent").on("click", ".button-blue", (e) => {
|
||||
value = "blue";
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
// Calling initialize_handler() doesn't immediately do much of interest.
|
||||
initialize_handler();
|
||||
assert.equal(value, undefined);
|
||||
|
||||
// We want to call the inner function, so first let's get it using the
|
||||
// get_on_handler() helper from zjquery.
|
||||
const red_handler_func = $("#my-parent").get_on_handler("click", ".button-red");
|
||||
|
||||
// Set up a stub event so that stopPropagation doesn't explode on us.
|
||||
const stub_event = {
|
||||
stopPropagation() {},
|
||||
};
|
||||
|
||||
// Now call the handler.
|
||||
red_handler_func(stub_event);
|
||||
|
||||
// And verify it did what it was supposed to do.
|
||||
assert.equal(value, "red");
|
||||
|
||||
// Test we can have multiple click handlers in the parent.
|
||||
const blue_handler_func = $("#my-parent").get_on_handler("click", ".button-blue");
|
||||
blue_handler_func(stub_event);
|
||||
assert.equal(value, "blue");
|
||||
});
|
||||
|
||||
run_test("create", () => {
|
||||
// You can create jQuery objects that aren't tied to any particular
|
||||
// selector, and which just have a name.
|
||||
|
||||
const $obj1 = $.create("the table holding employees");
|
||||
const $obj2 = $.create("the collection of rows in the table");
|
||||
|
||||
$obj1.show();
|
||||
assert.ok($obj1.visible());
|
||||
|
||||
$obj2.addClass(".striped");
|
||||
assert.ok($obj2.hasClass(".striped"));
|
||||
});
|
||||
Reference in New Issue
Block a user