diff --git a/app/presenters/response_rate_presenter.rb b/app/presenters/response_rate_presenter.rb index a8f45d63..0b25a79e 100644 --- a/app/presenters/response_rate_presenter.rb +++ b/app/presenters/response_rate_presenter.rb @@ -14,6 +14,8 @@ class ResponseRatePresenter end def percentage + return 0 if respondents_count.zero? + cap_at_100(actual_count.to_f / respondents_count.to_f * 100).round end @@ -33,9 +35,30 @@ class ResponseRatePresenter end def respondents_count - respondents = Respondent.find_by(school:, academic_year:) - count = respondents.total_students if focus == :student + return 0 if respondents.nil? + + count = enrollment if focus == :student count = respondents.total_teachers if focus == :teacher count end + + def enrollment + SurveyItemResponse.where(school:, academic_year:, grade: grades, + survey_item: SurveyItem.student_survey_items) + .select(:grade) + .distinct + .pluck(:grade) + .reject(&:nil?) + .map do |grade| + respondents.counts_by_grade[grade] + end.sum.to_f + end + + def respondents + Respondent.find_by(school:, academic_year:) + end + + def grades + respondents.counts_by_grade.keys + end end diff --git a/spec/presenters/response_rate_presenter_spec.rb b/spec/presenters/response_rate_presenter_spec.rb index 12ac726c..b467ffa7 100644 --- a/spec/presenters/response_rate_presenter_spec.rb +++ b/spec/presenters/response_rate_presenter_spec.rb @@ -45,8 +45,8 @@ describe ResponseRatePresenter do end it 'ignores all teacher items and only gets the modified date of the last student item' do - rdate = ResponseRatePresenter.new(focus: :student, academic_year:, school:).date - expect(rdate).to eq(newest_student_survey_response.updated_at) + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).date + expect(percentage).to eq(newest_student_survey_response.updated_at) end end context 'when focus is teacher' do @@ -58,8 +58,8 @@ describe ResponseRatePresenter do end it 'ignores all student responses and only gets the modified date of the last teacher item' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).date - expect(rdate).to eq(newest_teacher_survey_response.updated_at) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).date + expect(percentage).to eq(newest_teacher_survey_response.updated_at) end end end @@ -71,8 +71,8 @@ describe ResponseRatePresenter do end context 'when no survey responses are found for a school' do it 'returns a response rate of 0' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage - expect(rdate).to eq(0) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage + expect(percentage).to eq(0) end end @@ -83,8 +83,8 @@ describe ResponseRatePresenter do end it 'returns a response rate of 100' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage - expect(rdate).to eq(100) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage + expect(percentage).to eq(100) end end @@ -95,8 +95,8 @@ describe ResponseRatePresenter do end it 'returns a response rate of 100' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage - expect(rdate).to eq(100) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage + expect(percentage).to eq(100) end end @@ -107,8 +107,8 @@ describe ResponseRatePresenter do end it 'returns a response rate of 75' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage - expect(rdate).to eq(75) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage + expect(percentage).to eq(75) end end context 'when one quarter of the teachers responded to the survey' do @@ -118,8 +118,8 @@ describe ResponseRatePresenter do end it 'returns a response rate of 25' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage - expect(rdate).to eq(25) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage + expect(percentage).to eq(25) end end context 'When the percentage is not a round number' do @@ -129,8 +129,8 @@ describe ResponseRatePresenter do end it 'its rounded to the nearest integer' do - rdate = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage - expect(rdate).to eq(23) + percentage = ResponseRatePresenter.new(focus: :teacher, academic_year:, school:).percentage + expect(percentage).to eq(23) end end @@ -141,8 +141,8 @@ describe ResponseRatePresenter do end it 'returns a response rate of 100' do - rdate = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage - expect(rdate).to eq(100) + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(100) end end context 'when half of all students responded' do @@ -152,8 +152,98 @@ describe ResponseRatePresenter do end it 'returns a response rate of 50' do - rdate = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage - expect(rdate).to eq(50) + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(50) + end + end + + context 'when only a subset of grades was given the survey' do + before :each do + respondents.one = 20 + respondents.two = 20 + respondents.three = 20 + respondents.four = 20 + respondents.five = 20 + respondents.save + end + context 'and only first grade was given the survey' do + context 'and all the first grade responded' do + before :each do + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 1) + end + it 'returns a response rate of 100' do + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(100) + end + end + + context 'and half of first grade responded' do + before :each do + create_list(:survey_item_response, 10, school:, academic_year:, + survey_item: student_survey_item, grade: 1) + end + it 'returns a response rate of 50' do + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(50) + end + end + end + + context 'and two grades responded' do + context 'and both grades responded fully' do + before :each do + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 1) + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 2) + end + it 'returns a response rate of 100' do + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(100) + end + end + context 'and half of first grade responded' do + before :each do + create_list(:survey_item_response, 10, school:, academic_year:, + survey_item: student_survey_item, grade: 1) + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 2) + end + it 'returns a response rate of 75' do + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(75) + end + end + context 'and a quarter of first grade responded' do + before :each do + create_list(:survey_item_response, 5, school:, academic_year:, + survey_item: student_survey_item, grade: 1) + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 2) + end + it 'returns a response rate of 63 (rounded up from 62.5)' do + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(63) + end + end + end + + context 'and three grades responded' do + context 'and all three grades responded fully' do + before :each do + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 1) + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 2) + create_list(:survey_item_response, 20, school:, academic_year:, + survey_item: student_survey_item, grade: 3) + end + it 'returns a response rate of 100' do + percentage = ResponseRatePresenter.new(focus: :student, academic_year:, school:).percentage + expect(percentage).to eq(100) + end + end end end end