Skip to content
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
31 changes: 31 additions & 0 deletions app/helpers/better_together/events_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@
module BetterTogether
# View helpers for events
module EventsHelper
# Returns a formatted time range for an event
# If only a start time is present, it is formatted by itself.
# If the event ends on the same day, the end time is shown without the date.
# Otherwise, both start and end are fully formatted.
def event_time_range(event, format: :event)
return unless event&.starts_at

start_time = l(event.starts_at, format: format)
return start_time unless event.ends_at

end_time = if event.starts_at.to_date == event.ends_at.to_date
l(event.ends_at, format: '%-I:%M %p')
else
l(event.ends_at, format: format)
end

"#{start_time} - #{end_time}"
end

# Builds a location string from the event's location and its associated address
def event_location(event)
location = event&.location
return unless location

parts = []
parts << location.name if location.respond_to?(:name) && location.name.present?
parts << location.location.to_s if location.respond_to?(:location) && location.location.present?

parts.compact.join(', ').presence
end

# Return hosts for an event that the current user is authorized to view.
# Keeps view markup small and centralizes the policy logic for testing.
def visible_event_hosts(event)
Expand Down
21 changes: 10 additions & 11 deletions app/views/better_together/events/_event.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
<%= cache event.cache_key_with_version do %>
<% if policy(event).show? %>
<%= render 'better_together/shared/card', entity: event do %>
<% if event.location&.name&.present? %>
<div class="event-location card-text text-muted mt-2">
<i class="fas fa-map-marker-alt me-2"></i> <%= event.location %>
</div>
<% end %>
<% if event.starts_at.present? %>
<div class="event-datetime card-text text-muted mt-2">
<i class="fas fa-calendar-alt me-2"></i> <%= l(event.starts_at, format: :short) %>
</div>
<% end %>
<% if (location = event_location(event)) %>
<div class="event-location card-text text-muted mt-2">
<i class="fas fa-map-marker-alt me-2"></i> <%= location %>
</div>
<% end %>
<% if (time_range = event_time_range(event, format: :short)) %>
<div class="event-datetime card-text text-muted mt-2">
<i class="fas fa-calendar-alt me-2"></i> <%= time_range %>
</div>
<% end %>
<div class="event-categories">
<%= categories_badge(event) %>
</div>
Expand All @@ -25,4 +25,3 @@
<% end %>
<% end %>
<% end %>

18 changes: 9 additions & 9 deletions app/views/better_together/events/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
<div class="row align-items-end">
<div class="col">
<h1 class="event-name mt-3"><%= @resource.name %></h1>
<% if @event.location&.name&.present? %>
<% if (location = event_location(@event)) %>
<div class="event-location card-text text-muted mt-2">
<i class="fas fa-map-marker-alt me-2"></i> <%= @event.location %>
<i class="fas fa-map-marker-alt me-2"></i> <%= location %>
</div>
<% end %>
<% if @event.starts_at.present? %>
<% if (time_range = event_time_range(@event)) %>
<div class="event-datetime card-text text-muted mt-2">
<i class="fas fa-calendar-alt me-2"></i> <%= l(@event.starts_at, format: :event) %>
<i class="fas fa-calendar-alt me-2"></i> <%= time_range %>
</div>
<% end %>
</div>
Expand Down Expand Up @@ -92,16 +92,16 @@
<div class="event-datetime card-text text-muted mt-2">
<i class="fas fa-eye me-2"></i> <%= @event.privacy.humanize %>
</div>
<% if @event.location&.name&.present? %>
<% if (location = event_location(@event)) %>
<div class="event-location card-text text-muted mt-2">
<i class="fas fa-map-marker-alt me-2"></i> <%= @event.location %>
<i class="fas fa-map-marker-alt me-2"></i> <%= location %>
</div>
<% end %>
<% if @event.starts_at.present? %>
<% if (time_range = event_time_range(@event)) %>
<div class="event-datetime card-text text-muted mt-2">
<i class="fas fa-calendar-alt me-2"></i> <%= l(@event.starts_at, format: :event) %>
<i class="fas fa-calendar-alt me-2"></i> <%= time_range %>
</div>
<% end %>
<% end %
<% if @event.registration_url.present? %>
<div class="event-datetime card-text text-muted mt-2">
<i class="fas fa-ticket me-2"></i> <%= link_to t('better_together.events.register'), @event.registration_url, target: '_blank', class: 'text-decoration-none' %>
Expand Down
55 changes: 55 additions & 0 deletions spec/helpers/better_together/events_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

require 'rails_helper'

module BetterTogether
RSpec.describe EventsHelper, type: :helper do
describe '#event_time_range' do
let(:start_time) { Time.zone.parse('2024-03-10 15:00') }
let(:event) { instance_double(Event, starts_at: start_time, ends_at: end_time) }

context 'when end time is on same day' do
let(:end_time) { Time.zone.parse('2024-03-10 17:00') }

it 'formats with end time only' do
expected = "#{I18n.l(start_time, format: :event)} - #{I18n.l(end_time, format: '%-I:%M %p')}"
expect(helper.event_time_range(event)).to eq(expected)
end
end

context 'when end time is on a different day' do
let(:end_time) { Time.zone.parse('2024-03-11 17:00') }

it 'formats both start and end times fully' do
expected = "#{I18n.l(start_time, format: :event)} - #{I18n.l(end_time, format: :event)}"
expect(helper.event_time_range(event)).to eq(expected)
end
end

context 'without an end time' do
let(:end_time) { nil }

it 'returns only the start time' do
expect(helper.event_time_range(event)).to eq(I18n.l(start_time, format: :event))
end
end
end

describe '#event_location' do
it 'combines name and location' do
locatable = instance_double(
Geography::LocatableLocation,
name: 'Town Hall',
location: 'Springfield'
)
event = instance_double(Event, location: locatable)

expect(helper.event_location(event)).to eq('Town Hall, Springfield')
end

it 'returns nil when no location is present' do
expect(helper.event_location(instance_double(Event, location: nil))).to be_nil
end
end
end
end
36 changes: 36 additions & 0 deletions spec/views/better_together/events/_event.html.erb_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'better_together/events/_event', type: :view do
it 'renders formatted location and time range' do
start_time = Time.zone.parse('2024-03-10 15:00')
end_time = Time.zone.parse('2024-03-10 17:00')
locatable = instance_double(
BetterTogether::Geography::LocatableLocation,
name: 'Town Hall',
location: 'Springfield'
)
event = instance_double(
BetterTogether::Event,
cache_key_with_version: 'events/1-20240310',
starts_at: start_time,
ends_at: end_time,
location: locatable
)

view.define_singleton_method(:categories_badge) { |*_args| '' }
allow(view).to receive(:render).with('better_together/shared/card', entity: event).and_yield
allow(view).to receive(:event_time_range).and_call_original
allow(view).to receive(:event_location).and_call_original

render partial: 'better_together/events/event', locals: { event: event }

expect(view).to have_received(:event_time_range).with(event, format: :short)
expect(view).to have_received(:event_location).with(event)

expect(rendered).to include('Town Hall, Springfield')
expected_time = "#{I18n.l(start_time, format: :event)} - #{I18n.l(end_time, format: '%-I:%M %p')}"
expect(rendered).to include(expected_time)
end
end
Loading