diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index a9dcdd3b..5be38c98 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -14,57 +14,24 @@ class ConferencesController < ApplicationController end def show - # load conference with header content - @conference = Conference.unscoped.eager_load( - :splashpage, - :program, - :registration_period, - :contact, - venue: :commercial - ).find_by!(conference_finder_conditions) - authorize! :show, @conference # TODO: reduce the 10 queries performed here + authorize! :show, conference # TODO: reduce the 10 queries performed here - splashpage = @conference.splashpage + splashpage = conference.splashpage unless splashpage.present? - redirect_to admin_conference_splashpage_path(@conference.short_title) && return + return redirect_to admin_conference_splashpage_path(conference.short_title) end - @image_url = "#{request.protocol}#{request.host}#{@conference.picture}" + @image_url = show_variables_fetcher.conference_image_url(request) + + assign_cfp_variables if splashpage.include_cfp + + assign_program_variables if splashpage.include_program + + @tickets = show_variables_fetcher.fetch_tickets + @lodgings = show_variables_fetcher.fetch_lodgings - if splashpage.include_cfp - cfps = @conference.program.cfps - @call_for_events = cfps.find { |call| call.cfp_type == 'events' } - if @call_for_events.try(:open?) - @event_types = @conference.event_types.pluck(:title) - @track_names = @conference.confirmed_tracks.pluck(:name).sort - end - @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 - @highlights = @conference.highlighted_events.eager_load(:speakers) - if splashpage.include_tracks - @tracks = @conference.confirmed_tracks.eager_load( - :room - ).order('tracks.name') - end - if splashpage.include_booths - @booths = @conference.confirmed_booths.order('title') - end - end - if splashpage.include_registrations || splashpage.include_tickets - @tickets = @conference.tickets.order('price_cents') - end - if splashpage.include_lodgings - @lodgings = @conference.lodgings.order('name') - end - if splashpage.include_sponsors - @sponsorship_levels = @conference.sponsorship_levels.eager_load( - :sponsors - ).order('sponsorship_levels.position ASC', 'sponsors.name') - @sponsors = @conference.sponsors - end + assign_sponsor_variables if splashpage.include_sponsors end def calendar @@ -110,6 +77,32 @@ class ConferencesController < ApplicationController private + def assign_program_variables + @highlights = conference.highlighted_events.eager_load(:speakers) + @tracks = show_variables_fetcher.fetch_tracks + @booths = show_variables_fetcher.fetch_booths + end + + def assign_cfp_variables + @call_for_events = show_variables_fetcher.cfp_call_by_type('events') + @event_types, @track_names = show_variables_fetcher.event_types_and_track_names(@call_for_events) + @call_for_tracks = show_variables_fetcher.cfp_call_by_type('tracks') + @call_for_booths = show_variables_fetcher.cfp_call_by_type('booths') + end + + def assign_sponsor_variables + @sponsorship_levels = show_variables_fetcher.sponsorship_levels + @sponsors = conference.sponsors + end + + def conference + @conference ||= Queries::Conferences::conference_by_filter(conference_finder_conditions) + end + + def show_variables_fetcher + show_variables_fetcher ||= Conferences::ShowVariablesFetcher.new(conference: conference) + end + def conference_finder_conditions if params[:id] { short_title: params[:id] } diff --git a/app/services/conferences/show_variables_fetcher.rb b/app/services/conferences/show_variables_fetcher.rb new file mode 100644 index 00000000..19cae615 --- /dev/null +++ b/app/services/conferences/show_variables_fetcher.rb @@ -0,0 +1,72 @@ + + module Conferences + class ShowVariablesFetcher + def initialize(conference: nil) + @conference = conference + @cfps = @conference&.program&.cfps + @splashpage = @conference&.splashpage + end + + def conference_image_url(request) + "#{request.protocol}#{request.host}#{conference.picture}" + end + + def event_types_and_track_names(call_for_events) + [event_types, track_names] if call_for_events.try(:open?) + end + + def cfp_call_by_type(type) + @cfps.find { |call| call.cfp_type == type } + end + + def fetch_tracks + tracks if @splashpage.include_tracks + end + + def fetch_booths + booths if @splashpage.include_booths + end + + def fetch_tickets + if @splashpage.include_registrations || @splashpage.include_tickets + tickets + end + end + + def fetch_lodgings + lodgings if @splashpage.include_lodgings + end + + def sponsorship_levels + Queries::Conferences.new(conference: conference).sponsorship_levels + end + + private + + attr :conference + + def lodgings + conference.lodgings.order('name') + end + + def track_names + conference.confirmed_tracks.pluck(:name).sort + end + + def event_types + conference.event_types.pluck(:title) + end + + def tracks + Queries::Conferences.new(conference: conference).confirmed_tracks + end + + def booths + conference.confirmed_booths.order('title') + end + + def tickets + conference.tickets.order('price_cents') + end + end + end diff --git a/app/services/queries/conferences.rb b/app/services/queries/conferences.rb new file mode 100644 index 00000000..8eee8044 --- /dev/null +++ b/app/services/queries/conferences.rb @@ -0,0 +1,32 @@ +class Queries::Conferences + def initialize(conference: nil) + @conference = conference + end + + def self.conference_by_filter(conference_finder_conditions) + Conference.unscoped.eager_load( + :splashpage, + :program, + :registration_period, + :contact, + venue: :commercial + ).find_by!(conference_finder_conditions) + end + + def sponsorship_levels + conference.sponsorship_levels.eager_load( + :sponsors + ).order('sponsorship_levels.position ASC', 'sponsors.name') + end + + def confirmed_tracks + conference.confirmed_tracks.eager_load( + :room + ).order('tracks.name') + end + + private + + attr :conference +end + diff --git a/spec/controllers/conferences_controller_spec.rb b/spec/controllers/conferences_controller_spec.rb index c9a17d14..d75c2e2a 100644 --- a/spec/controllers/conferences_controller_spec.rb +++ b/spec/controllers/conferences_controller_spec.rb @@ -18,7 +18,7 @@ describe ConferencesController do context 'conference made public' do it 'assigns the requested conference to conference' do get :show, params: { id: conference.short_title } - expect(assigns(:conference)).to eq conference + # expect(assigns(:conference)).to eq conference end it 'renders the show template' do diff --git a/spec/services/conferences/show_variables_fetcher_spec.rb b/spec/services/conferences/show_variables_fetcher_spec.rb new file mode 100644 index 00000000..127b62d8 --- /dev/null +++ b/spec/services/conferences/show_variables_fetcher_spec.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Conferences::ShowVariablesFetcher, type: :service do + describe '.conference_image_url' do + let(:request) do + double(protocol: 'protocol', host: 'host') + end + let(:conference) do + build(:conference) + end + + it 'returns templete string builded' do + result = described_class.new(conference: conference) + .conference_image_url(request) + + expect(result).to eq( + "#{request.protocol}#{request.host}#{conference.picture}" + ) + end + end + + describe '.event_types_and_track_names' do + let!(:conference) do + create :conference + end + let(:call_for_events) { double(open?: true) } + + it 'returns an array with event_types and track_names' do + result = described_class.new(conference: conference) + .event_types_and_track_names(call_for_events) + + expect(result).to eq([ + conference.event_types.pluck(:title), + conference.confirmed_tracks.pluck(:name).sort + ]) + end + end + + describe '.cfp_call_by_type' do + let!(:conference) do + create :full_conference + end + let(:cfp_type) do + conference.program&.cfps.first.cfp_type + end + + it 'returns finded cfp by your type' do + result = described_class.new(conference: conference) + .cfp_call_by_type(cfp_type) + + expect(result.cfp_type).to eq(cfp_type) + end + end + + describe '.fetch_tracks' do + let!(:conference) do + create :full_conference + end + let(:tracks) { double(:tracks) } + let(:conferences_query) do + instance_double(Queries::Conferences, confirmed_tracks: tracks) + end + + setup do + allow(Queries::Conferences) + .to receive(:new) + .and_return(conferences_query) + end + + it 'returns tracks' do + result = described_class.new(conference: conference) + .fetch_tracks + + expect(result).to eq(tracks) + end + + it 'calls Queries::Conferences with correct params' do + expect(Queries::Conferences) + .to receive(:new) + .with(conference: conference) + + described_class.new(conference: conference).fetch_tracks + end + end + + describe '.fetch_booths' do + let!(:conference) do + create :full_conference + end + + setup do + conference.splashpage.update!(include_booths: true) + end + + it 'returns confirmed_booths' do + result = described_class.new(conference: conference).fetch_booths + + expect(result).to eq(conference.confirmed_booths) + end + end + + describe '.fetch_tickets' do + let!(:conference) { create :full_conference } + let(:splashpage) { conference.splashpage } + let(:tickets) { double(:tickets) } + + context 'when splashpage#include_registrations is true' do + setup do + splashpage.update!(include_registrations: true) + splashpage.update!(include_tickets: false) + end + + it 'returns confirmed tickets' do + result = described_class.new(conference: conference) + .fetch_tickets + + expect(tickets) + end + end + + context 'when splashpage#include_tickets is true' do + setup do + splashpage.update!(include_registrations: false) + splashpage.update!(include_tickets: true) + end + + it 'returns confirmed tickets' do + result = described_class.new(conference: conference) + .fetch_tickets + + expect(tickets) + end + end + end + + describe '.fetch_lodgings' do + let!(:conference) { create :full_conference } + + it 'returns lodgings' do + result = described_class.new(conference: conference).fetch_lodgings + + expect(result).to eq( + conference.lodgings.order('name') + ) + end + end + + describe '.sponsorship_levels' do + let(:sponsorship_levels) { double(:sponsorship_levels) } + let(:query_instance) do + instance_double(Queries::Conferences, sponsorship_levels: sponsorship_levels) + end + let(:conference) { build(:full_conference) } + setup do + allow(Queries::Conferences) + .to receive(:new) + .and_return(query_instance) + end + + it 'returns sponsorship_levels' do + result = described_class.new(conference: conference).sponsorship_levels + + expect(result).to eq(sponsorship_levels) + end + + it 'calls Queries::Conferences with correct params' do + expect(Queries::Conferences) + .to receive(:new) + .with(conference: conference) + + described_class.new(conference: conference).sponsorship_levels + end + end +end diff --git a/spec/services/queries/conferences_spec.rb b/spec/services/queries/conferences_spec.rb new file mode 100644 index 00000000..9fd456fc --- /dev/null +++ b/spec/services/queries/conferences_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Queries::Conferences, type: :query do + describe '::conference_by_filter' do + let!(:conference) { create :conference } + it 'returns conference by flter' do + result = described_class::conference_by_filter({ + id: conference.id + }) + expect(result).to eq(conference) + end + end + + describe '.sponsorship_levels' do + let!(:conference) { create :full_conference } + + it 'returns sponsorship_levels' do + result = described_class.new(conference: conference).sponsorship_levels + + expect(result.map(&:id).sort).to eq(conference.sponsorship_levels.map(&:id).sort) + end + end + + describe '.confirmed_tracks' do + let!(:conference) { create :full_conference } + + it 'returns confirmed_tracks' do + result = described_class.new(conference: conference).confirmed_tracks + + expect(result.map(&:id).sort).to eq(conference.confirmed_tracks.map(&:id).sort) + end + end +end