calagator 0.0.1.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +23 -0
- data/README.md +75 -0
- data/Rakefile +12 -0
- data/app/assets/images/confused-alligator-sm.png +0 -0
- data/app/assets/images/disk.png +0 -0
- data/app/assets/images/edit.png +0 -0
- data/app/assets/images/external_sites/epdx.png +0 -0
- data/app/assets/images/external_sites/external.gif +0 -0
- data/app/assets/images/external_sites/facebook.png +0 -0
- data/app/assets/images/external_sites/foursquare.png +0 -0
- data/app/assets/images/external_sites/gowalla.png +0 -0
- data/app/assets/images/external_sites/lanyrd.png +0 -0
- data/app/assets/images/external_sites/meetup.png +0 -0
- data/app/assets/images/external_sites/plancast.png +0 -0
- data/app/assets/images/external_sites/shizzow.png +0 -0
- data/app/assets/images/external_sites/upcoming.png +0 -0
- data/app/assets/images/external_sites/yelp.png +0 -0
- data/app/assets/images/feed.png +0 -0
- data/app/assets/images/heart.png +0 -0
- data/app/assets/images/icon_ical.gif +0 -0
- data/app/assets/images/information.png +0 -0
- data/app/assets/images/nav_marker.gif +0 -0
- data/app/assets/images/nav_marker.png +0 -0
- data/app/assets/images/plus.png +0 -0
- data/app/assets/images/redx.png +0 -0
- data/app/assets/images/site-icon.png +0 -0
- data/app/assets/images/spinner.gif +0 -0
- data/app/assets/images/star.png +0 -0
- data/app/assets/images/subnav_marker.gif +0 -0
- data/app/assets/images/subnav_marker.png +0 -0
- data/app/assets/images/tag_blue.png +0 -0
- data/app/assets/images/tag_icons/angular.png +0 -0
- data/app/assets/images/tag_icons/beer.png +0 -0
- data/app/assets/images/tag_icons/bitcoin.png +0 -0
- data/app/assets/images/tag_icons/free.png +0 -0
- data/app/assets/images/tag_icons/golang.png +0 -0
- data/app/assets/images/tag_icons/html.png +0 -0
- data/app/assets/images/tag_icons/javascript.png +0 -0
- data/app/assets/images/tag_icons/linux.png +0 -0
- data/app/assets/images/tag_icons/php.png +0 -0
- data/app/assets/images/tag_icons/pizza.png +0 -0
- data/app/assets/images/tag_icons/python.png +0 -0
- data/app/assets/images/tag_icons/rails.png +0 -0
- data/app/assets/images/tag_icons/ruby.png +0 -0
- data/app/assets/images/tag_icons/sass.png +0 -0
- data/app/assets/images/tag_icons/swift.png +0 -0
- data/app/assets/images/transmit_blue.png +0 -0
- data/app/assets/images/weekday_background.gif +0 -0
- data/app/assets/javascripts/calagator.js +18 -0
- data/app/assets/javascripts/calagator/forms.js +60 -0
- data/app/assets/stylesheets/calagator.scss +8 -0
- data/app/assets/stylesheets/calagator/common.scss +14 -0
- data/app/assets/stylesheets/calagator/datepicker.scss +177 -0
- data/app/assets/stylesheets/calagator/errors.css +110 -0
- data/app/assets/stylesheets/calagator/forms.scss +4 -0
- data/app/assets/stylesheets/calagator/reset.css +40 -0
- data/app/assets/stylesheets/calagator/theme.css +0 -0
- data/app/controllers/calagator/admin_controller.rb +27 -0
- data/app/controllers/calagator/application_controller.rb +82 -0
- data/app/controllers/calagator/events_controller.rb +171 -0
- data/app/controllers/calagator/site_controller.rb +35 -0
- data/app/controllers/calagator/sources_controller.rb +94 -0
- data/app/controllers/calagator/venues_controller.rb +133 -0
- data/app/controllers/calagator/versions_controller.rb +20 -0
- data/app/helpers/calagator/application_helper.rb +128 -0
- data/app/helpers/calagator/events_helper.rb +184 -0
- data/app/helpers/calagator/google_event_export_helper.rb +67 -0
- data/app/helpers/calagator/mapping_helper.rb +103 -0
- data/app/helpers/calagator/sources_helper.rb +10 -0
- data/app/helpers/calagator/tags_helper.rb +42 -0
- data/app/helpers/calagator/time_range_helper.rb +166 -0
- data/app/models/calagator/event.rb +246 -0
- data/app/models/calagator/event/cloner.rb +39 -0
- data/app/models/calagator/event/ical_renderer.rb +155 -0
- data/app/models/calagator/event/overview.rb +45 -0
- data/app/models/calagator/event/saver.rb +58 -0
- data/app/models/calagator/event/search.rb +72 -0
- data/app/models/calagator/event/search_engine.rb +28 -0
- data/app/models/calagator/event/search_engine/apache_sunspot.rb +106 -0
- data/app/models/calagator/event/search_engine/sql.rb +107 -0
- data/app/models/calagator/source.rb +115 -0
- data/app/models/calagator/source/importer.rb +46 -0
- data/app/models/calagator/source/parser.rb +128 -0
- data/app/models/calagator/source/parser/facebook.rb +67 -0
- data/app/models/calagator/source/parser/hcal.rb +108 -0
- data/app/models/calagator/source/parser/http_authentication_required_error.rb +6 -0
- data/app/models/calagator/source/parser/ical.rb +186 -0
- data/app/models/calagator/source/parser/meetup.rb +72 -0
- data/app/models/calagator/source/parser/not_found.rb +9 -0
- data/app/models/calagator/source/parser/plancast.rb +59 -0
- data/app/models/calagator/venue.rb +161 -0
- data/app/models/calagator/venue/geocoder.rb +51 -0
- data/app/models/calagator/venue/search.rb +63 -0
- data/app/models/calagator/venue/search_engine.rb +24 -0
- data/app/models/calagator/venue/search_engine/apache_sunspot.rb +85 -0
- data/app/models/calagator/venue/search_engine/sql.rb +68 -0
- data/app/models/event/search_engine/base.rb +0 -0
- data/app/observers/calagator/cache_observer.rb +37 -0
- data/app/views/calagator/admin/events.html.erb +28 -0
- data/app/views/calagator/admin/index.html.erb +8 -0
- data/app/views/calagator/events/_feed_item.html.erb +62 -0
- data/app/views/calagator/events/_form.html.erb +63 -0
- data/app/views/calagator/events/_gcal_reminder.html.erb +1 -0
- data/app/views/calagator/events/_hcal.html.erb +41 -0
- data/app/views/calagator/events/_item.html.erb +120 -0
- data/app/views/calagator/events/_list.html.erb +30 -0
- data/app/views/calagator/events/_list_item.html.erb +37 -0
- data/app/views/calagator/events/_search_section.html.erb +15 -0
- data/app/views/calagator/events/_subnav.html.erb +13 -0
- data/app/views/calagator/events/_table.html.erb +74 -0
- data/app/views/calagator/events/duplicates.html.erb +58 -0
- data/app/views/calagator/events/edit.html.erb +3 -0
- data/app/views/calagator/events/index.atom.builder +32 -0
- data/app/views/calagator/events/index.html.erb +51 -0
- data/app/views/calagator/events/index.kml.erb +20 -0
- data/app/views/calagator/events/new.html.erb +7 -0
- data/app/views/calagator/events/search.html.erb +25 -0
- data/app/views/calagator/events/show.html.erb +81 -0
- data/app/views/calagator/site/_appropriateness_message.html.erb +15 -0
- data/app/views/calagator/site/_description.html.erb +3 -0
- data/app/views/calagator/site/about.html.erb +7 -0
- data/app/views/calagator/site/defunct.html.erb +15 -0
- data/app/views/calagator/site/export.html.erb +4 -0
- data/app/views/calagator/site/index.html.erb +40 -0
- data/app/views/calagator/site/opensearch.xml.builder +8 -0
- data/app/views/calagator/sources/_subnav.html.erb +0 -0
- data/app/views/calagator/sources/edit.html.erb +12 -0
- data/app/views/calagator/sources/import.html.erb +10 -0
- data/app/views/calagator/sources/index.html.erb +22 -0
- data/app/views/calagator/sources/new.html.erb +32 -0
- data/app/views/calagator/sources/show.html.erb +16 -0
- data/app/views/calagator/venues/_form.html.erb +57 -0
- data/app/views/calagator/venues/_subnav.html.erb +10 -0
- data/app/views/calagator/venues/duplicates.html.erb +65 -0
- data/app/views/calagator/venues/edit.html.erb +3 -0
- data/app/views/calagator/venues/index.html.erb +93 -0
- data/app/views/calagator/venues/index.kml.erb +15 -0
- data/app/views/calagator/venues/map.html.erb +4 -0
- data/app/views/calagator/venues/new.html.erb +5 -0
- data/app/views/calagator/venues/show.html.erb +113 -0
- data/app/views/calagator/versions/_chooser.html.erb +28 -0
- data/app/views/calagator/versions/_edit_with_chooser.html.erb +16 -0
- data/app/views/layouts/calagator/application.html.erb +110 -0
- data/config/deploy/local.rb +37 -0
- data/config/deploy/lucca.rb +33 -0
- data/config/initializers/dates.rb +7 -0
- data/config/initializers/formtastic.rb +82 -0
- data/config/initializers/geokit.rb +74 -0
- data/config/initializers/ics_renderer.rb +6 -0
- data/config/initializers/load_tag_model_extensions.rb +3 -0
- data/config/initializers/mime_types.rb +9 -0
- data/config/initializers/observers.rb +1 -0
- data/config/initializers/search_engine.rb +4 -0
- data/config/initializers/set_default_url_host.rb +5 -0
- data/config/initializers/time_get_zone.rb +8 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +55 -0
- data/config/secrets.yml.blag +75 -0
- data/config/sunspot.yml +23 -0
- data/db/development.sqlite3 +0 -0
- data/db/development.sqlite3.bak +0 -0
- data/db/development.sqlite3.old +0 -0
- data/db/development~20111112@110950.sqlite3 +0 -0
- data/db/migrate/001_create_events.rb +17 -0
- data/db/migrate/002_create_venues.rb +17 -0
- data/db/migrate/003_create_sources.rb +16 -0
- data/db/migrate/004_add_detailed_fields_to_venue.rb +19 -0
- data/db/migrate/005_add_end_time_to_events.rb +9 -0
- data/db/migrate/006_add_source_id_to_events.rb +9 -0
- data/db/migrate/008_add_source_id_to_venues.rb +10 -0
- data/db/migrate/009_add_duplicate_of_column_to_venues.rb +9 -0
- data/db/migrate/010_add_duplicate_of_column_to_events.rb +9 -0
- data/db/migrate/011_change_lat_long_type.rb +12 -0
- data/db/migrate/012_add_source_reimport.rb +9 -0
- data/db/migrate/013_change_end_time_to_duration.rb +11 -0
- data/db/migrate/014_remove_format_type_from_source.rb +9 -0
- data/db/migrate/015_create_updates.rb +15 -0
- data/db/migrate/016_remove_next_update_from_source.rb +9 -0
- data/db/migrate/20080705163959_change_duration_to_end_time.rb +11 -0
- data/db/migrate/20080705164959_create_tags_and_taggings.rb +28 -0
- data/db/migrate/20081011181519_create_versioned_events.rb +25 -0
- data/db/migrate/20081011193124_create_versioned_venues.rb +32 -0
- data/db/migrate/20081115190515_add_rrule_to_events.rb +15 -0
- data/db/migrate/20090912082129_create_versions.rb +18 -0
- data/db/migrate/20110219205156_add_closed_flag_to_venues.rb +9 -0
- data/db/migrate/20110220001008_add_wifi_flag_to_venues.rb +9 -0
- data/db/migrate/20110220011427_add_access_notes_to_venues.rb +9 -0
- data/db/migrate/20110220031117_add_events_count_to_venues.rb +8 -0
- data/db/migrate/20110604174521_add_venue_details_to_events.rb +9 -0
- data/db/migrate/20110717231316_acts_as_taggable_on_migration.rb +50 -0
- data/db/migrate/20120709092821_cleanup.rb +14 -0
- data/db/migrate/20120831234448_specify_venues_latitude_and_longitude_precision.rb +11 -0
- data/db/migrate/20150206085809_remove_updates.rb +13 -0
- data/db/migrate/20150207231355_add_locked_status_to_events.rb +5 -0
- data/db/production.sqlite3 +0 -0
- data/db/schema.rb +102 -0
- data/db/seeds.rb +16 -0
- data/db/test.sqlite3 +0 -0
- data/db/test2.sqlite3 +0 -0
- data/lib/calagator.rb +30 -0
- data/lib/calagator/blacklist_validator.rb +69 -0
- data/lib/calagator/decode_html_entities_hack.rb +33 -0
- data/lib/calagator/duplicate_checking.rb +133 -0
- data/lib/calagator/duplicate_checking/controller_actions.rb +38 -0
- data/lib/calagator/duplicate_checking/duplicate_finder.rb +83 -0
- data/lib/calagator/duplicate_checking/duplicate_squasher.rb +74 -0
- data/lib/calagator/engine.rb +30 -0
- data/lib/calagator/strip_whitespace.rb +19 -0
- data/lib/calagator/tag_model_extensions.rb +104 -0
- data/lib/calagator/url_prefixer.rb +9 -0
- data/lib/calagator/version.rb +3 -0
- data/lib/generators/calagator/install_generator.rb +39 -0
- data/lib/generators/calagator/templates/config/calagator.rb +26 -0
- data/lib/generators/calagator/templates/config/secrets.yml.sample +83 -0
- data/lib/secrets_reader.rb +76 -0
- data/lib/tasks/spec_db.rake +53 -0
- data/lib/tasks/sunspot_reindex_calagator.rake +6 -0
- data/lib/tasks/sunspot_solr_restart_enhancements.rake +19 -0
- data/lib/tasks/update_counter_caches.rake +13 -0
- data/lib/templates/erb/scaffold/_form.html.erb +11 -0
- data/lib/theme_reader.rb +17 -0
- data/lib/wait_for_solr.rb +25 -0
- data/spec/controllers/calagator/application_controller_spec.rb +47 -0
- data/spec/controllers/calagator/events_controller_spec.rb +794 -0
- data/spec/controllers/calagator/site_controller_spec.rb +59 -0
- data/spec/controllers/calagator/sources_controller_spec.rb +439 -0
- data/spec/controllers/calagator/venues_controller_spec.rb +319 -0
- data/spec/controllers/calagator/versions_controller_spec.rb +82 -0
- data/spec/controllers/squash_many_duplicates_examples.rb +49 -0
- data/spec/dummy/Gemfile +39 -0
- data/spec/dummy/Gemfile.lock +195 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/stylesheets/application.css +14 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +62 -0
- data/spec/dummy/config/boot.rb +6 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/calagator.rb +26 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +59 -0
- data/spec/dummy/config/secrets.yml +83 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20150309023304_create_events.calagator.rb +18 -0
- data/spec/dummy/db/migrate/20150309023305_create_venues.calagator.rb +18 -0
- data/spec/dummy/db/migrate/20150309023306_create_sources.calagator.rb +17 -0
- data/spec/dummy/db/migrate/20150309023307_add_detailed_fields_to_venue.calagator.rb +20 -0
- data/spec/dummy/db/migrate/20150309023308_add_end_time_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023309_add_source_id_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023310_add_source_id_to_venues.calagator.rb +11 -0
- data/spec/dummy/db/migrate/20150309023311_add_duplicate_of_column_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023312_add_duplicate_of_column_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023313_change_lat_long_type.calagator.rb +13 -0
- data/spec/dummy/db/migrate/20150309023314_add_source_reimport.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023315_change_end_time_to_duration.calagator.rb +12 -0
- data/spec/dummy/db/migrate/20150309023316_remove_format_type_from_source.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023317_create_updates.calagator.rb +16 -0
- data/spec/dummy/db/migrate/20150309023318_remove_next_update_from_source.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023319_change_duration_to_end_time.calagator.rb +12 -0
- data/spec/dummy/db/migrate/20150309023320_create_tags_and_taggings.calagator.rb +29 -0
- data/spec/dummy/db/migrate/20150309023321_create_versioned_events.calagator.rb +26 -0
- data/spec/dummy/db/migrate/20150309023322_create_versioned_venues.calagator.rb +33 -0
- data/spec/dummy/db/migrate/20150309023323_add_rrule_to_events.calagator.rb +16 -0
- data/spec/dummy/db/migrate/20150309023324_create_versions.calagator.rb +19 -0
- data/spec/dummy/db/migrate/20150309023325_add_closed_flag_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023326_add_wifi_flag_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023327_add_access_notes_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023328_add_events_count_to_venues.calagator.rb +9 -0
- data/spec/dummy/db/migrate/20150309023329_add_venue_details_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023330_acts_as_taggable_on_migration.calagator.rb +51 -0
- data/spec/dummy/db/migrate/20150309023331_cleanup.calagator.rb +15 -0
- data/spec/dummy/db/migrate/20150309023332_specify_venues_latitude_and_longitude_precision.calagator.rb +12 -0
- data/spec/dummy/db/migrate/20150309023333_remove_updates.calagator.rb +14 -0
- data/spec/dummy/db/migrate/20150309023334_add_locked_status_to_events.calagator.rb +6 -0
- data/spec/dummy/db/schema.rb +95 -0
- data/spec/dummy/db/seeds.rb +7 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/doc/README_FOR_APP +2 -0
- data/spec/dummy/log/development.log +273 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/test/performance/browsing_test.rb +12 -0
- data/spec/dummy/test/test_helper.rb +13 -0
- data/spec/factories.rb +93 -0
- data/spec/features/add_event_spec.rb +99 -0
- data/spec/features/add_venue_spec.rb +34 -0
- data/spec/features/admin_auth_spec.rb +22 -0
- data/spec/features/admin_lock_event_spec.rb +41 -0
- data/spec/features/import_events_from_feed_spec.rb +43 -0
- data/spec/features/managing_event_spec.rb +111 -0
- data/spec/features/managing_venue_spec.rb +71 -0
- data/spec/features/search_event_spec.rb +27 -0
- data/spec/helpers/calagator/application_helper_spec.rb +82 -0
- data/spec/helpers/calagator/events_helper_spec.rb +172 -0
- data/spec/helpers/calagator/google_event_export_helper_spec.rb +70 -0
- data/spec/helpers/calagator/sources_helper_spec.rb +12 -0
- data/spec/helpers/calagator/tags_helper_spec.rb +85 -0
- data/spec/helpers/calagator/time_range_helper_spec.rb +59 -0
- data/spec/lib/calagator/blacklist_validator_spec.rb +65 -0
- data/spec/lib/calagator/decode_html_entities_hack_spec.rb +54 -0
- data/spec/lib/calagator/settings_spec.rb +20 -0
- data/spec/lib/calagator/url_prefixer_spec.rb +33 -0
- data/spec/lib/secrets_reader_spec.rb +65 -0
- data/spec/models/calagator/event/cloner_spec.rb +43 -0
- data/spec/models/calagator/event/overview_spec.rb +79 -0
- data/spec/models/calagator/event/search_spec.rb +103 -0
- data/spec/models/calagator/event_search_spec.rb +149 -0
- data/spec/models/calagator/event_spec.rb +859 -0
- data/spec/models/calagator/source/parser_facebook_spec.rb +73 -0
- data/spec/models/calagator/source/parser_hcal_spec.rb +69 -0
- data/spec/models/calagator/source/parser_ical_non_standard_spec.rb +91 -0
- data/spec/models/calagator/source/parser_ical_spec.rb +322 -0
- data/spec/models/calagator/source/parser_meetup_spec.rb +69 -0
- data/spec/models/calagator/source/parser_plancast_spec.rb +53 -0
- data/spec/models/calagator/source/parser_spec.rb +238 -0
- data/spec/models/calagator/source_spec.rb +135 -0
- data/spec/models/calagator/venue/search_spec.rb +92 -0
- data/spec/models/calagator/venue_search_spec.rb +124 -0
- data/spec/models/calagator/venue_spec.rb +346 -0
- data/spec/models/tag_spec.rb +35 -0
- data/spec/rails_helper.rb +39 -0
- data/spec/spec_helper.rb +140 -0
- data/spec/support/disable_geocoding.rb +1 -0
- data/spec/support/http_samples.rb +5 -0
- data/spec/support/samples/facebook.json +23 -0
- data/spec/support/samples/hcal_basic.xml +6 -0
- data/spec/support/samples/hcal_dup_event_dup_venue.xml +13 -0
- data/spec/support/samples/hcal_event_duplicates_fixture.xml +13 -0
- data/spec/support/samples/hcal_event_wo_lat_and_long.xml +14 -0
- data/spec/support/samples/hcal_multiple.xml +16 -0
- data/spec/support/samples/hcal_same_event_twice_with_different_venues.xml +12 -0
- data/spec/support/samples/hcal_single.xml +8 -0
- data/spec/support/samples/hcal_two_identical_events.xml +14 -0
- data/spec/support/samples/hcal_upcoming_v1.html +412 -0
- data/spec/support/samples/hcal_upcoming_v2.html +749 -0
- data/spec/support/samples/hcal_upcoming_v3.html +685 -0
- data/spec/support/samples/hcal_upcoming_v4.html +761 -0
- data/spec/support/samples/ical_apple.ics +22 -0
- data/spec/support/samples/ical_apple_v3.ics +37 -0
- data/spec/support/samples/ical_basic.ics +15 -0
- data/spec/support/samples/ical_basic_with_duration.ics +16 -0
- data/spec/support/samples/ical_event_with_squashed_venue.ics +12 -0
- data/spec/support/samples/ical_eventful_many.ics +504 -0
- data/spec/support/samples/ical_gmt.ics +12 -0
- data/spec/support/samples/ical_google.ics +786 -0
- data/spec/support/samples/ical_multiple_calendars.ics +111 -0
- data/spec/support/samples/ical_upcoming.ics +36 -0
- data/spec/support/samples/ical_upcoming_many.ics +682 -0
- data/spec/support/samples/ical_upcoming_v2.ics +43 -0
- data/spec/support/samples/ical_z.ics +10 -0
- data/spec/support/samples/meetup.ics +16 -0
- data/spec/support/samples/meetup.json +31 -0
- data/spec/support/samples/plancast.ics +59 -0
- data/spec/support/samples/plancast.json +51 -0
- data/spec/support/samples/plancast_with_missing_venue.json +39 -0
- data/spec/support/samples/upcoming_v1.xml +8 -0
- data/spec/support/samples/upcoming_v2_with_invalid_utc_dates.xml +8 -0
- data/spec/support/time_convenience_methods.rb +8 -0
- data/spec/support/time_zones.rb +12 -0
- data/spec/support/url_helpers.rb +5 -0
- data/spec/support/wait_for_ajax.rb +15 -0
- data/spec/support/webmock.rb +8 -0
- data/spec/travis_spec.rb +7 -0
- metadata +1194 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Calagator
|
|
4
|
+
|
|
5
|
+
describe Source::Parser::Facebook, :type => :model do
|
|
6
|
+
|
|
7
|
+
describe "when importing an event" do
|
|
8
|
+
before(:each) do
|
|
9
|
+
url = 'http://facebook.com/event.php?eid=247619485255249'
|
|
10
|
+
graph_url = "http://graph.facebook.com/247619485255249"
|
|
11
|
+
stub_request(:get, graph_url).to_return(body: read_sample('facebook.json'), headers: { content_type: "application/json" })
|
|
12
|
+
@events = Source::Parser::Facebook.to_events(url: url)
|
|
13
|
+
@event = @events.first
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should find one event" do
|
|
17
|
+
expect(@events.size).to eq 1
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should set event details" do
|
|
21
|
+
expect(@event.title).to eq "Open Source Bridge 2012"
|
|
22
|
+
time = Time.zone.parse("26 Jun 2012 09:00:00")
|
|
23
|
+
expect(@event.start_time).to eq time
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should tag Facebook events with automagic machine tags" do
|
|
27
|
+
expect(@event.tag_list).to eq ["facebook:event=247619485255249"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should set the event url to the original import URL" do
|
|
31
|
+
expect(@event.url).to eq 'http://facebook.com/event.php?eid=247619485255249'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should populate a venue when structured data is provided" do
|
|
35
|
+
expect(@event.venue.title).to eq "Eliot Center"
|
|
36
|
+
expect(@event.venue.street_address).to eq "1226 SW Salmon Street"
|
|
37
|
+
expect(@event.venue.locality).to eq "Portland"
|
|
38
|
+
expect(@event.venue.region).to eq "Oregon"
|
|
39
|
+
expect(@event.venue.country).to eq "United States"
|
|
40
|
+
expect(@event.venue.latitude.to_s).to eq "45.5236"
|
|
41
|
+
expect(@event.venue.longitude.to_s).to eq "-122.675"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe "when parsing Facebook URLs" do
|
|
46
|
+
def should_parse(url)
|
|
47
|
+
expect(url.match(Source::Parser::Facebook.url_pattern)[1]).to eq "247619485255249"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should parse a GET-style URL" do
|
|
51
|
+
should_parse 'http://facebook.com/event.php?eid=247619485255249'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should parse a GET-style URL using HTTPS" do
|
|
55
|
+
should_parse 'https://facebook.com/event.php?eid=247619485255249'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should parse a REST-style URL" do
|
|
59
|
+
should_parse 'http://www.facebook.com/events/247619485255249'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should parse a GET-style URL with a 'www.' host prefix" do
|
|
63
|
+
should_parse 'http://www.facebook.com/event.php?eid=247619485255249'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should parse a API uri" do
|
|
67
|
+
should_parse 'http://graph.facebook.com/247619485255249'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Calagator
|
|
4
|
+
|
|
5
|
+
describe Source::Parser::Hcal, "with hCalendar events", :type => :model do
|
|
6
|
+
it "should parse hcal" do
|
|
7
|
+
url = "http://mysample.hcal/"
|
|
8
|
+
stub_request(:get, url).to_return(body: read_sample('hcal_single.xml'))
|
|
9
|
+
hcal_source = Source.new(title: "Calendar event feed", url: url)
|
|
10
|
+
|
|
11
|
+
events = hcal_source.to_events
|
|
12
|
+
|
|
13
|
+
expect(events.size).to eq 1
|
|
14
|
+
for key, value in {
|
|
15
|
+
:title => "Calendar event",
|
|
16
|
+
:description => "Check it out!",
|
|
17
|
+
:start_time => Time.parse("2008-1-19"),
|
|
18
|
+
:end_time => Time.parse("2008-1-20"),
|
|
19
|
+
:url => "http://www.cubespacepdx.com",
|
|
20
|
+
:venue_id => nil, # TODO what should venue instance be?
|
|
21
|
+
}
|
|
22
|
+
expect(events.first.send(key)).to eq value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should strip html from the venue title" do
|
|
27
|
+
url = "http://mysample.hcal/"
|
|
28
|
+
stub_request(:get, url).to_return(body: read_sample('hcal_upcoming_v1.html'))
|
|
29
|
+
hcal_source = Source.new(title: "Calendar event feed", url: url)
|
|
30
|
+
|
|
31
|
+
events = hcal_source.to_events
|
|
32
|
+
|
|
33
|
+
expect(events.first.venue.title).to eq 'Jive Software Office'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should parse a page with multiple events" do
|
|
37
|
+
url = "http://mysample.hcal/"
|
|
38
|
+
stub_request(:get, url).to_return(body: read_sample('hcal_multiple.xml'))
|
|
39
|
+
hcal_source = Source.new(title: "Calendar event feed", url: url)
|
|
40
|
+
|
|
41
|
+
events = hcal_source.to_events
|
|
42
|
+
expect(events.size).to eq 2
|
|
43
|
+
first, second = *events
|
|
44
|
+
expect(first.start_time).to eq Time.parse('2008-1-19')
|
|
45
|
+
expect(first.end_time).to eq Time.parse('2008-01-20')
|
|
46
|
+
expect(second.start_time).to eq Time.parse('2008-2-2')
|
|
47
|
+
expect(second.end_time).to eq Time.parse('2008-02-03')
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe Source::Parser::Hcal, "with hCalendar to Venue parsing", :type => :model do
|
|
52
|
+
it "should extract an Venue from an hCalendar text" do
|
|
53
|
+
url = "http://mysample.hcal/"
|
|
54
|
+
stub_request(:get, url).to_return(body: read_sample('hcal_upcoming_v1.html'))
|
|
55
|
+
|
|
56
|
+
events = Source::Parser::Hcal.to_events(url: url)
|
|
57
|
+
event = events.first
|
|
58
|
+
venue = event.venue
|
|
59
|
+
|
|
60
|
+
expect(venue).to be_a_kind_of(Venue)
|
|
61
|
+
expect(venue.locality).to eq "portland"
|
|
62
|
+
expect(venue.street_address).to eq "317 SW Alder St Ste 500"
|
|
63
|
+
expect(venue.latitude).to be_within(0.1).of(45.5191)
|
|
64
|
+
expect(venue.longitude).to be_within(0.1).of(-122.675)
|
|
65
|
+
expect(venue.postal_code).to eq "97204"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Calagator
|
|
4
|
+
|
|
5
|
+
describe Calagator::Source::Parser::Ical, "when parsing VVENUE", :type => :model do
|
|
6
|
+
before(:each) do
|
|
7
|
+
@venue = Source::Parser::Ical.new.send(:to_venue, %(
|
|
8
|
+
BEGIN:VVENUE
|
|
9
|
+
X-VVENUE-INFO:http://evdb.com/docs/ical-venue/draft-norris-ical-venue.
|
|
10
|
+
html
|
|
11
|
+
UID:V0-001-001423875-1@eventful.com
|
|
12
|
+
NAME:Apple Store Pioneer Place
|
|
13
|
+
DESCRIPTION:(503) 222-3002 Driving Directions & Map Store Hours: Mon
|
|
14
|
+
- Fri: 9:30 a.m. to 9:00 p.m. Sat: 9:30 a.m. to 8:00 p.m. Sun: 11:00
|
|
15
|
+
a.m. to 6:00 p.m.
|
|
16
|
+
ADDRESS:700 Southwest Fifth Avenue Suite #1035
|
|
17
|
+
CITY:Portland
|
|
18
|
+
REGION;ABBREV=OR:Oregon
|
|
19
|
+
COUNTRY;ABBREV=USA:United States
|
|
20
|
+
POSTALCODE:97204
|
|
21
|
+
GEO:45.518798;-122.677583
|
|
22
|
+
URL;X-LABEL=Venue Info:http://eventful.com/V0-001-001423875-1
|
|
23
|
+
CATEGORIES:apple applecom appleinc technology
|
|
24
|
+
END:VVENUE))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should have a street_address" do
|
|
28
|
+
expect(@venue.street_address).not_to be_nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should have the adress as is" do
|
|
32
|
+
@venue.street_address == '700 Southwest Fifth Avenue Suite #1035'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should have a locality" do
|
|
36
|
+
expect(@venue.locality).not_to be_nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should have the locality as is" do
|
|
40
|
+
@venue.locality == 'Portland'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe Source::Parser::Ical, "when parsing VCARD lines", :type => :model do
|
|
45
|
+
before(:each) do
|
|
46
|
+
# Note that each line here represents a single, complete property definition -- this method doesn't do any magical unwrapping of text.
|
|
47
|
+
@vcard_hash = Source::Parser::Ical.new.send(:hash_from_vcard_lines, %(
|
|
48
|
+
X-VVENUE-INFO:http://evdb.com/docs/ical-venue/draft-norris-ical-venue.html
|
|
49
|
+
UID:V0-001-001423875-1@eventful.com
|
|
50
|
+
NAME:Apple Store Pioneer Place
|
|
51
|
+
DESCRIPTION:(503) 222-3002 Driving Directions & Map Store Hours: Mon - Fri: 9:30 a.m. to 9:00 p.m. Sat: 9:30 a.m. to 8:00 p.m. Sun: 11:00 a.m. to 6:00 p.m.
|
|
52
|
+
ADDRESS:700 Southwest Fifth Avenue Suite; #1035
|
|
53
|
+
CITY:Portland
|
|
54
|
+
REGION;KMeta=none&bizzare:Oregon
|
|
55
|
+
COUNTRY;;;ABBREV=USA:United States
|
|
56
|
+
POSTALCODE:97204
|
|
57
|
+
GEO:45.518798;-122.677583
|
|
58
|
+
URL;X-LABEL=Venue Info:http://eventful.com/V0-001-001423875-1
|
|
59
|
+
CATEGORIES:apple applecom appleinc technology).split("\n"))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should find a property set by its key" do
|
|
63
|
+
expect(@vcard_hash['NAME']).to eq 'Apple Store Pioneer Place'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should find a property set by its key and meta-qualifier" do
|
|
67
|
+
expect(@vcard_hash['URL;X-LABEL=Venue Info']).to eq 'http://eventful.com/V0-001-001423875-1'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should find a property set by its key and meta-qualifier by its key when one wasn't specified" do
|
|
71
|
+
expect(@vcard_hash['URL']).to eq 'http://eventful.com/V0-001-001423875-1'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should find a property set by its key and multiple meta-qualifier by" do
|
|
75
|
+
@vcard_hash['COUNTRY;;;ABBREV=USA'] == 'United States'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should find a property set by its key and multiple meta-qualifiers by its key when one wasn't specified" do
|
|
79
|
+
@vcard_hash['COUNTRY'] == 'United States'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should find a property set by its key and meta-qualifier with odd characters" do
|
|
83
|
+
@vcard_hash['REGION;KMeta=none&bizzare'] == 'Oregon'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should find a property set by its key and meta-qualifier with odd characters by its key when one wasn't specified" do
|
|
87
|
+
@vcard_hash['REGION'] == 'Oregon'
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
def events_from_ical_at(filename)
|
|
4
|
+
url = "http://foo.bar/"
|
|
5
|
+
source = Calagator::Source.new(:title => "Calendar event feed", :url => url)
|
|
6
|
+
stub_request(:get, url).to_return(body: read_sample(filename))
|
|
7
|
+
return source.to_events(:skip_old => false)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module Calagator
|
|
11
|
+
|
|
12
|
+
describe Source::Parser::Ical, "in general", :type => :model do
|
|
13
|
+
it "should read http URLs as-is" do
|
|
14
|
+
url = "http://foo.bar/"
|
|
15
|
+
stub_request(:get, url).to_return(body: "42")
|
|
16
|
+
expect(Source::Parser::Ical.read_url(url)).to eq "42"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should read webcal URLs as http" do
|
|
20
|
+
webcal_url = "webcal://foo.bar/"
|
|
21
|
+
http_url = "http://foo.bar/"
|
|
22
|
+
stub_request(:get, http_url).to_return(body: "42")
|
|
23
|
+
expect(Source::Parser::Ical.read_url(webcal_url)).to eq "42"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe Source::Parser::Ical, "when parsing events and their venues", :type => :model do
|
|
28
|
+
|
|
29
|
+
before(:each) do
|
|
30
|
+
url = "http://foo.bar/"
|
|
31
|
+
stub_request(:get, url).to_return(body: read_sample('ical_upcoming_many.ics'))
|
|
32
|
+
@events = Source::Parser.to_events(url: url, skip_old: false)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "venues should be" do
|
|
36
|
+
@events.each do |event|
|
|
37
|
+
expect(event.venue).not_to be_nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe Source::Parser::Ical, "when parsing multiple items in an Eventful feed", :type => :model do
|
|
44
|
+
before(:each) do
|
|
45
|
+
url = "http://foo.bar/"
|
|
46
|
+
stub_request(:get, url).to_return(body: read_sample('ical_eventful_many.ics'))
|
|
47
|
+
@events = Source::Parser.to_events(url: url, skip_old: false)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should find multiple events" do
|
|
51
|
+
expect(@events.size).to eq 15
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should find venues for events" do
|
|
55
|
+
@events.each do |event|
|
|
56
|
+
expect(event.venue.title).not_to be_nil
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should match each event with its venue" do
|
|
61
|
+
event_titles_and_street_addresses = [
|
|
62
|
+
["iMovie and iDVD Workshop", "7293 SW Bridgeport Road"],
|
|
63
|
+
["Portland Macintosh Users Group (PMUG)", "Jean Vollum Natural Capital Center"],
|
|
64
|
+
["Morning Meetings: IT", "622 SE Grand Avenue"]
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# Make sure each of the above events has the expected street address
|
|
68
|
+
event_titles_and_street_addresses.each do |event_title, street_address|
|
|
69
|
+
expect(@events.find { |event|
|
|
70
|
+
event.title == event_title && event.venue.street_address == street_address
|
|
71
|
+
}).not_to be_nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe Source::Parser::Ical, "with iCalendar events", :type => :model do
|
|
77
|
+
|
|
78
|
+
it "should parse Apple iCalendar v3 format" do
|
|
79
|
+
events = events_from_ical_at('ical_apple_v3.ics')
|
|
80
|
+
|
|
81
|
+
expect(events.size).to eq 1
|
|
82
|
+
event = events.first
|
|
83
|
+
expect(event.title).to eq "Coffee with Jason"
|
|
84
|
+
expect(event.start_time).to eq Time.zone.parse('2010-04-08 00:00:00 PDT -07:00')
|
|
85
|
+
expect(event.end_time).to eq Time.zone.parse('2010-04-08 01:00:00 PDT -07:00')
|
|
86
|
+
expect(event.venue).to be_nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should parse basic iCalendar format" do
|
|
90
|
+
events = events_from_ical_at('ical_basic.ics')
|
|
91
|
+
|
|
92
|
+
expect(events.size).to eq 1
|
|
93
|
+
event = events.first
|
|
94
|
+
expect(event.title).to be_blank
|
|
95
|
+
expect(event.start_time).to eq Time.zone.parse('Wed Jan 17 00:00:00 2007')
|
|
96
|
+
expect(event.venue).to be_nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should parse basic iCalendar format with a duration and set the correct end time" do
|
|
100
|
+
events = events_from_ical_at('ical_basic_with_duration.ics')
|
|
101
|
+
|
|
102
|
+
expect(events.size).to eq 1
|
|
103
|
+
event = events.first
|
|
104
|
+
expect(event.title).to be_blank
|
|
105
|
+
expect(event.start_time).to eq Time.zone.parse('2010-04-08 00:00:00')
|
|
106
|
+
expect(event.end_time).to eq Time.zone.parse('2010-04-08 01:00:00')
|
|
107
|
+
expect(event.venue).to be_nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should parse Google iCalendar feed with multiple events" do
|
|
111
|
+
events = events_from_ical_at('ical_google.ics')
|
|
112
|
+
# TODO add specs for venues/locations
|
|
113
|
+
|
|
114
|
+
expect(events.size).to eq 47
|
|
115
|
+
|
|
116
|
+
event = events.first
|
|
117
|
+
expect(event.title).to eq "XPDX (eXtreme Programming) at CubeSpace"
|
|
118
|
+
expect(event.description).to be_blank
|
|
119
|
+
expect(event.start_time).to eq Time.parse("2007-10-24 18:30:00 PDT")
|
|
120
|
+
expect(event.end_time).to eq Time.parse("2007-10-24 19:30:00 PDT")
|
|
121
|
+
|
|
122
|
+
event = events[17]
|
|
123
|
+
expect(event.title).to eq "Code Sprint/Coding Dojo at CubeSpace"
|
|
124
|
+
expect(event.description).to be_blank
|
|
125
|
+
expect(event.start_time).to eq Time.parse("2007-10-17 19:00:00 PDT")
|
|
126
|
+
expect(event.end_time).to eq Time.parse("2007-10-17 21:00:00 PDT")
|
|
127
|
+
|
|
128
|
+
event = events.last
|
|
129
|
+
expect(event.title).to eq "Adobe Developer User Group"
|
|
130
|
+
expect(event.description).to eq "http://pdxria.com/"
|
|
131
|
+
expect(event.start_time).to eq Time.parse("2007-01-16 17:30:00 PST")
|
|
132
|
+
expect(event.end_time).to eq Time.parse("2007-01-16 18:30:00 PST")
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "should parse non-Vcard locations" do
|
|
136
|
+
events = events_from_ical_at('ical_google.ics')
|
|
137
|
+
expect(events.first.venue.title).to eq 'CubeSpace'
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "should parse a calendar file with multiple calendars" do
|
|
141
|
+
events = events_from_ical_at('ical_multiple_calendars.ics')
|
|
142
|
+
expect(events.size).to eq 3
|
|
143
|
+
expect(events.map(&:title)).to eq ["Coffee with Jason", "Coffee with Mike", "Coffee with Kim"]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "should not swallow errors" do
|
|
147
|
+
expect(RiCal).to receive(:parse_string).and_raise(TypeError)
|
|
148
|
+
expect { events_from_ical_at('ical_multiple_calendars.ics') }.to raise_error(TypeError)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe Source::Parser::Ical, "when importing events with non-local times", :type => :model do
|
|
153
|
+
|
|
154
|
+
it "should store time ending in Z as UTC" do
|
|
155
|
+
url = "http://foo.bar/"
|
|
156
|
+
stub_request(:get, url).to_return(body: read_sample('ical_z.ics'))
|
|
157
|
+
@source = Source.new(:title => "Non-local time", :url => url)
|
|
158
|
+
events = @source.create_events!(:skip_old => false)
|
|
159
|
+
event = events.first
|
|
160
|
+
|
|
161
|
+
expect(event.start_time).to eq Time.parse('Thu Jul 01 08:00:00 +0000 2010')
|
|
162
|
+
expect(event.end_time).to eq Time.parse('Thu Jul 01 09:00:00 +0000 2010')
|
|
163
|
+
|
|
164
|
+
# time should be the same after saving event to, and getting it from, database
|
|
165
|
+
event.save
|
|
166
|
+
e = Event.find(event)
|
|
167
|
+
expect(e.start_time).to eq Time.parse('Thu Jul 01 08:00:00 +0000 2010')
|
|
168
|
+
expect(e.end_time).to eq Time.parse('Thu Jul 01 09:00:00 +0000 2010')
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should store time with TZID=GMT in UTC" do
|
|
172
|
+
events = events_from_ical_at('ical_gmt.ics')
|
|
173
|
+
expect(events.size).to eq 1
|
|
174
|
+
event = events.first
|
|
175
|
+
expect(event.start_time).to eq Time.parse('Fri May 07 08:00:00 +0000 2020')
|
|
176
|
+
expect(event.end_time).to eq Time.parse('Fri May 07 09:00:00 +0000 2020')
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
describe Source::Parser::Ical, "munge_gmt_dates", :type => :model do
|
|
181
|
+
it "should return unexpected-format strings unmodified" do
|
|
182
|
+
munged = Source::Parser::Ical.new.send(:munge_gmt_dates, 'justin bieber on a train')
|
|
183
|
+
expect(munged).to eq 'justin bieber on a train'
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it "should return GMT-less ical strings unmodified" do
|
|
187
|
+
icard = %{
|
|
188
|
+
BEGIN:VCALENDAR
|
|
189
|
+
BEGIN:VEVENT
|
|
190
|
+
DTSTART:20200507T080000
|
|
191
|
+
DTEND:20200507T090000
|
|
192
|
+
END:VEVENT
|
|
193
|
+
END:VCALENDAR
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
expect(Source::Parser::Ical.new.send(:munge_gmt_dates, icard)).to eq icard
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "should replace TZID=GMT with a TZID-less UTC time" do
|
|
200
|
+
icard = %{
|
|
201
|
+
BEGIN:VCALENDAR
|
|
202
|
+
BEGIN:VEVENT
|
|
203
|
+
DTSTART;TZID=GMT:20200507T080000
|
|
204
|
+
DTEND;TZID=GMT:20200507T090000
|
|
205
|
+
END:VEVENT
|
|
206
|
+
END:VCALENDAR
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
munged = %{
|
|
210
|
+
BEGIN:VCALENDAR
|
|
211
|
+
BEGIN:VEVENT
|
|
212
|
+
DTSTART:20200507T080000Z
|
|
213
|
+
DTEND:20200507T090000Z
|
|
214
|
+
END:VEVENT
|
|
215
|
+
END:VCALENDAR
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
expect(Source::Parser::Ical.new.send(:munge_gmt_dates, icard)).to eq munged
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
describe Source::Parser::Ical, "when skipping old events", :type => :model do
|
|
223
|
+
before(:each) do
|
|
224
|
+
url = "http://foo.bar/"
|
|
225
|
+
stub_request(:get, url).to_return(body:
|
|
226
|
+
%(BEGIN:VCALENDAR
|
|
227
|
+
X-WR-CALNAME;VALUE=TEXT:NERV
|
|
228
|
+
VERSION:2.0
|
|
229
|
+
CALSCALE:GREGORIAN
|
|
230
|
+
PRODID:-//nerv.go.jp//iCal 1.0//EN
|
|
231
|
+
X-WR-TIMEZONE;VALUE=TEXT:US/Eastern
|
|
232
|
+
BEGIN:VEVENT
|
|
233
|
+
UID:Unit-01
|
|
234
|
+
SUMMARY:Past start and no end
|
|
235
|
+
DESCRIPTION:Ayanami
|
|
236
|
+
DTSTART:#{(Time.now-1.year).strftime("%Y%m%d")}
|
|
237
|
+
DTSTAMP:040425
|
|
238
|
+
SEQ:0
|
|
239
|
+
END:VEVENT
|
|
240
|
+
BEGIN:VEVENT
|
|
241
|
+
UID:Unit-02
|
|
242
|
+
SUMMARY:Current start and no end
|
|
243
|
+
DESCRIPTION:Soryu
|
|
244
|
+
DTSTART:#{(Time.now+1.year).strftime("%Y%m%d")}
|
|
245
|
+
DTSTAMP:040425
|
|
246
|
+
SEQ:1
|
|
247
|
+
END:VEVENT
|
|
248
|
+
BEGIN:VEVENT
|
|
249
|
+
UID:Unit-03
|
|
250
|
+
SUMMARY:Past start and current end
|
|
251
|
+
DESCRIPTION:Soryu a
|
|
252
|
+
DTSTART:#{(Time.now-1.year).strftime("%Y%m%d")}
|
|
253
|
+
DTEND:#{(Time.now+1.year).strftime("%Y%m%d")}
|
|
254
|
+
DTSTAMP:040425
|
|
255
|
+
END:VEVENT
|
|
256
|
+
BEGIN:VEVENT
|
|
257
|
+
UID:Unit-04
|
|
258
|
+
SUMMARY:Current start and current end
|
|
259
|
+
DESCRIPTION:Soryu as
|
|
260
|
+
DTSTART:#{Time.now.strftime("%Y%m%d")}
|
|
261
|
+
DTEND:#{(Time.now+1.year).strftime("%Y%m%d")}
|
|
262
|
+
DTSTAMP:040425
|
|
263
|
+
END:VEVENT
|
|
264
|
+
BEGIN:VEVENT
|
|
265
|
+
UID:Unit-05
|
|
266
|
+
SUMMARY:Past start and past end
|
|
267
|
+
DESCRIPTION:Soryu qewr
|
|
268
|
+
DTSTART:#{(Time.now-1.year).strftime("%Y%m%d")}
|
|
269
|
+
DTEND:#{(Time.now-1.year).strftime("%Y%m%d")}
|
|
270
|
+
DTSTAMP:040425
|
|
271
|
+
END:VEVENT
|
|
272
|
+
BEGIN:VEVENT
|
|
273
|
+
UID:Unit-06
|
|
274
|
+
SUMMARY:Current start and past end
|
|
275
|
+
DESCRIPTION:Not a valid event
|
|
276
|
+
DTSTART:#{Time.now.strftime("%Y%m%d")}
|
|
277
|
+
DTEND:#{(Time.now-1.year).strftime("%Y%m%d")}
|
|
278
|
+
DTSTAMP:040425
|
|
279
|
+
END:VEVENT
|
|
280
|
+
END:VCALENDAR))
|
|
281
|
+
@source = Source.new(title: "Title", url: url)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# for following specs a 'valid' event does not start after it ends"
|
|
285
|
+
it "should be able to import all valid events" do
|
|
286
|
+
events = @source.create_events!(:skip_old => false)
|
|
287
|
+
expect(events.map(&:title)).to eq [
|
|
288
|
+
"Past start and no end",
|
|
289
|
+
"Current start and no end",
|
|
290
|
+
"Past start and current end",
|
|
291
|
+
"Current start and current end",
|
|
292
|
+
"Past start and past end"
|
|
293
|
+
]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it "should be able to skip invalid and old events" do
|
|
297
|
+
events = @source.create_events!(:skip_old => true)
|
|
298
|
+
expect(events.map(&:title)).to eq [
|
|
299
|
+
"Current start and no end",
|
|
300
|
+
"Past start and current end",
|
|
301
|
+
"Current start and current end"
|
|
302
|
+
]
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
describe Source::Parser::Ical, "when parsing an invalid ical", :type => :model do
|
|
307
|
+
before(:each) do
|
|
308
|
+
url = "http://foo.bar/"
|
|
309
|
+
stub_request(:get, url).to_return(body:
|
|
310
|
+
%(BEGIN:VCALENDAR
|
|
311
|
+
BEGIN:VEVENT
|
|
312
|
+
OMGWTFBBQ
|
|
313
|
+
END:VCALENDAR))
|
|
314
|
+
@source = Source.new(title: "Title", url: url)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "should return no events" do
|
|
318
|
+
@source.create_events!.should == []
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
end
|