diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 35e6b709..529d9fb4 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -40,7 +40,7 @@ class ConferencesController < ApplicationController @image_url = "#{request.protocol}#{request.host}#{@conference.picture}" - if splashpage.include_cfp + if splashpage.include_cfp? cfps = @conference.program.cfps @call_for_events = cfps.find { |call| call.cfp_type == 'events' } if @call_for_events.try(:open?) @@ -50,31 +50,27 @@ class ConferencesController < ApplicationController @call_for_tracks = cfps.find { |call| call.cfp_type == 'tracks' } @call_for_booths = cfps.find { |call| call.cfp_type == 'booths' } end - if splashpage.include_program + if splashpage.include_program? @highlights = @conference.highlighted_events.eager_load(:speakers) - if splashpage.include_tracks + if splashpage.include_tracks? @tracks = @conference.confirmed_tracks.eager_load( :room ).order('tracks.name') end - if splashpage.include_booths + if splashpage.include_booths? @booths = @conference.confirmed_booths.order('title') end - if splashpage.include_happening_now - events_schedules_list = get_happening_now_events_schedules(@conference) - @events_schedules_limit = EVENTS_PER_PAGE - @events_schedules_length = events_schedules_list.length - @pagy, @events_schedules = pagy_array(events_schedules_list, items: @events_schedules_limit, link_extra: 'data-remote="true"') - @happening_now_url = happening_now_conference_schedule_path(conference_id: @conference.short_title, format: :json) + if splashpage.include_happening_now? + load_happening_now end end - if splashpage.include_registrations || splashpage.include_tickets + if splashpage.include_registrations? || splashpage.include_tickets? @tickets = @conference.tickets.visible.order('price_cents') end - if splashpage.include_lodgings + if splashpage.include_lodgings? @lodgings = @conference.lodgings.order('id') end - if splashpage.include_sponsors + if splashpage.include_sponsors? @sponsorship_levels = @conference.sponsorship_levels.eager_load( :sponsors ).order('sponsorship_levels.position ASC', 'sponsors.name') @@ -151,4 +147,16 @@ class ConferencesController < ApplicationController def current_user_has_unpaid_tickets? current_user && current_user_tickets.unpaid.any? end + + def load_happening_now + events_schedules_list = get_happening_now_events_schedules(@conference) + @is_happening_next = false + if events_schedules_list.empty? + events_schedules_list = get_happening_next_events_schedules(@conference) + @is_happening_next = true + end + @events_schedules_limit = EVENTS_PER_PAGE + @events_schedules_length = events_schedules_list.length + @pagy, @events_schedules = pagy_array(events_schedules_list, items: @events_schedules_limit, link_extra: 'data-remote="true"') + end end diff --git a/app/helpers/conference_helper.rb b/app/helpers/conference_helper.rb index cf2c06ce..29db24d4 100644 --- a/app/helpers/conference_helper.rb +++ b/app/helpers/conference_helper.rb @@ -79,10 +79,30 @@ module ConferenceHelper end def get_happening_now_events_schedules(conference) - events_schedules = conference.program.selected_event_schedules( - includes: [:room, { event: %i[track event_type speakers submitter] }] - ).select(&:happening_now?) + events_schedules = filter_events_schedules(conference, :happening_now?) events_schedules ||= [] events_schedules end + + def get_happening_next_events_schedules(conference) + events_schedules = filter_events_schedules(conference, :happening_later?) + + if events_schedules.empty? + return [] + end + + # events_schedules have been sorted by start_time in selected_event_schedules + happening_next_time = events_schedules[0].start_time + events_schedules = events_schedules.select { |s| s.start_time == happening_next_time } + + events_schedules + end + + private + + def filter_events_schedules(conference, filter) + conference.program.selected_event_schedules( + includes: [:room, { event: %i[track event_type speakers submitter] }] + ).select(&filter) + end end diff --git a/app/models/event_schedule.rb b/app/models/event_schedule.rb index 036a89f2..f8a41d64 100644 --- a/app/models/event_schedule.rb +++ b/app/models/event_schedule.rb @@ -70,6 +70,14 @@ class EventSchedule < ApplicationRecord event_time_range.overlaps?(now_range) end + def happening_later? + # TODO: Save start_time with local timezone info when making an event schedule + in_tz_start = start_time.in_time_zone(timezone) + in_tz_start -= in_tz_start.utc_offset + + in_tz_start >= Time.now + end + def self.withdrawn_or_canceled_event_schedules(schedule_ids) EventSchedule .unscoped diff --git a/app/views/admin/emails/_help.html.haml b/app/views/admin/emails/_help.html.haml index 371bac7b..9de1e0f8 100644 --- a/app/views/admin/emails/_help.html.haml +++ b/app/views/admin/emails/_help.html.haml @@ -51,7 +51,7 @@ - if @conference.program.schedule_public %td {schedule_link} %td The link to complete schedule of the conference - - if @conference.splashpage && @conference.splashpage.public + - if @conference.splashpage && @conference.splashpage.public? %tr %td {conference_splash_link} %td The link to conference splash page diff --git a/app/views/admin/splashpages/show.html.haml b/app/views/admin/splashpages/show.html.haml index 08edb140..e3732b89 100644 --- a/app/views/admin/splashpages/show.html.haml +++ b/app/views/admin/splashpages/show.html.haml @@ -49,7 +49,7 @@ %i{ class: "fa-li #{icon_for_todo @splashpage.include_social_media?}" } Display social media links %li - - if @conference.splashpage && @conference.splashpage.public + - if @conference.splashpage && @conference.splashpage.public? %i{ class: "fa-li #{icon_for_todo @splashpage.public?}" } %text-muted.publicorprivate Public - else diff --git a/app/views/conferences/_about_and_happening_now.haml b/app/views/conferences/_about_and_happening_now.haml index c048b28d..ead36206 100644 --- a/app/views/conferences/_about_and_happening_now.haml +++ b/app/views/conferences/_about_and_happening_now.haml @@ -3,7 +3,8 @@ = render 'happening_now', conference: conference, events_schedules: events_schedules, pagy: pagy, events_schedules_length: events_schedules_length, - events_schedules_limit: events_schedules_limit + events_schedules_limit: events_schedules_limit, + is_happening_next: is_happening_next = content_for :about do #about diff --git a/app/views/conferences/_happening_now.haml b/app/views/conferences/_happening_now.haml index 66355a82..563a4b4f 100644 --- a/app/views/conferences/_happening_now.haml +++ b/app/views/conferences/_happening_now.haml @@ -1,7 +1,11 @@ - if conference.splashpage.include_program && conference.splashpage.include_happening_now - if events_schedules.any? .row - %h2.text-center{ style: 'margin-bottom:30px' } Happening Now + %h2.text-center{ style: 'margin-bottom:30px' } + - if is_happening_next + Happening Next + - else + Happening Now - events_schedules.each do |event_schedule| = render 'schedules/event', conference: conference, event_schedule: event_schedule, event: event_schedule.event, is_brief: true - if events_schedules_length > events_schedules_limit @@ -9,4 +13,4 @@ != pagy_bootstrap_nav_js(pagy) - else .row - %h3.text-center There are no events happening now. + %h3.text-center There are no events scheduled yet. diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml index 3a73c0b0..ed642f34 100644 --- a/app/views/conferences/show.html.haml +++ b/app/views/conferences/show.html.haml @@ -49,21 +49,22 @@ = render 'about_and_happening_now', conference: @conference, events_schedules: @events_schedules, pagy: @pagy, events_schedules_length: @events_schedules_length, - events_schedules_limit: @events_schedules_limit + events_schedules_limit: @events_schedules_limit, + is_happening_next: @is_happening_next -# calls for content, or program - - if @conference.splashpage.include_cfp + - if @conference.splashpage.include_cfp? = render 'call_for_content', conference: @conference, call_for_events: @call_for_events, call_for_tracks: @call_for_tracks, call_for_booths: @call_for_booths, event_types: @event_types, tracks: @track_names - - if @conference.splashpage.include_program + - if @conference.splashpage.include_program? = render 'program', conference: @conference, tracks: @tracks, highlights: @highlights, booths: @booths -# attendance/registration - - if @conference.splashpage.include_registrations + - if @conference.splashpage.include_registrations? - if @conference.registration_open? = render 'registration', conference: @conference, registration_period: @conference.registration_period, @@ -72,20 +73,20 @@ = render 'tickets', conference: @conference, tickets: @tickets -# geo - - if @conference.splashpage.include_venue && @conference.venue + - if @conference.splashpage.include_venue? && @conference.venue = render 'venue', conference: @conference, venue: @conference.venue, commercial: @conference.venue.commercial - if @conference.splashpage.include_lodgings && @conference.lodgings.any? = render 'lodging', venue: @conference.venue, lodgings: @lodgings -# sponsorship - - if @conference.splashpage.include_sponsors + - if @conference.splashpage.include_sponsors? = render 'sponsors', conference: @conference, sponsorship_levels: @sponsorship_levels, sponsors: @sponsors -# footer - - if @conference.splashpage.include_social_media + - if @conference.splashpage.include_social_media? - if @conference.contact.has_social_media? = render 'social_media', contact: @conference.contact = render 'footer' diff --git a/lib/tasks/demo_data_for_development.rake b/lib/tasks/demo_data_for_development.rake index d54f8cfb..026f3e20 100644 --- a/lib/tasks/demo_data_for_development.rake +++ b/lib/tasks/demo_data_for_development.rake @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'webmock' + namespace :data do desc 'Create demo data for our local development' include FactoryBot::Syntax::Methods diff --git a/spec/features/splashpage_spec.rb b/spec/features/splashpage_spec.rb index 69e1c6ae..7b9b8866 100644 --- a/spec/features/splashpage_spec.rb +++ b/spec/features/splashpage_spec.rb @@ -80,4 +80,88 @@ feature Splashpage do end end end + + context 'happening now section', feature: true, js: true do + let!(:conference2) { create(:full_conference, start_date: 1.day.ago, end_date: 7.days.from_now, start_hour: 0, end_hour: 24) } + let!(:program) { conference2.program } + let!(:selected_schedule) { create(:schedule, program: program) } + let!(:splashpage) { create(:full_splashpage, conference: conference2, public: true)} + + let!(:scheduled_event1) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed', abstract: '`markdown`') + end + let!(:scheduled_event2) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:scheduled_event3) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:scheduled_event4) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:current_time) { Time.now.in_time_zone(conference2.timezone) } + + before :each do + sign_in participant + end + + scenario 'displays \'There are no events scheduled yet.\' if nothing is happening now and next' do + visit conference_path(conference2.short_title) + happening_now = page.find('#happening-now') + expect(happening_now).to have_content('There are no events scheduled yet.') + end + + scenario 'shows all events happening next if nothing is happening now' do + event_schedule1 = create(:event_schedule, event: scheduled_event1, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule2 = create(:event_schedule, event: scheduled_event2, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) + visit conference_path(conference2.short_title) + happening_now = page.find('#happening-now') + expect(happening_now).to have_content(event_schedule1.event.title) + expect(happening_now).to have_content(event_schedule2.event.title) + end + + scenario 'only shows all events happening now if something is happening now and next' do + event_schedule1 = create(:event_schedule, event: scheduled_event1, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule2 = create(:event_schedule, event: scheduled_event2, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule3 = create(:event_schedule, event: scheduled_event3, schedule: selected_schedule, start_time: current_time.strftime('%a, %d %b %Y %H:%M:%S')) + visit conference_path(conference2.short_title) + happening_now = page.find('#happening-now') + expect(happening_now).to have_content(event_schedule3.event.title) + expect(happening_now).not_to have_content(event_schedule1.event.title) + expect(happening_now).not_to have_content(event_schedule2.event.title) + end + + scenario 'only shows events happening at the earliest time, not at a later time in the future' do + event_schedule1 = create(:event_schedule, event: scheduled_event1, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule2 = create(:event_schedule, event: scheduled_event2, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule3 = create(:event_schedule, event: scheduled_event3, schedule: selected_schedule, start_time: (current_time + 2.hours).strftime('%a, %d %b %Y %H:%M:%S')) + visit conference_path(conference2.short_title) + happening_now = page.find('#happening-now') + expect(happening_now).to have_content(event_schedule1.event.title) + expect(happening_now).to have_content(event_schedule2.event.title) + expect(happening_now).not_to have_content(event_schedule3.event.title) + end + + scenario 'only shows 3 events happening now because of pagination' do + event_schedule1 = create(:event_schedule, event: scheduled_event1, schedule: selected_schedule, start_time: current_time.strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule2 = create(:event_schedule, event: scheduled_event2, schedule: selected_schedule, start_time: current_time.strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule3 = create(:event_schedule, event: scheduled_event3, schedule: selected_schedule, start_time: current_time.strftime('%a, %d %b %Y %H:%M:%S')) + event_schedule4 = create(:event_schedule, event: scheduled_event4, schedule: selected_schedule, start_time: current_time.strftime('%a, %d %b %Y %H:%M:%S')) + + visit conference_path(conference2.short_title) + happening_now = page.find('#happening-now') + expect(happening_now).to have_content(event_schedule1.event.title) + expect(happening_now).to have_content(event_schedule2.event.title) + expect(happening_now).to have_content(event_schedule3.event.title) + expect(happening_now).not_to have_content(event_schedule4.event.title) + + visit conference_path(conference2.short_title, page: 2) + happening_now = page.find('#happening-now') + expect(happening_now).to have_content(event_schedule4.event.title) + end + end end diff --git a/spec/helpers/conference_helper_spec.rb b/spec/helpers/conference_helper_spec.rb index 4ea48496..5065411f 100644 --- a/spec/helpers/conference_helper_spec.rb +++ b/spec/helpers/conference_helper_spec.rb @@ -99,4 +99,39 @@ describe ConferenceHelper, type: :helper do expect(conference_color(conference2)).to eq('#0B3559') end end + + describe '#get_happening_next_events_schedules' do + let!(:conference2) { create(:full_conference, start_date: 1.day.ago, end_date: 7.days.from_now, start_hour: 0, end_hour: 24) } + let!(:program) { conference2.program } + let!(:selected_schedule) { create(:schedule, program: program) } + let!(:scheduled_event1) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed', abstract: '`markdown`') + end + let!(:current_time) { Time.now.in_time_zone(conference2.timezone) } + let!(:event_schedule1) { create(:event_schedule, event: scheduled_event1, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) } + let!(:scheduled_event2) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:event_schedule2) { create(:event_schedule, event: scheduled_event2, schedule: selected_schedule, start_time: (current_time + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) } + let!(:scheduled_event3) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:event_schedule3) { create(:event_schedule, event: scheduled_event3, schedule: selected_schedule, start_time: (current_time - 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) } + let!(:scheduled_event4) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:event_schedule4) { create(:event_schedule, event: scheduled_event4, schedule: selected_schedule, start_time: (current_time + 2.hours).strftime('%a, %d %b %Y %H:%M:%S')) } + + it 'returns all the events happening at the earliest time in the future but not later or in the past' do + events_schedules = get_happening_next_events_schedules(conference2) + expect(events_schedules).to include(event_schedule1) + expect(events_schedules).to include(event_schedule2) + expect(events_schedules).to_not include(event_schedule3) + expect(events_schedules).to_not include(event_schedule4) + end + end end diff --git a/spec/models/event_schedule_spec.rb b/spec/models/event_schedule_spec.rb index b160cf15..26cb5dff 100644 --- a/spec/models/event_schedule_spec.rb +++ b/spec/models/event_schedule_spec.rb @@ -165,4 +165,31 @@ describe EventSchedule do end end end + + describe 'happening_later' do + let!(:conference2) { create(:full_conference, start_date: 1.day.ago, end_date: 7.days.from_now, start_hour: 0, end_hour: 24) } + let!(:program) { conference2.program } + let!(:selected_schedule) { create(:schedule, program: program) } + let!(:scheduled_event1) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed', abstract: '`markdown`') + end + let!(:event_schedule1) { create(:event_schedule, event: scheduled_event1, schedule: selected_schedule, start_time: (Time.now.in_time_zone(conference2.timezone) + 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) } + let!(:scheduled_event2) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:event_schedule2) { create(:event_schedule, event: scheduled_event2, schedule: selected_schedule, start_time: (Time.now.in_time_zone(conference2.timezone) + 2.hour).strftime('%a, %d %b %Y %H:%M:%S')) } + let!(:scheduled_event3) do + program.update_attributes!(selected_schedule: selected_schedule) + create(:event, program: program, state: 'confirmed') + end + let!(:event_schedule3) { create(:event_schedule, event: scheduled_event3, schedule: selected_schedule, start_time: (Time.now.in_time_zone(conference2.timezone) - 1.hour).strftime('%a, %d %b %Y %H:%M:%S')) } + + it 'returns true if the event is happening in the future' do + expect(event_schedule1.happening_later?).to be true + expect(event_schedule2.happening_later?).to be true + expect(event_schedule3.happening_later?).to be false + end + end end