From 2a3f69b813b2b8ba86e16ed32a8f93bff0b9dc07 Mon Sep 17 00:00:00 2001 From: rebuilt Date: Tue, 23 May 2023 20:13:19 -0700 Subject: [PATCH] The overall response rate is artifically lower because we are including the number of all the students at the school, not just the number of students that took the survey. Updated the overall response rate presenter to return the count of only the grades that took the student survey. --- app/presenters/response_rate_presenter.rb | 27 +++- .../response_rate_presenter_spec.rb | 130 +++++++++++++++--- 2 files changed, 135 insertions(+), 22 deletions(-) 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