server: fix date parsing w/ TZ and cal widget highlight
This commit is contained in:
@@ -1837,39 +1837,42 @@ pub fn render_ical_summary(ical_data: &str) -> Result<String, ServerError> {
|
||||
}
|
||||
}
|
||||
|
||||
// Always use America/Los_Angeles for Google Calendar events if no TZID is present
|
||||
let event_tz: Tz = tzid
|
||||
.as_deref()
|
||||
.unwrap_or("America/Los_Angeles")
|
||||
.parse()
|
||||
.unwrap_or(chrono_tz::America::Los_Angeles);
|
||||
|
||||
// Parse start/end as chrono DateTime
|
||||
let (local_fmt_start, local_fmt_end, event_days, recurrence_display) =
|
||||
if let Some(dtstart) = dtstart {
|
||||
let tz: Tz = tzid
|
||||
.as_deref()
|
||||
.unwrap_or("UTC")
|
||||
.parse()
|
||||
.unwrap_or(chrono_tz::UTC);
|
||||
let fallback = chrono::DateTime::<chrono::Utc>::from_timestamp(0, 0)
|
||||
.map(|dt| dt.with_timezone(&tz))
|
||||
.map(|dt| dt.with_timezone(&event_tz))
|
||||
.unwrap_or_else(|| {
|
||||
tz.with_ymd_and_hms(1970, 1, 1, 0, 0, 0)
|
||||
event_tz
|
||||
.with_ymd_and_hms(1970, 1, 1, 0, 0, 0)
|
||||
.single()
|
||||
.unwrap_or_else(|| tz.timestamp_opt(0, 0).single().unwrap())
|
||||
.unwrap_or_else(|| event_tz.timestamp_opt(0, 0).single().unwrap())
|
||||
});
|
||||
let start = parse_ical_datetime_tz(dtstart, tz).unwrap_or(fallback);
|
||||
let start = parse_ical_datetime_tz(dtstart, event_tz).unwrap_or(fallback);
|
||||
let end = dtend
|
||||
.and_then(|d| parse_ical_datetime_tz(d, tz))
|
||||
.and_then(|d| parse_ical_datetime_tz(d, event_tz))
|
||||
.unwrap_or(start);
|
||||
let local_start = start.with_timezone(&Local);
|
||||
let local_end = end.with_timezone(&Local);
|
||||
// Use the event's TZ for all calendar grid/highlighting logic
|
||||
let allday =
|
||||
dtstart.len() == 8 && (dtend.map(|s| s.len() == 8).unwrap_or(false));
|
||||
let fmt_start = if allday {
|
||||
local_start.format("%a %b %e, %Y").to_string()
|
||||
start.format("%a %b %e, %Y").to_string()
|
||||
} else {
|
||||
local_start.format("%-I:%M %p %a %b %e, %Y").to_string()
|
||||
start.format("%-I:%M %p %a %b %e, %Y").to_string()
|
||||
};
|
||||
let fmt_end = if allday {
|
||||
local_end.format("%a %b %e, %Y").to_string()
|
||||
end.format("%a %b %e, %Y").to_string()
|
||||
} else {
|
||||
local_end.format("%-I:%M %p %a %b %e, %Y").to_string()
|
||||
end.format("%-I:%M %p %a %b %e, %Y").to_string()
|
||||
};
|
||||
// All calendar grid and event_days logic below uses start/end in event's TZ
|
||||
|
||||
// Recurrence support: parse RRULE and generate event_days accordingly
|
||||
let mut days = vec![];
|
||||
@@ -2144,6 +2147,39 @@ fn parse_ical_datetime_tz(dt: &str, tz: Tz) -> Option<chrono::DateTime<Tz>> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn google_calendar_email_thursday_highlights_thursday() {
|
||||
use mailparse::parse_mail;
|
||||
let raw_email = include_str!("../../server/testdata/google-calendar-example-thursday.eml");
|
||||
let parsed = parse_mail(raw_email.as_bytes()).expect("parse_mail");
|
||||
let mut part_addr = vec![];
|
||||
let body = extract_body(&parsed, &mut part_addr).expect("extract_body");
|
||||
let meta = extract_calendar_metadata_from_mail(&parsed, &body);
|
||||
// Assert detection as Google Calendar
|
||||
assert!(meta.is_google_calendar_event);
|
||||
// Debug: print the rendered HTML for inspection
|
||||
let html = meta.body_html.expect("body_html");
|
||||
println!("Rendered HTML: {}", html);
|
||||
// Check that the calendar table highlights Thursday, not Friday
|
||||
// Look for a table header row with days of week (allow whitespace)
|
||||
let thursday_idx = html
|
||||
.find(">\n Thu<")
|
||||
.or_else(|| html.find(">Thu<"))
|
||||
.expect("Should have a Thursday column");
|
||||
let friday_idx = html
|
||||
.find(">\n Fri<")
|
||||
.or_else(|| html.find(">Fri<"))
|
||||
.expect("Should have a Friday column");
|
||||
// Find the first highlighted cell (background:#ffd700)
|
||||
let highlight_idx = html
|
||||
.find("background:#ffd700")
|
||||
.expect("Should highlight a day");
|
||||
// The highlight should be closer to Thursday than Friday
|
||||
assert!(
|
||||
highlight_idx > thursday_idx && highlight_idx < friday_idx,
|
||||
"Thursday should be highlighted, not Friday"
|
||||
);
|
||||
}
|
||||
use super::*;
|
||||
#[test]
|
||||
fn google_calendar_email_3_single_event_metadata() {
|
||||
|
||||
Reference in New Issue
Block a user