Skip to content

Commit

Permalink
feat: add tests and more robustly deal with urls
Browse files Browse the repository at this point in the history
- Adds testing support for ICS, Eventbrite, and Meetup event ingress
- Reverts the exception throw on event merging
- Alters ICS event regex to more robustly deal with subdomains and url
  paths
  • Loading branch information
lexiwitch committed May 19, 2022
1 parent 31413ef commit c867ceb
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 21 deletions.
2 changes: 1 addition & 1 deletion app/jobs/calendar_importer/event_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def save_all_occurences

event_time[:are_spaces_available] = occurence.status if occurence.respond_to?(:status)

unless event.update! data.attributes.merge(event_time)
unless event.update data.attributes.merge(event_time)
notices << { event: event, errors: event.errors.full_messages }
end

Expand Down
23 changes: 13 additions & 10 deletions app/jobs/calendar_importer/events/ics_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,27 @@ def find_event_link
end

def event_link_regex
# (http(s)?://)? - will match against https:// or http:// or nothing
# [A-Za-z0-9]+ - will match against alphanumeric strings
# [^\s]+ - grab until we see a whitespace character
#
http = %r{(http(s)?://)?} # - https:// or http:// or nothing
alphanum = %r{[A-Za-z0-9]+} # - alphanumeric strings
subdomain = %r{(#{alphanum}\.)?} # - matches the www. or us04web in the zoom link
suffix = %r{[^\s<"]+} # - matches until we see a whitespace character,
# an angle bracket, or a quote (thanks html)

# We deal with the following strings:
# meet.jit.si/foobarbaz
# meet.google.com/kbv-byuf-cvq
# facebook.com/events/(really long url)
# us04web.zoom.us/j/(really long url)
# zoom.us/j/(really long url)
# We also deal with strings like
# <a href="(event url)">
# <p>(event url)</p>

http = %r{(http(s)?://)?}
alphanum = %r{[A-Za-z0-9]+}
links = {
'jitsi': %r{#{http}meet.jit.si/[^\s]+},
'meets': %r{#{http}meet.google.com/[^\s]+},
'facebook': %r{#{http}facebook.com/events/[^\s]+},
'zoom': %r{#{http}(#{alphanum}\.)?zoom.us/j/[^\s]+}
'jitsi': %r{#{http}#{subdomain}meet.jit.si/#{suffix}},
'meets': %r{#{http}#{subdomain}meet.google.com/#{suffix}},
'facebook': %r{#{http}#{subdomain}facebook.com/events/#{suffix}},
'zoom': %r{#{http}#{subdomain}zoom.us/j/#{suffix}}
}

Regexp.union links.values
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/calendar_importer/events/meetup_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def publisher_url
end

def location
return nil
return nil # TODO: ??? Why are we ignoring the venue for meetup events

venue = @event['venue']
if venue
Expand Down
180 changes: 171 additions & 9 deletions test/jobs/calendar_importer/event_resolver_test.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,89 @@
require 'test_helper'

class EventsResolverTest < ActiveSupport::TestCase
FakeEvent = Struct.new(
FakeICSEvent = Struct.new(
:uid,
:summary,
:description,
:location,
:rrule,
:last_modified,
:ocurrences_between
:ocurrences_between,
:custom_properties,
# Fixes bug where entire argument to .new ended up under the uid value lmao
# Who knew our importer was *that* robust?!
keyword_init: true
)

FakeEventbriteEvent = Struct.new(
:id,
:name,
:description,
:venue,
:start,
:end,
:online_event,
:url,
keyword_init: true
)

FakeMeetupEvent = Struct.new(
:id,
:name,
:description,
:link,
:venue,
:time,
:utc_offset,
:duration,
:is_online_event,
keyword_init: true
)

setup do
@start_date = Date.new(1990, 1, 1)
@end_date = Date.new(1990, 1, 2)
@start_date = DateTime.new(1990, 1, 1, 10, 30)
@end_date = DateTime.new(1990, 1, 2, 11, 40)

fake_event = FakeEvent.new(
@fake_ics_event = FakeICSEvent.new(
uid: 123,
summary: 'A summary',
description: 'A description',
location: 'A location',
rrule: '',
last_modified: '',
ocurrences_between: [[@start_date, @end_date]]
ocurrences_between: [[@start_date, @end_date]],
custom_properties: {}
)

@event_data = CalendarImporter::Events::IcsEvent.new(fake_event, @start_date, @end_date)
@fake_eventbrite_event = FakeEventbriteEvent.new(
id: '111111111111',
name: { 'text': 'A summary' },
description: { 'text': 'A description' },
venue: nil,
start: { 'local': @start_date.iso8601 },
'end': { 'local': @end_date.iso8601 },
online_event: true
)

@fake_meetup_event = FakeMeetupEvent.new(
id: '111111111',
name: { 'text': 'A summary' },
description: { 'text': '<p>This is a meetup description!</p>' },
venue: nil,
time: @start_date.to_i,
utc_offset: (@end_date.to_i - @start_date.to_i),
is_online_event: true
)

@ics_event_data = CalendarImporter::Events::IcsEvent.new(@fake_ics_event, @start_date, @end_date)
end

test 'online only strategy' do
calendar = create(:calendar, strategy: 'online_only')
notices = []
from_date = @start_date

resolver = CalendarImporter::EventResolver.new(@event_data, calendar, notices, from_date)
resolver = CalendarImporter::EventResolver.new(@ics_event_data, calendar, notices, from_date)
resolver.determine_location_for_strategy

# these are not set even if present in source
Expand All @@ -49,7 +99,7 @@ class EventsResolverTest < ActiveSupport::TestCase
notices = []
from_date = @start_date

resolver = CalendarImporter::EventResolver.new(@event_data, calendar, notices, from_date)
resolver = CalendarImporter::EventResolver.new(@ics_event_data, calendar, notices, from_date)
resolver.determine_location_for_strategy

# these are not set even if present in source
Expand All @@ -59,4 +109,116 @@ class EventsResolverTest < ActiveSupport::TestCase
# still sets partner
assert_equal calendar.partner_id, resolver.data.partner_id
end

test 'ics: can detect google meet url in custom properties' do
meet_link = 'https://meet.google.com/aaa-aaaa-aaa'
@fake_ics_event[:custom_properties] = { 'x_google_conference' => [meet_link] }
ics_event_data = CalendarImporter::Events::IcsEvent.new(@fake_ics_event, @start_date, @end_date)

calendar = create(:calendar, strategy: 'event') # strategy doesn't matter TBH

resolver = CalendarImporter::EventResolver.new(ics_event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, @fake_ics_event['custom_properties']['x_google_conference'].first
end

test 'ics: can detect jitsi link in description' do
jitsi_link = 'https://meet.jit.si/blahblabladsf'
@fake_ics_event[:description] = "Join us on jitsi: #{jitsi_link} words words words"
ics_event_data = CalendarImporter::Events::IcsEvent.new(@fake_ics_event, @start_date, @end_date)

calendar = create(:calendar, strategy: 'event')

resolver = CalendarImporter::EventResolver.new(ics_event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, jitsi_link
end

test 'ics: can detect google meet link in description' do
meet_link = 'https://meet.google.com/aaa-aaaa-aaa'
@fake_ics_event[:description] = "Join us on meets: #{meet_link} words words words"
ics_event_data = CalendarImporter::Events::IcsEvent.new(@fake_ics_event, @start_date, @end_date)

calendar = create(:calendar, strategy: 'event')

resolver = CalendarImporter::EventResolver.new(ics_event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, meet_link
end

test 'ics: can detect facebook event link in description' do
fb_link = 'https://www.facebook.com/events/349588176081231/'
@fake_ics_event[:description] = "See more info on facebook: #{fb_link} words words words"
ics_event_data = CalendarImporter::Events::IcsEvent.new(@fake_ics_event, @start_date, @end_date)

calendar = create(:calendar, strategy: 'event')

resolver = CalendarImporter::EventResolver.new(ics_event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, fb_link
end

test 'ics: can detect zoom link in description' do
zoom_link = 'https://us04web.zoom.us/j/78434510758?pwd=aILSsYSJRSb_uO87tFjulZuLAA0eXT.1'
@fake_ics_event[:description] = "join us on zoom: <p>#{zoom_link}<p> words words words"
ics_event_data = CalendarImporter::Events::IcsEvent.new(@fake_ics_event, @start_date, @end_date)

calendar = create(:calendar, strategy: 'event')

resolver = CalendarImporter::EventResolver.new(ics_event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, zoom_link
end

test 'eventbrite: can detect online event url' do
eventbrite_link = 'https://www.eventbrite.co.uk/e/some-random-event-woo-hoo-111111111111'
@fake_eventbrite_event[:url] = eventbrite_link
event_data = CalendarImporter::Events::EventbriteEvent.new(@fake_eventbrite_event)

calendar = create(:calendar, strategy: 'event')

resolver = CalendarImporter::EventResolver.new(event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, eventbrite_link
end

test 'meetup: can detect online event url' do
meetup_link = 'https://www.meetup.co.uk/e/some-random-event-woo-hoo-111111111111'
@fake_meetup_event[:link] = meetup_link
event_data = CalendarImporter::Events::MeetupEvent.new(@fake_meetup_event)

calendar = create(:calendar, strategy: 'event')

resolver = CalendarImporter::EventResolver.new(event_data, calendar, [], @start_date)
resolver.determine_online_location

assert resolver.data.online_address_id.present?

online_address = OnlineAddress.find(resolver.data.online_address_id)
assert_equal online_address.url, meetup_link
end
end

0 comments on commit c867ceb

Please sign in to comment.