mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 17:52:45 +08:00
![Martin Brennan](/assets/img/avatar_default.png)
We were changing the user's user_option.bookmark_auto_delete_preference to whatever they changed it to in the bookmark modal to use as default for future bookmarks. However this was leading to a lot of confusion since if you wanted to set it for one bookmark you had to remember to change it back on the next one. This commit removes that automatic functionality, and instead moves the bookmark auto delete preference to User Preferences > Interface in an explicit dropdown.
488 lines
16 KiB
JavaScript
488 lines
16 KiB
JavaScript
import {
|
|
acceptance,
|
|
exists,
|
|
loggedInUser,
|
|
query,
|
|
} from "discourse/tests/helpers/qunit-helpers";
|
|
import { click, fillIn, visit } from "@ember/test-helpers";
|
|
import I18n from "I18n";
|
|
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
|
import { test } from "qunit";
|
|
import topicFixtures from "discourse/tests/fixtures/topic";
|
|
import { cloneJSON } from "discourse-common/lib/object";
|
|
|
|
async function openBookmarkModal(postNumber = 1) {
|
|
if (exists(`#post_${postNumber} button.show-more-actions`)) {
|
|
await click(`#post_${postNumber} button.show-more-actions`);
|
|
}
|
|
await click(`#post_${postNumber} button.bookmark`);
|
|
}
|
|
|
|
async function openEditBookmarkModal() {
|
|
await click(".topic-post:first-child button.bookmarked");
|
|
}
|
|
|
|
async function testTopicLevelBookmarkButtonIcon(assert, postNumber) {
|
|
const iconWithoutClock = "d-icon-bookmark";
|
|
const iconWithClock = "d-icon-discourse-bookmark-clock";
|
|
|
|
await visit("/t/internationalization-localization/280");
|
|
assert.ok(
|
|
query("#topic-footer-button-bookmark svg").classList.contains(
|
|
iconWithoutClock
|
|
),
|
|
"Shows an icon without a clock when there is no a bookmark"
|
|
);
|
|
|
|
await openBookmarkModal(postNumber);
|
|
await click("#save-bookmark");
|
|
|
|
assert.ok(
|
|
query("#topic-footer-button-bookmark svg").classList.contains(
|
|
iconWithoutClock
|
|
),
|
|
"Shows an icon without a clock when there is a bookmark without a reminder"
|
|
);
|
|
|
|
await openBookmarkModal(postNumber);
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
assert.ok(
|
|
query("#topic-footer-button-bookmark svg").classList.contains(
|
|
iconWithClock
|
|
),
|
|
"Shows an icon with a clock when there is a bookmark with a reminder"
|
|
);
|
|
}
|
|
|
|
acceptance("Bookmarking", function (needs) {
|
|
needs.user();
|
|
|
|
const topicResponse = cloneJSON(topicFixtures["/t/280/1.json"]);
|
|
topicResponse.post_stream.posts[0].cooked += `<span data-date="2036-01-15" data-time="00:35:00" class="discourse-local-date cooked-date past" data-timezone="Europe/London">
|
|
<span>
|
|
<svg class="fa d-icon d-icon-globe-americas svg-icon" xmlns="http://www.w3.org/2000/svg">
|
|
<use href="#globe-americas"></use>
|
|
</svg>
|
|
<span class="relative-time">January 15, 2036 12:35 AM</span>
|
|
</span>
|
|
</span>`;
|
|
|
|
topicResponse.post_stream.posts[1].cooked += `<span data-date="2021-01-15" data-time="00:35:00" class="discourse-local-date cooked-date past" data-timezone="Europe/London">
|
|
<span>
|
|
<svg class="fa d-icon d-icon-globe-americas svg-icon" xmlns="http://www.w3.org/2000/svg">
|
|
<use href="#globe-americas"></use>
|
|
</svg>
|
|
<span class="relative-time">Today 10:30 AM</span>
|
|
</span>
|
|
</span>`;
|
|
|
|
needs.pretender((server, helper) => {
|
|
function handleRequest(request) {
|
|
const data = helper.parsePostData(request.requestBody);
|
|
|
|
if (data.bookmarkable_id === "398" && data.bookmarkable_type === "Post") {
|
|
return helper.response({ id: 1, success: "OK" });
|
|
} else if (data.bookmarkable_type === "Topic") {
|
|
return helper.response({ id: 3, success: "OK" });
|
|
} else if (
|
|
data.bookmarkable_id === "419" &&
|
|
data.bookmarkable_type === "Post"
|
|
) {
|
|
return helper.response({ id: 2, success: "OK" });
|
|
}
|
|
}
|
|
server.post("/bookmarks", handleRequest);
|
|
server.put("/bookmarks/1", handleRequest);
|
|
server.put("/bookmarks/2", handleRequest);
|
|
server.put("/bookmarks/3", handleRequest);
|
|
server.delete("/bookmarks/1", () =>
|
|
helper.response({ success: "OK", topic_bookmarked: false })
|
|
);
|
|
server.get("/t/280.json", () => helper.response(topicResponse));
|
|
});
|
|
|
|
test("Bookmarks modal opening", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal();
|
|
assert.ok(
|
|
exists("#bookmark-reminder-modal"),
|
|
"it shows the bookmark modal"
|
|
);
|
|
assert.ok(
|
|
exists("#tap_tile_none.active"),
|
|
"it highlights the None option by default"
|
|
);
|
|
});
|
|
|
|
test("Bookmarks modal selecting reminder type", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
|
|
await openBookmarkModal();
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
await openBookmarkModal();
|
|
await click("#tap_tile_start_of_next_business_week");
|
|
|
|
await openBookmarkModal();
|
|
await click("#tap_tile_next_month");
|
|
|
|
await openBookmarkModal();
|
|
await click("#tap_tile_custom");
|
|
assert.ok(exists("#tap_tile_custom.active"), "it selects custom");
|
|
assert.ok(exists(".tap-tile-date-input"), "it shows the custom date input");
|
|
assert.ok(exists(".tap-tile-time-input"), "it shows the custom time input");
|
|
await click("#save-bookmark");
|
|
});
|
|
|
|
test("Saving a bookmark with a reminder", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal();
|
|
await fillIn("input#bookmark-name", "Check this out later");
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
assert.ok(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"it shows the bookmarked icon on the post"
|
|
);
|
|
assert.ok(
|
|
exists(
|
|
".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock"
|
|
),
|
|
"it shows the bookmark clock icon because of the reminder"
|
|
);
|
|
});
|
|
|
|
test("Opening the options panel and remembering the option", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal();
|
|
assert.notOk(
|
|
exists(".bookmark-options-panel"),
|
|
"it should not open the options panel by default"
|
|
);
|
|
await click(".bookmark-options-button");
|
|
assert.ok(
|
|
exists(".bookmark-options-panel"),
|
|
"it should open the options panel"
|
|
);
|
|
await selectKit(".bookmark-option-selector").expand();
|
|
await selectKit(".bookmark-option-selector").selectRowByValue(1);
|
|
await click("#save-bookmark");
|
|
await openEditBookmarkModal();
|
|
|
|
assert.ok(
|
|
exists(".bookmark-options-panel"),
|
|
"it should reopen the options panel"
|
|
);
|
|
assert.strictEqual(
|
|
selectKit(".bookmark-option-selector").header().value(),
|
|
"1"
|
|
);
|
|
});
|
|
|
|
test("Saving a bookmark with no reminder or name", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal();
|
|
await click("#save-bookmark");
|
|
|
|
assert.ok(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"it shows the bookmarked icon on the post"
|
|
);
|
|
assert.notOk(
|
|
exists(
|
|
".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock"
|
|
),
|
|
"it shows the regular bookmark active icon"
|
|
);
|
|
});
|
|
|
|
test("Deleting a bookmark with a reminder", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal();
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
await openEditBookmarkModal();
|
|
|
|
assert.ok(
|
|
exists("#bookmark-reminder-modal"),
|
|
"it shows the bookmark modal"
|
|
);
|
|
|
|
await click("#delete-bookmark");
|
|
|
|
assert.ok(exists(".dialog-body"), "it asks for delete confirmation");
|
|
assert.ok(
|
|
query(".dialog-body").innerText.includes(
|
|
I18n.t("bookmarks.confirm_delete")
|
|
),
|
|
"it shows delete confirmation message"
|
|
);
|
|
|
|
await click(".dialog-footer .btn-danger");
|
|
|
|
assert.notOk(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"it no longer shows the bookmarked icon on the post after bookmark is deleted"
|
|
);
|
|
});
|
|
|
|
test("Cancelling saving a bookmark", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal();
|
|
await click(".d-modal-cancel");
|
|
assert.notOk(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"it does not show the bookmarked icon on the post because it is not saved"
|
|
);
|
|
});
|
|
|
|
test("Editing a bookmark", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
let now = moment.tz(loggedInUser().user_option.timezone);
|
|
let tomorrow = now.add(1, "day").format("YYYY-MM-DD");
|
|
await openBookmarkModal();
|
|
await fillIn("input#bookmark-name", "Test name");
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
await openEditBookmarkModal();
|
|
assert.strictEqual(
|
|
query("#bookmark-name").value,
|
|
"Test name",
|
|
"it should prefill the bookmark name"
|
|
);
|
|
assert.strictEqual(
|
|
query("#custom-date > input").value,
|
|
tomorrow,
|
|
"it should prefill the bookmark date"
|
|
);
|
|
assert.strictEqual(
|
|
query("#custom-time").value,
|
|
"08:00",
|
|
"it should prefill the bookmark time"
|
|
);
|
|
});
|
|
|
|
test("Using a post date for the reminder date", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
let postDate = moment.tz("2036-01-15", loggedInUser().user_option.timezone);
|
|
let postDateFormatted = postDate.format("YYYY-MM-DD");
|
|
await openBookmarkModal();
|
|
await fillIn("input#bookmark-name", "Test name");
|
|
await click("#tap_tile_post_local_date");
|
|
|
|
await openEditBookmarkModal();
|
|
assert.strictEqual(
|
|
query("#bookmark-name").value,
|
|
"Test name",
|
|
"it should prefill the bookmark name"
|
|
);
|
|
assert.strictEqual(
|
|
query("#custom-date > input").value,
|
|
postDateFormatted,
|
|
"it should prefill the bookmark date"
|
|
);
|
|
assert.strictEqual(
|
|
query("#custom-time").value,
|
|
"10:35",
|
|
"it should prefill the bookmark time"
|
|
);
|
|
});
|
|
|
|
test("Cannot use the post date for a reminder when the post date is in the past", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal(2);
|
|
assert.notOk(
|
|
exists("#tap_tile_post_local_date"),
|
|
"it does not show the local date tile"
|
|
);
|
|
});
|
|
|
|
test("The topic level bookmark button deletes all bookmarks if several posts on the topic are bookmarked", async function (assert) {
|
|
const yesButton = ".dialog-footer .btn-primary";
|
|
const noButton = ".dialog-footer .btn-default";
|
|
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal(1);
|
|
await click("#save-bookmark");
|
|
await openBookmarkModal(2);
|
|
await click("#save-bookmark");
|
|
|
|
assert.ok(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"the first bookmark is added"
|
|
);
|
|
assert.ok(
|
|
exists(".topic-post:nth-child(3) button.bookmark.bookmarked"),
|
|
"the second bookmark is added"
|
|
);
|
|
|
|
// open the modal and cancel deleting
|
|
await click("#topic-footer-button-bookmark");
|
|
await click(noButton);
|
|
|
|
assert.ok(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"the first bookmark isn't deleted"
|
|
);
|
|
assert.ok(
|
|
exists(".topic-post:nth-child(3) button.bookmark.bookmarked"),
|
|
"the second bookmark isn't deleted"
|
|
);
|
|
|
|
// open the modal and accept deleting
|
|
await click("#topic-footer-button-bookmark");
|
|
await click(yesButton);
|
|
|
|
assert.ok(
|
|
!exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"the first bookmark is deleted"
|
|
);
|
|
assert.ok(
|
|
!exists(".topic-post:nth-child(3) button.bookmark.bookmarked"),
|
|
"the second bookmark is deleted"
|
|
);
|
|
});
|
|
|
|
test("The topic level bookmark button opens the edit modal if only the first post on the topic is bookmarked", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal(1);
|
|
await click("#save-bookmark");
|
|
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.edit_bookmark"),
|
|
"A topic level bookmark button has a label 'Edit Bookmark'"
|
|
);
|
|
|
|
await click("#topic-footer-button-bookmark");
|
|
|
|
assert.ok(
|
|
exists("div.modal.bookmark-with-reminder"),
|
|
"The edit modal is opened"
|
|
);
|
|
});
|
|
|
|
test("Creating and editing a topic level bookmark", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await click("#topic-footer-button-bookmark");
|
|
await click("#save-bookmark");
|
|
|
|
assert.notOk(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"the first post is not marked as being bookmarked"
|
|
);
|
|
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.edit_bookmark"),
|
|
"A topic level bookmark button has a label 'Edit Bookmark'"
|
|
);
|
|
|
|
await click("#topic-footer-button-bookmark");
|
|
await fillIn("input#bookmark-name", "Test name");
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
await click("#topic-footer-button-bookmark");
|
|
|
|
assert.strictEqual(
|
|
query("input#bookmark-name").value,
|
|
"Test name",
|
|
"The topic level bookmark editing preserves the values entered"
|
|
);
|
|
|
|
await click(".d-modal-cancel");
|
|
|
|
await openBookmarkModal(1);
|
|
await click("#save-bookmark");
|
|
|
|
assert.ok(
|
|
exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"the first post is bookmarked independently of the topic level bookmark"
|
|
);
|
|
|
|
// deleting all bookmarks in the topic
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.clear_bookmarks"),
|
|
"the footer button says Clear Bookmarks because there is more than one"
|
|
);
|
|
await click("#topic-footer-button-bookmark");
|
|
await click(".dialog-footer .btn-primary");
|
|
|
|
assert.ok(
|
|
!exists(".topic-post:first-child button.bookmark.bookmarked"),
|
|
"the first post bookmark is deleted"
|
|
);
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.title"),
|
|
"the topic level bookmark is deleted"
|
|
);
|
|
});
|
|
|
|
test("Deleting a topic_level bookmark with a reminder", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await click("#topic-footer-button-bookmark");
|
|
await click("#save-bookmark");
|
|
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.edit_bookmark"),
|
|
"A topic level bookmark button has a label 'Edit Bookmark'"
|
|
);
|
|
|
|
await click("#topic-footer-button-bookmark");
|
|
await fillIn("input#bookmark-name", "Test name");
|
|
await click("#tap_tile_tomorrow");
|
|
|
|
await click("#topic-footer-button-bookmark");
|
|
await click("#delete-bookmark");
|
|
|
|
assert.ok(exists(".dialog-body"), "it asks for delete confirmation");
|
|
assert.ok(
|
|
query(".dialog-body").innerText.includes(
|
|
I18n.t("bookmarks.confirm_delete")
|
|
),
|
|
"it shows delete confirmation message"
|
|
);
|
|
|
|
await click(".dialog-footer .btn-danger");
|
|
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.title"),
|
|
"A topic level bookmark button no longer says 'Edit Bookmark' after deletion"
|
|
);
|
|
});
|
|
|
|
test("The topic level bookmark button opens the edit modal if only one post in the post stream is bookmarked", async function (assert) {
|
|
await visit("/t/internationalization-localization/280");
|
|
await openBookmarkModal(2);
|
|
await click("#save-bookmark");
|
|
|
|
assert.strictEqual(
|
|
query("#topic-footer-button-bookmark").innerText,
|
|
I18n.t("bookmarked.edit_bookmark"),
|
|
"A topic level bookmark button has a label 'Edit Bookmark'"
|
|
);
|
|
|
|
await click("#topic-footer-button-bookmark");
|
|
|
|
assert.ok(
|
|
exists("div.modal.bookmark-with-reminder"),
|
|
"The edit modal is opened"
|
|
);
|
|
});
|
|
|
|
test("The topic level bookmark button shows an icon with a clock if there is a bookmark with a reminder on the first post", async function (assert) {
|
|
const postNumber = 1;
|
|
await testTopicLevelBookmarkButtonIcon(assert, postNumber);
|
|
});
|
|
|
|
test("The topic level bookmark button shows an icon with a clock if there is a bookmark with a reminder on the second post", async function (assert) {
|
|
const postNumber = 2;
|
|
await testTopicLevelBookmarkButtonIcon(assert, postNumber);
|
|
});
|
|
});
|