Note the assumed duration in the calendar feed (#498) - #1093
Open
gangster wants to merge 1 commit into
Open
Conversation
A v-event needs an end time, so addDuration() adds an hour when the organizer gave no duration. Nothing said so, which left a guessed end time looking exactly as definite as a stated one. Add a line to the description saying the hour was assumed, but only when timedetails is empty. timedetails is free text about timing -- "meet 7pm, roll 7:30" -- and it prints on the line directly above, so repeating the point there reads as contradicting the organizer. Per AllEvents.md the one hour default and the timedetails line arrived together in shift-org#339, so they were meant to sit side by side. Also drop a stray global: addDuration was assigning an undeclared endTime on every call, which would throw under strict mode or ESM. Same pattern as shift-org#1089, in the function this change had to touch. Adds three cases to ical_test.js, and exports buildCalEntry for testing since the existing fixtures all hardcode a duration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #498.
A v-event needs an end time, so
addDuration()invents one hour when the organizer didn't give a duration. Nothing said so, which meant a listing with a guessed end time looked exactly as definite as one with a real end time.This adds a line to the description in that case:
The wording is a guess and easy to change. The issue says "consider adding something", so I picked something plain, in the voice of the confirmation email, using "organizer" as the rest of the app does. Say the word and I will swap it.
The change
ical.jsgains a constant and one conditional entry in the description array:escapeBreakalready drops null entries, so events with a duration are untouched.calEvent.jsgains thehasDuration()predicate, and loses a stray global:addDurationwas assigning an undeclaredendTime, creating an implicit global on every call. Same pattern as #1089, in the function this issue required me to reason about, so I fixed it here rather than filing a fourth one-line issue. Happy to split it out if you would rather keep this focused.Why it also checks
timedetailstimedetailsis organizer-written free text about timing — "meet 7pm, roll 7:30", "leave 7:30 ish" — and it prints on the line directly above this one. Saying "the organizer didn't specify an end time" immediately under the organizer's own note about the timing reads as the feed contradicting them.That reading is supported by where the one hour default came from.
docs/AllEvents.mdtraces it to the wishlist in #339, where it arrived in the same batch as the rest of the description:The assumed duration and the time details line were added together, so treating
timedetailsas the thing that already speaks to the timing seems closer to the original intent than an accident of the code.Worth flagging that this is still a departure from a literal reading of the issue, which says to note the assumption without qualifying when.
The cost of that choice, stated plainly: the
DTENDis invented in every case where there's no duration, including the ones withtimedetails. So those rides keep an unflagged assumed end time. I went narrow because widening later is a one-line change nobody notices, whereas walking it back means subscribers already saw it on entries where it wasn't wanted.Which way this should go depends on how often each case occurs across the real calendar — how many published rides have no duration, and how many of those also have no
timedetails. You can see that; I can't from here. If it turns out the narrow condition barely ever fires, drop the&& !evt.timedetailsand it applies to every assumed duration.Tests
Three cases added to
ical_test.js, bringing the suite to 56:null,0andundefined)timedetailsalready covers the timing — and checks the end time is still assumed at +60min, since this suppresses the message, not the behaviourThey go through
buildCalEntryrather than HTTP, because all three ical fixtures hardcodeeventduration: 60and changing one would churn the golden strings the existing tests compare against.buildCalEntryis now exported "for testing" alongsideescapeBreakandreplace.This also answers the standing todo in "can handle a canceled event":
Being straight about what these prove: "notes the assumed duration" fails on unpatched source for the right reason. The other two also fail there, but partly because
buildCalEntryis not exported yet — they are regression guards rather than evidence of the bug.Verification
The feed is consumed by real calendar clients, so I checked more than the string appearing.
Structure, across every feed shape, with a small RFC 5545 check (CRLF endings, 75-octet fold limit,
BEGIN/END:VEVENTbalance, well-formed content lines):The fold limit is the one that mattered, since this lengthens a description. The existing
escapeBreakhandles it.Whole-feed diff against unpatched
main, compared unfolded so folding noise could not hide anything:Three lines changed, nothing else — no timestamp drift, and no effect on the events that do have durations.
Parsed with
node-ical, to check the output against a real consumer rather than my own reading of the spec. Installed in a scratch directory outside the repo — no dependency added, nothing in anypackage.json.Comparing the parsed objects per uid, on
start,end,summary,location,statusandurl:And the note lands on exactly the events that need it:
The pedalpalooza feed parses too — 11 VEVENTs, 0 malformed, synthetic closing event intact.
What a subscriber sees, as
node-icaldecodes it:The comma and newline escapes round-trip correctly. I did not subscribe an actual calendar client (Google, Apple) to the feed, so that remains untested.
One more thing worth a decision
Cancelled occurrences get the note too. That falls out of the code path rather than being a decision: such an entry reads
CANCELLED: <title>withSTATUS:CANCELLEDand then the assumed-duration line. Harmless as far as I can tell, and arguably still accurate, but happy to suppress it there if you would rather.One thing I noticed but did not change
For an event with no duration the events endpoint returns
endtime: null, while the ical feed asserts a realDTENDan hour out —getEndTime()andaddDuration()answer the same question differently.calEvent.jsalready carries a comment doubting the split:Out of scope here, but this issue sits right on top of it, so it seemed worth surfacing.