From 715fa3aff6b43ab436a8410a0edb631f6c409ee3 Mon Sep 17 00:00:00 2001 From: Karl Stolley Date: Thu, 4 May 2023 09:00:27 -0500 Subject: [PATCH] scheduled_messages: Extract options logic from popover. This commit extracts date-based logic from the popover menu file and puts it in with the scheduled-messages logic. The aim is for greater testability, with some initial tests now presented on the date-based logic. --- web/src/popover_menus.js | 97 +++-------------------- web/src/scheduled_messages.js | 90 +++++++++++++++++++++ web/tests/scheduled_messages.test.js | 114 +++++++++++++++++++++++++++ 3 files changed, 214 insertions(+), 87 deletions(-) create mode 100644 web/tests/scheduled_messages.test.js diff --git a/web/src/popover_menus.js b/web/src/popover_menus.js index 4ecb2e01cc..4807166af5 100644 --- a/web/src/popover_menus.js +++ b/web/src/popover_menus.js @@ -3,7 +3,6 @@ popovers system in popovers.js. */ import ClipboardJS from "clipboard"; -import {format} from "date-fns"; import $ from "jquery"; import tippy, {delegate} from "tippy.js"; @@ -43,6 +42,7 @@ import * as popover_menus_data from "./popover_menus_data"; import * as popovers from "./popovers"; import * as read_receipts from "./read_receipts"; import * as rows from "./rows"; +import * as scheduled_messages from "./scheduled_messages"; import * as settings_data from "./settings_data"; import * as starred_messages from "./starred_messages"; import * as starred_messages_ui from "./starred_messages_ui"; @@ -789,70 +789,16 @@ export function initialize() { }, }); - const send_later_today = { - today_nine_am: { - text: $t({defaultMessage: "Today at 9:00 AM"}), - time: "9:00 am", - }, - today_four_pm: { - text: $t({defaultMessage: "Today at 4:00 PM "}), - time: "4:00 pm", - }, - }; - - const send_later_tomorrow = { - tomorrow_nine_am: { - text: $t({defaultMessage: "Tomorrow at 9:00 AM"}), - time: "9:00 am", - }, - tomorrow_four_pm: { - text: $t({defaultMessage: "Tomorrow at 4:00 PM "}), - time: "4:00 pm", - }, - }; - - const send_later_monday = { - monday_nine_am: { - text: $t({defaultMessage: "Monday at 9:00 AM"}), - time: "9:00 am", - }, - }; - - const send_later_custom = { - text: $t({defaultMessage: "Custom"}), - }; - function set_compose_box_schedule(element) { const send_later_in = element.id; const send_later_class = element.classList[0]; - switch (send_later_class) { - case "send_later_tomorrow": { - const send_time = send_later_tomorrow[send_later_in].time; - const date = new Date(); - const scheduled_date = date.setDate(date.getDate() + 1); - const send_at_time = format(scheduled_date, "MMM d yyyy ") + send_time; - return send_at_time; - } - case "send_later_today": { - const send_time = send_later_today[send_later_in].time; - const date = new Date(); - const send_at_time = - format(date.setDate(date.getDate()), "MMM d yyyy ") + send_time; - return send_at_time; - } - case "send_later_monday": { - const send_time = send_later_monday[send_later_in].time; - const date = new Date(); - // Subtract from 8 to find the next Monday. - const monday_offset = 8 - date.getDay(); - const scheduled_date = date.setDate(date.getDate() + monday_offset); - const send_at_time = format(scheduled_date, "MMM d yyyy ") + send_time; - return send_at_time; - } - // No default - } - blueslip.error("Not a valid time."); - return false; + const date = new Date(); + const selected_send_at_time = scheduled_messages.get_send_at_time_from_opts( + send_later_in, + send_later_class, + date, + ); + return selected_send_at_time; } delegate("body", { @@ -888,32 +834,9 @@ export function initialize() { // Only show send later options that are possible today. const date = new Date(); - const day = date.getDay(); // Starts with 0 for Sunday. - const hours = date.getHours(); - let possible_send_later_today = {}; - let possible_send_later_monday = {}; - if (hours <= 8) { - possible_send_later_today = send_later_today; - } else if (hours <= 15) { - possible_send_later_today.today_four_pm = send_later_today.today_four_pm; - } else { - possible_send_later_today = false; - } - // Show send_later_monday options only on Fridays and Saturdays. - if (day >= 5) { - possible_send_later_monday = send_later_monday; - } else { - possible_send_later_monday = false; - } + const filtered_send_opts = scheduled_messages.get_filtered_send_opts(date); + $("body").append(render_send_later_modal(filtered_send_opts)); - $("body").append( - render_send_later_modal({ - possible_send_later_today, - send_later_tomorrow, - possible_send_later_monday, - send_later_custom, - }), - ); overlays.open_modal("send_later_modal", { autoremove: true, on_show() { diff --git a/web/src/scheduled_messages.js b/web/src/scheduled_messages.js index 48f1a2a0b4..9c528583fe 100644 --- a/web/src/scheduled_messages.js +++ b/web/src/scheduled_messages.js @@ -1,13 +1,16 @@ +import {format} from "date-fns"; import $ from "jquery"; import render_success_message_scheduled_banner from "../templates/compose_banner/success_message_scheduled_banner.hbs"; +import * as blueslip from "./blueslip"; import * as channel from "./channel"; import * as compose from "./compose"; import * as compose_actions from "./compose_actions"; import * as compose_banner from "./compose_banner"; import * as compose_ui from "./compose_ui"; import * as drafts from "./drafts"; +import {$t} from "./i18n"; import * as narrow from "./narrow"; import * as people from "./people"; import * as popover_menus from "./popover_menus"; @@ -15,6 +18,39 @@ import * as stream_data from "./stream_data"; export let scheduled_messages_data = []; +const send_later_today = { + today_nine_am: { + text: $t({defaultMessage: "Today at 9:00 AM"}), + time: "9:00 am", + }, + today_four_pm: { + text: $t({defaultMessage: "Today at 4:00 PM"}), + time: "4:00 pm", + }, +}; + +const send_later_tomorrow = { + tomorrow_nine_am: { + text: $t({defaultMessage: "Tomorrow at 9:00 AM"}), + time: "9:00 am", + }, + tomorrow_four_pm: { + text: $t({defaultMessage: "Tomorrow at 4:00 PM"}), + time: "4:00 pm", + }, +}; + +const send_later_monday = { + monday_nine_am: { + text: $t({defaultMessage: "Monday at 9:00 AM"}), + time: "9:00 am", + }, +}; + +const send_later_custom = { + text: $t({defaultMessage: "Custom"}), +}; + function sort_scheduled_messages_data() { scheduled_messages_data.sort( (msg1, msg2) => msg1.scheduled_delivery_timestamp - msg2.scheduled_delivery_timestamp, @@ -144,6 +180,60 @@ export function get_count() { return scheduled_messages_data.length; } +export function get_filtered_send_opts(date) { + const day = date.getDay(); // Starts with 0 for Sunday. + const hours = date.getHours(); + let possible_send_later_today = {}; + let possible_send_later_monday = {}; + if (hours <= 8) { + possible_send_later_today = send_later_today; + } else if (hours <= 15) { + possible_send_later_today.today_four_pm = send_later_today.today_four_pm; + } else { + possible_send_later_today = false; + } + // Show send_later_monday options only on Fridays and Saturdays. + if (day >= 5) { + possible_send_later_monday = send_later_monday; + } else { + possible_send_later_monday = false; + } + + return { + possible_send_later_today, + send_later_tomorrow, + possible_send_later_monday, + send_later_custom, + }; +} + +export function get_send_at_time_from_opts(send_later_in, send_later_class, date) { + switch (send_later_class) { + case "send_later_tomorrow": { + const send_time = send_later_tomorrow[send_later_in].time; + const scheduled_date = date.setDate(date.getDate() + 1); + const send_at_time = format(scheduled_date, "MMM d yyyy ") + send_time; + return send_at_time; + } + case "send_later_today": { + const send_time = send_later_today[send_later_in].time; + const send_at_time = format(date.setDate(date.getDate()), "MMM d yyyy ") + send_time; + return send_at_time; + } + case "send_later_monday": { + const send_time = send_later_monday[send_later_in].time; + // Subtract from 8 to find the next Monday. + const monday_offset = 8 - date.getDay(); + const scheduled_date = date.setDate(date.getDate() + monday_offset); + const send_at_time = format(scheduled_date, "MMM d yyyy ") + send_time; + return send_at_time; + } + // No default + } + blueslip.error("Not a valid time."); + return false; +} + export function initialize(scheduled_messages_params) { scheduled_messages_data = scheduled_messages_params.scheduled_messages; diff --git a/web/tests/scheduled_messages.test.js b/web/tests/scheduled_messages.test.js new file mode 100644 index 0000000000..4978536366 --- /dev/null +++ b/web/tests/scheduled_messages.test.js @@ -0,0 +1,114 @@ +"use strict"; + +const {strict: assert} = require("assert"); + +const {zrequire} = require("./lib/namespace"); +const {run_test} = require("./lib/test"); + +const scheduled_messages = zrequire("scheduled_messages"); + +function get_expected_send_opts(expecteds) { + const modal_opts = { + send_later_tomorrow: { + tomorrow_nine_am: { + text: "translated: Tomorrow at 9:00 AM", + time: "9:00 am", + }, + tomorrow_four_pm: { + text: "translated: Tomorrow at 4:00 PM", + time: "4:00 pm", + }, + }, + send_later_custom: { + text: "translated: Custom", + }, + possible_send_later_today: false, + possible_send_later_monday: false, + }; + const optional_modal_opts = { + send_later_today: { + today_nine_am: { + text: "translated: Today at 9:00 AM", + time: "9:00 am", + }, + today_four_pm: { + text: "translated: Today at 4:00 PM", + time: "4:00 pm", + }, + }, + send_later_monday: { + monday_nine_am: { + text: "translated: Monday at 9:00 AM", + time: "9:00 am", + }, + }, + }; + + // 'today_nine_am' + // 'today_four_pm' + // 'monday_nine_am' + for (const expect of expecteds) { + const day = expect.split("_")[0]; // "today", "monday" + if (!modal_opts[`possible_send_later_${day}`]) { + modal_opts[`possible_send_later_${day}`] = {}; + } + modal_opts[`possible_send_later_${day}`][expect] = + optional_modal_opts[`send_later_${day}`][expect]; + } + + return modal_opts; +} + +run_test("scheduled_modal_opts", () => { + // Sunday thru Saturday + const days = [ + "2023-04-30", + "2023-05-01", + "2023-05-02", + "2023-05-03", + "2023-05-04", + "2023-05-05", + "2023-05-06", + ]; + // Extra options change based on the hour of day + const options_by_hour = [ + {hour: "T06:00:00", extras: ["today_nine_am", "today_four_pm"]}, + {hour: "T11:00:00", extras: ["today_four_pm"]}, + {hour: "T17:00:00", extras: []}, + ]; + + // Now we can test those hourly options on each day of the week + for (const day of days) { + for (const opts of options_by_hour) { + const date = new Date(day + opts.hour); + // On Fridays (5) and Saturdays (6), add the Monday option + if (date.getDay() > 4) { + opts.extras.push("monday_nine_am"); + } + const modal_opts = scheduled_messages.get_filtered_send_opts(date); + const expected_opts = get_expected_send_opts(opts.extras); + assert.deepEqual(modal_opts, expected_opts); + } + } +}); + +run_test("scheduled_selected_times", () => { + // When scheduling a message on a Monday at 6:00am + // that will be sent tomorrow at 4pm + let date = new Date("2023-05-01T06:00:00"); + let send_at_time = scheduled_messages.get_send_at_time_from_opts( + "tomorrow_four_pm", + "send_later_tomorrow", + date, + ); + assert.equal(send_at_time, "May 2 2023 4:00 pm"); + // When scheduling a message on a Friday at 5:00pm + // that will be sent Monday at 9am + date = new Date("2023-05-05T17:00:00"); + send_at_time = scheduled_messages.get_send_at_time_from_opts( + "monday_nine_am", + "send_later_monday", + date, + ); + assert.equal(send_at_time, "May 8 2023 9:00 am"); +});