diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 52d5f5ca..11397297 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -180,6 +180,7 @@ linters: - "app/views/tracks/_form.html.haml" - "app/views/tracks/index.html.haml" - "app/views/tracks/show.html.haml" + - "app/views/conferences/_call_for_tracks.html.haml" # Offense count: 223 InstanceVariables: @@ -242,6 +243,8 @@ linters: - "app/views/schedules/_schedule_tabs.html.haml" - "app/views/admin/cfps/_events_cfp.html.haml" - "app/views/tracks/_form.html.haml" + - "app/views/admin/cfps/_tracks_cfp.html.haml" + - "app/views/conferences/_call_for_tracks.html.haml" # Offense count: 32 IdNames: @@ -261,6 +264,7 @@ linters: - "app/views/admin/users/show.html.haml" - "app/views/users/edit.html.haml" - "app/views/admin/cfps/_events_cfp.html.haml" + - "app/views/admin/cfps/_tracks_cfp.html.haml" # Offense count: 4 UnnecessaryInterpolation: diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0abf6088..fdef7b4a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -56,7 +56,7 @@ module ApplicationHelper end def tracks(conference) - all = conference.program.tracks.map {|t| t.name} + all = conference.program.tracks.map { |t| t.name if !t.self_organized? || t.confirmed? && t.cfp_active }.compact first = all[0...-1] last = all[-1] ts = '' diff --git a/app/models/ability.rb b/app/models/ability.rb index 0ebabfdc..e5dbd7e4 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -95,6 +95,14 @@ class Ability can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id) can [:destroy], Openid + + can [:new, :create], Track do |track| + track.new_record? && track.program.cfps.for_tracks.try(:open?) + end + + can [:index, :show, :edit, :update], Track do |track| + user == track.submitter + end end # Abilities for users with roles wandering around in non-admin views. diff --git a/app/models/cfp.rb b/app/models/cfp.rb index 97f276c9..44d8281b 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -1,9 +1,10 @@ # cannot delete program if there are events submitted class Cfp < ActiveRecord::Base - TYPES = %w(events booths).freeze + TYPES = %w(events booths tracks).freeze scope :for_events, (-> { find_by(cfp_type: 'events') }) + scope :for_tracks, (-> { find_by(cfp_type: 'tracks') }) has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id } belongs_to :program diff --git a/app/views/admin/cfps/_tracks_cfp.html.haml b/app/views/admin/cfps/_tracks_cfp.html.haml new file mode 100644 index 00000000..e381df96 --- /dev/null +++ b/app/views/admin/cfps/_tracks_cfp.html.haml @@ -0,0 +1,12 @@ +%dt + Start Date: +%dd#start_date + = @cfp.start_date.strftime('%A, %B %-d. %Y') +%dt + End Date: +%dd#end_date + = @cfp.end_date.strftime('%A, %B %-d. %Y') +%dt + Days Left: +%dd + = pluralize(@cfp.remaining_days, 'day') diff --git a/app/views/conferences/_call_for_tracks.html.haml b/app/views/conferences/_call_for_tracks.html.haml new file mode 100644 index 00000000..1abeb956 --- /dev/null +++ b/app/views/conferences/_call_for_tracks.html.haml @@ -0,0 +1,30 @@ += content_for :splash_nav do + %li + %a.smoothscroll{ href: '#callfortracks' } Call For Tracks + +.container + .row + .col-md-12.text-center + %h2 + Call for Tracks + %p.lead + We are ready to accept requests for tracks! + .row + .col-md-6.col-md-offset-3.col-sm-10.col-sm-offset-1 + %p + The submission period for track requests has begun + %em.notranslate + = @conference.program.cfps.for_tracks.start_date.strftime('%A, %B %-d. %Y') + and closes + %em.notranslate + = @conference.program.cfps.for_tracks.end_date.strftime('%A, %B %-d. %Y.') + - if @conference.program.cfps.for_tracks.try(:open?) + That means you have only + %b.notranslate= pluralize(@conference.program.cfps.for_tracks.remaining_days, 'day') + left! + - else + The submission period for track requests is closed. + .row + .col-md-12.text-center + %p.cta-button + = link_to "Submit your request for track", conference_program_tracks_path(@conference.short_title), class: 'btn btn-success btn-lg text-center' diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml index d5bafad4..e8ca2449 100644 --- a/app/views/conferences/_conference_details.html.haml +++ b/app/views/conferences/_conference_details.html.haml @@ -30,6 +30,10 @@ = link_to "Register", new_conference_conference_registration_path(conference.short_title), class: "btn btn-default", disabled: cannot?(:new, Registration.new(conference_id: conference.id)) - if cannot?(:new, Registration.new(conference_id: conference.id)) && conference.registration_limit_exceeded? Sorry, no places left + - if !current_user.nil? && current_user.tracks.where(program: conference.program).length > 0 + = link_to "My Track Requests", conference_program_tracks_path(conference.short_title), class: 'btn btn-default' + - elsif can? :new, conference.program.tracks.new + = link_to "Submit Track Request", new_conference_program_track_path(conference.short_title), class: 'btn btn-default' - if !current_user.nil? && current_user.proposal_count(conference) > 0 = link_to "My Proposals", conference_program_proposals_path(conference.short_title), class: 'btn btn-default' - elsif can? :new, conference.program.events.new diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml index fb488e22..edc72726 100644 --- a/app/views/conferences/show.html.haml +++ b/app/views/conferences/show.html.haml @@ -45,6 +45,10 @@ %section#program = render 'schedule_splashpage' + - if @conference.program.cfps.for_tracks.try(:open?) && @conference.splashpage.include_cfp + %section#callfortracks + = render 'call_for_tracks' + - if @conference.program.cfp_open? and @conference.splashpage.include_cfp %section#callforpapers = render 'call_for_paper' diff --git a/app/views/tracks/index.html.haml b/app/views/tracks/index.html.haml index d4670bf4..7e16304f 100644 --- a/app/views/tracks/index.html.haml +++ b/app/views/tracks/index.html.haml @@ -32,7 +32,7 @@ %span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"} = track.color %td - = track.state + = track.state.humanize %td = link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track), method: :get, class: 'btn btn-primary' diff --git a/app/views/tracks/show.html.haml b/app/views/tracks/show.html.haml index c08818eb..37c180ae 100644 --- a/app/views/tracks/show.html.haml +++ b/app/views/tracks/show.html.haml @@ -16,7 +16,7 @@ %dt State: %dd - = @track.state + = @track.state.humanize %dt Description %dd diff --git a/spec/features/cfp_ability_spec.rb b/spec/features/cfp_ability_spec.rb index d40a54a4..cd9fa3bd 100644 --- a/spec/features/cfp_ability_spec.rb +++ b/spec/features/cfp_ability_spec.rb @@ -64,29 +64,51 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) - # Both event and booth exists + # Event and booth cfps exist cfb = create(:cfp, cfp_type: 'booths', program: conference.program) visit new_admin_conference_program_cfp_path(conference.short_title) - expect(current_path).to eq root_path + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + # Event, booth, track cfps exist + cft = create(:cfp, cfp_type: 'tracks', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + + # Booth and track cfps exist conference.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) # Only booth exists + cft.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) visit edit_admin_conference_program_cfp_path(conference.short_title, cfb) expect(current_path). to eq(edit_admin_conference_program_cfp_path(conference.short_title, cfb)) + # No cfp exists cfb.destroy visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + # Only Tracks cfp exists + cft = create(:cfp, cfp_type: 'tracks', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) + + visit edit_admin_conference_program_cfp_path(conference.short_title, cft) + expect(current_path).to eq edit_admin_conference_program_cfp_path(conference.short_title, cft) + + # Event and track cfps exist + create(:cfp, cfp_type: 'events', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) + + cft.destroy! create(:event, program: conference.program) visit edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first) expect(current_path).to eq(edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first)) diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb index 274d345f..12fd038b 100644 --- a/spec/features/organization_admin_ability_spec.rb +++ b/spec/features/organization_admin_ability_spec.rb @@ -106,29 +106,51 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) - # Both event and booth exists + # Event and booth cfps exist cfb = create(:cfp, cfp_type: 'booths', program: conference.program) visit new_admin_conference_program_cfp_path(conference.short_title) - expect(current_path).to eq root_path + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + # Event, booth, track cfps exist + cft = create(:cfp, cfp_type: 'tracks', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + + # Booth and track cfps exist conference.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) # Only booth exists + cft.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) visit edit_admin_conference_program_cfp_path(conference.short_title, cfb) expect(current_path). to eq(edit_admin_conference_program_cfp_path(conference.short_title, cfb)) + # No cfp exists cfb.destroy visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + # Only Tracks cfp exists + cft = create(:cfp, cfp_type: 'tracks', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) + + visit edit_admin_conference_program_cfp_path(conference.short_title, cft) + expect(current_path).to eq edit_admin_conference_program_cfp_path(conference.short_title, cft) + + # Event and track cfps exist + create(:cfp, cfp_type: 'events', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) + + cft.destroy! visit admin_conference_program_events_path(conference.short_title) expect(current_path).to eq(admin_conference_program_events_path(conference.short_title)) diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 3ed6ee39..ef2b3744 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -112,29 +112,51 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) - # Both event and booth exists + # Event and booth cfps exist cfb = create(:cfp, cfp_type: 'booths', program: conference.program) visit new_admin_conference_program_cfp_path(conference.short_title) - expect(current_path).to eq root_path + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + # Event, booth, track cfps exist + cft = create(:cfp, cfp_type: 'tracks', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + + # Booth and track cfps exist conference.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) # Only booth exists + cft.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) visit edit_admin_conference_program_cfp_path(conference.short_title, cfb) expect(current_path). to eq(edit_admin_conference_program_cfp_path(conference.short_title, cfb)) + # No cfp exists cfb.destroy visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + # Only Tracks cfp exists + cft = create(:cfp, cfp_type: 'tracks', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) + + visit edit_admin_conference_program_cfp_path(conference.short_title, cft) + expect(current_path).to eq edit_admin_conference_program_cfp_path(conference.short_title, cft) + + # Event and track cfps exist + create(:cfp, cfp_type: 'events', program: conference.program) + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) + + cft.destroy! visit admin_conference_program_events_path(conference.short_title) expect(current_path).to eq(admin_conference_program_events_path(conference.short_title)) diff --git a/spec/models/program_spec.rb b/spec/models/program_spec.rb index d81e32bc..1c8eabd9 100644 --- a/spec/models/program_spec.rb +++ b/spec/models/program_spec.rb @@ -253,28 +253,34 @@ describe Program do end describe '#remaining_cfp_types' do - it 'returns an array with the types for which a cfp doesn\'t exist, when only the Event type does' do - expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + it 'returns an array without the \'events\' type, when the cfp for events exists' do create(:cfp, cfp_type: 'events', program: program) - expect(program.remaining_cfp_types).to eq(['booths']) + expect(program.remaining_cfp_types).to be_a Array + expect(program.remaining_cfp_types.include?('events')).to eq false end - it 'returns an array with the types for which a cfp doesn\'t exist, when only the Booth type does' do - expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + it 'returns an array without the \'booths\' type, when the cfp for booths exists' do create(:cfp, cfp_type: 'booths', program: program) - expect(program.remaining_cfp_types).to eq(['events']) + expect(program.remaining_cfp_types).to be_a Array + expect(program.remaining_cfp_types.include?('booths')).to eq false end - it 'returns an empty array when all the cfp types exist' do - expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + it 'returns an array without the \'tracks\' type, when the cfp for tracks exists' do + create(:cfp, cfp_type: 'tracks', program: program) + expect(program.remaining_cfp_types).to be_a Array + expect(program.remaining_cfp_types.include?('tracks')).to eq false + end + + it 'returns an empty array when cfps for all the types exist' do create(:cfp, cfp_type: 'events', program: program) create(:cfp, cfp_type: 'booths', program: program) + create(:cfp, cfp_type: 'tracks', program: program) expect(program.remaining_cfp_types).to eq([]) end - it 'returns all the possible cfp types when there is no existed cfp type' do + it 'returns all the possible cfp types when there is no cfp' do expect(program.remaining_cfp_types).to eq(Cfp::TYPES) - expect(program.remaining_cfp_types). to eq(%w[events booths]) + expect(program.remaining_cfp_types). to eq(%w[events booths tracks]) end end end