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.
Files changed (384) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +23 -0
  3. data/README.md +75 -0
  4. data/Rakefile +12 -0
  5. data/app/assets/images/confused-alligator-sm.png +0 -0
  6. data/app/assets/images/disk.png +0 -0
  7. data/app/assets/images/edit.png +0 -0
  8. data/app/assets/images/external_sites/epdx.png +0 -0
  9. data/app/assets/images/external_sites/external.gif +0 -0
  10. data/app/assets/images/external_sites/facebook.png +0 -0
  11. data/app/assets/images/external_sites/foursquare.png +0 -0
  12. data/app/assets/images/external_sites/gowalla.png +0 -0
  13. data/app/assets/images/external_sites/lanyrd.png +0 -0
  14. data/app/assets/images/external_sites/meetup.png +0 -0
  15. data/app/assets/images/external_sites/plancast.png +0 -0
  16. data/app/assets/images/external_sites/shizzow.png +0 -0
  17. data/app/assets/images/external_sites/upcoming.png +0 -0
  18. data/app/assets/images/external_sites/yelp.png +0 -0
  19. data/app/assets/images/feed.png +0 -0
  20. data/app/assets/images/heart.png +0 -0
  21. data/app/assets/images/icon_ical.gif +0 -0
  22. data/app/assets/images/information.png +0 -0
  23. data/app/assets/images/nav_marker.gif +0 -0
  24. data/app/assets/images/nav_marker.png +0 -0
  25. data/app/assets/images/plus.png +0 -0
  26. data/app/assets/images/redx.png +0 -0
  27. data/app/assets/images/site-icon.png +0 -0
  28. data/app/assets/images/spinner.gif +0 -0
  29. data/app/assets/images/star.png +0 -0
  30. data/app/assets/images/subnav_marker.gif +0 -0
  31. data/app/assets/images/subnav_marker.png +0 -0
  32. data/app/assets/images/tag_blue.png +0 -0
  33. data/app/assets/images/tag_icons/angular.png +0 -0
  34. data/app/assets/images/tag_icons/beer.png +0 -0
  35. data/app/assets/images/tag_icons/bitcoin.png +0 -0
  36. data/app/assets/images/tag_icons/free.png +0 -0
  37. data/app/assets/images/tag_icons/golang.png +0 -0
  38. data/app/assets/images/tag_icons/html.png +0 -0
  39. data/app/assets/images/tag_icons/javascript.png +0 -0
  40. data/app/assets/images/tag_icons/linux.png +0 -0
  41. data/app/assets/images/tag_icons/php.png +0 -0
  42. data/app/assets/images/tag_icons/pizza.png +0 -0
  43. data/app/assets/images/tag_icons/python.png +0 -0
  44. data/app/assets/images/tag_icons/rails.png +0 -0
  45. data/app/assets/images/tag_icons/ruby.png +0 -0
  46. data/app/assets/images/tag_icons/sass.png +0 -0
  47. data/app/assets/images/tag_icons/swift.png +0 -0
  48. data/app/assets/images/transmit_blue.png +0 -0
  49. data/app/assets/images/weekday_background.gif +0 -0
  50. data/app/assets/javascripts/calagator.js +18 -0
  51. data/app/assets/javascripts/calagator/forms.js +60 -0
  52. data/app/assets/stylesheets/calagator.scss +8 -0
  53. data/app/assets/stylesheets/calagator/common.scss +14 -0
  54. data/app/assets/stylesheets/calagator/datepicker.scss +177 -0
  55. data/app/assets/stylesheets/calagator/errors.css +110 -0
  56. data/app/assets/stylesheets/calagator/forms.scss +4 -0
  57. data/app/assets/stylesheets/calagator/reset.css +40 -0
  58. data/app/assets/stylesheets/calagator/theme.css +0 -0
  59. data/app/controllers/calagator/admin_controller.rb +27 -0
  60. data/app/controllers/calagator/application_controller.rb +82 -0
  61. data/app/controllers/calagator/events_controller.rb +171 -0
  62. data/app/controllers/calagator/site_controller.rb +35 -0
  63. data/app/controllers/calagator/sources_controller.rb +94 -0
  64. data/app/controllers/calagator/venues_controller.rb +133 -0
  65. data/app/controllers/calagator/versions_controller.rb +20 -0
  66. data/app/helpers/calagator/application_helper.rb +128 -0
  67. data/app/helpers/calagator/events_helper.rb +184 -0
  68. data/app/helpers/calagator/google_event_export_helper.rb +67 -0
  69. data/app/helpers/calagator/mapping_helper.rb +103 -0
  70. data/app/helpers/calagator/sources_helper.rb +10 -0
  71. data/app/helpers/calagator/tags_helper.rb +42 -0
  72. data/app/helpers/calagator/time_range_helper.rb +166 -0
  73. data/app/models/calagator/event.rb +246 -0
  74. data/app/models/calagator/event/cloner.rb +39 -0
  75. data/app/models/calagator/event/ical_renderer.rb +155 -0
  76. data/app/models/calagator/event/overview.rb +45 -0
  77. data/app/models/calagator/event/saver.rb +58 -0
  78. data/app/models/calagator/event/search.rb +72 -0
  79. data/app/models/calagator/event/search_engine.rb +28 -0
  80. data/app/models/calagator/event/search_engine/apache_sunspot.rb +106 -0
  81. data/app/models/calagator/event/search_engine/sql.rb +107 -0
  82. data/app/models/calagator/source.rb +115 -0
  83. data/app/models/calagator/source/importer.rb +46 -0
  84. data/app/models/calagator/source/parser.rb +128 -0
  85. data/app/models/calagator/source/parser/facebook.rb +67 -0
  86. data/app/models/calagator/source/parser/hcal.rb +108 -0
  87. data/app/models/calagator/source/parser/http_authentication_required_error.rb +6 -0
  88. data/app/models/calagator/source/parser/ical.rb +186 -0
  89. data/app/models/calagator/source/parser/meetup.rb +72 -0
  90. data/app/models/calagator/source/parser/not_found.rb +9 -0
  91. data/app/models/calagator/source/parser/plancast.rb +59 -0
  92. data/app/models/calagator/venue.rb +161 -0
  93. data/app/models/calagator/venue/geocoder.rb +51 -0
  94. data/app/models/calagator/venue/search.rb +63 -0
  95. data/app/models/calagator/venue/search_engine.rb +24 -0
  96. data/app/models/calagator/venue/search_engine/apache_sunspot.rb +85 -0
  97. data/app/models/calagator/venue/search_engine/sql.rb +68 -0
  98. data/app/models/event/search_engine/base.rb +0 -0
  99. data/app/observers/calagator/cache_observer.rb +37 -0
  100. data/app/views/calagator/admin/events.html.erb +28 -0
  101. data/app/views/calagator/admin/index.html.erb +8 -0
  102. data/app/views/calagator/events/_feed_item.html.erb +62 -0
  103. data/app/views/calagator/events/_form.html.erb +63 -0
  104. data/app/views/calagator/events/_gcal_reminder.html.erb +1 -0
  105. data/app/views/calagator/events/_hcal.html.erb +41 -0
  106. data/app/views/calagator/events/_item.html.erb +120 -0
  107. data/app/views/calagator/events/_list.html.erb +30 -0
  108. data/app/views/calagator/events/_list_item.html.erb +37 -0
  109. data/app/views/calagator/events/_search_section.html.erb +15 -0
  110. data/app/views/calagator/events/_subnav.html.erb +13 -0
  111. data/app/views/calagator/events/_table.html.erb +74 -0
  112. data/app/views/calagator/events/duplicates.html.erb +58 -0
  113. data/app/views/calagator/events/edit.html.erb +3 -0
  114. data/app/views/calagator/events/index.atom.builder +32 -0
  115. data/app/views/calagator/events/index.html.erb +51 -0
  116. data/app/views/calagator/events/index.kml.erb +20 -0
  117. data/app/views/calagator/events/new.html.erb +7 -0
  118. data/app/views/calagator/events/search.html.erb +25 -0
  119. data/app/views/calagator/events/show.html.erb +81 -0
  120. data/app/views/calagator/site/_appropriateness_message.html.erb +15 -0
  121. data/app/views/calagator/site/_description.html.erb +3 -0
  122. data/app/views/calagator/site/about.html.erb +7 -0
  123. data/app/views/calagator/site/defunct.html.erb +15 -0
  124. data/app/views/calagator/site/export.html.erb +4 -0
  125. data/app/views/calagator/site/index.html.erb +40 -0
  126. data/app/views/calagator/site/opensearch.xml.builder +8 -0
  127. data/app/views/calagator/sources/_subnav.html.erb +0 -0
  128. data/app/views/calagator/sources/edit.html.erb +12 -0
  129. data/app/views/calagator/sources/import.html.erb +10 -0
  130. data/app/views/calagator/sources/index.html.erb +22 -0
  131. data/app/views/calagator/sources/new.html.erb +32 -0
  132. data/app/views/calagator/sources/show.html.erb +16 -0
  133. data/app/views/calagator/venues/_form.html.erb +57 -0
  134. data/app/views/calagator/venues/_subnav.html.erb +10 -0
  135. data/app/views/calagator/venues/duplicates.html.erb +65 -0
  136. data/app/views/calagator/venues/edit.html.erb +3 -0
  137. data/app/views/calagator/venues/index.html.erb +93 -0
  138. data/app/views/calagator/venues/index.kml.erb +15 -0
  139. data/app/views/calagator/venues/map.html.erb +4 -0
  140. data/app/views/calagator/venues/new.html.erb +5 -0
  141. data/app/views/calagator/venues/show.html.erb +113 -0
  142. data/app/views/calagator/versions/_chooser.html.erb +28 -0
  143. data/app/views/calagator/versions/_edit_with_chooser.html.erb +16 -0
  144. data/app/views/layouts/calagator/application.html.erb +110 -0
  145. data/config/deploy/local.rb +37 -0
  146. data/config/deploy/lucca.rb +33 -0
  147. data/config/initializers/dates.rb +7 -0
  148. data/config/initializers/formtastic.rb +82 -0
  149. data/config/initializers/geokit.rb +74 -0
  150. data/config/initializers/ics_renderer.rb +6 -0
  151. data/config/initializers/load_tag_model_extensions.rb +3 -0
  152. data/config/initializers/mime_types.rb +9 -0
  153. data/config/initializers/observers.rb +1 -0
  154. data/config/initializers/search_engine.rb +4 -0
  155. data/config/initializers/set_default_url_host.rb +5 -0
  156. data/config/initializers/time_get_zone.rb +8 -0
  157. data/config/locales/en.yml +5 -0
  158. data/config/routes.rb +55 -0
  159. data/config/secrets.yml.blag +75 -0
  160. data/config/sunspot.yml +23 -0
  161. data/db/development.sqlite3 +0 -0
  162. data/db/development.sqlite3.bak +0 -0
  163. data/db/development.sqlite3.old +0 -0
  164. data/db/development~20111112@110950.sqlite3 +0 -0
  165. data/db/migrate/001_create_events.rb +17 -0
  166. data/db/migrate/002_create_venues.rb +17 -0
  167. data/db/migrate/003_create_sources.rb +16 -0
  168. data/db/migrate/004_add_detailed_fields_to_venue.rb +19 -0
  169. data/db/migrate/005_add_end_time_to_events.rb +9 -0
  170. data/db/migrate/006_add_source_id_to_events.rb +9 -0
  171. data/db/migrate/008_add_source_id_to_venues.rb +10 -0
  172. data/db/migrate/009_add_duplicate_of_column_to_venues.rb +9 -0
  173. data/db/migrate/010_add_duplicate_of_column_to_events.rb +9 -0
  174. data/db/migrate/011_change_lat_long_type.rb +12 -0
  175. data/db/migrate/012_add_source_reimport.rb +9 -0
  176. data/db/migrate/013_change_end_time_to_duration.rb +11 -0
  177. data/db/migrate/014_remove_format_type_from_source.rb +9 -0
  178. data/db/migrate/015_create_updates.rb +15 -0
  179. data/db/migrate/016_remove_next_update_from_source.rb +9 -0
  180. data/db/migrate/20080705163959_change_duration_to_end_time.rb +11 -0
  181. data/db/migrate/20080705164959_create_tags_and_taggings.rb +28 -0
  182. data/db/migrate/20081011181519_create_versioned_events.rb +25 -0
  183. data/db/migrate/20081011193124_create_versioned_venues.rb +32 -0
  184. data/db/migrate/20081115190515_add_rrule_to_events.rb +15 -0
  185. data/db/migrate/20090912082129_create_versions.rb +18 -0
  186. data/db/migrate/20110219205156_add_closed_flag_to_venues.rb +9 -0
  187. data/db/migrate/20110220001008_add_wifi_flag_to_venues.rb +9 -0
  188. data/db/migrate/20110220011427_add_access_notes_to_venues.rb +9 -0
  189. data/db/migrate/20110220031117_add_events_count_to_venues.rb +8 -0
  190. data/db/migrate/20110604174521_add_venue_details_to_events.rb +9 -0
  191. data/db/migrate/20110717231316_acts_as_taggable_on_migration.rb +50 -0
  192. data/db/migrate/20120709092821_cleanup.rb +14 -0
  193. data/db/migrate/20120831234448_specify_venues_latitude_and_longitude_precision.rb +11 -0
  194. data/db/migrate/20150206085809_remove_updates.rb +13 -0
  195. data/db/migrate/20150207231355_add_locked_status_to_events.rb +5 -0
  196. data/db/production.sqlite3 +0 -0
  197. data/db/schema.rb +102 -0
  198. data/db/seeds.rb +16 -0
  199. data/db/test.sqlite3 +0 -0
  200. data/db/test2.sqlite3 +0 -0
  201. data/lib/calagator.rb +30 -0
  202. data/lib/calagator/blacklist_validator.rb +69 -0
  203. data/lib/calagator/decode_html_entities_hack.rb +33 -0
  204. data/lib/calagator/duplicate_checking.rb +133 -0
  205. data/lib/calagator/duplicate_checking/controller_actions.rb +38 -0
  206. data/lib/calagator/duplicate_checking/duplicate_finder.rb +83 -0
  207. data/lib/calagator/duplicate_checking/duplicate_squasher.rb +74 -0
  208. data/lib/calagator/engine.rb +30 -0
  209. data/lib/calagator/strip_whitespace.rb +19 -0
  210. data/lib/calagator/tag_model_extensions.rb +104 -0
  211. data/lib/calagator/url_prefixer.rb +9 -0
  212. data/lib/calagator/version.rb +3 -0
  213. data/lib/generators/calagator/install_generator.rb +39 -0
  214. data/lib/generators/calagator/templates/config/calagator.rb +26 -0
  215. data/lib/generators/calagator/templates/config/secrets.yml.sample +83 -0
  216. data/lib/secrets_reader.rb +76 -0
  217. data/lib/tasks/spec_db.rake +53 -0
  218. data/lib/tasks/sunspot_reindex_calagator.rake +6 -0
  219. data/lib/tasks/sunspot_solr_restart_enhancements.rake +19 -0
  220. data/lib/tasks/update_counter_caches.rake +13 -0
  221. data/lib/templates/erb/scaffold/_form.html.erb +11 -0
  222. data/lib/theme_reader.rb +17 -0
  223. data/lib/wait_for_solr.rb +25 -0
  224. data/spec/controllers/calagator/application_controller_spec.rb +47 -0
  225. data/spec/controllers/calagator/events_controller_spec.rb +794 -0
  226. data/spec/controllers/calagator/site_controller_spec.rb +59 -0
  227. data/spec/controllers/calagator/sources_controller_spec.rb +439 -0
  228. data/spec/controllers/calagator/venues_controller_spec.rb +319 -0
  229. data/spec/controllers/calagator/versions_controller_spec.rb +82 -0
  230. data/spec/controllers/squash_many_duplicates_examples.rb +49 -0
  231. data/spec/dummy/Gemfile +39 -0
  232. data/spec/dummy/Gemfile.lock +195 -0
  233. data/spec/dummy/README.rdoc +261 -0
  234. data/spec/dummy/Rakefile +7 -0
  235. data/spec/dummy/app/assets/images/rails.png +0 -0
  236. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  237. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  238. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  239. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  240. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  241. data/spec/dummy/config.ru +4 -0
  242. data/spec/dummy/config/application.rb +62 -0
  243. data/spec/dummy/config/boot.rb +6 -0
  244. data/spec/dummy/config/database.yml +25 -0
  245. data/spec/dummy/config/environment.rb +5 -0
  246. data/spec/dummy/config/environments/development.rb +37 -0
  247. data/spec/dummy/config/environments/production.rb +67 -0
  248. data/spec/dummy/config/environments/test.rb +37 -0
  249. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  250. data/spec/dummy/config/initializers/calagator.rb +26 -0
  251. data/spec/dummy/config/initializers/inflections.rb +15 -0
  252. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  253. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  254. data/spec/dummy/config/initializers/session_store.rb +8 -0
  255. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  256. data/spec/dummy/config/locales/en.yml +5 -0
  257. data/spec/dummy/config/routes.rb +59 -0
  258. data/spec/dummy/config/secrets.yml +83 -0
  259. data/spec/dummy/db/development.sqlite3 +0 -0
  260. data/spec/dummy/db/migrate/20150309023304_create_events.calagator.rb +18 -0
  261. data/spec/dummy/db/migrate/20150309023305_create_venues.calagator.rb +18 -0
  262. data/spec/dummy/db/migrate/20150309023306_create_sources.calagator.rb +17 -0
  263. data/spec/dummy/db/migrate/20150309023307_add_detailed_fields_to_venue.calagator.rb +20 -0
  264. data/spec/dummy/db/migrate/20150309023308_add_end_time_to_events.calagator.rb +10 -0
  265. data/spec/dummy/db/migrate/20150309023309_add_source_id_to_events.calagator.rb +10 -0
  266. data/spec/dummy/db/migrate/20150309023310_add_source_id_to_venues.calagator.rb +11 -0
  267. data/spec/dummy/db/migrate/20150309023311_add_duplicate_of_column_to_venues.calagator.rb +10 -0
  268. data/spec/dummy/db/migrate/20150309023312_add_duplicate_of_column_to_events.calagator.rb +10 -0
  269. data/spec/dummy/db/migrate/20150309023313_change_lat_long_type.calagator.rb +13 -0
  270. data/spec/dummy/db/migrate/20150309023314_add_source_reimport.calagator.rb +10 -0
  271. data/spec/dummy/db/migrate/20150309023315_change_end_time_to_duration.calagator.rb +12 -0
  272. data/spec/dummy/db/migrate/20150309023316_remove_format_type_from_source.calagator.rb +10 -0
  273. data/spec/dummy/db/migrate/20150309023317_create_updates.calagator.rb +16 -0
  274. data/spec/dummy/db/migrate/20150309023318_remove_next_update_from_source.calagator.rb +10 -0
  275. data/spec/dummy/db/migrate/20150309023319_change_duration_to_end_time.calagator.rb +12 -0
  276. data/spec/dummy/db/migrate/20150309023320_create_tags_and_taggings.calagator.rb +29 -0
  277. data/spec/dummy/db/migrate/20150309023321_create_versioned_events.calagator.rb +26 -0
  278. data/spec/dummy/db/migrate/20150309023322_create_versioned_venues.calagator.rb +33 -0
  279. data/spec/dummy/db/migrate/20150309023323_add_rrule_to_events.calagator.rb +16 -0
  280. data/spec/dummy/db/migrate/20150309023324_create_versions.calagator.rb +19 -0
  281. data/spec/dummy/db/migrate/20150309023325_add_closed_flag_to_venues.calagator.rb +10 -0
  282. data/spec/dummy/db/migrate/20150309023326_add_wifi_flag_to_venues.calagator.rb +10 -0
  283. data/spec/dummy/db/migrate/20150309023327_add_access_notes_to_venues.calagator.rb +10 -0
  284. data/spec/dummy/db/migrate/20150309023328_add_events_count_to_venues.calagator.rb +9 -0
  285. data/spec/dummy/db/migrate/20150309023329_add_venue_details_to_events.calagator.rb +10 -0
  286. data/spec/dummy/db/migrate/20150309023330_acts_as_taggable_on_migration.calagator.rb +51 -0
  287. data/spec/dummy/db/migrate/20150309023331_cleanup.calagator.rb +15 -0
  288. data/spec/dummy/db/migrate/20150309023332_specify_venues_latitude_and_longitude_precision.calagator.rb +12 -0
  289. data/spec/dummy/db/migrate/20150309023333_remove_updates.calagator.rb +14 -0
  290. data/spec/dummy/db/migrate/20150309023334_add_locked_status_to_events.calagator.rb +6 -0
  291. data/spec/dummy/db/schema.rb +95 -0
  292. data/spec/dummy/db/seeds.rb +7 -0
  293. data/spec/dummy/db/test.sqlite3 +0 -0
  294. data/spec/dummy/doc/README_FOR_APP +2 -0
  295. data/spec/dummy/log/development.log +273 -0
  296. data/spec/dummy/public/404.html +26 -0
  297. data/spec/dummy/public/422.html +26 -0
  298. data/spec/dummy/public/500.html +25 -0
  299. data/spec/dummy/public/favicon.ico +0 -0
  300. data/spec/dummy/public/robots.txt +5 -0
  301. data/spec/dummy/script/rails +6 -0
  302. data/spec/dummy/test/performance/browsing_test.rb +12 -0
  303. data/spec/dummy/test/test_helper.rb +13 -0
  304. data/spec/factories.rb +93 -0
  305. data/spec/features/add_event_spec.rb +99 -0
  306. data/spec/features/add_venue_spec.rb +34 -0
  307. data/spec/features/admin_auth_spec.rb +22 -0
  308. data/spec/features/admin_lock_event_spec.rb +41 -0
  309. data/spec/features/import_events_from_feed_spec.rb +43 -0
  310. data/spec/features/managing_event_spec.rb +111 -0
  311. data/spec/features/managing_venue_spec.rb +71 -0
  312. data/spec/features/search_event_spec.rb +27 -0
  313. data/spec/helpers/calagator/application_helper_spec.rb +82 -0
  314. data/spec/helpers/calagator/events_helper_spec.rb +172 -0
  315. data/spec/helpers/calagator/google_event_export_helper_spec.rb +70 -0
  316. data/spec/helpers/calagator/sources_helper_spec.rb +12 -0
  317. data/spec/helpers/calagator/tags_helper_spec.rb +85 -0
  318. data/spec/helpers/calagator/time_range_helper_spec.rb +59 -0
  319. data/spec/lib/calagator/blacklist_validator_spec.rb +65 -0
  320. data/spec/lib/calagator/decode_html_entities_hack_spec.rb +54 -0
  321. data/spec/lib/calagator/settings_spec.rb +20 -0
  322. data/spec/lib/calagator/url_prefixer_spec.rb +33 -0
  323. data/spec/lib/secrets_reader_spec.rb +65 -0
  324. data/spec/models/calagator/event/cloner_spec.rb +43 -0
  325. data/spec/models/calagator/event/overview_spec.rb +79 -0
  326. data/spec/models/calagator/event/search_spec.rb +103 -0
  327. data/spec/models/calagator/event_search_spec.rb +149 -0
  328. data/spec/models/calagator/event_spec.rb +859 -0
  329. data/spec/models/calagator/source/parser_facebook_spec.rb +73 -0
  330. data/spec/models/calagator/source/parser_hcal_spec.rb +69 -0
  331. data/spec/models/calagator/source/parser_ical_non_standard_spec.rb +91 -0
  332. data/spec/models/calagator/source/parser_ical_spec.rb +322 -0
  333. data/spec/models/calagator/source/parser_meetup_spec.rb +69 -0
  334. data/spec/models/calagator/source/parser_plancast_spec.rb +53 -0
  335. data/spec/models/calagator/source/parser_spec.rb +238 -0
  336. data/spec/models/calagator/source_spec.rb +135 -0
  337. data/spec/models/calagator/venue/search_spec.rb +92 -0
  338. data/spec/models/calagator/venue_search_spec.rb +124 -0
  339. data/spec/models/calagator/venue_spec.rb +346 -0
  340. data/spec/models/tag_spec.rb +35 -0
  341. data/spec/rails_helper.rb +39 -0
  342. data/spec/spec_helper.rb +140 -0
  343. data/spec/support/disable_geocoding.rb +1 -0
  344. data/spec/support/http_samples.rb +5 -0
  345. data/spec/support/samples/facebook.json +23 -0
  346. data/spec/support/samples/hcal_basic.xml +6 -0
  347. data/spec/support/samples/hcal_dup_event_dup_venue.xml +13 -0
  348. data/spec/support/samples/hcal_event_duplicates_fixture.xml +13 -0
  349. data/spec/support/samples/hcal_event_wo_lat_and_long.xml +14 -0
  350. data/spec/support/samples/hcal_multiple.xml +16 -0
  351. data/spec/support/samples/hcal_same_event_twice_with_different_venues.xml +12 -0
  352. data/spec/support/samples/hcal_single.xml +8 -0
  353. data/spec/support/samples/hcal_two_identical_events.xml +14 -0
  354. data/spec/support/samples/hcal_upcoming_v1.html +412 -0
  355. data/spec/support/samples/hcal_upcoming_v2.html +749 -0
  356. data/spec/support/samples/hcal_upcoming_v3.html +685 -0
  357. data/spec/support/samples/hcal_upcoming_v4.html +761 -0
  358. data/spec/support/samples/ical_apple.ics +22 -0
  359. data/spec/support/samples/ical_apple_v3.ics +37 -0
  360. data/spec/support/samples/ical_basic.ics +15 -0
  361. data/spec/support/samples/ical_basic_with_duration.ics +16 -0
  362. data/spec/support/samples/ical_event_with_squashed_venue.ics +12 -0
  363. data/spec/support/samples/ical_eventful_many.ics +504 -0
  364. data/spec/support/samples/ical_gmt.ics +12 -0
  365. data/spec/support/samples/ical_google.ics +786 -0
  366. data/spec/support/samples/ical_multiple_calendars.ics +111 -0
  367. data/spec/support/samples/ical_upcoming.ics +36 -0
  368. data/spec/support/samples/ical_upcoming_many.ics +682 -0
  369. data/spec/support/samples/ical_upcoming_v2.ics +43 -0
  370. data/spec/support/samples/ical_z.ics +10 -0
  371. data/spec/support/samples/meetup.ics +16 -0
  372. data/spec/support/samples/meetup.json +31 -0
  373. data/spec/support/samples/plancast.ics +59 -0
  374. data/spec/support/samples/plancast.json +51 -0
  375. data/spec/support/samples/plancast_with_missing_venue.json +39 -0
  376. data/spec/support/samples/upcoming_v1.xml +8 -0
  377. data/spec/support/samples/upcoming_v2_with_invalid_utc_dates.xml +8 -0
  378. data/spec/support/time_convenience_methods.rb +8 -0
  379. data/spec/support/time_zones.rb +12 -0
  380. data/spec/support/url_helpers.rb +5 -0
  381. data/spec/support/wait_for_ajax.rb +15 -0
  382. data/spec/support/webmock.rb +8 -0
  383. data/spec/travis_spec.rb +7 -0
  384. metadata +1194 -0
@@ -0,0 +1,111 @@
1
+ require 'rails_helper'
2
+
3
+ feature 'Event Editing' do
4
+ background do
5
+ Timecop.travel('2014-10-09')
6
+ create :event, title: 'Ruby Future', start_time: Time.zone.now
7
+ end
8
+
9
+ after do
10
+ Timecop.return
11
+ end
12
+
13
+ scenario 'A user edits an existing event' do
14
+ visit '/'
15
+
16
+ within '#today' do
17
+ click_on 'Ruby Future'
18
+ end
19
+
20
+ click_on 'edit'
21
+
22
+ expect(find_field('Event Name').value).to have_content 'Ruby Future'
23
+ fill_in 'Event Name', with: 'Ruby ABCs'
24
+ fill_in 'start_date', with: '2014-10-10'
25
+ fill_in 'start_time', with: '06:00 PM'
26
+ fill_in 'end_date', with: '2014-10-10'
27
+ fill_in 'end_time', with: '07:00 PM'
28
+ fill_in 'Website', with: 'www.rubynewbies.com'
29
+ fill_in 'Description', with: 'An event for beginners'
30
+ fill_in 'Tags', with: 'beginners,ruby'
31
+ click_on 'Update Event'
32
+
33
+ expect(page).to have_content 'Event was successfully saved'
34
+ expect(page).to have_content 'Ruby ABCs'
35
+ expect(page).to have_content 'Friday, October 10, 2014 from 6–7pm'
36
+ expect(page).to have_content 'Website http://www.rubynewbies.com'
37
+ expect(page).to have_content 'Description An event for beginners'
38
+ expect(page).to have_content 'Tags beginners, ruby'
39
+
40
+ click_on 'Calagator'
41
+ within '#tomorrow' do
42
+ expect(page).to have_content 'Ruby ABCs'
43
+ end
44
+ end
45
+ end
46
+
47
+ feature 'Event Cloning' do
48
+ background do
49
+ Timecop.travel('2014-10-09')
50
+ create :event, title: 'Ruby Event Part One', start_time: 4.days.from_now
51
+ end
52
+
53
+ after do
54
+ Timecop.return
55
+ end
56
+
57
+ scenario 'A user clones an existing event' do
58
+ visit '/'
59
+
60
+ within '#next_two_weeks' do
61
+ click_on 'Ruby Event Part One'
62
+ end
63
+ click_on 'clone'
64
+
65
+ expect(find_field('Event Name').value).to have_content 'Ruby Event Part One'
66
+
67
+ fill_in 'Event Name', with: 'Ruby Event Part Two'
68
+ fill_in 'start_date', with: '2014-10-27'
69
+ fill_in 'start_time', with: '06:00 PM'
70
+ fill_in 'end_time', with: '11:00 PM'
71
+ fill_in 'end_date', with: '2014-27-13'
72
+ fill_in 'Website', with: 'www.rubynewbies.com'
73
+ fill_in 'Description', with: 'An event for beginners'
74
+ fill_in 'Tags', with: 'beginners,ruby'
75
+ click_on 'Create Event'
76
+
77
+ expect(page).to have_content 'Event was successfully saved'
78
+ expect(page).to have_content 'Ruby Event Part Two'
79
+ expect(page).to have_content 'Monday, October 27, 2014 at 6pm'
80
+ expect(page).to have_content 'Website http://www.rubynewbies.com'
81
+ expect(page).to have_content 'Description An event for beginners'
82
+ expect(page).to have_content 'Tags beginners, ruby'
83
+
84
+ click_on 'Calagator'
85
+ click_on 'View future events »'
86
+ expect(page).to have_content 'Ruby Event Part Two'
87
+ end
88
+ end
89
+
90
+ feature 'Event Deletion' do
91
+ background do
92
+ create :event, title: 'Ruby and You', start_time: 1.day.from_now
93
+ end
94
+
95
+ scenario 'A user deletes an event' do
96
+ visit '/'
97
+
98
+ within '#tomorrow' do
99
+ click_on 'Ruby and You'
100
+ end
101
+
102
+ click_on 'delete'
103
+
104
+ expect(page).to have_content '"Ruby and You" has been deleted'
105
+
106
+ click_on 'Calagator'
107
+ within '#tomorrow' do
108
+ expect(page).to have_content '- No events -'
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,71 @@
1
+ require 'rails_helper'
2
+
3
+ feature 'Venue Editing' do
4
+ let!(:venue) { create(:venue) }
5
+ let!(:event) { create(:event, venue: venue, start_time: Time.now.end_of_day - 1.hour) }
6
+ let!(:new_venue) { build(:venue) }
7
+
8
+ scenario 'A user edits an existing venue' do
9
+
10
+ visit "/"
11
+ click_on venue.title
12
+ click_on 'edit'
13
+
14
+ venue_name = find_field('Venue Name').value
15
+ expect(venue_name).to have_content "#{venue.title}"
16
+
17
+ fill_in 'Venue Name', with: new_venue.title
18
+ fill_in 'Street address', with: new_venue.street_address
19
+ fill_in 'City', with: new_venue.locality
20
+ fill_in 'State', with: new_venue.region
21
+ fill_in 'Zip Code', with: new_venue.postal_code
22
+ fill_in 'Country', with: new_venue.country
23
+ fill_in 'Web Link', with: new_venue.url
24
+ fill_in 'Email', with: new_venue.email
25
+ fill_in 'Telephone', with: new_venue.telephone
26
+ check('venue_wifi') if new_venue.wifi
27
+ fill_in 'Description', with: new_venue.description
28
+ fill_in 'Access notes', with: 'Just pay the ticket price.'
29
+ check('venue_closed') if new_venue.closed
30
+
31
+ click_on 'Update Venue'
32
+
33
+ expect(page).to have_content 'Venue was successfully saved.'
34
+ expect(page).to have_content new_venue.title
35
+ expect(page).to have_content new_venue.street_address
36
+ expect(page).to have_content new_venue.locality
37
+ expect(page).to have_content new_venue.region
38
+ expect(page).to have_content new_venue.postal_code
39
+ expect(page).to have_content new_venue.country
40
+ expect(page).to have_content new_venue.url
41
+ expect(page).to have_content new_venue.email
42
+ expect(page).to have_content new_venue.telephone
43
+ expect(page).to have_content new_venue.description
44
+ expect(page).to have_content 'Public WiFi'
45
+ expect(page).to have_content 'Just pay the ticket price.'
46
+ expect(page).to have_content 'This venue is no longer open for business.' if new_venue.closed
47
+ end
48
+ end
49
+
50
+ feature 'Venue Deletion' do
51
+ background do
52
+ create :venue, title: 'Test Venue'
53
+ end
54
+
55
+ scenario 'A user deletes a venue' do
56
+ visit '/'
57
+ click_on 'Venues'
58
+
59
+ within '#newest' do
60
+ click_on 'Test Venue'
61
+ end
62
+
63
+ click_on 'delete'
64
+
65
+ expect(page).to have_content %("Test Venue" has been deleted)
66
+
67
+ click_on "List all venues"
68
+
69
+ expect(page).to have_content "Sorry, there are no venues"
70
+ end
71
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails_helper'
2
+
3
+ feature 'search for events' do
4
+ background do
5
+ create :event, title: 'Ruby Future', start_time: today + 1.day
6
+ create :event, title: 'Python Past', start_time: today - 1.day
7
+ create :event, title: 'Ruby Part 2 Past', start_time: today - 2.day
8
+ create :event, title: 'Ruby Part 1 Past', start_time: today - 3.day
9
+ end
10
+
11
+ scenario 'User searches for an event by name' do
12
+ visit '/'
13
+
14
+ find_field('Search Events').native.send_keys "Ruby\n"
15
+
16
+ within('#current') do
17
+ expect(page).to have_content 'Viewing 1 current event'
18
+ expect(page).to have_content 'Ruby Future'
19
+ end
20
+
21
+ within('#past') do
22
+ expect(page).to have_content 'Viewing 2 past events'
23
+ expect(page).to have_content 'Ruby Part 2 Past'
24
+ expect(page).to have_content 'Ruby Part 1 Past'
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ module Calagator
4
+
5
+ describe ApplicationHelper, :type => :helper do
6
+ describe "when escaping HTML while preserving entities (cleanse)" do
7
+ it "should preserve plain text" do
8
+ expect(cleanse("Allison to Lillia")).to eq "Allison to Lillia"
9
+ end
10
+
11
+ it "should escape HTML" do
12
+ expect(cleanse("<Fiona>")).to eq "&lt;Fiona&gt;"
13
+ end
14
+
15
+ it "should preserve HTML entities" do
16
+ expect(cleanse("Allison &amp; Lillia")).to eq "Allison &amp; Lillia"
17
+ end
18
+
19
+ it "should handle text, HTML and entities together" do
20
+ expect(cleanse("&quot;<Allison> &amp; Lillia&quot;")).to eq "&quot;&lt;Allison&gt; &amp; Lillia&quot;"
21
+ end
22
+ end
23
+
24
+ describe "#format_description" do
25
+ it "should autolink" do
26
+ expect(helper.format_description("foo http://mysite.com/~user bar")).to eq \
27
+ '<p>foo <a href="http://mysite.com/~user">http://mysite.com/~user</a> bar</p>'
28
+ end
29
+
30
+ it "should process Markdown links" do
31
+ expect(helper.format_description("[ClojureScript](https://github.com/clojure/clojurescript), the Clojure to JS compiler")).to eq \
32
+ '<p><a href="https://github.com/clojure/clojurescript">ClojureScript</a>, the Clojure to JS compiler</p>'
33
+ end
34
+
35
+ it "should process Markdown references" do
36
+ expect(helper.format_description("
37
+ [SocketStream][1], a phenomenally fast real-time web framework for Node.js
38
+
39
+ [1]: https://github.com/socketstream/socketstream
40
+ ")).to eq \
41
+ '<p><a href="https://github.com/socketstream/socketstream">SocketStream</a>, a phenomenally fast real-time web framework for Node.js</p>'
42
+ end
43
+ end
44
+
45
+ describe "the source code version date" do
46
+ it "returns the timestamp from git" do
47
+ expect(ApplicationHelper).to receive(:system).with(/git/).and_return(true)
48
+ expect(ApplicationHelper).to receive(:`).with(/git/).and_return("Tue Jul 29 01:22:49 2014 -0700")
49
+ expect(ApplicationHelper.source_code_version_raw).to match(/Git timestamp: Tue Jul 29 01:22:49 2014 -0700/)
50
+ end
51
+
52
+ describe "when the git command can't be found" do
53
+ it "returns empty string" do
54
+ expect(ApplicationHelper).to receive(:system).with(/git/).and_return(true)
55
+ expect(ApplicationHelper).to receive(:`).with(/git/).and_raise(Errno::ENOENT)
56
+ expect(ApplicationHelper.source_code_version_raw).to eq("")
57
+ end
58
+ end
59
+
60
+ describe "when the git command returns a non-zero exit status" do
61
+ it "returns empty string" do
62
+ expect(ApplicationHelper).to receive(:system).with(/git/).and_return(false)
63
+ expect(ApplicationHelper.source_code_version_raw).to eq("")
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#datestamp" do
69
+ it "constructs a sentence describing the item's history" do
70
+ event = FactoryGirl.create(:event, created_at: "2010-01-01", updated_at: "2010-01-02")
71
+ event.create_source! title: "google", url: "http://google.com"
72
+ allow(event.source).to receive_messages id: 1
73
+ expect(helper.datestamp(event)).to eq(
74
+ %(This item was imported from <a href="/sources/1">google</a> <br />) +
75
+ %(<strong>Friday, January 1, 2010 at midnight</strong> ) +
76
+ %(and last updated <br /><strong>Saturday, January 2, 2010 at midnight</strong>.)
77
+ )
78
+ end
79
+ end
80
+ end
81
+
82
+ end
@@ -0,0 +1,172 @@
1
+ require 'spec_helper'
2
+
3
+ module Calagator
4
+
5
+ describe EventsHelper, :type => :helper do
6
+ describe "#events_sort_link" do
7
+ it "renders a sorting link with the field for the supplied key" do
8
+ params.merge! action: "index", controller: "calagator/events"
9
+ expect(helper.events_sort_link("score")).to eq(%(<a href="/events?order=score">Relevance</a>))
10
+ end
11
+
12
+ it "removes any existing order if no key is entered" do
13
+ params.merge! action: "index", controller: "calagator/events", order: "score"
14
+ expect(helper.events_sort_link(nil)).to eq(%(<a href="/events">Default</a>))
15
+ end
16
+ end
17
+
18
+ describe "#events_sort_label" do
19
+ it "should return nil without arguments" do
20
+ expect(helper.events_sort_label(nil)).to be_nil
21
+ end
22
+
23
+ it "should return string for a string key" do
24
+ expect(helper.events_sort_label("score")).to eq(" by <strong>Relevance.</strong>")
25
+ end
26
+
27
+ it "should return string for a symbol key" do
28
+ expect(helper.events_sort_label(:score)).to eq(" by <strong>Relevance.</strong>")
29
+ end
30
+
31
+ it "should use the label Date when using a tag" do
32
+ assign :tag, ActsAsTaggableOn::Tag.new
33
+ expect(helper.events_sort_label(nil)).to eq(" by <strong>Date.</strong>")
34
+ end
35
+ end
36
+
37
+ describe "#today_tomorrow_or_weekday" do
38
+ it "should display day of the week" do
39
+ event = Event.new start_time: "2010-01-01"
40
+ expect(helper.today_tomorrow_or_weekday(event)).to eq("Friday")
41
+ end
42
+
43
+ it "should display tomorrow as 'Tomorrow'" do
44
+ event = Event.new start_time: "2010-01-01", end_time: 1.day.from_now
45
+ expect(helper.today_tomorrow_or_weekday(event)).to eq("Started Friday")
46
+ end
47
+ end
48
+
49
+ describe "#google_events_subscription_link" do
50
+ def method(*args)
51
+ helper.google_events_subscription_link(*args)
52
+ end
53
+
54
+ it "should fail if given unknown options" do
55
+ expect { method(:omg => :kittens) }.to raise_error ArgumentError
56
+ end
57
+
58
+ it "should generate a default link" do
59
+ expect(method).to eq "http://www.google.com/calendar/render?cid=http%3A%2F%2Ftest.host%2Fevents.ics"
60
+ end
61
+
62
+ it "should generate a search link" do
63
+ expect(method(:query => "my query")).to eq "http://www.google.com/calendar/render?cid=http%3A%2F%2Ftest.host%2Fevents%2Fsearch.ics%3Fquery%3Dmy%2Bquery"
64
+ end
65
+
66
+ it "should generate a tag link" do
67
+ expect(method(:tag => "mytag")).to eq "http://www.google.com/calendar/render?cid=http%3A%2F%2Ftest.host%2Fevents%2Fsearch.ics%3Ftag%3Dmytag"
68
+ end
69
+ end
70
+
71
+ describe "#icalendar_feed_link" do
72
+ def method(*args)
73
+ helper.icalendar_feed_link(*args)
74
+ end
75
+
76
+ it "should fail if given unknown options" do
77
+ expect { method(:omg => :kittens) }.to raise_error ArgumentError
78
+ end
79
+
80
+ it "should generate a default link" do
81
+ expect(method).to eq "webcal://test.host/events.ics"
82
+ end
83
+
84
+ it "should generate a search link" do
85
+ expect(method(:query => "my query")).to eq "webcal://test.host/events/search.ics?query=my+query"
86
+ end
87
+
88
+ it "should generate a tag link" do
89
+ expect(method(:tag => "mytag")).to eq "webcal://test.host/events/search.ics?tag=mytag"
90
+ end
91
+ end
92
+
93
+ describe "#icalendar_export_link" do
94
+ def method(*args)
95
+ helper.icalendar_export_link(*args)
96
+ end
97
+
98
+ it "should fail if given unknown options" do
99
+ expect { method(:omg => :kittens) }.to raise_error ArgumentError
100
+ end
101
+
102
+ it "should generate a default link" do
103
+ expect(method).to eq "http://test.host/events.ics"
104
+ end
105
+
106
+ it "should generate a search link" do
107
+ expect(method(:query => "my query")).to eq "http://test.host/events/search.ics?query=my+query"
108
+ end
109
+
110
+ it "should generate a tag link" do
111
+ expect(method(:tag => "mytag")).to eq "http://test.host/events/search.ics?tag=mytag"
112
+ end
113
+ end
114
+
115
+ describe "#atom_feed_link" do
116
+ def method(*args)
117
+ helper.atom_feed_link(*args)
118
+ end
119
+
120
+ it "should fail if given unknown options" do
121
+ expect { method(:omg => :kittens) }.to raise_error ArgumentError
122
+ end
123
+
124
+ it "should generate a default link" do
125
+ expect(method).to eq "http://test.host/events.atom"
126
+ end
127
+
128
+ it "should generate a search link" do
129
+ expect(method(:query => "my query")).to eq "http://test.host/events/search.atom?query=my+query"
130
+ end
131
+
132
+ it "should generate a tag link" do
133
+ expect(method(:tag => "mytag")).to eq "http://test.host/events/search.atom?tag=mytag"
134
+ end
135
+ end
136
+
137
+ describe "#tweet_text" do
138
+ it "contructs a tweet" do
139
+ event = FactoryGirl.create(:event,
140
+ title: "hip and/or hop",
141
+ start_time: "2010-01-01 12:00:00",
142
+ end_time: "2010-01-02 12:00:00")
143
+ event.venue = FactoryGirl.create(:venue, title: "holocene")
144
+ expect(tweet_text(event)).to eq("hip and/or hop - 12:00PM 01.01.2010 @ holocene")
145
+ end
146
+
147
+ it "crops it at 140 characters" do
148
+ event = FactoryGirl.create(:event,
149
+ title: "hip and/or hop, hip and/or hop, hip and/or hop, hip and/or hop, hip and/or hop, hip and/or hop",
150
+ start_time: "2010-01-01 12:00:00",
151
+ end_time: "2010-01-02 12:00:00")
152
+ event.venue = FactoryGirl.create(:venue, title: "holocene")
153
+ expect(tweet_text(event)).to eq("hip and/or hop, hip and/or hop, hip and/or hop, hip and/or hop, hip and/or hop, h... - 12:00PM 01.01.2010 @ holocene")
154
+ end
155
+ end
156
+
157
+ describe "sorting labels" do
158
+ it "should display human-friendly label for a known value" do
159
+ expect(helper.sorting_label_for('name')).to eq 'Event Name'
160
+ end
161
+
162
+ it "should display a default label" do
163
+ expect(helper.sorting_label_for(nil)).to eq 'Relevance'
164
+ end
165
+
166
+ it "should display a different default label when searching by tag" do
167
+ expect(helper.sorting_label_for(nil, true)).to eq 'Date'
168
+ end
169
+ end
170
+ end
171
+
172
+ end