Move score computation into SurveyItemResponse

pull/1/head
Alex Basson 4 years ago
parent b4a6ae0bd7
commit 07b7561b55

@ -15,7 +15,6 @@ class DashboardController < SqmApplicationController
end end
private private
def measure_ids def measure_ids
@ -23,22 +22,8 @@ class DashboardController < SqmApplicationController
end end
def presenter_for_measure(measure) def presenter_for_measure(measure)
score = sufficient_data?(measure: measure) ? score(measure: measure) : nil score = SurveyItemResponse.score(measure: measure, school: school, academic_year: academic_year)
MeasureGraphRowPresenter.new(
measure: measure,
score: score
)
end
def sufficient_data?(measure:) MeasureGraphRowPresenter.new(measure: measure, score: score)
SurveyItemResponse.sufficient_data?(measure: measure, academic_year: academic_year, school: school)
end end
def score(measure:)
SurveyItemResponse.for_measure(measure)
.where(academic_year: academic_year, school: school)
.average(:likert_score)
end
end end

@ -8,17 +8,29 @@ class SurveyItemResponse < ActiveRecord::Base
scope :for_measures, ->(measures) { joins(:survey_item).where('survey_items.measure_id': measures.map(&:id)) } scope :for_measures, ->(measures) { joins(:survey_item).where('survey_items.measure_id': measures.map(&:id)) }
scope :for_measure, ->(measure) { joins(:survey_item).where('survey_items.measure_id': measure.id) } scope :for_measure, ->(measure) { joins(:survey_item).where('survey_items.measure_id': measure.id) }
scope :for_teacher_responses_for_measure, ->(measure) { for_measure(measure).where("survey_items.survey_item_id LIKE 't-%'") }
scope :for_student_responses_for_measure, ->(measure) { for_measure(measure).where("survey_items.survey_item_id LIKE 's-%'") }
def self.sufficient_data?(measure:, academic_year:, school:) def self.score(measure:, school:, academic_year:)
return nil unless SurveyItemResponse.sufficient_data?(measure: measure, school: school, academic_year: academic_year)
SurveyItemResponse.for_measure(measure)
.where(academic_year: academic_year, school: school)
.average(:likert_score)
end
private
def self.sufficient_data?(measure:, school:, academic_year:)
meets_teacher_threshold = true meets_teacher_threshold = true
meets_student_threshold = true meets_student_threshold = true
if measure.includes_teacher_survey_items? if measure.includes_teacher_survey_items?
meets_teacher_threshold = SurveyItemResponse.for_measure(measure).where("survey_items.survey_item_id LIKE 't-%'").where(academic_year: academic_year, school: school).count >= TEACHER_RESPONSE_THRESHOLD meets_teacher_threshold = SurveyItemResponse.for_teacher_responses_for_measure(measure).where(academic_year: academic_year, school: school).count >= TEACHER_RESPONSE_THRESHOLD
end end
if measure.includes_student_survey_items? if measure.includes_student_survey_items?
meets_student_threshold = SurveyItemResponse.for_measure(measure).where("survey_items.survey_item_id LIKE 's-%'").where(academic_year: academic_year, school: school).count >= STUDENT_RESPONSE_THRESHOLD meets_student_threshold = SurveyItemResponse.for_student_responses_for_measure(measure).where(academic_year: academic_year, school: school).count >= STUDENT_RESPONSE_THRESHOLD
end end
meets_teacher_threshold and meets_student_threshold meets_teacher_threshold and meets_student_threshold

@ -30,25 +30,33 @@ feature 'School dashboard', type: feature do
before :each do before :each do
survey_items_for_measure_1A_i.each do |survey_item| survey_items_for_measure_1A_i.each do |survey_item|
200.times do
SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
survey_item: survey_item, likert_score: 4 survey_item: survey_item, likert_score: 4
end end
end
survey_items_for_measure_2A_i.each do |survey_item| survey_items_for_measure_2A_i.each do |survey_item|
200.times do
SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
survey_item: survey_item, likert_score: 5 survey_item: survey_item, likert_score: 5
end end
end
survey_items_for_measure_4C_i.each do |survey_item| survey_items_for_measure_4C_i.each do |survey_item|
200.times do
SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
survey_item: survey_item, likert_score: 1 survey_item: survey_item, likert_score: 1
end end
end
survey_items_for_subcategory.each do |survey_item| survey_items_for_subcategory.each do |survey_item|
200.times do
SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
survey_item: survey_item, likert_score: 4 survey_item: survey_item, likert_score: 4
end end
end end
end
scenario 'User authentication fails' do scenario 'User authentication fails' do
page.driver.browser.basic_authorize('wrong username', 'wrong password') page.driver.browser.basic_authorize('wrong username', 'wrong password')

@ -1,7 +1,6 @@
require 'rails_helper' require 'rails_helper'
describe SurveyItemResponse, type: :model do describe SurveyItemResponse, type: :model do
describe '.sufficient_data?' do describe '.sufficient_data?' do
let(:measure) { create(:measure) } let(:measure) { create(:measure) }
let(:school) { create(:school) } let(:school) { create(:school) }
@ -9,16 +8,22 @@ describe SurveyItemResponse, type: :model do
context 'when the measure includes only teacher data' do context 'when the measure includes only teacher data' do
let(:teacher_survey_item_1) { create(:survey_item, survey_item_id: 't-question-1', measure: measure) } let(:teacher_survey_item_1) { create(:survey_item, survey_item_id: 't-question-1', measure: measure) }
let(:teacher_survey_item_2) { create(:survey_item, survey_item_id: 't-question-2', measure: measure) }
let(:teacher_survey_item_3) { create(:survey_item, survey_item_id: 't-question-3', measure: measure) }
context 'and there is sufficient teacher data' do context 'and there is sufficient teacher data' do
before :each do before :each do
SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do 4.times do
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school) create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 3)
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 5)
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 3)
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 5)
end end
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end end
it 'is truthy' do it 'returns the average of the likert scores of the survey items' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_truthy expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to eq 4
end end
end end
@ -29,24 +34,28 @@ describe SurveyItemResponse, type: :model do
end end
end end
it 'is falsey' do it 'returns nil' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to be_nil
end end
end end
end end
context 'when the measure includes only student data' do context 'when the measure includes only student data' do
let(:student_survey_item_1) { create(:survey_item, survey_item_id: 's-question-1', measure: measure) } let(:student_survey_item_1) { create(:survey_item, survey_item_id: 's-question-1', measure: measure) }
let(:student_survey_item_2) { create(:survey_item, survey_item_id: 's-question-2', measure: measure) }
context 'and there is sufficient student data' do context 'and there is sufficient student data' do
before :each do before :each do
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do (SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD/4).times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school) create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 1)
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 5)
create(:survey_item_response, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 1)
create(:survey_item_response, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 5)
end end
end end
it 'is truthy' do it 'returns the average of the likert scores of the survey items' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_truthy expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to eq 3
end end
end end
@ -57,8 +66,8 @@ describe SurveyItemResponse, type: :model do
end end
end end
it 'is falsey' do it 'returns nil' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to be_nil
end end
end end
end end
@ -70,15 +79,15 @@ describe SurveyItemResponse, type: :model do
context 'and there is sufficient teacher data and sufficient student data' do context 'and there is sufficient teacher data and sufficient student data' do
before :each do before :each do
SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school) create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 5)
end end
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school) create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 5)
end end
end end
it 'is truthy' do it 'returns the average of the likert scores of the survey items' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_truthy expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to eq 5
end end
end end
@ -92,8 +101,8 @@ describe SurveyItemResponse, type: :model do
end end
end end
it 'is falsey' do it 'returns nil' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to be_nil
end end
end end
@ -107,8 +116,8 @@ describe SurveyItemResponse, type: :model do
end end
end end
it 'is falsey' do it 'returns nil' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to be_nil
end end
end end
@ -122,8 +131,8 @@ describe SurveyItemResponse, type: :model do
end end
end end
it 'is falsey' do it 'returns nil' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey expect(SurveyItemResponse.score(measure: measure, school: school, academic_year: ay)).to be_nil
end end
end end
end end

Loading…
Cancel
Save