open_conference_ware 1.0.0.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.
- data.tar.gz.sig +0 -0
- data/.autotest +14 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/.travis.yml +18 -0
- data/CHANGES.md +280 -0
- data/CONTRIBUTORS.markdown +17 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +296 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +23 -0
- data/README.markdown +173 -0
- data/Rakefile +27 -0
- data/TODO.txt +22 -0
- data/app/assets/images/open_conference_ware/accept.png +0 -0
- data/app/assets/images/open_conference_ware/arrow-left.png +0 -0
- data/app/assets/images/open_conference_ware/arrow-out.png +0 -0
- data/app/assets/images/open_conference_ware/arrow-right.png +0 -0
- data/app/assets/images/open_conference_ware/arrow-up.png +0 -0
- data/app/assets/images/open_conference_ware/arrow_refresh.png +0 -0
- data/app/assets/images/open_conference_ware/comment.png +0 -0
- data/app/assets/images/open_conference_ware/comment_edit.png +0 -0
- data/app/assets/images/open_conference_ware/delete.png +0 -0
- data/app/assets/images/open_conference_ware/disk.png +0 -0
- data/app/assets/images/open_conference_ware/document-blank.png +0 -0
- data/app/assets/images/open_conference_ware/document.png +0 -0
- data/app/assets/images/open_conference_ware/edit.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_01.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_05.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_05x16.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_21.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_23.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_24.png +0 -0
- data/app/assets/images/open_conference_ware/extras/001_29.png +0 -0
- data/app/assets/images/open_conference_ware/extras/01.png +0 -0
- data/app/assets/images/open_conference_ware/extras/05.png +0 -0
- data/app/assets/images/open_conference_ware/extras/06.png +0 -0
- data/app/assets/images/open_conference_ware/extras/1.png +0 -0
- data/app/assets/images/open_conference_ware/extras/14.png +0 -0
- data/app/assets/images/open_conference_ware/extras/16.png +0 -0
- data/app/assets/images/open_conference_ware/extras/2.png +0 -0
- data/app/assets/images/open_conference_ware/extras/21.png +0 -0
- data/app/assets/images/open_conference_ware/extras/28.png +0 -0
- data/app/assets/images/open_conference_ware/extras/3.png +0 -0
- data/app/assets/images/open_conference_ware/extras/31.png +0 -0
- data/app/assets/images/open_conference_ware/extras/32.png +0 -0
- data/app/assets/images/open_conference_ware/extras/35.png +0 -0
- data/app/assets/images/open_conference_ware/extras/36.png +0 -0
- data/app/assets/images/open_conference_ware/extras/4.png +0 -0
- data/app/assets/images/open_conference_ware/extras/44.png +0 -0
- data/app/assets/images/open_conference_ware/extras/45.png +0 -0
- data/app/assets/images/open_conference_ware/extras/46.png +0 -0
- data/app/assets/images/open_conference_ware/extras/cancel.png +0 -0
- data/app/assets/images/open_conference_ware/extras/cancelx16.png +0 -0
- data/app/assets/images/open_conference_ware/extras/icon.trashcan.gif +0 -0
- data/app/assets/images/open_conference_ware/favorite.png +0 -0
- data/app/assets/images/open_conference_ware/feed.png +0 -0
- data/app/assets/images/open_conference_ware/heart.png +0 -0
- data/app/assets/images/open_conference_ware/house.png +0 -0
- data/app/assets/images/open_conference_ware/ignite_portland_header3_clear.png +0 -0
- data/app/assets/images/open_conference_ware/ignite_portland_header3_clear_cropped.png +0 -0
- data/app/assets/images/open_conference_ware/jquery.wysiwyg.gif +0 -0
- data/app/assets/images/open_conference_ware/lock.png +0 -0
- data/app/assets/images/open_conference_ware/new_window.gif +0 -0
- data/app/assets/images/open_conference_ware/openid-icon.gif +0 -0
- data/app/assets/images/open_conference_ware/pencil.png +0 -0
- data/app/assets/images/open_conference_ware/plus.png +0 -0
- data/app/assets/images/open_conference_ware/quote.png +0 -0
- data/app/assets/images/open_conference_ware/rails.png +0 -0
- data/app/assets/images/open_conference_ware/redx.png +0 -0
- data/app/assets/images/open_conference_ware/reset-fff.png +0 -0
- data/app/assets/images/open_conference_ware/spinner-big.gif +0 -0
- data/app/assets/images/open_conference_ware/spinner.gif +0 -0
- data/app/assets/images/open_conference_ware/star.png +0 -0
- data/app/assets/images/open_conference_ware/tag_blue.png +0 -0
- data/app/assets/images/open_conference_ware/time.png +0 -0
- data/app/assets/javascripts/open_conference_ware/application.js +18 -0
- data/app/assets/javascripts/open_conference_ware/base.js +15 -0
- data/app/assets/javascripts/open_conference_ware/favorites.js +76 -0
- data/app/assets/javascripts/open_conference_ware/ie.js +2 -0
- data/app/assets/javascripts/open_conference_ware/menu.js +47 -0
- data/app/assets/javascripts/open_conference_ware/persona.js +10 -0
- data/app/assets/javascripts/open_conference_ware/proposals.js +208 -0
- data/app/assets/javascripts/open_conference_ware/schedule.js +20 -0
- data/app/assets/javascripts/open_conference_ware/spinner.js +11 -0
- data/app/assets/javascripts/open_conference_ware/util.js +23 -0
- data/app/assets/stylesheets/open_conference_ware/application.css +8 -0
- data/app/assets/stylesheets/open_conference_ware/common.css.scss +491 -0
- data/app/assets/stylesheets/open_conference_ware/custom.css.scss +1033 -0
- data/app/assets/stylesheets/open_conference_ware/scaffold.css +54 -0
- data/app/controllers/open_conference_ware/application_controller.rb +488 -0
- data/app/controllers/open_conference_ware/authentications_controller.rb +42 -0
- data/app/controllers/open_conference_ware/comments_controller.rb +86 -0
- data/app/controllers/open_conference_ware/events_controller.rb +36 -0
- data/app/controllers/open_conference_ware/manage/events_controller.rb +157 -0
- data/app/controllers/open_conference_ware/manage/snippets_controller.rb +110 -0
- data/app/controllers/open_conference_ware/proposals_controller.rb +521 -0
- data/app/controllers/open_conference_ware/rooms_controller.rb +130 -0
- data/app/controllers/open_conference_ware/schedule_items_controller.rb +128 -0
- data/app/controllers/open_conference_ware/selector_votes_controller.rb +71 -0
- data/app/controllers/open_conference_ware/session_types_controller.rb +123 -0
- data/app/controllers/open_conference_ware/tracks_controller.rb +118 -0
- data/app/controllers/open_conference_ware/user_favorites_controller.rb +68 -0
- data/app/controllers/open_conference_ware/users_controller.rb +120 -0
- data/app/helpers/open_conference_ware/application_helper.rb +167 -0
- data/app/helpers/open_conference_ware/authentications_helper.rb +25 -0
- data/app/helpers/open_conference_ware/cache_if_helper.rb +13 -0
- data/app/helpers/open_conference_ware/display_link_to_helper.rb +25 -0
- data/app/helpers/open_conference_ware/display_textile_for_helper.rb +11 -0
- data/app/helpers/open_conference_ware/field_annotation_helper.rb +11 -0
- data/app/helpers/open_conference_ware/focus_helper.rb +16 -0
- data/app/helpers/open_conference_ware/localcss_helper.rb +10 -0
- data/app/helpers/open_conference_ware/page_title_helper.rb +17 -0
- data/app/helpers/open_conference_ware/proposals_helper.rb +54 -0
- data/app/helpers/open_conference_ware/rooms_helper.rb +5 -0
- data/app/helpers/open_conference_ware/scroll_to_helper.rb +15 -0
- data/app/helpers/open_conference_ware/session_types_helper.rb +5 -0
- data/app/helpers/open_conference_ware/snippets_helper.rb +36 -0
- data/app/helpers/open_conference_ware/time_range_helper.rb +198 -0
- data/app/helpers/open_conference_ware/tracks_helper.rb +9 -0
- data/app/helpers/open_conference_ware/user_favorites_helper.rb +15 -0
- data/app/mailers/open_conference_ware/speaker_mailer.rb +51 -0
- data/app/mixins/open_conference_ware/breadcrumbs_mixin.rb +76 -0
- data/app/mixins/open_conference_ware/cache_lookups_mixin.rb +128 -0
- data/app/mixins/open_conference_ware/faux_routes_mixin.rb +83 -0
- data/app/mixins/open_conference_ware/normalize_url_mixin.rb +40 -0
- data/app/mixins/open_conference_ware/public_attributes_mixin.rb +62 -0
- data/app/mixins/open_conference_ware/schedule_overlaps_mixin.rb +12 -0
- data/app/mixins/open_conference_ware/settings_checkers_mixin.rb +50 -0
- data/app/mixins/open_conference_ware/simple_slug_mixin.rb +26 -0
- data/app/models/open_conference_ware/authentication.rb +47 -0
- data/app/models/open_conference_ware/base.rb +6 -0
- data/app/models/open_conference_ware/comment.rb +26 -0
- data/app/models/open_conference_ware/event.rb +227 -0
- data/app/models/open_conference_ware/proposal.rb +625 -0
- data/app/models/open_conference_ware/room.rb +42 -0
- data/app/models/open_conference_ware/schedule.rb +216 -0
- data/app/models/open_conference_ware/schedule_item.rb +55 -0
- data/app/models/open_conference_ware/selector_vote.rb +22 -0
- data/app/models/open_conference_ware/session_type.rb +33 -0
- data/app/models/open_conference_ware/snippet.rb +58 -0
- data/app/models/open_conference_ware/track.rb +51 -0
- data/app/models/open_conference_ware/user.rb +262 -0
- data/app/models/open_conference_ware/user_favorite.rb +42 -0
- data/app/observers/open_conference_ware/cache_watcher.rb +42 -0
- data/app/views/layouts/open_conference_ware/_header.html.erb +106 -0
- data/app/views/layouts/open_conference_ware/application.atom.erb +1 -0
- data/app/views/layouts/open_conference_ware/application.html.erb +126 -0
- data/app/views/layouts/open_conference_ware/scaffold.html.erb +21 -0
- data/app/views/open_conference_ware/404.html.erb +8 -0
- data/app/views/open_conference_ware/422.html.erb +11 -0
- data/app/views/open_conference_ware/500.html.erb +11 -0
- data/app/views/open_conference_ware/_email_link.html.erb +24 -0
- data/app/views/open_conference_ware/_google_analytics.html.erb +9 -0
- data/app/views/open_conference_ware/authentications/_developer.html.erb +7 -0
- data/app/views/open_conference_ware/authentications/_openid.html.erb +11 -0
- data/app/views/open_conference_ware/authentications/_persona.html.erb +17 -0
- data/app/views/open_conference_ware/authentications/sign_in.html.erb +12 -0
- data/app/views/open_conference_ware/comments/_list.html.erb +31 -0
- data/app/views/open_conference_ware/comments/index.atom.builder +25 -0
- data/app/views/open_conference_ware/comments/index.html.erb +3 -0
- data/app/views/open_conference_ware/events/index.html.erb +9 -0
- data/app/views/open_conference_ware/events/show.html.erb +0 -0
- data/app/views/open_conference_ware/events/speakers.html.erb +7 -0
- data/app/views/open_conference_ware/manage/events/_form.html.erb +107 -0
- data/app/views/open_conference_ware/manage/events/edit.html.erb +3 -0
- data/app/views/open_conference_ware/manage/events/index.html.erb +41 -0
- data/app/views/open_conference_ware/manage/events/new.html.erb +3 -0
- data/app/views/open_conference_ware/manage/events/proposals.html.erb +133 -0
- data/app/views/open_conference_ware/manage/events/show.html.erb +181 -0
- data/app/views/open_conference_ware/manage/snippets/_form.html.erb +30 -0
- data/app/views/open_conference_ware/manage/snippets/edit.html.erb +3 -0
- data/app/views/open_conference_ware/manage/snippets/index.html.erb +34 -0
- data/app/views/open_conference_ware/manage/snippets/new.html.erb +3 -0
- data/app/views/open_conference_ware/manage/snippets/show.html.erb +32 -0
- data/app/views/open_conference_ware/proposals/_admin_controls.html.erb +33 -0
- data/app/views/open_conference_ware/proposals/_form.html.erb +381 -0
- data/app/views/open_conference_ware/proposals/_list.html.erb +164 -0
- data/app/views/open_conference_ware/proposals/_list_concise.html.erb +93 -0
- data/app/views/open_conference_ware/proposals/_manage_speakers.html.erb +30 -0
- data/app/views/open_conference_ware/proposals/_room_control.html.erb +21 -0
- data/app/views/open_conference_ware/proposals/_schedule_block.html.erb +8 -0
- data/app/views/open_conference_ware/proposals/_schedule_control.html.erb +13 -0
- data/app/views/open_conference_ware/proposals/_search_speakers.html.erb +20 -0
- data/app/views/open_conference_ware/proposals/_sub_list.html.erb +65 -0
- data/app/views/open_conference_ware/proposals/_sub_list_for_kind.html.erb +31 -0
- data/app/views/open_conference_ware/proposals/_transition_control.html.erb +16 -0
- data/app/views/open_conference_ware/proposals/create.html.erb +29 -0
- data/app/views/open_conference_ware/proposals/edit.html.erb +7 -0
- data/app/views/open_conference_ware/proposals/index.atom.builder +63 -0
- data/app/views/open_conference_ware/proposals/index.html.erb +46 -0
- data/app/views/open_conference_ware/proposals/new.html.erb +3 -0
- data/app/views/open_conference_ware/proposals/schedule.html.erb +108 -0
- data/app/views/open_conference_ware/proposals/sessions_index_terse.html.erb +22 -0
- data/app/views/open_conference_ware/proposals/show.html.erb +316 -0
- data/app/views/open_conference_ware/proposals/stats.html.erb +72 -0
- data/app/views/open_conference_ware/rooms/_form.html.erb +36 -0
- data/app/views/open_conference_ware/rooms/edit.html.erb +3 -0
- data/app/views/open_conference_ware/rooms/index.html.erb +13 -0
- data/app/views/open_conference_ware/rooms/new.html.erb +3 -0
- data/app/views/open_conference_ware/rooms/show.html.erb +27 -0
- data/app/views/open_conference_ware/schedule_items/_form.html.erb +35 -0
- data/app/views/open_conference_ware/schedule_items/edit.html.erb +3 -0
- data/app/views/open_conference_ware/schedule_items/index.html.erb +31 -0
- data/app/views/open_conference_ware/schedule_items/new.html.erb +3 -0
- data/app/views/open_conference_ware/schedule_items/show.html.erb +30 -0
- data/app/views/open_conference_ware/selector_votes/index.html.erb +81 -0
- data/app/views/open_conference_ware/session_types/_form.html.erb +23 -0
- data/app/views/open_conference_ware/session_types/edit.html.erb +3 -0
- data/app/views/open_conference_ware/session_types/index.html.erb +18 -0
- data/app/views/open_conference_ware/session_types/new.html.erb +3 -0
- data/app/views/open_conference_ware/session_types/show.html.erb +14 -0
- data/app/views/open_conference_ware/speaker_mailer/speaker_email.text.erb +14 -0
- data/app/views/open_conference_ware/tracks/_colors.css.erb +7 -0
- data/app/views/open_conference_ware/tracks/_form.html.erb +36 -0
- data/app/views/open_conference_ware/tracks/edit.html.erb +3 -0
- data/app/views/open_conference_ware/tracks/index.html.erb +25 -0
- data/app/views/open_conference_ware/tracks/new.html.erb +3 -0
- data/app/views/open_conference_ware/tracks/show.html.erb +19 -0
- data/app/views/open_conference_ware/user_favorites/index.html.erb +12 -0
- data/app/views/open_conference_ware/users/_account_box.html.erb +10 -0
- data/app/views/open_conference_ware/users/_block.html.erb +80 -0
- data/app/views/open_conference_ware/users/_list.html.erb +17 -0
- data/app/views/open_conference_ware/users/edit.html.erb +73 -0
- data/app/views/open_conference_ware/users/index.html.erb +28 -0
- data/app/views/open_conference_ware/users/new.html.erb +7 -0
- data/app/views/open_conference_ware/users/proposals.html.erb +24 -0
- data/app/views/open_conference_ware/users/show.html.erb +5 -0
- data/app/views/open_conference_ware/welcome/test.html.haml +8 -0
- data/bin/rails +8 -0
- data/ci/Gemfile.ci +13 -0
- data/ci/copy_database_config.rb +6 -0
- data/ci/database.mysql.yml +5 -0
- data/ci/database.postgresql.yml +4 -0
- data/ci/database.sqlite.yml +5 -0
- data/config/initializers/acts_as_taggable_on.rb +2 -0
- data/config/initializers/date_time_formats.rb +9 -0
- data/config/routes.rb +74 -0
- data/db/migrate/20131203235128_create_open_conference_ware_authentications.rb +14 -0
- data/db/migrate/20131203235216_create_open_conference_ware_comments.rb +14 -0
- data/db/migrate/20131203235418_create_open_conference_ware_events.rb +27 -0
- data/db/migrate/20131203235524_create_open_conference_ware_proposals.rb +36 -0
- data/db/migrate/20131203235723_create_open_conference_ware_rooms.rb +20 -0
- data/db/migrate/20131203235831_create_open_conference_ware_schedule_items.rb +18 -0
- data/db/migrate/20131203235910_create_open_conference_ware_selector_votes.rb +10 -0
- data/db/migrate/20131203235934_create_open_conference_ware_session_types.rb +14 -0
- data/db/migrate/20131204000008_create_open_conference_ware_snippets.rb +15 -0
- data/db/migrate/20131204000048_create_open_conference_ware_taggings.rb +16 -0
- data/db/migrate/20131204000129_create_open_conference_ware_tags.rb +7 -0
- data/db/migrate/20131204000147_create_open_conference_ware_tracks.rb +15 -0
- data/db/migrate/20131204000230_create_open_conference_ware_user_favorites.rb +10 -0
- data/db/migrate/20131204000251_create_open_conference_ware_users.rb +24 -0
- data/db/migrate/20131204000355_create_proposals_users_join_table.rb +8 -0
- data/db/seeds.rb +31 -0
- data/features/comment_create.feature +9 -0
- data/features/comment_destroy.feature +22 -0
- data/features/comment_new.feature +22 -0
- data/features/step_definitions/authentication_steps.rb +22 -0
- data/features/step_definitions/comment_create_steps.rb +5 -0
- data/features/step_definitions/comment_destroy_steps.rb +13 -0
- data/features/step_definitions/comment_new_steps.rb +41 -0
- data/features/step_definitions/notification_steps.rb +3 -0
- data/features/step_definitions/web_steps.rb +263 -0
- data/features/support/env.rb +58 -0
- data/features/support/helpers.rb +17 -0
- data/features/support/paths.rb +35 -0
- data/gem-public_cert.pem +22 -0
- data/lib/defer_proxy.rb +127 -0
- data/lib/ext/color_rgb_serializer_fix.rb +18 -0
- data/lib/ext/string_possessiveize.rb +7 -0
- data/lib/ext/vpim_icalendar_extra_properties.rb +25 -0
- data/lib/generators/open_conference_ware/install/USAGE +12 -0
- data/lib/generators/open_conference_ware/install/install_generator.rb +35 -0
- data/lib/generators/open_conference_ware/install/templates/config_initializer.rb +110 -0
- data/lib/generators/open_conference_ware/install/templates/omniauth_initializer.rb +33 -0
- data/lib/open_conference_ware.rb +156 -0
- data/lib/open_conference_ware/dependencies.rb +38 -0
- data/lib/open_conference_ware/engine.rb +38 -0
- data/lib/open_conference_ware/omni_auth_builder.rb +8 -0
- data/lib/open_conference_ware/version.rb +3 -0
- data/lib/rwikibot_page_drone.rb +70 -0
- data/lib/tasks/.gitkeep +0 -0
- data/lib/tasks/audio.rake +53 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/export.rake +170 -0
- data/lib/tasks/mediawiki.rake +96 -0
- data/lib/tasks/open_conference_ware_tasks.rake +16 -0
- data/lib/tasks/schedule.rake +103 -0
- data/lib/tasks/snippets.rake +23 -0
- data/open_conference_ware.gemspec +67 -0
- data/original_graphics/favorite.psd +0 -0
- data/spec/controllers/open_conference_ware/application_controller_spec.rb +309 -0
- data/spec/controllers/open_conference_ware/authentications_controller_spec.rb +87 -0
- data/spec/controllers/open_conference_ware/comments_controller_spec.rb +146 -0
- data/spec/controllers/open_conference_ware/events_controller_spec.rb +102 -0
- data/spec/controllers/open_conference_ware/manage_events_controller_spec.rb +103 -0
- data/spec/controllers/open_conference_ware/proposals_controller_spec.rb +1273 -0
- data/spec/controllers/open_conference_ware/rooms_controller_spec.rb +190 -0
- data/spec/controllers/open_conference_ware/selector_votes_controller_spec.rb +263 -0
- data/spec/controllers/open_conference_ware/session_types_controller_spec.rb +190 -0
- data/spec/controllers/open_conference_ware/sessions_routing_spec.rb +13 -0
- data/spec/controllers/open_conference_ware/tracks_controller_spec.rb +190 -0
- data/spec/controllers/open_conference_ware/user_favorites_controller_spec.rb +127 -0
- data/spec/controllers/open_conference_ware/users_controller_spec.rb +166 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +30 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/01_open_conference_ware.rb +110 -0
- data/spec/dummy/config/initializers/02_omniauth.rb +17 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/schema.rb +219 -0
- data/spec/dummy/db/seeds.rb +10 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/authentication_factory.rb +16 -0
- data/spec/factories/common_factory.rb +4 -0
- data/spec/factories/event_factory.rb +26 -0
- data/spec/factories/proposal_factory.rb +57 -0
- data/spec/factories/proposal_user_factory.rb +7 -0
- data/spec/factories/room_factory.rb +11 -0
- data/spec/factories/schedule_item_factory.rb +13 -0
- data/spec/factories/session_types_factory.rb +10 -0
- data/spec/factories/snippet_factory.rb +7 -0
- data/spec/factories/track_factory.rb +12 -0
- data/spec/factories/user_factory.rb +22 -0
- data/spec/factories/user_favorite_factory.rb +7 -0
- data/spec/features/sign_in_spec.rb +11 -0
- data/spec/features/snippets_spec.rb +38 -0
- data/spec/fixtures/open_conference_ware_comments.yml +27 -0
- data/spec/fixtures/open_conference_ware_events.yml +56 -0
- data/spec/fixtures/open_conference_ware_proposals.yml +256 -0
- data/spec/fixtures/open_conference_ware_rooms.yml +13 -0
- data/spec/fixtures/open_conference_ware_schedule_items.yml +23 -0
- data/spec/fixtures/open_conference_ware_session_types.yml +19 -0
- data/spec/fixtures/open_conference_ware_snippets.yml +62 -0
- data/spec/fixtures/open_conference_ware_tracks.yml +65 -0
- data/spec/fixtures/open_conference_ware_user_favorites.yml +7 -0
- data/spec/fixtures/open_conference_ware_users.yml +87 -0
- data/spec/helpers/open_conference_ware/application_helper_spec.rb +58 -0
- data/spec/helpers/open_conference_ware/authentications_helper_spec.rb +15 -0
- data/spec/helpers/open_conference_ware/display_link_to_helper_spec.rb +52 -0
- data/spec/helpers/open_conference_ware/proposals_helper_spec.rb +32 -0
- data/spec/helpers/open_conference_ware/rooms_helper_spec.rb +11 -0
- data/spec/helpers/open_conference_ware/session_types_helper_spec.rb +15 -0
- data/spec/helpers/open_conference_ware/time_range_helper_spec.rb +56 -0
- data/spec/helpers/open_conference_ware/tracks_helper_spec.rb +11 -0
- data/spec/helpers/open_conference_ware/user_favorites_helper_spec.rb +11 -0
- data/spec/integration/open_conference_ware/cache_lookups_mixin_spec.rb +122 -0
- data/spec/mixins/open_conference_ware/normalize_url_mixin_spec.rb +65 -0
- data/spec/models/open_conference_ware/authentication_spec.rb +67 -0
- data/spec/models/open_conference_ware/event_spec.rb +211 -0
- data/spec/models/open_conference_ware/proposal_spec.rb +606 -0
- data/spec/models/open_conference_ware/room_spec.rb +14 -0
- data/spec/models/open_conference_ware/schedule_item_spec.rb +12 -0
- data/spec/models/open_conference_ware/schedule_spec.rb +358 -0
- data/spec/models/open_conference_ware/selector_vote_spec.rb +12 -0
- data/spec/models/open_conference_ware/session_type_spec.rb +15 -0
- data/spec/models/open_conference_ware/snippet_spec.rb +13 -0
- data/spec/models/open_conference_ware/speaker_mailer_spec.rb +91 -0
- data/spec/models/open_conference_ware/track_spec.rb +36 -0
- data/spec/models/open_conference_ware/user_favorite_spec.rb +41 -0
- data/spec/models/open_conference_ware/user_spec.rb +77 -0
- data/spec/ocw_config.rb +76 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +55 -0
- data/spec/spec_helper_customizations.rb +125 -0
- data/spec/support/add_all_helpers_to_view.rb +24 -0
- data/spec/support/authenticated_test_helper.rb +27 -0
- data/spec/support/fixture_shortcuts.rb +18 -0
- data/spec/support/omniauth.rb +34 -0
- data/spec/support/valid_params_extraction.rb +15 -0
- data/spec/views/open_conference_ware/proposals/_room_control.html.erb_spec.rb +23 -0
- data/spec/views/open_conference_ware/proposals/_transition_control.html.erb_spec.rb +14 -0
- data/spec/views/open_conference_ware/proposals/show.html.erb_spec.rb +128 -0
- data/spec/views/open_conference_ware/rooms/index.html.erb_spec.rb +19 -0
- data/spec/views/open_conference_ware/rooms/show.html.erb_spec.rb +15 -0
- data/spec/views/open_conference_ware/selector_votes/index.html.erb_spec.rb +41 -0
- data/spec/views/open_conference_ware/session_types/edit.html.erb_spec.rb +25 -0
- data/spec/views/open_conference_ware/session_types/index.html.erb_spec.rb +19 -0
- data/spec/views/open_conference_ware/session_types/new.html.erb_spec.rb +24 -0
- data/spec/views/open_conference_ware/session_types/show.html.erb_spec.rb +18 -0
- data/spec/views/open_conference_ware/tracks/edit.html.erb_spec.rb +25 -0
- data/spec/views/open_conference_ware/tracks/index.html.erb_spec.rb +56 -0
- data/spec/views/open_conference_ware/tracks/new.html.erb_spec.rb +26 -0
- data/spec/views/open_conference_ware/tracks/show.html.erb_spec.rb +23 -0
- data/spec/views/open_conference_ware/user_favorites/index.html.erb_spec.rb +29 -0
- data/spec/views/open_conference_ware/users/index_spec.rb +24 -0
- data/util/add_id3_tags_to_mp3.rb +57 -0
- data/util/schedule_demo.rb +36 -0
- data/util/seed_schedule.rb +61 -0
- data/util/sessions_to_lanyrd.rb +166 -0
- data/util/transfer_schedule_items.rb +25 -0
- data/util/update_proposal_status_from_voting_spreadsheet.rb +26 -0
- data/util/user_favorites_contention_report.rb +42 -0
- data/util/user_favorites_contention_report.sh +9 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.svg +228 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/images/farbtastic/marker.png +0 -0
- data/vendor/assets/images/farbtastic/mask.png +0 -0
- data/vendor/assets/images/farbtastic/wheel.png +0 -0
- data/vendor/assets/images/idselector/aol.ico +0 -0
- data/vendor/assets/images/idselector/arrow.gif +0 -0
- data/vendor/assets/images/idselector/arrow_white_back.png +0 -0
- data/vendor/assets/images/idselector/arrow_white_forward.png +0 -0
- data/vendor/assets/images/idselector/blogger.ico +0 -0
- data/vendor/assets/images/idselector/claimid.ico +0 -0
- data/vendor/assets/images/idselector/flickr.ico +0 -0
- data/vendor/assets/images/idselector/google.ico +0 -0
- data/vendor/assets/images/idselector/lj.ico +0 -0
- data/vendor/assets/images/idselector/myopenid.ico +0 -0
- data/vendor/assets/images/idselector/openid.ico +0 -0
- data/vendor/assets/images/idselector/technorati.ico +0 -0
- data/vendor/assets/images/idselector/verisign.ico +0 -0
- data/vendor/assets/images/idselector/vidoop2.ico +0 -0
- data/vendor/assets/images/idselector/vox.ico +0 -0
- data/vendor/assets/images/idselector/yahoo.ico +0 -0
- data/vendor/assets/javascripts/audiojs/audio.min.js +23 -0
- data/vendor/assets/javascripts/audiojs/audiojs.swf +0 -0
- data/vendor/assets/javascripts/audiojs/player-graphics.gif +0 -0
- data/vendor/assets/javascripts/bootstrap.js +1999 -0
- data/vendor/assets/javascripts/farbtastic.js +329 -0
- data/vendor/assets/javascripts/html5shiv.js +8 -0
- data/vendor/assets/javascripts/idselector.js +538 -0
- data/vendor/assets/javascripts/idselector~original.js +532 -0
- data/vendor/assets/javascripts/jquery-migrate-1.2.1.js +521 -0
- data/vendor/assets/javascripts/jquery.localScroll.js +106 -0
- data/vendor/assets/javascripts/jquery.scrollTo.js +174 -0
- data/vendor/assets/javascripts/respond.min.js +6 -0
- data/vendor/assets/stylesheets/bootstrap-theme.css +384 -0
- data/vendor/assets/stylesheets/bootstrap.css +6805 -0
- data/vendor/assets/stylesheets/farbtastic.css.scss +38 -0
- data/vendor/assets/stylesheets/persona-buttons.css +229 -0
- data/vendor/assets/stylesheets/reset-fonts-grids.css +7 -0
- metadata +1174 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OpenConferenceWare::NormalizeUrlMixin do
|
|
4
|
+
NormalizeUrlMixin = OpenConferenceWare::NormalizeUrlMixin
|
|
5
|
+
|
|
6
|
+
describe "normalize_url!" do
|
|
7
|
+
it "should preserve valid URLs as-is" do
|
|
8
|
+
NormalizeUrlMixin.normalize_url!('http://foo.bar/').should == 'http://foo.bar/'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should append trailing slash to URLs" do
|
|
12
|
+
NormalizeUrlMixin.normalize_url!('http://foo.bar').should == 'http://foo.bar/'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should preserve valid URLs with paths as-is" do
|
|
16
|
+
NormalizeUrlMixin.normalize_url!('http://foo.bar/baz').should == 'http://foo.bar/baz'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should add http schema to pure hostnames" do
|
|
20
|
+
NormalizeUrlMixin.normalize_url!('foo.bar').should == 'http://foo.bar/'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should add http schema to hostname/paths" do
|
|
24
|
+
NormalizeUrlMixin.normalize_url!('foo.bar/baz').should == 'http://foo.bar/baz'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "validation" do
|
|
29
|
+
fixtures :open_conference_ware_users
|
|
30
|
+
# TODO Mock an entire ActiveRecord model to isolate these behaviors, rather than relying on User
|
|
31
|
+
before(:each) do
|
|
32
|
+
@record = users(:aaron)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should handle nil" do
|
|
36
|
+
@record.website = nil
|
|
37
|
+
@record.should be_valid
|
|
38
|
+
@record.website.should be_blank
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should handle blank" do
|
|
42
|
+
@record.website = ''
|
|
43
|
+
@record.should be_valid
|
|
44
|
+
@record.website.should be_blank
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should handle valid" do
|
|
48
|
+
@record.website = 'http://foo.bar/'
|
|
49
|
+
@record.should be_valid
|
|
50
|
+
@record.website.should == 'http://foo.bar/'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should handle unqualified" do
|
|
54
|
+
@record.website = 'foo.bar'
|
|
55
|
+
@record.should be_valid
|
|
56
|
+
@record.website.should == 'http://foo.bar/'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should fail invalid" do
|
|
60
|
+
@record.website = '<asdf>'
|
|
61
|
+
@record.should_not be_valid
|
|
62
|
+
@record.errors[:website].should == ["is invalid"]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OpenConferenceWare::Authentication do
|
|
4
|
+
describe "finding or creating from an auth hash" do
|
|
5
|
+
describe "when an an existing Authentication does not exist" do
|
|
6
|
+
before do
|
|
7
|
+
@auth_hash = OmniAuth::AuthHash.new(
|
|
8
|
+
'provider' => 'test_provider',
|
|
9
|
+
'uid' => Time.now.to_i.to_s,
|
|
10
|
+
'info' => {
|
|
11
|
+
'name' => 'Boris',
|
|
12
|
+
'email' => 'boris@example.com'
|
|
13
|
+
}
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
@new_auth = OpenConferenceWare::Authentication.find_and_update_or_create_from_auth_hash(@auth_hash)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should create new Authentications" do
|
|
20
|
+
@new_auth.should_not be_new_record
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should set base attributes from the auth hash" do
|
|
24
|
+
@new_auth.provider.should == @auth_hash['provider']
|
|
25
|
+
@new_auth.uid.should == @auth_hash['uid']
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should set name and email from the info hash" do
|
|
29
|
+
@new_auth.name.should == @auth_hash['info']['name']
|
|
30
|
+
@new_auth.email.should == @auth_hash['info']['email']
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should stash the info hash" do
|
|
34
|
+
@new_auth.info.should == @auth_hash['info']
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "when an existing Authentication record exists" do
|
|
39
|
+
before do
|
|
40
|
+
@existing = create(:authentication)
|
|
41
|
+
@auth_hash = OmniAuth::AuthHash.new(
|
|
42
|
+
'provider' => @existing.provider,
|
|
43
|
+
'uid' => @existing.uid,
|
|
44
|
+
'info' => {
|
|
45
|
+
'name' => 'Beth',
|
|
46
|
+
'email' => 'beth@example.com'
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
@found = OpenConferenceWare::Authentication.find_and_update_or_create_from_auth_hash(@auth_hash)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should find the existing record" do
|
|
53
|
+
@found.should == @existing
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should update the record's name and email from the auth hash" do
|
|
57
|
+
@found.name.should == @auth_hash['info']['name']
|
|
58
|
+
@found.email.should == @auth_hash['info']['email']
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should update the stashed copy of the info hash" do
|
|
62
|
+
@found.info.should == @auth_hash['info']
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OpenConferenceWare::Event do
|
|
4
|
+
describe "when accepting proposals" do
|
|
5
|
+
fixtures :all
|
|
6
|
+
|
|
7
|
+
it "should accept proposals for future" do
|
|
8
|
+
events(:closed).accepting_proposals?.should be_false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should not accept proposals for past" do
|
|
12
|
+
events(:open).accepting_proposals?.should be_true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "when determining if proposal status is visible" do
|
|
17
|
+
before :each do
|
|
18
|
+
@event = Event.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should not be published by default" do
|
|
22
|
+
@event.proposal_status_published.should be_false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should be possible to publish proposal statuses" do
|
|
26
|
+
@event.proposal_status_published = true
|
|
27
|
+
@event.proposal_status_published.should be_true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe "when finding current event" do
|
|
32
|
+
fixtures :all
|
|
33
|
+
|
|
34
|
+
it "should use find event" do
|
|
35
|
+
event = events(:open)
|
|
36
|
+
|
|
37
|
+
Event.should_receive(:current_by_settings).and_return(nil)
|
|
38
|
+
Event.should_receive(:current_by_deadline).and_return(event)
|
|
39
|
+
|
|
40
|
+
Event.current.should == event
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should return nil if no current event is available" do
|
|
44
|
+
Event.destroy_all
|
|
45
|
+
Event.current.should be_nil
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe "#populated_proposals" do
|
|
50
|
+
fixtures :all
|
|
51
|
+
|
|
52
|
+
before(:each) do
|
|
53
|
+
@event = events(:open)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should get proposals and sessions for :proposals" do
|
|
57
|
+
records = @event.populated_proposals(:proposals)
|
|
58
|
+
|
|
59
|
+
records.select(&:confirmed?).should_not be_empty
|
|
60
|
+
records.reject(&:confirmed?).should_not be_empty
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should get just sessions for :sessions" do
|
|
64
|
+
records = @event.populated_proposals(:sessions)
|
|
65
|
+
|
|
66
|
+
records.select(&:confirmed?).should_not be_empty
|
|
67
|
+
records.reject(&:confirmed?).should be_empty
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should fail to get invalid kind" do
|
|
71
|
+
lambda { @event.populated_proposals(:omg) }.should raise_error(ArgumentError)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe "#dates" do
|
|
76
|
+
it "should return range between start_date and end_date" do
|
|
77
|
+
start_date = Time.now.utc.to_date + 1.week
|
|
78
|
+
end_date = Time.now.utc.to_date + 2.weeks
|
|
79
|
+
event = build(:event, start_date: start_date, end_date: end_date)
|
|
80
|
+
|
|
81
|
+
event.dates.should == Array(start_date..end_date)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should return empty array if no dates" do
|
|
85
|
+
Event.new().dates.should == []
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should return empty array if no start_date" do
|
|
89
|
+
build(:event, start_date: nil).dates.should == []
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should return empty array if no end_date" do
|
|
93
|
+
build(:event, end_date: nil).dates.should == []
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "#parent_or_self" do
|
|
98
|
+
it "should find a parent when there is one" do
|
|
99
|
+
parent = create(:event, title: "Mommy!", slug: "mommy", open_text: "Open!", closed_text: "Closed!")
|
|
100
|
+
child = create(:event, title: "Baby!", slug: "baby", open_text: "Open!", closed_text: "Closed!", parent: parent)
|
|
101
|
+
|
|
102
|
+
child.parent_or_self.should == parent
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should find self when there's no parent" do
|
|
106
|
+
event = create(:event, title: "Event!", slug: "event", open_text: "Open!", closed_text: "Closed!")
|
|
107
|
+
|
|
108
|
+
event.parent_or_self.should == event
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe "#related_proposals" do
|
|
113
|
+
before :each do
|
|
114
|
+
Event.destroy_all
|
|
115
|
+
|
|
116
|
+
@parent = create :populated_event
|
|
117
|
+
@event = create :populated_event, parent: @parent
|
|
118
|
+
@child = create :populated_event, parent: @event
|
|
119
|
+
@unrelated = create :populated_event
|
|
120
|
+
|
|
121
|
+
@event_proposal = proposal_for_event @event
|
|
122
|
+
@parent_proposal = proposal_for_event @parent
|
|
123
|
+
@child_proposal = proposal_for_event @child
|
|
124
|
+
@unrelated_proposal = proposal_for_event @unrelated
|
|
125
|
+
|
|
126
|
+
@proposals = [@event_proposal, @parent_proposal, @child_proposal, @unrelated_proposal]
|
|
127
|
+
|
|
128
|
+
@event.reload
|
|
129
|
+
|
|
130
|
+
@related = @event.related_proposals @proposals
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should find the event's proposals" do
|
|
134
|
+
@related.should include(@event_proposal)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should find the event parent's proposals" do
|
|
138
|
+
@related.should include(@parent_proposal)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should find the event children's proposals" do
|
|
142
|
+
@related.should include(@child_proposal)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "should not find unrelated event's proposals" do
|
|
146
|
+
@related.should_not include(@unrelated_proposal)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe "#descendents" do
|
|
151
|
+
before :each do
|
|
152
|
+
@parent = create :populated_event
|
|
153
|
+
@event = create :populated_event, parent: @parent
|
|
154
|
+
@child = create :populated_event, parent: @event
|
|
155
|
+
@grandchild = create :populated_event, parent: @child
|
|
156
|
+
@unrelated = create :populated_event
|
|
157
|
+
|
|
158
|
+
@descendents = @event.descendents
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "should include an event's children" do
|
|
162
|
+
@descendents.should include(@child)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should include an event's children's children" do
|
|
166
|
+
@descendents.should include(@grandchild)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should not include parent" do
|
|
170
|
+
@descendents.should_not include(@parent)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "should not include unrelated event" do
|
|
174
|
+
@descendents.should_not include(@unrelated)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe "#family" do
|
|
179
|
+
before :each do
|
|
180
|
+
@parent = create :populated_event
|
|
181
|
+
@stepchild = create :populated_event, parent: @parent
|
|
182
|
+
@event = create :populated_event, parent: @parent
|
|
183
|
+
@child = create :populated_event, parent: @event
|
|
184
|
+
@grandchild = create :populated_event, parent: @child
|
|
185
|
+
@unrelated = create :populated_event
|
|
186
|
+
|
|
187
|
+
@family = @event.family
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "should include an event's children" do
|
|
191
|
+
@family.should include(@child)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should include an event's children's children" do
|
|
195
|
+
@family.should include(@grandchild)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "should include parent" do
|
|
199
|
+
@family.should include(@parent)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "should include step-child" do
|
|
203
|
+
@family.should include(@stepchild)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should not include unrelated event" do
|
|
207
|
+
@family.should_not include(@unrelated)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end
|
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OpenConferenceWare::Proposal do
|
|
4
|
+
fixtures :all
|
|
5
|
+
|
|
6
|
+
describe "when checking authorization for altering" do
|
|
7
|
+
before(:each) do
|
|
8
|
+
@proposal = proposals(:quentin_widgets)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should not allow anonymous" do
|
|
12
|
+
@proposal.can_alter?(nil).should be_false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should not allow wrong mortal" do
|
|
16
|
+
@proposal.can_alter?(users(:clio)).should be_false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should allow mortal owner" do
|
|
20
|
+
@proposal.can_alter?(users(:quentin)).should be_true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should allow admin" do
|
|
24
|
+
@proposal.can_alter?(users(:aaron)).should be_true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "when setting submitted_at date" do
|
|
29
|
+
it "should set value on save" do
|
|
30
|
+
proposal = proposals(:quentin_widgets)
|
|
31
|
+
proposal.submitted_at = nil
|
|
32
|
+
proposal.save!
|
|
33
|
+
proposal.reload
|
|
34
|
+
|
|
35
|
+
proposal.submitted_at.should_not be_nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should set value to created_at date" do
|
|
39
|
+
proposal = proposals(:quentin_widgets)
|
|
40
|
+
proposal.submitted_at = nil
|
|
41
|
+
proposal.save!
|
|
42
|
+
proposal.reload
|
|
43
|
+
|
|
44
|
+
proposal.submitted_at.should == proposal.created_at
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "when setting status" do
|
|
49
|
+
before(:each) do
|
|
50
|
+
@proposal = new_proposal
|
|
51
|
+
@proposal.save!
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should default to a state of 'proposed'" do
|
|
55
|
+
@proposal.should be_proposed
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should be possible to accept a proposed proposal" do
|
|
59
|
+
@proposal.accept!
|
|
60
|
+
@proposal.should be_accepted
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should be possible to confirm a proposed proposal" do
|
|
64
|
+
@proposal.accept_and_confirm!
|
|
65
|
+
@proposal.should be_confirmed
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should be possible to decline a proposed proposal" do
|
|
69
|
+
@proposal.accept_and_decline!
|
|
70
|
+
@proposal.should be_declined
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should be possible to reject a proposed proposal" do
|
|
74
|
+
@proposal.reject!
|
|
75
|
+
@proposal.should be_rejected
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should be possible to confirm an accepted proposal" do
|
|
79
|
+
@proposal.status = 'accepted'
|
|
80
|
+
@proposal.confirm!
|
|
81
|
+
@proposal.should be_confirmed
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should be possible to decline an accepted proposal" do
|
|
85
|
+
@proposal.status = 'accepted'
|
|
86
|
+
@proposal.decline!
|
|
87
|
+
@proposal.should be_declined
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should be possible to accept a rejected proposal" do
|
|
91
|
+
@proposal.status = 'rejected'
|
|
92
|
+
@proposal.accept!
|
|
93
|
+
@proposal.should be_accepted
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should be possible to reject an accepted proposal" do
|
|
97
|
+
@proposal.status = 'accepted'
|
|
98
|
+
@proposal.reject!
|
|
99
|
+
@proposal.should be_rejected
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should be possible to mark a proposed proposal as junk" do
|
|
103
|
+
@proposal.mark_as_junk!
|
|
104
|
+
@proposal.should be_junk
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should be possible to cancel a confirmed proposal" do
|
|
108
|
+
@proposal.status = 'confirmed'
|
|
109
|
+
@proposal.cancel!
|
|
110
|
+
@proposal.should be_cancelled
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should be possible to waitlist a proposed proposal" do
|
|
114
|
+
@proposal.waitlist!
|
|
115
|
+
@proposal.should be_waitlisted
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should be possible to waitlist an accepted proposal" do
|
|
119
|
+
@proposal.status = 'accepted'
|
|
120
|
+
@proposal.waitlist!
|
|
121
|
+
@proposal.should be_waitlisted
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should be possible to waitlist a rejected proposal" do
|
|
125
|
+
@proposal.status = 'rejected'
|
|
126
|
+
@proposal.waitlist!
|
|
127
|
+
@proposal.should be_waitlisted
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "should be possible to accept a waitlisted proposal" do
|
|
131
|
+
@proposal.status = 'waitlisted'
|
|
132
|
+
@proposal.accept!
|
|
133
|
+
@proposal.should be_accepted
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "should be possible to confirm a waitlisted proposal" do
|
|
137
|
+
@proposal.status = 'waitlisted'
|
|
138
|
+
@proposal.accept_and_confirm!
|
|
139
|
+
@proposal.should be_confirmed
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should be possible to decline a waitlisted proposal" do
|
|
143
|
+
@proposal.status = 'waitlisted'
|
|
144
|
+
@proposal.accept_and_decline!
|
|
145
|
+
@proposal.should be_declined
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "should be possible to reject a waitlisted proposal" do
|
|
149
|
+
@proposal.status = 'waitlisted'
|
|
150
|
+
@proposal.reject!
|
|
151
|
+
@proposal.should be_rejected
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
%w(accepted confirmed waitlisted rejected declined junk cancelled).each do |initial_status|
|
|
155
|
+
it "should be posible to reset a #{initial_status} proposal back to proposed" do
|
|
156
|
+
@proposal.status = initial_status
|
|
157
|
+
@proposal.reset_status!
|
|
158
|
+
@proposal.should be_proposed
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "through the transition accessor" do
|
|
163
|
+
it "should be possible to call a valid event" do
|
|
164
|
+
@proposal.should be_proposed
|
|
165
|
+
@proposal.transition = 'accept'
|
|
166
|
+
@proposal.should be_accepted
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should not call invalid event methods" do
|
|
170
|
+
@proposal.should_not_receive(:destroy!)
|
|
171
|
+
@proposal.transition = 'destroy'
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe "when getting comments" do
|
|
177
|
+
before(:each) do
|
|
178
|
+
@proposal = proposals(:quentin_widgets)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should return nothing if no comments" do
|
|
182
|
+
@proposal.comments_text.blank?.should be_true
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "should return one comment" do
|
|
186
|
+
comments = [
|
|
187
|
+
double(Comment, email: "bubba@smith.com", message: "Hi"),
|
|
188
|
+
]
|
|
189
|
+
@proposal.should_receive(:comments).and_return(comments)
|
|
190
|
+
|
|
191
|
+
@proposal.comments_text.should == "bubba@smith.com: Hi"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should return multiple comments" do
|
|
195
|
+
comments = [
|
|
196
|
+
double(Comment, email: "bubba@smith.com", message: "Hi"),
|
|
197
|
+
double(Comment, email: "billy.sue@smith.com", message: "Yo"),
|
|
198
|
+
]
|
|
199
|
+
@proposal.should_receive(:comments).and_return(comments)
|
|
200
|
+
|
|
201
|
+
@proposal.comments_text.should ==
|
|
202
|
+
"bubba@smith.com: Hi\nbilly.sue@smith.com: Yo"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
describe "when getting profile" do
|
|
207
|
+
before(:each) do
|
|
208
|
+
@proposal = proposals(:quentin_widgets)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should return false if multiple_presenters is enabled" do
|
|
212
|
+
OpenConferenceWare.stub(:have_multiple_presenters).and_return(true)
|
|
213
|
+
@proposal.profile.should be_false
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "should return the user if user_profiles is enabled" do
|
|
217
|
+
OpenConferenceWare.stub(:have_multiple_presenters).and_return(false)
|
|
218
|
+
OpenConferenceWare.stub(:have_user_profiles).and_return(true)
|
|
219
|
+
@proposal.profile.should == @proposal.user
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "should return itself if multiple_presenters and user_profiles are disabled" do
|
|
223
|
+
OpenConferenceWare.stub(:have_multiple_presenters).and_return(false)
|
|
224
|
+
OpenConferenceWare.stub(:have_user_profiles).and_return(false)
|
|
225
|
+
@proposal.profile.should == @proposal
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
describe "when adding or removing user" do
|
|
230
|
+
before(:each) do
|
|
231
|
+
@user = stub_model(User)
|
|
232
|
+
@users = []
|
|
233
|
+
@proposal = stub_model(Proposal)
|
|
234
|
+
@proposal.should_receive(:users).at_least(:once).and_return(@users)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
describe "when adding user" do
|
|
238
|
+
it "should add a user" do
|
|
239
|
+
@users.should_receive(:include?).with(@user).and_return(false)
|
|
240
|
+
@users.should_receive(:<<).with(@user).and_return(@user)
|
|
241
|
+
|
|
242
|
+
@proposal.add_user(@user)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "should not re-add an existing user" do
|
|
246
|
+
@users.should_receive(:include?).with(@user).and_return(true)
|
|
247
|
+
@users.should_not_receive(:<<)
|
|
248
|
+
|
|
249
|
+
@proposal.add_user(@user)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe "when removing user" do
|
|
254
|
+
it "should remove a user" do
|
|
255
|
+
@users.should_receive(:include?).with(@user).and_return(true)
|
|
256
|
+
@users.should_receive(:delete).with(@user).and_return(@user)
|
|
257
|
+
|
|
258
|
+
@proposal.remove_user(@user)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it "should not remove a non-existent user" do
|
|
262
|
+
@users.should_receive(:include?).with(@user).and_return(false)
|
|
263
|
+
@users.should_not_receive(:delete)
|
|
264
|
+
|
|
265
|
+
@proposal.remove_user(@user)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
describe "with rooms" do
|
|
271
|
+
before :each do
|
|
272
|
+
@proposal = Proposal.new
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
it "should be able to assign a room to an proposal" do
|
|
276
|
+
room = stub_model(Room)
|
|
277
|
+
@proposal.room = room
|
|
278
|
+
@proposal.room.should==room
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
describe "to_icalendar" do
|
|
283
|
+
def assert_calendar_match(item, component, url_helper=nil)
|
|
284
|
+
component.should_not be_nil
|
|
285
|
+
|
|
286
|
+
# This is hacky, but necessary because vPim doesn't actually parse
|
|
287
|
+
# time zone information out of iCalendar files.
|
|
288
|
+
#
|
|
289
|
+
# The files are output with the correct time zone, but seem to be
|
|
290
|
+
# parsed in the computer's local time, regardless of the Rails
|
|
291
|
+
# time zone setting.
|
|
292
|
+
dtstart = Time.parse(component.dtstart.strftime('%Y-%m-%d %H:%M:%S UTC'))
|
|
293
|
+
dtstart.to_i.should == item.start_time.to_i
|
|
294
|
+
if item.duration
|
|
295
|
+
dtend = Time.parse(component.dtend.strftime('%Y-%m-%d %H:%M:%S UTC'))
|
|
296
|
+
dtend.to_i.should == item.end_time.to_i
|
|
297
|
+
else
|
|
298
|
+
component.dtend.should be_nil
|
|
299
|
+
end
|
|
300
|
+
component.summary.should == item.title
|
|
301
|
+
component.description.should == (item.respond_to?(:users) ?
|
|
302
|
+
"#{item.users.map(&:fullname).join(', ')}: #{item.excerpt}" :
|
|
303
|
+
item.excerpt)
|
|
304
|
+
component.url.should == url_helper.call(item) if url_helper
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
it "should export proposals to iCalendar" do
|
|
308
|
+
mysql_record = proposals(:mysql_session)
|
|
309
|
+
postgresql_record = proposals(:postgresql_session)
|
|
310
|
+
items = [ mysql_record, postgresql_record ]
|
|
311
|
+
title = "MyTitle"
|
|
312
|
+
url_helper = lambda {|item| "http://foo.bar/#{item.id}"}
|
|
313
|
+
|
|
314
|
+
data = Proposal.to_icalendar(items, title: title, url_helper: url_helper)
|
|
315
|
+
|
|
316
|
+
calendar = Vpim::Icalendar.decode(data).first
|
|
317
|
+
components = Array(calendar)
|
|
318
|
+
components.size.should == 2
|
|
319
|
+
assert_calendar_match(mysql_record, components.find{|t| t.summary == mysql_record.title}, url_helper)
|
|
320
|
+
assert_calendar_match(postgresql_record, components.find{|t| t.summary == postgresql_record.title}, url_helper)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
it "should skip items without a start time" do
|
|
324
|
+
event = create :populated_event
|
|
325
|
+
item = create :schedule_item, start_time: nil, duration: nil
|
|
326
|
+
|
|
327
|
+
data = Proposal.to_icalendar([item])
|
|
328
|
+
calendar = Vpim::Icalendar.decode(data).first
|
|
329
|
+
components = Array(calendar)
|
|
330
|
+
components.size.should == 0
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it "should not raise exceptions if nil duration" do
|
|
334
|
+
event = create :populated_event
|
|
335
|
+
item = create :schedule_item, duration: nil
|
|
336
|
+
|
|
337
|
+
data = Proposal.to_icalendar([item])
|
|
338
|
+
calendar = Vpim::Icalendar.decode(data).first
|
|
339
|
+
components = Array(calendar)
|
|
340
|
+
components.size.should == 1
|
|
341
|
+
component = components.first
|
|
342
|
+
assert_calendar_match(item, component)
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
describe "session_notes_url" do
|
|
347
|
+
before do
|
|
348
|
+
@proposal = proposals(:clio_chupacabras)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
it "should be nil if no session_notes_url_format is defined" do
|
|
352
|
+
OpenConferenceWare.stub(session_notes_url_format: nil)
|
|
353
|
+
|
|
354
|
+
@proposal.session_notes_url.should be_nil
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
describe "with wiki" do
|
|
358
|
+
before :each do
|
|
359
|
+
OpenConferenceWare.stub(
|
|
360
|
+
session_notes_url_format: '%1$s%2$s/wiki/',
|
|
361
|
+
public_url: 'http://mysite.com/'
|
|
362
|
+
)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
it "should interpolate content if session_notes_url_format is defined" do
|
|
366
|
+
@proposal.session_notes_url.should == "http://mysite.com/closed/wiki/Chupacabras_and_you"
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it "should replace slashes with dashes" do
|
|
370
|
+
@proposal.title = "CouchApp Evently Guided Hack w/ CouchDB"
|
|
371
|
+
@proposal.session_notes_url.should == "http://mysite.com/closed/wiki/CouchApp_Evently_Guided_Hack_w-_CouchDB"
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
describe "when sorting" do
|
|
377
|
+
before(:each) do
|
|
378
|
+
@shonen = stub_model(Track, title: "Shonen")
|
|
379
|
+
@bishoujo = stub_model(Track, title: "Bishoujo")
|
|
380
|
+
@tracks = [@shonen, @bishoujo]
|
|
381
|
+
|
|
382
|
+
@naruto = stub_model(Proposal,
|
|
383
|
+
title: "Naruto",
|
|
384
|
+
track: @shonen,
|
|
385
|
+
status: "proposed",
|
|
386
|
+
submitted_at: Time.parse('2009/12/09 01:00'),
|
|
387
|
+
start_time: Time.parse('2009/12/10 05:00'))
|
|
388
|
+
@bleach = stub_model(Proposal,
|
|
389
|
+
title: "Bleach",
|
|
390
|
+
track: @shonen,
|
|
391
|
+
status: "confirmed",
|
|
392
|
+
submitted_at: Time.parse('2009/12/09 02:00'),
|
|
393
|
+
start_time: Time.parse('2009/12/10 04:00'))
|
|
394
|
+
@sera_mun = stub_model(Proposal,
|
|
395
|
+
title: "Bishoujo Senshi Sera Mun",
|
|
396
|
+
track: @bishoujo,
|
|
397
|
+
status: "confirmed",
|
|
398
|
+
submitted_at: Time.parse('2009/12/09 04:00'),
|
|
399
|
+
start_time: Time.parse('2009/12/10 01:00'))
|
|
400
|
+
@kadocapta_sakura = stub_model(Proposal,
|
|
401
|
+
title: "Kadocapta Sakura",
|
|
402
|
+
track: @bishoujo,
|
|
403
|
+
status: "accepted",
|
|
404
|
+
submitted_at: Time.parse('2009/12/09 03:00'),
|
|
405
|
+
start_time: Time.parse('2009/12/10 02:00'))
|
|
406
|
+
@kino = stub_model(Proposal,
|
|
407
|
+
title: "Kino no Tabi",
|
|
408
|
+
track: nil,
|
|
409
|
+
status: "accepted",
|
|
410
|
+
submitted_at: Time.parse('2009/12/09 06:00'),
|
|
411
|
+
start_time: Time.parse('2009/12/10 06:00'))
|
|
412
|
+
@proposals = [@kadocapta_sakura, @bleach, @kino, @naruto, @sera_mun]
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
it "should sort by title" do
|
|
416
|
+
Proposal.sort(@proposals, :title).should == [@sera_mun, @bleach, @kadocapta_sakura, @kino, @naruto]
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it "should sort by title descending" do
|
|
420
|
+
Proposal.sort(@proposals, :title, false).should == [@naruto, @kino, @kadocapta_sakura, @bleach, @sera_mun]
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it "should sort by track" do
|
|
424
|
+
Proposal.sort(@proposals, :track).should == [@sera_mun, @kadocapta_sakura, @bleach, @naruto, @kino]
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it "should sort by status" do
|
|
428
|
+
Proposal.sort(@proposals, :status).should == [@kadocapta_sakura, @kino, @sera_mun, @bleach, @naruto]
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it "should sort by submitted date" do
|
|
432
|
+
Proposal.sort(@proposals, :submitted_at).should == [@naruto, @bleach, @kadocapta_sakura, @sera_mun, @kino]
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
it "should default to sorting by submitted date if given unknown sorting" do
|
|
436
|
+
Proposal.sort(@proposals, :submitted_at).should == [@naruto, @bleach, @kadocapta_sakura, @sera_mun, @kino]
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
describe "when retreiving slug" do
|
|
441
|
+
it "should return a slug composed of the organization and event slugs plus the proposal identifier" do
|
|
442
|
+
proposal = proposals(:clio_chupacabras)
|
|
443
|
+
|
|
444
|
+
proposal.slug.should == "#{OpenConferenceWare.organization_slug}#{proposal.event.slug}-%04d" % proposal.id
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
describe "is a proposal related to an event?" do
|
|
449
|
+
it "should be related to its own event" do
|
|
450
|
+
event = create :populated_event
|
|
451
|
+
proposal = proposal_for_event(event)
|
|
452
|
+
|
|
453
|
+
proposal.related_to_event?(proposal.event).should be_true
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
it "should be related to its own event's parent" do
|
|
457
|
+
parent = create :populated_event
|
|
458
|
+
event = create :populated_event, parent: parent
|
|
459
|
+
proposal = proposal_for_event(event)
|
|
460
|
+
|
|
461
|
+
proposal.related_to_event?(event).should be_true
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "should be related to its own event's parent's children" do
|
|
465
|
+
event = create :populated_event
|
|
466
|
+
child = create :populated_event, parent: event
|
|
467
|
+
proposal = proposal_for_event(event)
|
|
468
|
+
|
|
469
|
+
proposal.related_to_event?(event).should be_true
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it "should not be related to an unrelated event" do
|
|
473
|
+
event = create :populated_event
|
|
474
|
+
proposal = proposal_for_event(event)
|
|
475
|
+
unrelated = create :populated_event
|
|
476
|
+
|
|
477
|
+
proposal.related_to_event?(unrelated).should be_false
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
describe "traversal" do
|
|
482
|
+
before(:each) do
|
|
483
|
+
@event = create :populated_event
|
|
484
|
+
@event.proposals.destroy_all
|
|
485
|
+
@proposal1 = proposal_for_event(@event)
|
|
486
|
+
@proposal2 = proposal_for_event(@event)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
describe "when finding next proposal" do
|
|
490
|
+
it "should return the next proposal when it exists" do
|
|
491
|
+
@proposal1.next_proposal.should == @proposal2
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
it "should return nil when it's the last" do
|
|
495
|
+
@proposal2.next_proposal.should be_nil
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
describe "when finding previous proposal" do
|
|
500
|
+
it "should return the previous proposal when it exists" do
|
|
501
|
+
@proposal2.previous_proposal.should == @proposal1
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
it "should return nil when it's the first" do
|
|
505
|
+
@proposal1.previous_proposal.should be_nil
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
describe "when notifying accepted speakers" do
|
|
511
|
+
before(:each) do
|
|
512
|
+
@proposal = proposals(:quentin_widgets)
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
it "should not notify unaccepted proposal speakers" do
|
|
516
|
+
emailed, already = @proposal.notify_accepted_speakers
|
|
517
|
+
emailed.should be_nil
|
|
518
|
+
already.should be_nil
|
|
519
|
+
@proposal.notified_at.should be_nil
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
it "should not notify already-notified proposal speakers" do
|
|
523
|
+
@proposal.accept!
|
|
524
|
+
@proposal.notified_at = Time.now
|
|
525
|
+
emailed, already = @proposal.notify_accepted_speakers
|
|
526
|
+
emailed.should be_nil
|
|
527
|
+
already.should == @proposal.mailto_emails
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
it "should notify accepted proposal speakers" do
|
|
531
|
+
@proposal.accept!
|
|
532
|
+
emailed, already = @proposal.notify_accepted_speakers
|
|
533
|
+
emailed.should == @proposal.mailto_emails
|
|
534
|
+
already.should be_nil
|
|
535
|
+
@proposal.notified_at.should_not be_nil
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
describe "when notifying rejected speakers" do
|
|
540
|
+
before(:each) do
|
|
541
|
+
@proposal = proposals(:quentin_widgets)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
it "should not notify unrejected proposal speakers" do
|
|
545
|
+
emailed, already = @proposal.notify_rejected_speakers
|
|
546
|
+
emailed.should be_nil
|
|
547
|
+
already.should be_nil
|
|
548
|
+
@proposal.notified_at.should be_nil
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
it "should not notify already-notified proposal speakers" do
|
|
552
|
+
@proposal.reject!
|
|
553
|
+
@proposal.notified_at = Time.now
|
|
554
|
+
emailed, already = @proposal.notify_rejected_speakers
|
|
555
|
+
emailed.should be_nil
|
|
556
|
+
already.should == @proposal.mailto_emails
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it "should notify rejected proposal speakers" do
|
|
560
|
+
@proposal.reject!
|
|
561
|
+
emailed, already = @proposal.notify_rejected_speakers
|
|
562
|
+
emailed.should == @proposal.mailto_emails
|
|
563
|
+
already.should be_nil
|
|
564
|
+
@proposal.notified_at.should_not be_nil
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
describe "validating acceptance of the policy agreement," do
|
|
569
|
+
before(:each) do
|
|
570
|
+
@proposal = proposals(:quentin_widgets)
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
describe "when one exists," do
|
|
574
|
+
it "should require presenters to accept the agreement" do
|
|
575
|
+
@proposal.agreement = false
|
|
576
|
+
@proposal.should_not be_valid
|
|
577
|
+
@proposal.agreement = true
|
|
578
|
+
@proposal.should be_valid
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
describe "when no agreement is set" do
|
|
583
|
+
before do
|
|
584
|
+
OpenConferenceWare.stub(agreement: nil)
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
it "should not require presenters to accept the agreement" do
|
|
588
|
+
@proposal.agreement = false
|
|
589
|
+
@proposal.should be_valid
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
private
|
|
596
|
+
|
|
597
|
+
def new_proposal(attr = {})
|
|
598
|
+
# TODO: The proposal factory should handle these associations
|
|
599
|
+
valid_attr = {
|
|
600
|
+
event: mock_model(Event),
|
|
601
|
+
track: mock_model(Track),
|
|
602
|
+
session_type: mock_model(SessionType)
|
|
603
|
+
}
|
|
604
|
+
build(:proposal, valid_attr.merge(attr))
|
|
605
|
+
end
|
|
606
|
+
end
|