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,319 @@
1
+ require 'spec_helper'
2
+ require './spec/controllers/squash_many_duplicates_examples'
3
+
4
+ module Calagator
5
+
6
+ describe VenuesController, :type => :controller do
7
+ routes { Calagator::Engine.routes }
8
+
9
+ render_views
10
+
11
+ it "should redirect duplicate venues to their master" do
12
+ venue_master = FactoryGirl.create(:venue)
13
+ venue_duplicate = FactoryGirl.create(:venue)
14
+
15
+ # No redirect when they're unique
16
+ get 'show', :id => venue_duplicate.id
17
+ expect(response).not_to be_redirect
18
+ expect(assigns(:venue).id).to eq venue_duplicate.id
19
+
20
+ # Mark as duplicate
21
+ venue_duplicate.duplicate_of = venue_master
22
+ venue_duplicate.save!
23
+
24
+ # Now check that redirection happens
25
+ get 'show', :id => venue_duplicate.id
26
+ expect(response).to be_redirect
27
+ expect(response).to redirect_to(venue_url(venue_master.id))
28
+ end
29
+
30
+ context "with admin auth for duplicates" do
31
+ before do
32
+ credentials = ActionController::HttpAuthentication::Basic.encode_credentials SECRETS.admin_username, SECRETS.admin_password
33
+ request.env['HTTP_AUTHORIZATION'] = credentials
34
+ end
35
+
36
+ it "should display an error message if given invalid arguments" do
37
+ get 'duplicates', :type => 'omgwtfbbq'
38
+
39
+ expect(response).to be_success
40
+ expect(response.body).to have_selector('.failure', text: 'omgwtfbbq')
41
+ end
42
+
43
+ context do
44
+ include_examples "#squash_many_duplicates", :venue
45
+ end
46
+ end
47
+
48
+ describe "when creating venues" do
49
+ it "should redirect to the newly created venue" do
50
+ post :create, venue: FactoryGirl.attributes_for(:venue)
51
+ expect(response).to redirect_to(assigns(:venue))
52
+ end
53
+
54
+ it "should stop evil robots" do
55
+ post :create, :trap_field => "I AM AN EVIL ROBOT, I EAT OLD PEOPLE'S MEDICINE FOR FOOD!"
56
+ expect(response).to render_template :new
57
+ end
58
+ end
59
+
60
+ describe "when updating venues" do
61
+ before do
62
+ @venue = FactoryGirl.create(:venue)
63
+ end
64
+
65
+ it "should redirect to the updated venue" do
66
+ put :update, id: @venue.id, venue: FactoryGirl.attributes_for(:venue)
67
+ expect(response).to redirect_to(@venue)
68
+ end
69
+
70
+ it "should redirect to any associated event" do
71
+ @event = FactoryGirl.create(:event, venue: @venue)
72
+ put :update, id: @venue.id, from_event: @event.id, venue: FactoryGirl.attributes_for(:venue)
73
+ expect(response).to redirect_to(@event)
74
+ end
75
+
76
+ it "should stop evil robots" do
77
+ put :update, id: @venue.id, trap_field: "I AM AN EVIL ROBOT, I EAT OLD PEOPLE'S MEDICINE FOR FOOD!"
78
+ expect(response).to render_template :edit
79
+ end
80
+ end
81
+
82
+ describe "when rendering the new venue page" do
83
+ it "passes the template a new venue" do
84
+ get :new
85
+ expect(assigns[:venue]).to be_a Venue
86
+ expect(assigns[:venue]).to be_new_record
87
+ end
88
+ end
89
+
90
+ describe "when rendering the edit venue page" do
91
+ it "passes the template the specified venue" do
92
+ @venue = FactoryGirl.create(:venue)
93
+ get :edit, id: @venue.id
94
+ expect(assigns[:venue]).to eq(@venue)
95
+ end
96
+ end
97
+
98
+ describe "when rendering the map page" do
99
+ before do
100
+ @open_venue = FactoryGirl.create(:venue)
101
+ @closed_venue = FactoryGirl.create(:venue, closed: true)
102
+ @duplicate_venue = FactoryGirl.create(:venue, duplicate_of: @open_venue)
103
+ end
104
+
105
+ it "only shows open non-duplicate venues" do
106
+ get :map
107
+ expect(assigns[:venues]).to eq([@open_venue])
108
+ end
109
+ end
110
+
111
+ describe "when rendering the venues index" do
112
+ before do
113
+ @venues = [FactoryGirl.create(:venue), FactoryGirl.create(:venue)]
114
+ end
115
+
116
+ it "should assign the search object to @search" do
117
+ get :index
118
+ expect(assigns[:search]).to be_a Venue::Search
119
+ end
120
+
121
+ it "should assign search results to @venues" do
122
+ get :index
123
+ expect(assigns[:venues]).to eq(@venues)
124
+ end
125
+
126
+ describe "in JSON format" do
127
+ it "should produce JSON" do
128
+ get :index, :format => "json"
129
+
130
+ struct = ActiveSupport::JSON.decode(response.body)
131
+ expect(struct).to be_a_kind_of Array
132
+ end
133
+
134
+ it "should accept a JSONP callback" do
135
+ get :index, :format => "json", :callback => "some_function"
136
+
137
+ expect(response.body.split("\n").join).to match /^\s*some_function\(.*\);?\s*$/
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ describe "when showing venues" do
144
+ it "redirects to all venues if venue doesn't exist" do
145
+ get :show, id: "garbage"
146
+ expect(response).to redirect_to("/venues")
147
+ end
148
+
149
+ describe "in JSON format" do
150
+ describe "with events" do
151
+ before do
152
+ @venue = FactoryGirl.build(:venue, :id => 123)
153
+ allow(Venue).to receive(:find).and_return(@venue)
154
+ end
155
+
156
+ it "should produce JSON" do
157
+ get :show, :id => @venue.to_param, :format => "json"
158
+
159
+ struct = ActiveSupport::JSON.decode(response.body)
160
+ expect(struct).to be_a_kind_of Hash
161
+ %w[id title description address].each do |field|
162
+ expect(struct[field]).to eq @venue.send(field)
163
+ end
164
+ end
165
+
166
+ it "should accept a JSONP callback" do
167
+ get :show, :id => @venue.to_param, :format => "json", :callback => "some_function"
168
+
169
+ expect(response.body.split("\n").join).to match /^\s*some_function\(.*\);?\s*$/
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "in HTML format" do
175
+ describe "venue with future and past events" do
176
+ before do
177
+ @venue = FactoryGirl.create(:venue)
178
+ @future_event = FactoryGirl.create(:event, :venue => @venue)
179
+ @past_event = FactoryGirl.create(:event, :venue => @venue,
180
+ :start_time => Time.now - 1.week + 1.hour,
181
+ :end_time => Time.now - 1.week + 2.hours)
182
+
183
+ get :show, :id => @venue.to_param, :format => "html"
184
+ expect(response).to be_success
185
+ end
186
+
187
+ it "should have a venue" do
188
+ expect(response.body).to have_selector(".location .fn", text: @venue.title)
189
+ end
190
+
191
+ it "should have a future event" do
192
+ expect(response.body).to have_selector("#events #future_events .summary", text: @future_event.title)
193
+ end
194
+
195
+ it "should have a past event" do
196
+ expect(response.body).to have_selector("#events #past_events .summary", text: @past_event.title)
197
+ end
198
+ end
199
+ end
200
+
201
+ describe "as an iCalendar" do
202
+ before do
203
+ @venue = FactoryGirl.create(:venue)
204
+ @future_event = FactoryGirl.create(:event, :venue => @venue, :start_time => today + 1.hour)
205
+ @past_event = FactoryGirl.create(:event, :venue => @venue, :start_time => today - 1.hour)
206
+
207
+ get :show, :id => @venue.to_param, :format => "ics"
208
+ end
209
+
210
+ it "should have a calendar" do
211
+ expect(response.body).to match /BEGIN:VCALENDAR/
212
+ end
213
+
214
+ it "should have events" do
215
+ expect(response.body).to match /BEGIN:VEVENT/
216
+ end
217
+
218
+ it "should render all future events" do
219
+ expect(response.body).to match /SUMMARY:#{@future_event.title}/
220
+ end
221
+
222
+ it "should render all past events" do
223
+ expect(response.body).to match /SUMMARY:#{@past_event.title}/
224
+ end
225
+ end
226
+
227
+ end
228
+
229
+ describe "DELETE" do
230
+ describe "when deleting a venue without events" do
231
+ before do
232
+ @venue = FactoryGirl.create(:venue)
233
+ end
234
+
235
+ shared_examples_for "destroying a Venue record without events" do
236
+ it "should destroy the Venue record" do
237
+ expect { Venue.find(@venue.id) }.to raise_error ActiveRecord::RecordNotFound
238
+ end
239
+ end
240
+
241
+ describe "and rendering HTML" do
242
+ before do
243
+ delete :destroy, :id => @venue.id
244
+ end
245
+
246
+ it_should_behave_like "destroying a Venue record without events"
247
+
248
+ it "should display a success message" do
249
+ expect(flash[:success]).to be_present
250
+ end
251
+
252
+ it "should redirect to the venues listing" do
253
+ expect(response).to redirect_to(venues_path)
254
+ end
255
+ end
256
+
257
+ describe "and rendering XML" do
258
+ render_views
259
+
260
+ before do
261
+ delete :destroy, :id => @venue.id, :format => "xml"
262
+ end
263
+
264
+ it_should_behave_like "destroying a Venue record without events"
265
+
266
+ it "should return a success status" do
267
+ expect(response).to be_success
268
+ end
269
+ end
270
+ end
271
+
272
+ describe "when deleting a venue with events" do
273
+ before do
274
+ @event = FactoryGirl.create(:event, :with_venue)
275
+ @venue = @event.venue
276
+ end
277
+
278
+ shared_examples_for "destroying a Venue record with events" do
279
+ it "should not destroy the Venue record" do
280
+ expect(Venue.find(@venue.id)).to be_present
281
+ end
282
+ end
283
+
284
+ describe "and rendering HTML" do
285
+ before do
286
+ delete :destroy, :id => @venue.id
287
+ end
288
+
289
+ it_should_behave_like "destroying a Venue record with events"
290
+
291
+ it "should display a failure message" do
292
+ expect(flash[:failure]).to be_present
293
+ end
294
+
295
+ it "should redirect to the venue page" do
296
+ expect(response).to redirect_to(venue_path(@venue))
297
+ end
298
+ end
299
+
300
+ describe "and rendering XML" do
301
+ before do
302
+ delete :destroy, :id => @venue.id, :format => "xml"
303
+ end
304
+
305
+ it_should_behave_like "destroying a Venue record with events"
306
+
307
+ it "should return unprocessable entity status" do
308
+ expect(response.code.to_i).to eq 422
309
+ end
310
+
311
+ it "should describing the problem" do
312
+ expect(response.body).to match /cannot/i
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
318
+
319
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ module Calagator
4
+
5
+ describe VersionsController, :type => :controller do
6
+ routes { Calagator::Engine.routes }
7
+
8
+ describe "without versions" do
9
+ it "should raise RecordNotFound if not given an id" do
10
+ expect do
11
+ get :edit, :id => ''
12
+ end.to raise_error ActiveRecord::RecordNotFound
13
+ end
14
+
15
+ it "should raise RecordNotFound if given invalid id" do
16
+ expect do
17
+ get :edit, :id => '-1'
18
+ end.to raise_error ActiveRecord::RecordNotFound
19
+ end
20
+
21
+ it "should raise RecordNotFound if given id that doesn't exist" do
22
+ expect do
23
+ get :edit, :id => '1234'
24
+ end.to raise_error ActiveRecord::RecordNotFound
25
+ end
26
+ end
27
+
28
+ describe "with versions" do
29
+ before do
30
+ @create_title = "myevent"
31
+ @update_title = "myevent v2"
32
+ @final_title = "myevent v3"
33
+
34
+ @event = FactoryGirl.create(:event, :title => @create_title)
35
+
36
+ @event.title = @update_title
37
+ @event.save!
38
+
39
+ @event.title = @final_title
40
+ @event.save!
41
+
42
+ @event.destroy
43
+ end
44
+
45
+ # Returns the versioned record's title for the event (e.g. :update).
46
+ def title_for(event)
47
+ version_id = @event.versions.where(event: event).pluck(:id).first
48
+
49
+ get :edit, :id => version_id
50
+
51
+ return assigns[:event].title
52
+ end
53
+
54
+ it "should render the initial content for a 'create'" do
55
+ expect(title_for(:create)).to eq @create_title
56
+ end
57
+
58
+ it "should render the updated content for an 'update'" do
59
+ expect(title_for(:update)).to eq @update_title
60
+ end
61
+
62
+ it "should render the final content for a 'destroy'" do
63
+ expect(title_for(:destroy)).to eq @final_title
64
+ end
65
+
66
+ it "should render html" do
67
+ version_id = @event.versions.first.id
68
+ get :edit, id: version_id
69
+ expect(response).to be_success
70
+ expect(response).to render_template "events/edit"
71
+ end
72
+
73
+ it "should render html via xhr" do
74
+ version_id = @event.versions.first.id
75
+ xhr :get, :edit, id: version_id
76
+ expect(response).to be_success
77
+ expect(response).to render_template "events/_form"
78
+ end
79
+ end
80
+ end
81
+
82
+ end
@@ -0,0 +1,49 @@
1
+ shared_examples "#squash_many_duplicates" do |model|
2
+ before do
3
+ @master = FactoryGirl.create(model, title: "master")
4
+ @dup1 = FactoryGirl.create(model, title: "dup1")
5
+ @dup2 = FactoryGirl.create(model, title: "dup2")
6
+ end
7
+
8
+ context "happy path" do
9
+ before do
10
+ post :squash_many_duplicates, master_id: @master.id, duplicate_id_1: @dup1.id, duplicate_id_2: @dup2.id
11
+ end
12
+
13
+ it "squashes the duplicates into the master" do
14
+ expect(@master.duplicate_ids).to match_array([@dup1.id, @dup2.id])
15
+ end
16
+
17
+ it "redirects to duplicates page for more duplicate squashing" do
18
+ expect(response).to redirect_to("/#{model}s/duplicates")
19
+ end
20
+
21
+ it "sets the flash success message" do
22
+ expect(flash[:success]).to eq(%(Squashed duplicate #{model}s ["dup1", "dup2"] into master #{@master.id}.))
23
+ end
24
+ end
25
+
26
+ context "with no master" do
27
+ it "redirects with a failure message" do
28
+ post :squash_many_duplicates, duplicate_id_1: @dup1.id, duplicate_id_2: @dup2.id
29
+ expect(flash[:failure]).to eq("A master #{model} must be selected.")
30
+ expect(response).to redirect_to("/#{model}s/duplicates")
31
+ end
32
+ end
33
+
34
+ context "with no duplicates" do
35
+ it "redirects with a failure message" do
36
+ post :squash_many_duplicates, master_id: @master.id
37
+ expect(flash[:failure]).to eq("At least one duplicate #{model} must be selected.")
38
+ expect(response).to redirect_to("/#{model}s/duplicates")
39
+ end
40
+ end
41
+
42
+ context "with duplicates containing master" do
43
+ it "redirects with a failure message" do
44
+ post :squash_many_duplicates, master_id: @master.id, duplicate_id_1: @master.id
45
+ expect(flash[:failure]).to eq("The master #{model} could not be squashed into itself.")
46
+ expect(response).to redirect_to("/#{model}s/duplicates")
47
+ end
48
+ end
49
+ end