feat: Round up response rate. Survey response rates above 24.5 will now meet sufficiency

pull/1/head
rebuilt 2 years ago
parent b58ff3e519
commit 6edc0db868

@ -18,7 +18,7 @@ class ResponseRateCalculator
return 0 unless total_possible_responses.positive? return 0 unless total_possible_responses.positive?
cap_at_one_hundred(raw_response_rate) cap_at_one_hundred(raw_response_rate).round
end end
def meets_student_threshold? def meets_student_threshold?

@ -29,7 +29,7 @@ describe ResponseRateCalculator, type: :model do
context "or when the count of survey items does not meet the minimum threshold" do context "or when the count of survey items does not meet the minimum threshold" do
before do before do
create_list(:survey_item_response, 9, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 9, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
it "returns an average of the response rates for all grades" do it "returns an average of the response rates for all grades" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 0 expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 0
@ -41,25 +41,25 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20)
create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
context "and half of students responded" do context "and half of students responded" do
it "reports a response rate of fifty percent" do it "reports a response rate of fifty percent" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, expect(StudentResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 50 academic_year:).rate).to eq 50
end end
end end
context "and another unrelated subcategory has responses" do context "and another unrelated subcategory has responses" do
before do before do
create_list(:survey_item_response, 10, create_list(:survey_item_response, 10,
survey_item: second_subcategory.measures.first.scales.first.survey_items.first, academic_year:, school:, grade: 1) survey_item: second_subcategory.measures.first.scales.first.survey_items.first, academic_year:, school:, grade: 1)
end end
it "does not count the responses for the unrelated subcategory" do it "does not count the responses for the unrelated subcategory" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, expect(StudentResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 50 academic_year:).rate).to eq 50
end end
end end
@ -67,7 +67,7 @@ describe ResponseRateCalculator, type: :model do
before do before do
less_than_a_quarter_of_respondents_for_first_grade = 4 less_than_a_quarter_of_respondents_for_first_grade = 4
create_list(:survey_item_response, less_than_a_quarter_of_respondents_for_first_grade, survey_item: insufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, less_than_a_quarter_of_respondents_for_first_grade, survey_item: insufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
it "returns an average of the response rates for all grades" do it "returns an average of the response rates for all grades" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 50 expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 50
@ -79,20 +79,20 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20)
create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_2, academic_year:, create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_2, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
xcontext "and the response rate is a decimal number" do context "and the response rate is a decimal number" do
before do before do
create_list(:survey_item_response, 1, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 1, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
it "rounds the response rate to the nearest whole number" do it "rounds the response rate to the nearest whole number" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, expect(StudentResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 78 academic_year:).rate).to eq 78
end end
end end
@ -105,7 +105,7 @@ describe ResponseRateCalculator, type: :model do
context "and another unrelated subcategory has responses" do context "and another unrelated subcategory has responses" do
before do before do
create_list(:survey_item_response, 10, create_list(:survey_item_response, 10,
survey_item: second_subcategory.measures.first.scales.first.survey_items.first, academic_year:, school:, grade: 1) survey_item: second_subcategory.measures.first.scales.first.survey_items.first, academic_year:, school:, grade: 1)
end end
it "does not count the responses for the unrelated subcategory" do it "does not count the responses for the unrelated subcategory" do
@ -118,11 +118,11 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20)
create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:, create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:,
school:, grade: 1) school:, grade: 1)
create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_3, academic_year:, create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_3, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
context "one scale got all students to respond and another scale got an average response rate of fifty percent" do context "one scale got all students to respond and another scale got an average response rate of fifty percent" do
@ -135,7 +135,7 @@ describe ResponseRateCalculator, type: :model do
context "and another unrelated subcategory has responses" do context "and another unrelated subcategory has responses" do
before do before do
create_list(:survey_item_response, 10, create_list(:survey_item_response, 10,
survey_item: second_subcategory.measures.first.scales.first.survey_items.first, academic_year:, school:, grade: 1) survey_item: second_subcategory.measures.first.scales.first.survey_items.first, academic_year:, school:, grade: 1)
end end
it "does not count the responses for the unrelated subcategory" do it "does not count the responses for the unrelated subcategory" do
@ -148,9 +148,9 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20)
create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 2) school:, grade: 2)
end end
it "reports a response rate that averages fifty and 100" do it "reports a response rate that averages fifty and 100" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 75 expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 75
@ -161,9 +161,9 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20)
create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_2, academic_year:, create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_2, academic_year:,
school:, grade: 2) school:, grade: 2)
end end
it "reports a response rate that averages fifty and 100" do it "reports a response rate that averages fifty and 100" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 75 expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 75
@ -171,33 +171,33 @@ describe ResponseRateCalculator, type: :model do
end end
end end
xcontext "when two grades have different numbers of students" do context "when two grades have different numbers of students" do
before do before do
create(:respondent, school:, academic_year:, total_students: 60, one: 40, two: 20) create(:respondent, school:, academic_year:, total_students: 60, one: 40, two: 20)
create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) # 50% school:, grade: 1) # 50%
create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:, create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:,
school:, grade: 2) # 75% school:, grade: 2) # 75%
end end
it "weights the average response rate by the number of students in each grade" do it "weights the average response rate by the number of students in each grade" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, expect(StudentResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to be_within(0.01).of(58) academic_year:).rate).to be_within(0.01).of(58)
end end
end end
xcontext "when three grades have different numbers of students" do context "when three grades have different numbers of students" do
before do before do
create(:respondent, school:, academic_year:, total_students: 120, one: 40, two: 20, three: 60) create(:respondent, school:, academic_year:, total_students: 120, one: 40, two: 20, three: 60)
create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 20, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) # 50% school:, grade: 1) # 50%
create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:, create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:,
school:, grade: 2) # 75% school:, grade: 2) # 75%
create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:, create_list(:survey_item_response, 15, survey_item: sufficient_student_survey_item_2, academic_year:,
school:, grade: 3) # 25% school:, grade: 3) # 25%
end end
it "weights the average response rate by the number of students in each grade" do it "weights the average response rate by the number of students in each grade" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, expect(StudentResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to be_within(0.01).of(42) academic_year:).rate).to be_within(0.01).of(42)
end end
end end
@ -205,7 +205,7 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20)
create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:, create_list(:survey_item_response, 10, survey_item: sufficient_student_survey_item_1, academic_year:,
school:, grade: 1) school:, grade: 1)
end end
it "reports a response rate that averages fifty and 100" do it "reports a response rate that averages fifty and 100" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 50 expect(StudentResponseRateCalculator.new(subcategory:, school:, academic_year:).rate).to eq 50
@ -217,11 +217,11 @@ describe ResponseRateCalculator, type: :model do
before do before do
create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20) create(:respondent, school:, academic_year:, total_students: 20, one: 20, two: 20)
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD * 11, survey_item: sufficient_student_survey_item_2, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD * 11, survey_item: sufficient_student_survey_item_2,
academic_year:, school:, likert_score: 1, grade: 1) academic_year:, school:, likert_score: 1, grade: 1)
end end
it "returns 100 percent" do it "returns 100 percent" do
expect(StudentResponseRateCalculator.new(subcategory:, school:, expect(StudentResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 100 academic_year:).rate).to eq 100
end end
end end
@ -247,11 +247,11 @@ describe ResponseRateCalculator, type: :model do
before :each do before :each do
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item_1, create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item_1,
academic_year:, school:, likert_score: 1) academic_year:, school:, likert_score: 1)
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item_2, create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item_2,
academic_year:, school:, likert_score: 1) academic_year:, school:, likert_score: 1)
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: sufficient_student_survey_item_1, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: sufficient_student_survey_item_1,
academic_year:, school:, likert_score: 4) academic_year:, school:, likert_score: 4)
end end
context "when the average number of teacher responses per question in a subcategory is at the threshold" do context "when the average number of teacher responses per question in a subcategory is at the threshold" do
@ -260,7 +260,7 @@ describe ResponseRateCalculator, type: :model do
end end
it "returns 25 percent" do it "returns 25 percent" do
expect(TeacherResponseRateCalculator.new(subcategory:, school:, expect(TeacherResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 25 academic_year:).rate).to eq 25
end end
end end
@ -268,11 +268,11 @@ describe ResponseRateCalculator, type: :model do
before do before do
respondent respondent
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD + 1, survey_item: sufficient_teacher_survey_item_3, create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD + 1, survey_item: sufficient_teacher_survey_item_3,
academic_year:, school:, likert_score: 1) academic_year:, school:, likert_score: 1)
end end
it "it will return the nearest whole number" do it "it will return the nearest whole number" do
expect(TeacherResponseRateCalculator.new(subcategory:, school:, expect(TeacherResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 29 academic_year:).rate).to eq 29
end end
end end
@ -280,18 +280,18 @@ describe ResponseRateCalculator, type: :model do
before do before do
respondent respondent
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD * 11, survey_item: sufficient_teacher_survey_item_3, create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD * 11, survey_item: sufficient_teacher_survey_item_3,
academic_year:, school:, likert_score: 1) academic_year:, school:, likert_score: 1)
end end
it "returns 100 percent" do it "returns 100 percent" do
expect(TeacherResponseRateCalculator.new(subcategory:, school:, expect(TeacherResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 100 academic_year:).rate).to eq 100
end end
end end
context "when no survey information exists for that school and academic_year" do context "when no survey information exists for that school and academic_year" do
it "returns 100 percent" do it "returns 100 percent" do
expect(TeacherResponseRateCalculator.new(subcategory:, school:, expect(TeacherResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 100 academic_year:).rate).to eq 100
end end
end end
@ -303,7 +303,7 @@ describe ResponseRateCalculator, type: :model do
end end
it "ignores the empty survey item and returns only the average response rate of teacher survey items with responses" do it "ignores the empty survey item and returns only the average response rate of teacher survey items with responses" do
expect(TeacherResponseRateCalculator.new(subcategory:, school:, expect(TeacherResponseRateCalculator.new(subcategory:, school:,
academic_year:).rate).to eq 25 academic_year:).rate).to eq 25
end end
end end
end end

Loading…
Cancel
Save