Make iCalendar feed routes return calendar data

Both iCalendar routes were unusable:

* `/conferences/.../schedule.ics` raised
  `NoMethodError: undefined method 'icalendar_proposals'` because the
  `ConferenceHelper#icalendar_proposals` helper isn't auto-included in
  controllers; the action crashed before rendering.

* `/calendar.ics` silently redirected to `/`. The controller goes
  through `load_and_authorize_resource`, which authorises `:calendar`
  on `Conference` and is rejected for anonymous visitors because no
  ability grants it — CanCan's `AccessDenied` rescue redirects to
  root.

The helper is invoked through the controller `helpers` proxy so it
works in both contexts, and the calendar action is opted out of
resource loading and explicitly marked as not requiring authorization
since it serves a public feed across conferences. The helper is also
hardened so that proposals missing a room, difficulty level, track,
event type or scheduled time produce a valid event instead of
crashing the whole feed.
This commit is contained in:
Asish Kumar 2026-05-14 11:02:49 +05:30
parent c8e6fabed1
commit c5e84221c2
5 changed files with 83 additions and 30 deletions

View file

@ -6,13 +6,13 @@ describe SchedulesController do
let(:conference) { create(:conference, splashpage: create(:splashpage, public: true), venue: create(:venue)) }
describe 'GET #show' do
before :each do
conference.program.update!(schedule_public: true)
create_pair(:event_scheduled, program: conference.program)
end
context 'XML' do
before :each do
conference.program.schedule_public = true
conference.program.save!
create(:event_scheduled, program: conference.program)
create(:event_scheduled, program: conference.program)
get :show, params: { conference_id: conference.short_title, format: :xml }
end
@ -26,5 +26,20 @@ describe SchedulesController do
expect(response).to be_successful
end
end
context 'iCalendar' do
before :each do
get :show, params: { conference_id: conference.short_title, format: :ics }
end
it 'has 200 status code' do
expect(response).to be_successful
end
it 'returns iCalendar data' do
expect(response.content_type).to start_with('text/calendar')
expect(response.body).to start_with('BEGIN:VCALENDAR')
end
end
end
end