"use strict"; const {strict: assert} = require("assert"); const {add} = require("date-fns"); const MockDate = require("mockdate"); const {$t} = require("../zjsunit/i18n"); const {zrequire} = require("../zjsunit/namespace"); const {run_test} = require("../zjsunit/test"); const $ = require("../zjsunit/zjquery"); const {user_settings} = require("../zjsunit/zpage_params"); user_settings.twenty_four_hour_time = true; const timerender = zrequire("timerender"); function get_date(time_ISO, DOW) { const time = new Date(time_ISO); // DOW helps the test reader to know the DOW of the current date being tested. assert.equal(new Intl.DateTimeFormat("en-US", {weekday: "long"}).format(time), DOW); return time; } const date_2017 = get_date("2017-05-18T07:12:53.000Z", "Thursday"); // Check there is no UTC offset. assert.equal(timerender.get_tz_with_UTC_offset(date_2017.getTime()), "UTC"); const date_2017_PM = get_date("2017-05-18T21:12:53.000Z", "Thursday"); const date_2019 = get_date("2019-04-12T17:52:53.000Z", "Friday"); const date_2021 = get_date("2021-01-27T01:53:08.000Z", "Wednesday"); const date_2025 = get_date("2025-03-03T12:10:00.000Z", "Monday"); run_test("get_tz_with_UTC_offset", () => { let time = date_2019; assert.equal(timerender.get_tz_with_UTC_offset(time), "UTC"); const previous_env_tz = process.env.TZ; // Test the GMT[+-]x:y logic. process.env.TZ = "Asia/Kolkata"; assert.equal(timerender.get_tz_with_UTC_offset(time), "(UTC+05:30)"); process.env.TZ = "America/Los_Angeles"; assert.equal(timerender.get_tz_with_UTC_offset(time), "PDT (UTC-07:00)"); time = date_2025; assert.equal(timerender.get_tz_with_UTC_offset(time), "PST (UTC-08:00)"); process.env.TZ = previous_env_tz; }); run_test("render_now_returns_today", () => { const today = date_2019; const expected = { time_str: $t({defaultMessage: "Today"}), formal_time_str: "Friday, April 12, 2019", needs_update: true, }; const actual = timerender.render_now(today, today); assert.equal(actual.time_str, expected.time_str); assert.equal(actual.formal_time_str, expected.formal_time_str); assert.equal(actual.needs_update, expected.needs_update); }); run_test("render_now_returns_yesterday", () => { const today = date_2019; const yesterday = add(today, {days: -1}); const expected = { time_str: $t({defaultMessage: "Yesterday"}), formal_time_str: "Thursday, April 11, 2019", needs_update: true, }; const actual = timerender.render_now(yesterday, today); assert.equal(actual.time_str, expected.time_str); assert.equal(actual.formal_time_str, expected.formal_time_str); assert.equal(actual.needs_update, expected.needs_update); }); run_test("render_now_returns_year", () => { const today = date_2019; const year_ago = add(today, {years: -1}); const expected = { time_str: "Apr 12, 2018", formal_time_str: "Thursday, April 12, 2018", needs_update: false, }; const actual = timerender.render_now(year_ago, today); assert.equal(actual.time_str, expected.time_str); assert.equal(actual.formal_time_str, expected.formal_time_str); assert.equal(actual.needs_update, expected.needs_update); }); run_test("render_now_returns_month_and_day", () => { const today = date_2019; const three_months_ago = add(today, {months: -3}); const expected = { time_str: "Jan 12", formal_time_str: "Saturday, January 12, 2019", needs_update: false, }; const actual = timerender.render_now(three_months_ago, today); assert.equal(actual.time_str, expected.time_str); assert.equal(actual.formal_time_str, expected.formal_time_str); assert.equal(actual.needs_update, expected.needs_update); }); run_test("format_time_modern", () => { const today = date_2021; const few_minutes_in_future = add(today, {minutes: 30}); const weeks_in_future = add(today, {days: 20}); const less_than_24_hours_ago = add(today, {hours: -23}); const twenty_four_hours_ago = add(today, {hours: -24}); const more_than_24_hours_ago = add(today, {hours: -25}); const less_than_a_week_ago = add(today, {days: -6}); const one_week_ago = add(today, {days: -7}); const less_than_6_months_ago = add(today, {months: -3}); const more_than_6_months_ago = add(today, {months: -9}); const previous_year_but_less_than_6_months = add(today, {months: -1}); assert.equal(timerender.format_time_modern(few_minutes_in_future, today), "Jan 27, 2021"); assert.equal(timerender.format_time_modern(weeks_in_future, today), "Feb 16, 2021"); assert.equal(timerender.format_time_modern(less_than_24_hours_ago, today), "2:53 AM"); assert.equal( timerender.format_time_modern(twenty_four_hours_ago, today), "translated: Yesterday", ); assert.equal( timerender.format_time_modern(more_than_24_hours_ago, today), "translated: Yesterday", ); assert.equal(timerender.format_time_modern(less_than_a_week_ago, today), "Thursday"); assert.equal(timerender.format_time_modern(one_week_ago, today), "Jan 20"); assert.equal( timerender.format_time_modern(previous_year_but_less_than_6_months, today), "Dec 27", ); assert.equal(timerender.format_time_modern(less_than_6_months_ago, today), "Oct 27"); assert.equal(timerender.format_time_modern(more_than_6_months_ago, today), "Apr 27, 2020"); }); run_test("format_time_modern_different_timezones", () => { const utc_tz = process.env.TZ; // Day is yesterday in UTC+0 but is 2 days ago in local timezone hence DOW is returned. let today = date_2017_PM; let yesterday = add(date_2017, {days: -1}); assert.equal(timerender.format_time_modern(yesterday, today), "translated: Yesterday"); process.env.TZ = "America/Juneau"; let expected = "translated: 5/16/2017 at 11:12:53 PM AKDT (UTC-08:00)"; assert.equal(timerender.get_full_datetime(yesterday), expected); assert.equal(timerender.format_time_modern(yesterday, today), "Tuesday"); process.env.TZ = utc_tz; // Day is 2 days ago in UTC+0 but is yesterday in local timezone. today = date_2017; yesterday = add(date_2017_PM, {days: -2}); assert.equal(timerender.format_time_modern(yesterday, today), "Tuesday"); process.env.TZ = "Asia/Brunei"; expected = "translated: 5/17/2017 at 5:12:53 AM (UTC+08:00)"; assert.equal(timerender.get_full_datetime(yesterday), expected); assert.equal(timerender.format_time_modern(yesterday, today), "translated: Yesterday"); process.env.TZ = utc_tz; // Day is 6 days ago in UTC+0 but a week ago in local timezone hence difference in returned strings. today = date_2017_PM; yesterday = add(date_2017, {days: -6}); assert.equal(timerender.format_time_modern(yesterday, today), "Friday"); process.env.TZ = "America/Juneau"; expected = "translated: 5/11/2017 at 11:12:53 PM AKDT (UTC-08:00)"; assert.equal(timerender.get_full_datetime(yesterday), expected); assert.equal(timerender.format_time_modern(yesterday, today), "May 11"); process.env.TZ = utc_tz; }); run_test("render_now_returns_year_with_year_boundary", () => { const today = date_2019; const six_months_ago = add(today, {months: -6}); const expected = { time_str: "Oct 12, 2018", formal_time_str: "Friday, October 12, 2018", needs_update: false, }; const actual = timerender.render_now(six_months_ago, today); assert.equal(actual.time_str, expected.time_str); assert.equal(actual.formal_time_str, expected.formal_time_str); assert.equal(actual.needs_update, expected.needs_update); }); run_test("render_date_renders_time_html", () => { timerender.clear_for_testing(); const today = date_2019; const message_time = today; const expected_html = $t({defaultMessage: "Today"}); const attrs = {}; const span_stub = $(""); span_stub.attr = (name, val) => { attrs[name] = val; return span_stub; }; span_stub.append = (str) => { span_stub.html(str); return span_stub; }; const actual = timerender.render_date(message_time, undefined, today); assert.equal(actual.html(), expected_html); assert.equal(attrs["data-tippy-content"], "Friday, April 12, 2019"); assert.equal(attrs.class, "timerender0"); }); run_test("render_date_renders_time_above_html", () => { const today = date_2019; const message_time = today; const message_time_above = add(today, {days: -1}); const span_stub = $(""); let appended_val; span_stub.append = (...val) => { appended_val = val; return span_stub; }; const expected = [ '', $t({defaultMessage: "Yesterday"}), '