From cfa9613a8d750bacdffccc2f5b951208ee7f4127 Mon Sep 17 00:00:00 2001 From: Morgan Roderick Date: Wed, 6 May 2026 12:15:35 +0200 Subject: [PATCH] fix: workshop capacity checks now properly compare attending count with available spaces PR #2605 changed the capacity check methods from student_spaces?/ coach_spaces? to event_student_spaces?/event_coach_spaces?, but the new methods in EventPresenter called model.student_spaces? which just checks if the attribute is present (truthy), not if spaces are actually available. This fix adds proper event_student_spaces? and event_coach_spaces? methods to WorkshopPresenter that correctly compare the number of attending students/coaches with the available spaces from the workshop model (using model.student_spaces and model.coach_spaces). This ensures that: - When 2 students attend a workshop with 2 spaces, event_student_spaces? returns false (correctly indicating the workshop is full) - When 1 student attends a workshop with 2 spaces, event_student_spaces? returns true (correctly indicating space is available) Fixes the bug where workshops showed as full even when spaces were available, and vice versa. --- app/presenters/workshop_presenter.rb | 8 ++ .../workshop_presenter_capacity_spec.rb | 75 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 spec/presenters/workshop_presenter_capacity_spec.rb diff --git a/app/presenters/workshop_presenter.rb b/app/presenters/workshop_presenter.rb index 84fecaa6d..ee4509171 100644 --- a/app/presenters/workshop_presenter.rb +++ b/app/presenters/workshop_presenter.rb @@ -74,6 +74,14 @@ def student_spaces venue.seats end + def event_student_spaces? + model.student_spaces > attending_students.length + end + + def event_coach_spaces? + model.coach_spaces > attending_coaches.length + end + def pairing_csv pairing_details = model.attendances.inject([PAIRING_HEADINGS]) do |content, invitation| member = MemberPresenter.new(invitation.member) diff --git a/spec/presenters/workshop_presenter_capacity_spec.rb b/spec/presenters/workshop_presenter_capacity_spec.rb new file mode 100644 index 000000000..6ba0e52ff --- /dev/null +++ b/spec/presenters/workshop_presenter_capacity_spec.rb @@ -0,0 +1,75 @@ +require 'rails_helper' + +RSpec.describe 'WorkshopPresenter capacity checks', type: :model do + describe '#event_student_spaces?' do + let(:workshop) { Fabricate(:workshop, student_count: 2, coach_count: 2) } + let(:presenter) { WorkshopPresenter.new(workshop) } + + context 'when workshop is at capacity' do + before do + # Create 2 attending students (at capacity) + 2.times do + member = Fabricate(:member) + Fabricate(:workshop_invitation, workshop: workshop, member: member, role: 'Student', attending: true) + end + end + + it 'returns false when no spaces are available' do + expect(workshop.attending_students.count).to eq(2) + expect(workshop.student_spaces).to eq(2) + expect(presenter.event_student_spaces?).to eq(false), + "Expected event_student_spaces? to be false when at capacity (2/2), but got true" + end + end + + context 'when workshop has available spaces' do + before do + # Create 1 attending student (below capacity) + member = Fabricate(:member) + Fabricate(:workshop_invitation, workshop: workshop, member: member, role: 'Student', attending: true) + end + + it 'returns true when spaces are available' do + expect(workshop.attending_students.count).to eq(1) + expect(workshop.student_spaces).to eq(2) + expect(presenter.event_student_spaces?).to eq(true), + "Expected event_student_spaces? to be true when spaces available (1/2), but got false" + end + end + end + + describe '#event_coach_spaces?' do + let(:workshop) { Fabricate(:workshop, student_count: 2, coach_count: 2) } + let(:presenter) { WorkshopPresenter.new(workshop) } + + context 'when workshop is at coach capacity' do + before do + # Create 2 attending coaches (at capacity) + 2.times do + member = Fabricate(:member) + Fabricate(:workshop_invitation, workshop: workshop, member: member, role: 'Coach', attending: true) + end + end + + it 'returns false when no coach spaces are available' do + expect(workshop.attending_coaches.count).to eq(2) + expect(presenter.event_coach_spaces?).to eq(false), + "Expected event_coach_spaces? to be false when at capacity (2/2), but got true" + end + end + + context 'when workshop has available coach spaces' do + before do + # Create 1 attending coach (below capacity) + member = Fabricate(:member) + Fabricate(:workshop_invitation, workshop: workshop, member: member, role: 'Coach', attending: true) + end + + it 'returns true when coach spaces are available' do + expect(workshop.attending_coaches.count).to eq(1) + expect(presenter.event_coach_spaces?).to eq(true), + "Expected event_coach_spaces? to be true when spaces available (1/2), but got false" + end + end + end +end