Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions sources/ti.to/find-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,34 @@ function extractEventDetails(html, url) {
throw new Error(`No calendar info found on ${url}`);
}

const locationHref = $(".tito-event-homepage--basic-info-location a").attr(
"href",
);
const locationLink = $(".tito-event-homepage--basic-info-location a");
const locationHref = locationLink.attr("href");
if (!locationHref) {
throw new Error(`No location link found on ${url}`);
}

const description = getText($(".tito-description"));

// An organiser can type a location instead of picking a venue. The page
// then has no venue record: no address list, and a maps link that searches
// for the typed text rather than pointing at coordinates. The typed text is
// all there is, so the event is matched on that name alone.
const venueAddress = getText($(".tito-venues li a span"));
if (!venueAddress) {
throw new Error(`No .tito-venues address found on ${url}`);
const locationText = getText(locationLink);
if (!locationText) {
throw new Error(`No .tito-venues address or location text on ${url}`);
}
return {
title,
venueName: locationText,
venueAddress: locationText,
coordinates: null,
parsedDate: parseCalText(calText),
description,
};
}

const description = getText($(".tito-description"));

const coordinates = extractCoordinatesFromMapsUrl(locationHref);

// First segment of venue address is the venue name
Expand Down
61 changes: 61 additions & 0 deletions sources/ti.to/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,65 @@ describe(`${attributes.name}`, () => {

expect(output).toHaveLength(0);
});

// Markup from https://ti.to/queereast/girlfriends_uea_2026, whose organiser
// typed a location rather than picking a venue
describe("an event with a typed location and no venue record", () => {
const html = `
<h1 class="event-title">Girlfriends (University of East Anglia)</h1>
<div class="tito-event-homepage--basic-info tito-event-homepage--basic-info-cal">
<a href="https://checkout.tito.io/queereast/girlfriends_uea_2026?format=ics">
6:30–8pm, November 18th, 2026
</a>
</div>
<div class="tito-event-homepage--basic-info tito-event-homepage--basic-info-location">
<a href="https://maps.google.com/maps?q=University+of+East+Anglia+">
University of East Anglia
</a>
</div>
<div class="tito-description markdown"><p>Join Queer East for a screening of Girlfriends (2025)</p></div>
<div class="tito-links-section">
<h4 class="tito-venues-heading">Links</h4>
<ul class="tito-links"><li><a href="mailto:info@queereast.org.uk"><span>info@queereast.org.uk</span></a></li></ul>
</div>`;
const venues = {
queereast: {
moviePages: {
"https://ti.to/queereast/girlfriends_uea_2026": html,
},
},
};
const geo = { lat: 51.5162287, lon: -0.1213371 };

it("is matched to a cinema of that name", async () => {
readJSON.mockImplementation(() => venues);

const output = await findEvents({
name: "University of East Anglia",
alternativeNames: [],
address: "39-41 Parker St, London WC2B 5PQ, UK",
geo,
});

expect(output).toHaveLength(1);
expect(output[0].title).toBe("Girlfriends (University of East Anglia)");
expect(output[0].performances).toHaveLength(1);
expect(output[0].performances[0].time).toBe(
new Date("2026-11-18T18:30:00Z").getTime(),
);
});

it("is not matched to any other cinema", async () => {
readJSON.mockImplementation(() => venues);

const output = await findEvents({
name: "The Garden Cinema",
alternativeNames: [],
address: "39-41 Parker St, London WC2B 5PQ, UK",
geo,
});

expect(output).toHaveLength(0);
});
});
});
Loading