From b3efbdeb339463adf65d4fad771f935051228b9d 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 22f85699..9e18f9d2 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 d3eb94d7..525fa794 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