refactored ConferencesController#calendar: separated calendar event creation into an specific service
This commit is contained in:
parent
6e276b2787
commit
69c06b4229
6 changed files with 249 additions and 34 deletions
|
|
@ -68,42 +68,22 @@ class ConferencesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def calendar
|
def calendar
|
||||||
|
i_calendar = Icalendar::Calendar.new
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.ics do
|
format.ics do
|
||||||
calendar = Icalendar::Calendar.new
|
Conference.all.each do |conference|
|
||||||
Conference.all.each do |conf|
|
conference_url = conference_url(conference.short_title)
|
||||||
if params[:full]
|
Conference::Calendar::EventBuilder.call(
|
||||||
event_schedules = conf.program.selected_event_schedules(
|
conference: conference,
|
||||||
includes: [{ event: %i[event_type speakers submitter] }]
|
conference_url: conference_url,
|
||||||
)
|
calendar: i_calendar,
|
||||||
calendar = icalendar_proposals(calendar, event_schedules.map(&:event), conf)
|
is_full_calendar: params[:full]
|
||||||
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
|
|
||||||
end
|
end
|
||||||
calendar.publish
|
|
||||||
render inline: calendar.to_ical
|
i_calendar.publish
|
||||||
|
render inline: i_calendar.to_ical
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
64
app/services/conference/calendar.rb
Normal file
64
app/services/conference/calendar.rb
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
class Conferences::Calendar
|
||||||
|
private_class_method :new
|
||||||
|
|
||||||
|
def self.call(conference:, is_full_calendar:)
|
||||||
|
new(conference, is_full_calendar).call
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(conference:, is_full_calendar:)
|
||||||
|
@calendar = Icalendar::Calendar.new
|
||||||
|
@conference = conference
|
||||||
|
@is_full_calendar = is_full_calendar
|
||||||
|
end
|
||||||
|
|
||||||
|
def not_full_calendar
|
||||||
|
calendar.event do |e|
|
||||||
|
default_calendar_params(e)
|
||||||
|
if @conference.venue
|
||||||
|
venue_calendar_params(e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
calendar
|
||||||
|
end
|
||||||
|
|
||||||
|
def full_calendar
|
||||||
|
icalendar_proposals(@calendar, event_schedules.map(&:event), @conference)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def default_calendar_params(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(@conference.short_title)
|
||||||
|
end
|
||||||
|
|
||||||
|
def venue_calendar_params(event)
|
||||||
|
venue = @conference.venue
|
||||||
|
event.geo = venue.latitude, venue.longitude if venue.latitude && venue.longitude
|
||||||
|
location = location(venue)
|
||||||
|
event.location = location if location
|
||||||
|
end
|
||||||
|
|
||||||
|
def location(venue)
|
||||||
|
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
|
||||||
|
|
||||||
|
def event_schedules
|
||||||
|
@conference.program.selected_event_schedules(
|
||||||
|
includes: [{ event: %i[event_type speakers submitter] }]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
67
app/services/conference/calendar/event_builder.rb
Normal file
67
app/services/conference/calendar/event_builder.rb
Normal file
|
|
@ -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
|
||||||
|
|
@ -215,7 +215,7 @@ Osem::Application.routes.draw do
|
||||||
|
|
||||||
get '/admin' => redirect('/admin/conferences')
|
get '/admin' => redirect('/admin/conferences')
|
||||||
|
|
||||||
get '/calendar' => 'conferences#calendar'
|
get '/calendar' => 'conferences#calendar', action: :calendar
|
||||||
|
|
||||||
if ENV.fetch('OSEM_ROOT_CONFERENCE', nil)
|
if ENV.fetch('OSEM_ROOT_CONFERENCE', nil)
|
||||||
root to: redirect("/conferences/#{ENV.fetch('OSEM_ROOT_CONFERENCE')}")
|
root to: redirect("/conferences/#{ENV.fetch('OSEM_ROOT_CONFERENCE')}")
|
||||||
|
|
|
||||||
|
|
@ -49,4 +49,44 @@ describe ConferencesController do
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
||||||
64
spec/services/conference/calendar/event_builder_spec.rb
Normal file
64
spec/services/conference/calendar/event_builder_spec.rb
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue