diff --git a/Gemfile b/Gemfile index 14d7aabb..3bbfec2b 100644 --- a/Gemfile +++ b/Gemfile @@ -45,7 +45,7 @@ gem 'sass-rails', '>= 4.0.2' gem 'uglifier', '>= 1.3.0' # as the front-end framework -gem 'bootstrap-sass' +gem 'bootstrap-sass', '~> 3.3.4.1' gem 'autoprefixer-rails' gem 'formtastic-bootstrap' gem 'formtastic', '~> 2.3.0.rc3' diff --git a/Gemfile.lock b/Gemfile.lock index 194e2684..6a948871 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,8 +56,9 @@ GEM uuidtools arel (5.0.1.20140414130214) ast (2.0.0) - autoprefixer-rails (4.0.1) + autoprefixer-rails (5.1.9) execjs + json awesome_nested_set (3.0.0.rc.5) activerecord (>= 4.0.0, < 5) axlsx (2.0.1) @@ -68,8 +69,9 @@ GEM axlsx (>= 2.0.1) rails (>= 3.1) bcrypt (3.1.7) - bootstrap-sass (3.3.1.0) - sass (~> 3.2) + bootstrap-sass (3.3.4.1) + autoprefixer-rails (>= 5.0.0.1) + sass (>= 3.2.19) bootstrap-switch-rails (3.0.2) bootstrap3-datetimepicker-rails (3.0.3) momentjs-rails (>= 2.8.1) @@ -138,7 +140,7 @@ GEM diff-lcs (1.2.5) docile (1.1.3) erubis (2.7.0) - execjs (2.0.2) + execjs (2.5.2) factory_girl (4.4.0) activesupport (>= 3.0.0) factory_girl_rails (4.4.1) @@ -440,7 +442,7 @@ DEPENDENCIES autoprefixer-rails awesome_nested_set (~> 3.0.0.rc.5) axlsx_rails - bootstrap-sass + bootstrap-sass (~> 3.3.4.1) bootstrap-switch-rails (~> 3.0.0) bootstrap3-datetimepicker-rails (~> 3.0.2) byebug diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 8111385d..6f915715 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -36,6 +36,7 @@ //= require osem-tickets //= require bootstrap-switch //= require osem-switch +//= require osem-bootstrap $(document).ready(function() { $('a[disabled=disabled]').click(function(event){ diff --git a/app/assets/javascripts/osem-bootstrap.js b/app/assets/javascripts/osem-bootstrap.js new file mode 100644 index 00000000..f1335473 --- /dev/null +++ b/app/assets/javascripts/osem-bootstrap.js @@ -0,0 +1,24 @@ +$(function() { + // add a hash to the URL when the user clicks on a tab + $('a[data-toggle="tab"]').on('click', function(e) { + history.pushState(null, null, $(this).attr('href')); + }); + // navigate to a tab when the history changes + window.addEventListener("popstate", function(e) { + var activeTab = $('a[href="' + location.hash + '"]'); + if (activeTab.length) { + activeTab.tab('show'); + } else { + $('.nav-tabs a').first().tab('show'); + } + }); +}); + +$(function() { + var hash = window.location.hash; + hash && $('ul.nav a[href="' + hash + '"]').tab('show'); +}); + +$(function () { + $('[data-toggle="popover"]').popover({html: true}) +}); diff --git a/app/assets/javascripts/osem.js b/app/assets/javascripts/osem.js index 92a770b4..cd1f5304 100644 --- a/app/assets/javascripts/osem.js +++ b/app/assets/javascripts/osem.js @@ -27,11 +27,15 @@ $(function () { $("#" + id).toggle(); }); }); - $("#commercial_commercial_type").change(function () { - $(".media-type").hide(); - $('#' + $(this).val().toLowerCase() + '-help').show(); + + $(".select-help-toggle").change(function () { + var id = $(this).attr('id'); + $('.' + id).collapse('hide'); + + $('#' + $(this).val() + '-help.' + id).collapse('show'); }); $('.dropdown-toggle').dropdown(); + /** * Adds the default template as value to the regarding email textarea field. */ diff --git a/app/controllers/commercials_controller.rb b/app/controllers/commercials_controller.rb index e9c886e8..c2992594 100644 --- a/app/controllers/commercials_controller.rb +++ b/app/controllers/commercials_controller.rb @@ -15,7 +15,7 @@ class CommercialsController < ApplicationController authorize! :create, @commercial if @commercial.save - redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id), + redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), notice: 'Commercial was successfully created.' else flash[:error] = "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." @@ -25,7 +25,7 @@ class CommercialsController < ApplicationController def update if @commercial.update(commercial_params) - redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id), + redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), notice: 'Commercial was successfully updated.' else flash[:error] = "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." diff --git a/app/controllers/proposal_controller.rb b/app/controllers/proposal_controller.rb index e21c77be..2bc9e099 100644 --- a/app/controllers/proposal_controller.rb +++ b/app/controllers/proposal_controller.rb @@ -1,5 +1,5 @@ class ProposalController < ApplicationController - before_filter :authenticate_user!, except: [:show] + before_filter :authenticate_user!, except: [:show, :new, :create] load_resource :conference, find_by: :short_title load_and_authorize_resource :event, parent: false, through: :conference @@ -13,6 +13,7 @@ class ProposalController < ApplicationController end def new + @user = User.new @url = conference_proposal_index_path(@conference.short_title) end @@ -24,35 +25,37 @@ class ProposalController < ApplicationController def create @url = conference_proposal_index_path(@conference.short_title) + unless current_user + @user = User.new(params[:user]) + if @user.save + sign_in(@user) + else + flash[:error] = "Could not save user: #{@user.errors.full_messages.join(', ')}" + render action: 'new' + return + end + end + params[:event].delete :user + @event = Event.new(params[:event]) @event.conference = @conference - # First, update the submitter's info, if they've changed anything - current_user.assign_attributes(params[:user]) - if current_user.changed? - current_user.save - end - @event.event_users.new(user: current_user, event_role: 'submitter') @event.event_users.new(user: current_user, event_role: 'speaker') - if !@event.save + unless @event.save flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}" render action: 'new' return end ahoy.track 'Event submission', title: 'New submission' - if @conference.user_registered?(current_user) - redirect_to(conference_proposal_index_path(@conference.short_title), - notice: 'Event was successfully submitted.') - else - redirect_to(new_conference_conference_registrations_path(conference_id: @conference.short_title), - alert: 'Event was successfully submitted. You should register for the conference now.') - end + + flash[:notice] = 'Proposal was successfully submitted.' + redirect_to conference_proposal_index_path(@conference.short_title) end def update diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0de2afb9..ef409eb1 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,4 +1,34 @@ module ApplicationHelper + def pluralize_without_count(count, noun, text = nil) + if count != 0 + count == 1 ? "#{noun}#{text}" : "#{noun.pluralize}#{text}" + end + end + + def event_status_icon(event) + case event.state + when 'new' + 'fa-eye' + when 'unconfirmed' + 'fa-check text-muted' + when 'confirmed' + 'fa-check text-success' + when 'rejected', 'withdrawn', 'canceled' + 'fa-ban' + end + end + + def event_progress_color(progress) + progress = progress.to_i + + case progress + when 100 then 'progress-bar-success' + when 86 then 'progress-bar-info' + when 71 then 'progress-bar-warning' + when 14, 29, 43, 57 then 'progress-bar-danger' + end + end + def target_progress_color(progress) progress = progress.to_i result = @@ -67,9 +97,9 @@ module ApplicationHelper def class_for_todo(bool) if bool - return 'list-group-item todolist-ok' + return 'todolist-ok' else - return 'list-group-item todolist-missing' + return 'todolist-missing' end end diff --git a/app/models/ability.rb b/app/models/ability.rb index fe8452f2..4a1abe99 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -52,6 +52,10 @@ class Ability can [:show, :create], Registration do |registration| registration.new_record? end + + can [:show, :create], Event do |event| + event.new_record? + end end # Abilities for signed in users diff --git a/app/models/commercial.rb b/app/models/commercial.rb index a633102c..d38661cd 100644 --- a/app/models/commercial.rb +++ b/app/models/commercial.rb @@ -3,7 +3,8 @@ class Commercial < ActiveRecord::Base attr_accessible :commercial_id, :commercial_type - validates :commercial_id, :commercial_type, presence: true + validates :commercial_id, presence: true + validates :commercial_type, presence: true - validates :commercial_type, inclusion: { in: CONFIG['commercial_types'].values }, allow_blank: true + validates :commercial_type, inclusion: { in: CONFIG['commercial_types'].values } end diff --git a/app/models/conference.rb b/app/models/conference.rb index 9bfe8948..38e2976e 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -911,10 +911,10 @@ class Conference < ActiveRecord::Base # Creates default EventTypes for this Conference. Used as before_create. # def create_event_types - event_types << EventType.create(title: 'Talk', length: 30, color: '#FF0000', + event_types << EventType.create(title: 'Talk', length: 30, color: '#FF0000', description: 'Presentation in lecture format', minimum_abstract_length: 0, maximum_abstract_length: 500) - event_types << EventType.create(title: 'Workshop', length: 60, color: '#0000FF', + event_types << EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice', minimum_abstract_length: 0, maximum_abstract_length: 500) true diff --git a/app/models/event.rb b/app/models/event.rb index 320c4b28..a325b290 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -26,17 +26,18 @@ class Event < ActiveRecord::Base accepts_nested_attributes_for :event_users, allow_destroy: true accepts_nested_attributes_for :users + before_create :generate_guid validate :abstract_limit validate :before_end_of_conference, on: :create - validate :name_and_biography_exists validates :title, presence: true validates :abstract, presence: true validates :event_type, presence: true validates :conference, presence: true scope :confirmed, -> { where(state: 'confirmed') } + scope :highlighted, -> { where(is_highlight: true) } state_machine initial: :new do state :new @@ -212,6 +213,32 @@ class Event < ActiveRecord::Base result.to_a.to_sentence end + ## + # + # Returns +Hash+ + def progress_status + { + registered: self.conference.user_registered?(self.submitter), + commercials: self.commercials.any?, + biography: !self.submitter.biography.blank?, + subtitle: !self.subtitle.blank?, + difficulty_level: !self.difficulty_level.blank?, + title: true, + abstract: true + }.with_indifferent_access + end + + ## + # Returns the progress of the proposal's set up + # + # ====Returns + # * +Fixnum+ -> Progress in Percent + def calculate_progress + result = self.progress_status + true_items = result.select { |_key, value| value }.length + (true_items / result.length.to_f * 100).round(0).to_s + end + private def abstract_limit @@ -225,11 +252,6 @@ class Event < ActiveRecord::Base errors.add(:abstract, "cannot have more than #{max_words} words") if len > max_words end - def name_and_biography_exists - errors.add(:biography, "cant' be blank") if submitter.biography.blank? - errors.add(:name, " can't be blank") if submitter.name.blank? - end - # TODO: create a module to be mixed into model to perform same operation # venue.rb has same functionality which can be shared # TODO: rename guid to UUID as guid is specifically Microsoft term diff --git a/app/models/event_type.rb b/app/models/event_type.rb index 2430b76e..90abc542 100644 --- a/app/models/event_type.rb +++ b/app/models/event_type.rb @@ -1,6 +1,6 @@ class EventType < ActiveRecord::Base attr_accessible :title, :length, :minimum_abstract_length, :maximum_abstract_length, :color, - :conference_id + :conference_id, :description belongs_to :conference has_many :events, dependent: :restrict_with_error diff --git a/app/views/admin/commercials/_form.html.haml b/app/views/admin/commercials/_form.html.haml index 169c04b6..a85aebf2 100644 --- a/app/views/admin/commercials/_form.html.haml +++ b/app/views/admin/commercials/_form.html.haml @@ -8,13 +8,8 @@ .row .col-md-8 = semantic_form_for(@commercial, :url => (@commercial.new_record? ? admin_conference_commercials_path : admin_conference_commercial_path(@conference.short_title, @commercial))) do |f| - = f.input :commercial_type, as: :select, label: 'Conference Promo Media Type', class: 'form-control', collection: CONFIG['commercial_types'].values, include_blank: false, hint: 'This media-item will be used to represent this conference at various places in OSEM.' + = f.input :commercial_type, as: :select, label: 'Conference Promo Media Type', input_html: { class: 'select-help-toggle' }, collection: CONFIG['commercial_types'].values, include_blank: false, hint: 'This media-item will be used to represent this conference at various places in OSEM.' = f.input :commercial_id, label: 'Conference Promo Media ID', as: :string - %p{ class: 'help-block media-type', id: 'youtube-help' } Go to your YouTube video, click on "share" and copy everything behind http://youtu.be/" - %p{ class: 'help-block media-type', id: 'slideshare-help', style: 'display:none' } Go to your SlideShare, click on "share" -> "embed" and copy the id - %p{ class: 'help-block media-type', id: 'flickr-help', style: 'display:none' } Go to your flickr image, click on "Grab the link" -> "Show short url" and copy everything behind https://flic.kr/p/ - %p{ class: 'help-block media-type', id: 'vimeo-help', style: 'display:none' } Go to your vimeo video, click on "share" and copy everything behind http://vimeo.com/ - %p{ class: 'help-block media-type', id: 'speakerdeck-help', style: 'display:none' } Go to your SpeakerDeck, click on "share" -> "embed" and copy the data-id - %p{ class: 'help-block media-type', id: 'instagram-help', style: 'display:none' } Go to your Instagram photo page and copy everything behind instagram.com/p/ (without trailing /# hash symbol) + = render partial: 'commercials/commercial_help' %p.text-right = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } diff --git a/app/views/admin/conference/_todo_list.html.haml b/app/views/admin/conference/_todo_list.html.haml index d5a700d6..5ea159d5 100644 --- a/app/views/admin/conference/_todo_list.html.haml +++ b/app/views/admin/conference/_todo_list.html.haml @@ -6,7 +6,7 @@ .progress-bar{ 'role'=>'progressbar', 'aria-valuenow'=>"#{conference_progress['process']}", 'aria-valuemin'=>'0', 'aria-valuemax'=>'100', 'style'=>"width: #{conference_progress['process']}%;" } = conference_progress['process'] + '%' - %li{'class'=>class_for_todo(conference_progress['registration'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['registration'])}"} %span{'class'=>icon_for_todo(conference_progress['registration'])} - if can? :update, @conference - if conference.registration_period @@ -15,43 +15,43 @@ = link_to 'Set up registration period', new_admin_conference_registration_period_path(conference_progress['short_title']) - else Set up registration period - %li{'class'=>class_for_todo(conference_progress['cfp'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['cfp'])}"} %span{'class'=>icon_for_todo(conference_progress['cfp'])} - if can? :update, CallForPaper.new(conference_id: @conference.id) = link_to 'Set up call for papers', admin_conference_call_for_paper_path(conference_progress['short_title']) - else Set up call for papers - %li{'class'=>class_for_todo(conference_progress['venue'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['venue'])}"} %span{'class'=>icon_for_todo(conference_progress['venue'])} - if can? :update, @conference.venue = link_to 'Add venue', edit_admin_conference_venue_path(conference_progress['short_title']) - else Add venue - %li{'class'=>class_for_todo(conference_progress['rooms'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['rooms'])}"} %span{'class'=>icon_for_todo(conference_progress['rooms'])} - if can? :update, @conference.rooms.build = link_to 'Add rooms', admin_conference_rooms_path(conference_progress['short_title']) - else Add rooms - %li{'class'=>class_for_todo(conference_progress['tracks'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['tracks'])}"} %span{'class'=>icon_for_todo(conference_progress['tracks'])} - if can? :update, @conference.tracks.build = link_to 'Add tracks', admin_conference_tracks_path(conference_progress['short_title']) - else Add tracks - %li{'class'=>class_for_todo(conference_progress['event_types'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['event_types'])}"} %span{'class'=>icon_for_todo(conference_progress['event_types'])} - if can? :update, @conference.event_types.build = link_to 'Add event types', admin_conference_event_types_path(conference_progress['short_title']) - else Add event types - %li{'class'=>class_for_todo(conference_progress['difficulty_levels'])} + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['difficulty_levels'])}"} %span{'class'=>icon_for_todo(conference_progress['difficulty_levels'])} - if can? :update, @conference.difficulty_levels.build = link_to 'Add difficulty levels', admin_conference_difficulty_levels_path(conference_progress['short_title']) - else Add difficulty levels - %li{class: class_for_todo(conference_progress['splashpage'])} + %li{class: "list-group-item #{class_for_todo(conference_progress['splashpage'])}"} %span{'class'=>icon_for_todo(conference_progress['splashpage'])} - if can? :update, @conference = link_to 'Set up a Splashpage', admin_conference_splashpage_path(conference_progress['short_title']) diff --git a/app/views/admin/event_types/_form.html.haml b/app/views/admin/event_types/_form.html.haml index 8ef37e4e..0e0db179 100644 --- a/app/views/admin/event_types/_form.html.haml +++ b/app/views/admin/event_types/_form.html.haml @@ -11,8 +11,9 @@ = semantic_form_for(@event_type, :url => (@event_type.new_record? ? admin_conference_event_types_path : admin_conference_event_type_path(@conference.short_title, @event_type))) do |f| = f.input :title = f.input :length, :input_html => {:size => 3} + = f.input :description = f.input :minimum_abstract_length, :input_html => {:size => 3} = f.input :maximum_abstract_length, :input_html => {:size => 3} = f.input :color, :input_html => { :size => 6, :type => 'color' } %p.text-right - = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } \ No newline at end of file + = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } diff --git a/app/views/commercials/_commercial_help.html.haml b/app/views/commercials/_commercial_help.html.haml new file mode 100644 index 00000000..67487613 --- /dev/null +++ b/app/views/commercials/_commercial_help.html.haml @@ -0,0 +1,6 @@ +%p{ class: 'help-block commercial_commercial_type collapse in', id: 'YouTube-help' } Go to your YouTube video, click on "share" and copy everything behind http://youtu.be/" +%p{ class: 'help-block commercial_commercial_type collapse', id: 'SlideShare-help' } Go to your SlideShare, click on "share" -> "embed" and copy the id +%p{ class: 'help-block commercial_commercial_type collapse', id: 'Flickr-help' } Go to your flickr image, click on "Grab the link" -> "Show short url" and copy everything behind https://flic.kr/p/ +%p{ class: 'help-block commercial_commercial_type collapse', id: 'Vimeo-help' } Go to your vimeo video, click on "share" and copy everything behind http://vimeo.com/ +%p{ class: 'help-block commercial_commercial_type collapse', id: 'Speakerdeck-help' } Go to your SpeakerDeck, click on "share" -> "embed" and copy the data-id +%p{ class: 'help-block commercial_commercial_type collapse', id: 'Instagram-help' } Go to your Instagram photo page and copy everything behind instagram.com/p/ (without trailing /# hash symbol) diff --git a/app/views/commercials/_form.html.haml b/app/views/commercials/_form.html.haml index ea9e75cd..13ca4fa5 100644 --- a/app/views/commercials/_form.html.haml +++ b/app/views/commercials/_form.html.haml @@ -1,9 +1,4 @@ -= f.input :commercial_type, as: :select, label: 'Conference Promo Media Type', class: 'form-control', collection: CONFIG['commercial_types'].values, include_blank: false, hint: 'This media-item will be used to represent this conference at various places in OSEM.' -= f.input :commercial_id, label: 'Conference Promo Media ID', as: :string -%p{ class: 'help-block media-type', id: 'youtube-help' } Go to your YouTube video, click on "share" and copy everything behind http://youtu.be/" -%p{ class: 'help-block media-type', id: 'slideshare-help', style: 'display:none' } Go to your SlideShare, click on "share" -> "embed" and copy the id -%p{ class: 'help-block media-type', id: 'flickr-help', style: 'display:none' } Go to your flickr image, click on "Grab the link" -> "Show short url" and copy everything behind https://flic.kr/p/ -%p{ class: 'help-block media-type', id: 'vimeo-help', style: 'display:none' } Go to your vimeo video, click on "share" and copy everything behind http://vimeo.com/ -%p{ class: 'help-block media-type', id: 'speakerdeck-help', style: 'display:none' } Go to your SpeakerDeck, click on "share" -> "embed" and copy the data-id -%p{ class: 'help-block media-type', id: 'instagram-help', style: 'display:none' } Go to your Instagram photo page and copy everything behind instagram.com/p/ (without trailing /# hash symbol) -= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } += f.input :commercial_type, as: :select, label: 'Type', input_html: { class: 'form-control select-help-toggle' }, collection: CONFIG['commercial_types'].values, include_blank: false, hint: 'This media-item will be used to represent this conference at various places in OSEM.' += f.input :commercial_id, label: 'ID', as: :string, input_html: { required: 'required' } += render partial: 'commercial_help' += f.action :submit, as: :button, button_html: { class: 'btn btn-primary pull-right' } diff --git a/app/views/commercials/edit.html.haml b/app/views/commercials/edit.html.haml index 1f85f432..5abb7914 100644 --- a/app/views/commercials/edit.html.haml +++ b/app/views/commercials/edit.html.haml @@ -7,4 +7,3 @@ .col-md-12 = semantic_form_for @commercial, url: conference_proposal_commercial_path(conference_id: @conference.short_title, proposal_id: @event.id, id: @commercial.id) do |f| = render 'form', f: f - = link_to 'Back', edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id) diff --git a/app/views/commercials/new.html.haml b/app/views/commercials/new.html.haml index e4d96ee5..a4f91ea4 100644 --- a/app/views/commercials/new.html.haml +++ b/app/views/commercials/new.html.haml @@ -7,4 +7,3 @@ .col-md-12 = semantic_form_for @commercial, url: conference_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event.id) do |f| = render 'form', f: f - = link_to 'Back', edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id) diff --git a/app/views/conference/_conference_details.html.haml b/app/views/conference/_conference_details.html.haml index bb680a99..07704360 100644 --- a/app/views/conference/_conference_details.html.haml +++ b/app/views/conference/_conference_details.html.haml @@ -31,7 +31,7 @@ - if !current_user.nil? && current_user.proposal_count(conference) > 0 = link_to "My Proposals", conference_proposal_index_path(conference.short_title), :class =>"btn btn-default" - elsif conference.cfp_open? - = link_to "Submit Proposal", conference_proposal_index_path(conference.short_title), :class =>"btn btn-default" + = link_to "Submit Proposal", new_conference_proposal_path(conference.short_title), :class =>"btn btn-default" - if current_user.nil? || !current_user.subscribed?(conference) = link_to 'Subscribe', conference_subscriptions_path(conference.short_title), method: :post, class: 'btn btn-default' - else diff --git a/app/views/conference_registrations/_form.html.haml b/app/views/conference_registrations/_form.html.haml index 89025cda..ef619583 100644 --- a/app/views/conference_registrations/_form.html.haml +++ b/app/views/conference_registrations/_form.html.haml @@ -21,10 +21,7 @@ = semantic_form_for(@registration, url: conference_conference_registrations_path(@conference.short_title)) do |f| - if !current_user = f.fields_for :user do |u| - = u.input :username, input_html: {required: 'required', autocomplete: 'off'} - = u.input :email, input_html: {required: 'required', autocomplete: 'off'} - = u.input :password, input_html: {required: 'required', autocomplete: 'off'} - = u.input :password_confirmation, :required => true, input_html: {required: 'required', autocomplete: 'off'} + = render partial: 'devise/shared/sign_up_fields', locals: { u: u} - if @conference.questions.any? = render partial: 'questions', locals: { f: f } - if @conference.events.workshops.any? @@ -64,4 +61,4 @@ %p.text-center or sign in using .text-center - = render 'devise/shared/openid' \ No newline at end of file + = render 'devise/shared/openid' diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index d81a264b..f866ae26 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -7,11 +7,7 @@ Sign Up .panel-body = semantic_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| - = f.input :username, required: true - = f.input :email - = f.input :name, required: true - = f.input :password - = f.input :password_confirmation + = render partial: 'devise/shared/sign_up_fields', locals: { u: f} %p.text-right = f.action :submit, as: :button, label: 'Sign Up', button_html: {class: 'btn btn-success' } - unless omniauth_configured.empty? diff --git a/app/views/devise/shared/_sign_up_fields.html.haml b/app/views/devise/shared/_sign_up_fields.html.haml new file mode 100644 index 00000000..9cced15f --- /dev/null +++ b/app/views/devise/shared/_sign_up_fields.html.haml @@ -0,0 +1,4 @@ += u.input :username, input_html: {required: 'required', autocomplete: 'off'} += u.input :email, input_html: {required: 'required', autocomplete: 'off'} += u.input :password, input_html: {required: 'required', autocomplete: 'off', id: 'password_inline'} += u.input :password_confirmation, :required => true, input_html: {required: 'required', autocomplete: 'off'} diff --git a/app/views/proposal/_encouragement_text.html.haml b/app/views/proposal/_encouragement_text.html.haml new file mode 100644 index 00000000..44b51d95 --- /dev/null +++ b/app/views/proposal/_encouragement_text.html.haml @@ -0,0 +1,23 @@ +%p.lead + - if @conference.event_types.any? + You can submit proposals for + = "#{event_types(@conference)}." + - if @conference.tracks.any? + Proposals should fit in one of the + = "#{pluralize(@conference.tracks.count, 'track')}:" + = "#{tracks(@conference)}." + - if @conference.call_for_paper + The submission period has begun + %em + = @conference.call_for_paper.start_date.strftime('%A, %B %-d. %Y') + and closes + %em + = @conference.call_for_paper.end_date.strftime('%A, %B %-d. %Y.') + That means you have only + - days = (@conference.call_for_paper.end_date - Date.today).to_i + %b + = pluralize(days, 'days') + left! + Remember + = @conference.title + will only be as good as the content you present. Submit early, submit often! diff --git a/app/views/proposal/_form.html.haml b/app/views/proposal/_form.html.haml index a5b586e0..f7eb3f3b 100644 --- a/app/views/proposal/_form.html.haml +++ b/app/views/proposal/_form.html.haml @@ -12,10 +12,10 @@ = render 'proposal/proposal_form' #commercials-content.tab-pane %p.text-muted - You can add commercials for your event. These commercials will be displayed on the event detail site. + You can add commercials for your proposal. These commercials will be displayed on the + = link_to 'public proposal page.', conference_proposal_path(@conference.short_title, @event) If you don't add a commercial, the conference commercial will be displayed! - We currently support the following commercial types: YouTube, Vimeo, Instagram, Flickr, Speakerdeck and SlideShare. - + - @event.commercials.each_slice(3) do |slice| .row - slice.each do |commercial| diff --git a/app/views/proposal/_proposal_form.html.haml b/app/views/proposal/_proposal_form.html.haml index 805d2224..8b748139 100644 --- a/app/views/proposal/_proposal_form.html.haml +++ b/app/views/proposal/_proposal_form.html.haml @@ -1,55 +1,53 @@ -= semantic_form_for(@event, :url => @url) do |f| - %section#basic - = f.inputs :name => "Session Information" do - - if can? :update, @event or can? :create, @event - = f.input :title, :as => :string, :required => true - - else - Title: #{@event.title} - %br - %br - = f.input :subtitle, :as => :string - %section#details - - if can? :update, @event or can? :create, @event - = f.input :event_type_id, as: :select, += semantic_form_for(@event, url: @url) do |f| + = f.inputs name: 'Proposal Information' do + = f.input :title, as: :string, required: true + + = f.input :subtitle, as: :string + + = f.input :event_type_id, as: :select, collection: @conference.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id, data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length }]}, - include_blank: false, label: 'Session Type' - - else - Event type: #{@event.event_type.title} + include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' } + + - @conference.event_types.each do |event_type| + %span{ class: 'help-block select-help-text event_event_type_id collapse', id: "#{event_type.id}-help" } + = event_type.description + + :javascript + $("##{@conference.event_types.first.id}-help").collapse('show'); + + = f.input :difficulty_level, as: :select, collection: @conference.difficulty_levels, input_html: { class: 'select-help-toggle' }, + include_blank: '(Please select)' if @conference.difficulty_levels.any? + + - @conference.difficulty_levels.each do |difficulty_level| + %span{ class: 'help-block select-help-text collapse event_difficulty_level_id', id: "#{difficulty_level.id}-help" } + = difficulty_level.description + + = f.input :abstract, input_html: { rows: 5 }, + required: true, hint: link_to('Tips to improve your presentations', 'http://blog.hubspot.com/blog/tabid/6307/bid/5975/10-Rules-to-Instantly-Improve-Your-Presentations.aspx') + + %p + You have used + %span#abstract-count #{@event.abstract_word_count} + words. Abstracts must be between + %span#abstract-minimum-word-count + 0 + and + %span#abstract-maximum-word-count + 250 + words. + + = f.input :require_registration, label: 'Require participants to register to your event' - if current_user.has_any_role? :admin, { name: :organizer, resource: @conference }, { name: :cfp, resource: @conference } - = f.label :is_highlight - %br - = f.check_box :is_highlight, class: 'switch-checkbox', data: { size: "small" } + = f.input :is_highlight + + %p.text-right + = link_to '#description', "data-toggle"=>"collapse" do + Do you require something special? + .collapse#description + = f.input :description, input_html: { rows: 5 }, label: 'Requirements', placeholder: 'Eg. Whiteboard, printer, or something like that.' - %br - = f.input :difficulty_level, :as => :select, :collection => @conference.difficulty_levels, :include_blank => "(Please select)" if @conference.difficulty_levels.any? - = f.input :require_registration - = f.input :abstract, :input_html => {:rows => 5, :class => "span11"}, - :required => true, :label => "Session Abstract" - You have used - %span#abstract-count #{@event.abstract_word_count} - words. Abstracts must be between - %span#abstract-minimum-word-count - 0 - and - %span#abstract-maximum-word-count - 250 - words. - %br - %br - = f.input :description, :input_html => {:rows => 5, :class=> "span11"}, :hint => "This will only be shown to organizers, not to attendees." - %section#information - - if current_user.name.blank? || current_user.biography.blank? - = f.inputs :name => "Your Information" do - = semantic_fields_for current_user do |u| - - if current_user.name.blank? - = u.input :name, :as => :string, :required => true - - if current_user.biography.blank? - = u.input :biography, :required => true, :input_html => {:rows => 5, :class => 'span11', "onkeyup" => "word_count(this, 'biography-count', 150)"} - You have used - %span#biography-count #{current_user.biography_word_count} - words. Biographies are limited to 150 words. %p.text-right - = f.action :submit, :as => :button, :button_html => {:class => "btn btn-success"} + = f.action :submit, :as => :button, :button_html => {:class => "btn btn-success"}, label: 'Update Proposal' diff --git a/app/views/proposal/_tooltip.html.haml b/app/views/proposal/_tooltip.html.haml new file mode 100644 index 00000000..fba4ab7a --- /dev/null +++ b/app/views/proposal/_tooltip.html.haml @@ -0,0 +1,36 @@ +- progress_status = event.progress_status +%ul.list-unstyled + %li{'class'=>class_for_todo(progress_status['registered'])} + %span{'class'=>icon_for_todo(progress_status['registered'])} + - if progress_status['registered'] + = link_to 'Edit your registration', edit_conference_conference_registrations_path(event.conference.short_title) + - else + = link_to 'Register to the conference', new_conference_conference_registrations_path(event.conference.short_title) + + %li{'class'=>class_for_todo(progress_status['biography'])} + %span{'class'=>icon_for_todo(progress_status['biography'])} + - if progress_status['biography'] + = link_to 'Edit your biography', edit_user_path(event.submitter) + - else + = link_to 'Fill out your biography', edit_user_path(event.submitter) + + %li{'class'=>class_for_todo(progress_status['subtitle'])} + %span{'class'=>icon_for_todo(progress_status['subtitle'])} + - if progress_status['subtitle'] + = link_to 'Edit the subtitle', edit_conference_proposal_path(event.conference.short_title, event) + - else + = link_to 'Add a subtitle', edit_conference_proposal_path(event.conference.short_title, event) + + %li{'class'=>class_for_todo(progress_status['commercials'])} + %span{'class'=>icon_for_todo(progress_status['commercials'])} + - if progress_status['commercials'] + = link_to 'Edit the commercials', edit_conference_proposal_path(event.conference.short_title, event, anchor: 'commercials-content') + - else + = link_to 'Add a commercial', new_conference_proposal_commercial_path(event.conference.short_title, event) + + %li{'class'=>class_for_todo(progress_status['difficulty_level'])} + %span{'class'=>icon_for_todo(progress_status['difficulty_level'])} + - if progress_status['difficulty_level'] + = link_to 'Change the difficulty level', edit_conference_proposal_path(event.conference.short_title, event) + - else + = link_to 'Add a difficulty level', edit_conference_proposal_path(event.conference.short_title, event) diff --git a/app/views/proposal/index.html.haml b/app/views/proposal/index.html.haml index facfcce8..0c901f0c 100644 --- a/app/views/proposal/index.html.haml +++ b/app/views/proposal/index.html.haml @@ -3,45 +3,99 @@ .col-md-12.page-header %h1 = "My Proposals for #{@conference.title}" - - if @conference.cfp_open? || (current_user.has_role? :organizer, @conference) - = link_to "New Proposal", new_conference_proposal_path(@conference.short_title), :class => "btn btn-success pull-right" - - if current_user.proposal_count(@conference) > 0 + + .row + .col-md-12 + = render partial: 'encouragement_text' + - if @events.any? + - if @events.highlighted.any? + .row + .col-md-12 + + %p.lead + %strong + Congratulations! + Some of your proposals have been selected as a highlight of #{@conference.title}! + %ul + - @events.highlighted.each do |event| + %li= link_to event.title, conference_proposal_path(@conference.short_title, event) + + .row .col-md-12 - %table.table.table-bordered.table-striped - %thead - %th - %b Title - %th - %b Status - %th + %p.text-right + = link_to '#status-help', class: 'btn btn-default', "data-toggle"=>"collapse" do + Help? + .collapse#status-help + %p + %strong + What happens next with my proposal? + %p + If you submit a proposal, the conference organizers will review it and either accept or reject it. + %br + If your proposal is accepted, the conference organizers expect you to confirm that you will be able to hold it. + %br + If your proposal is rejected, you can either live with that or adapt it and resubmit it for review again. + %br + If something changes and you can't hold the presentation any more, you should withdraw it. + + %p + %strong + Why do I need to add more information? + %p + The more information you add to your proposal, the more likely it is that the conference organizers accept your proposal. + %br + It will also be more likely that visitors find your proposal interesting enough to attend. + + %p + %strong + Why do I need to register to the conference? + %p + Knowing the number of visitors for the conference helps the organizers plan better. + + %table.table.table-striped - @events.each do |event| %tr - %td + %td{style: "padding:20px 8px 20px 8px;"} + %span{ title: event.state.humanize, class: "fa #{event_status_icon(event)}" } + + %td.col-md-7{style: "padding:20px 8px 20px 8px;"} = link_to event.title, conference_proposal_path(@conference.short_title, event.id) - %td - - if event.state == 'new' - Review pending - - else - = event.state.humanize - - if event.state == 'confirmed' && event.require_registration == true - (Pre-registered: #{pre_registered(event).count}) - - if event.confirmed? && !@conference.user_registered?(current_user) - %br - = link_to "Register to attend", new_conference_conference_registrations_path(@conference.short_title), :style => "font-size:10px;" - %td + %br + %small.text-muted + = event.event_type.title + = "(#{event.event_type.length} min)" + - if event.state == 'confirmed' && event.require_registration == true + , + Pre-registered: #{pre_registered(event).count} + + %td.col-md-2{style: "padding:20px 8px 20px 8px;"} + = link_to 'Complete your todo list', 'javascript: void(0)', "type"=>"button", "data-trigger"=>"focus", "data-toggle"=>"popover", "title"=>"Your todo list", "data-content"=>"#{render partial: 'tooltip', locals: { event: event} }" + + - progress_percentage = event.calculate_progress + .progress + %div{class: "progress-bar #{event_progress_color(progress_percentage)}", style: "width:#{progress_percentage}%;"} + = event.progress_status.reject{ |_key, value| value }.length + left + + %td.col-md-3{style: "padding:20px 0px 20px 0px;"} .pull-right - if event.transition_possible? :confirm = link_to 'Confirm', confirm_conference_proposal_path(@conference.short_title, event), method: :patch, class: 'btn btn-mini btn-success', id: "confirm_proposal_#{event.id}" - = link_to 'Edit', edit_conference_proposal_path(@conference.short_title, event.id), - class: 'btn btn-mini btn-primary', id: "edit_proposal_#{event.id}" + - if event.transition_possible? :withdraw = link_to 'Withdraw', conference_proposal_path(@conference.short_title, event.id), method: :delete, - confirm: 'Are you sure you want to withdraw this proposal?', class: 'btn btn-mini btn-warning', + data: { confirm: 'Are you sure you want to withdraw this proposal?' }, class: 'btn btn-mini btn-warning', id: "delete_proposal_#{event.id}" - if event.state == 'withdrawn' || event.state == 'rejected' = link_to 'Re-Submit', restart_conference_proposal_path(@conference.short_title, event.id), method: :patch, class: 'btn btn-mini btn-success', id: "review_event_#{event.id}" + = link_to 'Edit', edit_conference_proposal_path(@conference.short_title, event.id), + class: 'btn btn-default', id: "edit_proposal_#{event.id}" + .row + .col-md-12 + - if @conference.cfp_open? || (current_user.has_role? :organizer, @conference) + = link_to "New Proposal", new_conference_proposal_path(@conference.short_title), :class => "btn btn-success pull-right" diff --git a/app/views/proposal/new.html.haml b/app/views/proposal/new.html.haml index 70bb36ee..03db0032 100644 --- a/app/views/proposal/new.html.haml +++ b/app/views/proposal/new.html.haml @@ -1,28 +1,93 @@ .container .row .col-md-12 - %p - - if @conference.event_types.any? - You can submit proposals for - = "#{event_types(@conference)}." - - if @conference.tracks.any? - Proposals should fit in one of the - = "#{pluralize(@conference.tracks.count, 'track')}:" - = "#{tracks(@conference)}." - The submission period has begun - %em - = @conference.call_for_paper.start_date.strftime('%A, %B %-d. %Y') - and closes - %em - = @conference.call_for_paper.end_date.strftime('%A, %B %-d. %Y.') - That means you have only - - days = (@conference.call_for_paper.end_date - Date.today).to_i - %b - = pluralize(days, 'days') - left! - Remember - = @conference.short_title - will only be as good as the sessions you present. Submit early, submit often! + .page-header + %h1 New Proposal .row .col-md-12 - = render 'proposal_form' + = render partial: 'encouragement_text' + .row + .col-md-8 + - if !current_user + %legend + %span + =link_to('#signup', role: 'tab', "aria-controls" => "home", "data-toggle" => "tab") do + = CONFIG['name'] + Account + %span.pull-right#account-already + =link_to('#signin', role: 'tab', "aria-controls" => "home", "data-toggle" => "tab") do + Already have an account? + .tab-content + .tab-pane.active{role: 'tabpanel', id: 'signup'} + + = semantic_form_for(@event, url: @url) do |f| + + - unless current_user + = semantic_fields_for @user do |u| + = render partial: 'devise/shared/sign_up_fields', locals: { u: u } + = f.inputs name: 'Proposal Information' do + = f.input :title, as: :string, required: true + = f.input :event_type_id, as: :select, + collection: @conference.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id, + data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length }]}, + include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' } + + - @conference.event_types.each do |event_type| + %span{ class: 'help-block event_event_type_id collapse', id: "#{event_type.id}-help" } + = event_type.description + + :javascript + $("##{@conference.event_types.first.id}-help").collapse('show'); + + = f.input :abstract, input_html: { rows: 5 }, + required: true, hint: link_to('Tips to improve your presentations', 'http://blog.hubspot.com/blog/tabid/6307/bid/5975/10-Rules-to-Instantly-Improve-Your-Presentations.aspx') + + %p + You have used + %span#abstract-count #{@event.abstract_word_count} + words. Abstracts must be between + %span#abstract-minimum-word-count + 0 + and + %span#abstract-maximum-word-count + 250 + words. + + = f.input :require_registration, label: 'Require participants to register to your event' + + %p.text-right + = link_to '#description', "data-toggle"=>"collapse", id: 'description_link' do + Do you require something special? + .collapse#description + = f.input :description, input_html: { rows: 5 }, label: 'Requirements', placeholder: 'Eg. Whiteboard, printer, or something like that.' + + %p.text-right + = f.action :submit, :as => :button, :button_html => {:class => "btn btn-success"}, label: 'Create Proposal' + .tab-pane{role: 'tabpanel', id: 'signin'} + - if !CONFIG['authentication']['ichain']['enabled'] + = form_tag(new_user_session_path, class: 'form-horizontal') do + %legend + %span + Sign In + .form-group + %label{for: "user[login]", class: 'col-sm-2 control-label'} + Username + .col-sm-10 + = text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required' + .form-group + %label{for: "user[password]", class: 'col-sm-2 control-label'} + Password + .col-sm-10 + = password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required' + .form-group + .col-sm-12 + %button.btn.btn-success.pull-right + Sign in + - unless omniauth_configured.empty? + .form-group + %hr + %p.text-center + or sign in using + .text-center + = render 'devise/shared/openid' + diff --git a/db/migrate/20150415121038_add_description_to_event_type.rb b/db/migrate/20150415121038_add_description_to_event_type.rb new file mode 100644 index 00000000..fa688c02 --- /dev/null +++ b/db/migrate/20150415121038_add_description_to_event_type.rb @@ -0,0 +1,5 @@ +class AddDescriptionToEventType < ActiveRecord::Migration + def change + add_column :event_types, :description, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 38c9bda2..086a703f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150304135935) do +ActiveRecord::Schema.define(version: 20150415121038) do create_table "ahoy_events", force: true do |t| t.uuid "visit_id" @@ -196,6 +196,7 @@ ActiveRecord::Schema.define(version: 20150304135935) do t.integer "minimum_abstract_length", default: 0 t.integer "maximum_abstract_length", default: 500 t.string "color" + t.string "description" end create_table "event_users", force: true do |t| @@ -275,8 +276,8 @@ ActiveRecord::Schema.define(version: 20150304135935) do end create_table "qanswers", force: true do |t| - t.integer "question_id" - t.integer "answer_id" + t.integer "question_id" + t.integer "answer_id" t.datetime "created_at" t.datetime "updated_at" end diff --git a/spec/features/commercials_spec.rb b/spec/features/commercials_spec.rb index 57d9a59b..b445e8b6 100644 --- a/spec/features/commercials_spec.rb +++ b/spec/features/commercials_spec.rb @@ -75,7 +75,7 @@ feature Commercial do sign_out end - scenario 'adds a invalid commercial to an event', feature: true, js: true do + scenario 'adds a valid commercial to an event', feature: true, js: true do visit edit_conference_proposal_path(conference.short_title, event.id) click_link 'Commercials' @@ -89,7 +89,7 @@ feature Commercial do expect(event.commercials.count).to eq(@expected_count) end - scenario 'adds a valid commercial to an event', feature: true, js: true do + scenario 'adds an invalid commercial to an event', feature: true, js: true do visit edit_conference_proposal_path(conference.short_title, event.id) click_link 'Commercials' click_link 'Add Commercial' @@ -97,7 +97,6 @@ feature Commercial do select('SlideShare', from: 'commercial_commercial_type') click_button 'Create Commercial' - expect(flash).to eq("An error prohibited this Commercial from being saved: Commercial can't be blank.") expect(event.commercials.count).to eq(@expected_count - 1) end @@ -125,7 +124,6 @@ feature Commercial do select('SlideShare', from: 'commercial_commercial_type') fill_in 'commercial_commercial_id', with: '' click_button 'Update Commercial' - expect(flash).to eq("An error prohibited this Commercial from being saved: Commercial can't be blank.") expect(event.commercials.count).to eq(@expected_count) end diff --git a/spec/features/proposal_spec.rb b/spec/features/proposal_spec.rb index 38b8c415..43f4a5f2 100644 --- a/spec/features/proposal_spec.rb +++ b/spec/features/proposal_spec.rb @@ -67,26 +67,60 @@ feature Event do event_role: 'submitter')] end - scenario 'submits a valid proposal', feature: true, js: true do + scenario 'not signed_in user submits proposal' do + expected_count_event = Event.count + 1 + expected_count_user = User.count + 1 + + visit new_conference_proposal_path(conference.short_title) + + fill_in 'user_username', with: 'Test User' + fill_in 'user_email', with: 'testuser@osem.io' + fill_in 'password_inline', with: 'testuserpassword' + fill_in 'user_password_confirmation', with: 'testuserpassword' + + fill_in 'event_title', with: 'Example Proposal' + select('Example Event Type', from: 'event[event_type_id]') + fill_in 'event_abstract', with: 'Lorem ipsum abstract' + + click_button 'Create Proposal' + expect(flash).to eq('Proposal was successfully submitted.') + + expect(Event.count).to eq(expected_count_event) + expect(User.count).to eq(expected_count_user) + end + + scenario 'update a proposal' do + proposal = create(:event) + + sign_in proposal.submitter + + visit edit_conference_proposal_path(proposal.conference.short_title, proposal) + + fill_in 'event_subtitle', with: 'My event subtitle' + select('Easy', from: 'event[difficulty_level_id]') + + click_button 'Update Proposal' + expect(flash).to eq('Proposal was successfully updated.') + end + + scenario 'signed_in user submits a valid proposal', feature: true, js: true do sign_in participant_without_bio expected_count = Event.count + 1 visit conference_proposal_index_path(conference.short_title) click_link 'New Proposal' fill_in 'event_title', with: 'Example Proposal' - fill_in 'event_subtitle', with: 'Example Proposal Subtitle' select('Example Event Type', from: 'event[event_type_id]') fill_in 'event_abstract', with: 'Lorem ipsum abstract' + click_link 'description_link' fill_in 'event_description', with: 'Lorem ipsum description' - fill_in 'user_biography', with: 'Lorem ipsum biography' + click_button 'Create Proposal' + expect(flash).to eq('Proposal was successfully submitted.') - click_button 'Create Event' - expect(flash).to eq('Event was successfully submitted. You should register for the conference now.') - - expect(current_path).to eq(new_conference_conference_registrations_path(conference.short_title)) + expect(current_path).to eq(conference_proposal_index_path(conference.short_title)) expect(Event.count).to eq(expected_count) end @@ -94,7 +128,7 @@ feature Event do sign_in participant visit conference_proposal_index_path(conference.short_title) expect(page.has_content?('Example Proposal')).to be true - expect(page.has_content?('Unconfirmed')).to be true + expect(@event.state).to eq('unconfirmed') click_link "confirm_proposal_#{@event.id}" expect(flash). to eq('The proposal was confirmed. Please register to attend the conference.') @@ -107,7 +141,6 @@ feature Event do @event.confirm! visit conference_proposal_index_path(conference.short_title) expect(page.has_content?('Example Proposal')).to be true - expect(page.has_content?('Confirmed')).to be true click_link "delete_proposal_#{@event.id}" expect(flash).to eq('Proposal was successfully withdrawn.') @event.reload diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index acfacf5b..b3859748 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -43,6 +43,9 @@ describe 'User' do it{ should be_able_to(:show, Registration.new)} it{ should_not be_able_to(:manage, registration)} + it{ should be_able_to(:create, Event)} + it{ should be_able_to(:show, Event.new)} + it{ should_not be_able_to(:manage, :any)} end