Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactored ConferencesController#calendar: separated calendar event c… #3101

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 13 additions & 33 deletions app/controllers/conferences_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,42 +68,22 @@ def show
end

def calendar
i_calendar = Icalendar::Calendar.new

respond_to do |format|
format.ics do
calendar = Icalendar::Calendar.new
Conference.all.each do |conf|
if params[:full]
event_schedules = conf.program.selected_event_schedules(
includes: [{ event: %i[event_type speakers submitter] }]
)
calendar = icalendar_proposals(calendar, event_schedules.map(&:event), conf)
else
calendar.event do |e|
e.dtstart = conf.start_date
e.dtstart.ical_params = { 'VALUE'=>'DATE' }
e.dtend = conf.end_date
e.dtend.ical_params = { 'VALUE'=>'DATE' }
e.duration = "P#{(conf.end_date - conf.start_date + 1).floor}D"
e.created = conf.created_at
e.last_modified = conf.updated_at
e.summary = conf.title
e.description = conf.description
e.uid = conf.guid
e.url = conference_url(conf.short_title)
v = conf.venue
if v
e.geo = v.latitude, v.longitude if v.latitude && v.longitude
location = ''
location += "#{v.street}, " if v.street
location += "#{v.postalcode} #{v.city}, " if v.postalcode && v.city
location += v.country_name if v.country_name
e.location = location if location
end
end
end
Conference.all.each do |conference|
conference_url = conference_url(conference.short_title)
Conference::Calendar::EventBuilder.call(
conference: conference,
conference_url: conference_url,
calendar: i_calendar,
is_full_calendar: params[:full]
)
end
calendar.publish
render inline: calendar.to_ical

i_calendar.publish
render inline: i_calendar.to_ical
end
end
end
Expand Down
67 changes: 67 additions & 0 deletions app/services/conference/calendar/event_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
class Conference::Calendar::EventBuilder
include ConferenceHelper

def self.call(conference:, is_full_calendar:, calendar:, conference_url:)
new(conference:, is_full_calendar:, calendar:, conference_url:).call
end

def initialize(conference:, is_full_calendar:, calendar:, conference_url:)
@calendar = calendar
@conference_url = conference_url
@conference = conference
@is_full_calendar = is_full_calendar
@venue = conference.venue
end

def call
return build_full_calendar if is_full_calendar

build_not_full_calendar
end

private
attr :conference, :is_full_calendar, :calendar, :conference_url, :venue

def build_full_calendar
event_schedules = conference.program.selected_event_schedules(
includes: [{ event: %i[event_type speakers submitter] }]
)
icalendar_proposals(calendar, event_schedules.map(&:event), conference)
end

def build_not_full_calendar
calendar.event do |event|
build_event_general_informations(event)
build_event_venue(event) if venue
end
calendar
end

def build_event_general_informations(event)
event.dtstart = conference.start_date
event.dtstart.ical_params = { 'VALUE'=>'DATE' }
event.dtend = conference.end_date
event.dtend.ical_params = { 'VALUE'=>'DATE' }
event.duration = "P#{(conference.end_date - conference.start_date + 1).floor}D"
event.created = conference.created_at
event.last_modified = conference.updated_at
event.summary = conference.title
event.description = conference.description
event.uid = conference.guid
event.url = conference_url
end

def build_event_venue(event)
event.geo = venue.latitude, venue.longitude if venue.latitude && venue.longitude
location = build_venue_location
event.location = location if location
end

def build_venue_location
location = ''
location += "#{venue.street}, " if venue.street
location += "#{venue.postalcode} #{venue.city}, " if venue.postalcode && venue.city
location += venue.country_name if venue.country_name
location
end
end
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@

get '/admin' => redirect('/admin/conferences')

get '/calendar' => 'conferences#calendar'
get '/calendar' => 'conferences#calendar', action: :calendar

if ENV.fetch('OSEM_ROOT_CONFERENCE', nil)
root to: redirect("/conferences/#{ENV.fetch('OSEM_ROOT_CONFERENCE')}")
Expand Down
40 changes: 40 additions & 0 deletions spec/controllers/conferences_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,44 @@
end
end

describe 'GET#calendar' do
let(:i_calendar) do
instance_double(Icalendar::Calendar, publish: true, to_ical: true)
end
let!(:conference) { create(:conference) }
let(:params) { { full: double(:full), format: :ics } }
let(:user) { create :user, is_admin: true }

setup do
user.update!(is_admin: true)

sign_in user

allow(Conference::Calendar::EventBuilder)
.to receive(:call)

allow(Icalendar::Calendar)
.to receive(:new)
.and_return(i_calendar)
end

it 'calls Conference::Calendar::EventBuilder with correct params' do
expect(Conference::Calendar::EventBuilder)
.to receive(:call)
.with(
conference: conference,
conference_url: conference_url(conference.short_title),
calendar: i_calendar,
is_full_calendar: params[:full].to_s
)

get :calendar, params: params
end

it 'calls calendar#publish' do
expect(i_calendar).to receive(:publish)

get :calendar, params: params
end
end
end
64 changes: 64 additions & 0 deletions spec/services/conference/calendar/event_builder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

require 'spec_helper'

describe Conference::Calendar::EventBuilder, type: :serializer do
describe '.call' do
let(:conference_url) { 'www.sample.com' }
let!(:calendar) { Icalendar::Calendar.new }
let(:conference) { create :full_conference }

context 'when is a full calendar' do
let(:proposals_calendar) { double(:proposals_calendar) }

setup do
allow_any_instance_of(ConferenceHelper)
.to receive(:icalendar_proposals)
.and_return(proposals_calendar)
end

it 'returns icalendar_proposals' do
result = described_class.call(
conference: conference,
calendar: calendar,
is_full_calendar: true,
conference_url: conference_url
)

expect(result).to eq(proposals_calendar)
end
end

context 'when is a not full calendar' do
let(:venue) { conference.venue }
setup do
venue.update(latitude: '-100', longitude:'-200')
end

it 'set callendar params' do
calendar = Icalendar::Calendar.new
described_class.call(
conference: conference,
calendar: calendar,
is_full_calendar: false,
conference_url: conference_url
)
event = calendar.events.first

expect(event.location).to eq("#{venue.street}, #{venue.postalcode} #{venue.city}, #{venue.country_name}")
expect(event.dtstart).to eq(conference.start_date)
expect(event.dtstart.ical_params).to eq({ 'VALUE'=>'DATE' })
expect(event.dtend).to eq(conference.end_date)
expect(event.dtend.ical_params).to eq({ 'VALUE'=>'DATE' })
expect(event.duration.present?).to eq(true)
expect(event.created).to eq(conference.created_at)
expect(event.last_modified).to eq(conference.updated_at)
expect(event.summary).to eq(conference.title)
expect(event.description).to eq(conference.description)
expect(event.uid).to eq(conference.guid)
expect(event.url.value_ical).to eq(conference_url)
expect(event.geo).to eq([conference.venue.latitude.to_f, conference.venue.longitude.to_f])
end
end
end
end