Show icon/explanation in measure accordion when a section has insufficient data

pull/1/head
Liam Morley 4 years ago
parent 75c3a1fccc
commit aa4ce86eaa

@ -21,6 +21,10 @@ $spacers: (
$font-family-base: 'Cabin', sans-serif; $font-family-base: 'Cabin', sans-serif;
$body-color: $black; $body-color: $black;
$alert-border-radius: 0.5rem;
$alert-color-scale: 0%;
$alert-border-width: 0;
$headings-font-family: 'Bitter', serif; $headings-font-family: 'Bitter', serif;
$headings-font-weight: 700; $headings-font-weight: 700;

@ -8,7 +8,7 @@ class DashboardController < SqmApplicationController
private private
def presenter_for_measure(measure) def presenter_for_measure(measure)
score = SurveyItemResponse.score_for_measure(measure: measure, school: @school, academic_year: @academic_year) score = SurveyItemResponse.score_for_measure(measure: measure, school: @school, academic_year: @academic_year).average
VarianceChartRowPresenter.new(measure: measure, score: score) VarianceChartRowPresenter.new(measure: measure, score: score)
end end

@ -14,39 +14,36 @@ class SurveyItemResponse < ActiveRecord::Base
.average(:likert_score) .average(:likert_score)
end end
def self.score_for_measure(measure:, school:, academic_year:) Score = Struct.new(:average, :meets_teacher_threshold?, :meets_student_threshold?)
survey_item_responses = for_measure_meeting_threshold(measure: measure, school: school, academic_year: academic_year)
unless survey_item_responses.nil?
survey_item_responses
.where(academic_year: academic_year, school: school)
.average(:likert_score)
end
end
def self.sufficient_data?(measure:, school:, academic_year:)
meets_teacher_threshold = teacher_sufficient_data?(measure: measure, school: school, academic_year: academic_year)
meets_student_threshold = student_sufficient_data?(measure: measure, school: school, academic_year: academic_year)
meets_teacher_threshold || meets_student_threshold
end
private
def self.for_measure_meeting_threshold(measure:, school:, academic_year:) def self.score_for_measure(measure:, school:, academic_year:)
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_all_thresholds = meets_teacher_threshold && meets_student_threshold meets_all_thresholds = meets_teacher_threshold && meets_student_threshold
if meets_all_thresholds survey_item_responses = if meets_all_thresholds
SurveyItemResponse.for_measure(measure) SurveyItemResponse.for_measure(measure)
elsif meets_teacher_threshold elsif meets_teacher_threshold
SurveyItemResponse.teacher_responses_for_measure(measure) SurveyItemResponse.teacher_responses_for_measure(measure)
elsif meets_student_threshold elsif meets_student_threshold
SurveyItemResponse.student_responses_for_measure(measure) SurveyItemResponse.student_responses_for_measure(measure)
end end
unless survey_item_responses.nil?
score_for_measure = survey_item_responses.average(:likert_score)
end end
Score.new(score_for_measure, meets_teacher_threshold, meets_student_threshold)
end
def self.sufficient_data?(measure:, school:, academic_year:)
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_teacher_threshold || meets_student_threshold
end
private
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_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 :teacher_responses_for_measure, ->(measure) { for_measure(measure).where("survey_items.survey_item_id LIKE 't-%'") } scope :teacher_responses_for_measure, ->(measure) { for_measure(measure).where("survey_items.survey_item_id LIKE 't-%'") }
@ -60,7 +57,7 @@ class SurveyItemResponse < ActiveRecord::Base
meets_student_threshold = average_number_of_survey_item_responses >= STUDENT_RESPONSE_THRESHOLD meets_student_threshold = average_number_of_survey_item_responses >= STUDENT_RESPONSE_THRESHOLD
end end
meets_student_threshold !!meets_student_threshold
end end
def self.teacher_sufficient_data?(measure:, school:, academic_year:) def self.teacher_sufficient_data?(measure:, school:, academic_year:)
@ -70,6 +67,6 @@ class SurveyItemResponse < ActiveRecord::Base
meets_teacher_threshold = average_number_of_survey_item_responses >= TEACHER_RESPONSE_THRESHOLD meets_teacher_threshold = average_number_of_survey_item_responses >= TEACHER_RESPONSE_THRESHOLD
end end
meets_teacher_threshold !!meets_teacher_threshold
end end
end end

@ -1,6 +1,6 @@
class AdminDataPresenter < DataItemPresenter class AdminDataPresenter < DataItemPresenter
def initialize(measure_id:, admin_data_items:) def initialize(measure_id:, admin_data_items:)
super(measure_id: measure_id) super(measure_id: measure_id, has_sufficient_data: true)
@admin_data_items = admin_data_items @admin_data_items = admin_data_items
end end

@ -1,9 +1,14 @@
class DataItemPresenter class DataItemPresenter
def initialize(measure_id:) def initialize(measure_id:, has_sufficient_data:)
@measure_id = measure_id @measure_id = measure_id
@has_sufficient_data = has_sufficient_data
end end
def data_item_accordion_id def data_item_accordion_id
"data-item-accordion-#{@measure_id}" "data-item-accordion-#{@measure_id}"
end end
def sufficient_data?
@has_sufficient_data
end
end end

@ -14,8 +14,7 @@ class MeasurePresenter
end end
def gauge_presenter def gauge_presenter
average_score = SurveyItemResponse.score_for_measure(measure: @measure, academic_year: @academic_year, school: @school) GaugePresenter.new(scale: scale, score: score_for_measure.average)
GaugePresenter.new(scale: scale, score: average_score)
end end
def data_item_accordion_id def data_item_accordion_id
@ -24,14 +23,18 @@ class MeasurePresenter
def data_item_presenters def data_item_presenters
Array.new.tap do |array| Array.new.tap do |array|
array << StudentSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.student_survey_items) if @measure.student_survey_items.any? array << StudentSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.student_survey_items, has_sufficient_data: score_for_measure.meets_student_threshold?) if @measure.student_survey_items.any?
array << TeacherSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.teacher_survey_items) if @measure.teacher_survey_items.any? array << TeacherSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.teacher_survey_items, has_sufficient_data: score_for_measure.meets_teacher_threshold?) if @measure.teacher_survey_items.any?
array << AdminDataPresenter.new(measure_id: @measure.measure_id, admin_data_items: @measure.admin_data_items) if @measure.admin_data_items.any? array << AdminDataPresenter.new(measure_id: @measure.measure_id, admin_data_items: @measure.admin_data_items) if @measure.admin_data_items.any?
end end
end end
private private
def score_for_measure
@score ||= SurveyItemResponse.score_for_measure(measure: @measure, academic_year: @academic_year, school: @school)
end
def scale def scale
Scale.new( Scale.new(
watch_low_benchmark: @measure.watch_low_benchmark, watch_low_benchmark: @measure.watch_low_benchmark,

@ -1,6 +1,6 @@
class StudentSurveyPresenter < DataItemPresenter class StudentSurveyPresenter < DataItemPresenter
def initialize(measure_id:, survey_items:) def initialize(measure_id:, survey_items:, has_sufficient_data:)
super(measure_id: measure_id) super(measure_id: measure_id, has_sufficient_data: has_sufficient_data)
@survey_items = survey_items @survey_items = survey_items
end end

@ -1,6 +1,6 @@
class TeacherSurveyPresenter < DataItemPresenter class TeacherSurveyPresenter < DataItemPresenter
def initialize(measure_id:, survey_items:) def initialize(measure_id:, survey_items:, has_sufficient_data:)
super(measure_id: measure_id) super(measure_id: measure_id, has_sufficient_data: has_sufficient_data)
@survey_items = survey_items @survey_items = survey_items
end end

@ -8,6 +8,9 @@
aria-controls="<%= data_item_section.id %>" aria-controls="<%= data_item_section.id %>"
> >
<%= data_item_section.title %> <%= data_item_section.title %>
<% unless data_item_section.sufficient_data? %>
&nbsp;<i class="fa-solid fa-circle-exclamation"></i>
<% end %>
</button> </button>
</h3> </h3>
@ -18,6 +21,11 @@
data-bs-parent="#<%= data_item_section.data_item_accordion_id %>" data-bs-parent="#<%= data_item_section.data_item_accordion_id %>"
> >
<div class="accordion-body measure-accordion-body font-cabin font-size-14 weight-400"> <div class="accordion-body measure-accordion-body font-cabin font-size-14 weight-400">
<% unless data_item_section.sufficient_data? %>
<div class="alert alert-secondary" role="alert">
Data not included due to low response rate
</div>
<% end %>
<ul> <ul>
<% data_item_section.item_descriptions.each do |description| %> <% data_item_section.item_descriptions.each do |description| %>
<li><%= description %></li> <li><%= description %></li>

@ -8,179 +8,156 @@ describe SurveyItemResponse, type: :model do
let(:measure) { create(:measure) } let(:measure) { create(:measure) }
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(:teacher_survey_item, measure: measure) }
let(:teacher_survey_item_2) { create(:survey_item, survey_item_id: 't-question-2', measure: measure) } let(:teacher_survey_item_2) { create(:teacher_survey_item, measure: measure) }
let(:teacher_survey_item_3) { create(:survey_item, survey_item_id: 't-question-3', measure: measure) } let(:teacher_survey_item_3) { create(:teacher_survey_item, measure: measure) }
context "and the number of responses for each of the measure's survey items meets the teacher threshold of 17" do context "and the number of responses for each of the measure's survey items meets the teacher threshold of 17" do
before :each do before :each do
17.times do create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, 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: 3) create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: 5)
17.times do
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end
17.times do
create(:survey_item_response, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: 5)
end
end end
it 'returns the average of the likert scores of the survey items' do it 'returns the average of the likert scores of the survey items' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to eq 4 expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to eq 4
end
it 'affirms that the result meets the threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be true
end end
end end
context "and the average number of responses across the measure's survey items meets the teacher threshold of 17" do context "and the average number of responses across the measure's survey items meets the teacher threshold of 17" do
before :each do before :each do
19.times do create_list(:survey_item_response, 19, 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: 3) create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: 5)
16.times do
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end
16.times do
create(:survey_item_response, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: 5)
end
end end
it 'returns the average of the likert scores of the survey items' do it 'returns the average of the likert scores of the survey items' do
average_score = 3.941 average_score = 3.941
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_within(0.001).of(average_score) expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_within(0.001).of(average_score)
end end
end end
context "and none of the measure's survey items meets the teacher threshold of 17" do context "and none of the measure's survey items meets the teacher threshold of 17" do
before :each do before :each do
16.times do create_list(:survey_item_response, 16, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: rand)
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: rand) create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: rand)
16.times do
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end
16.times do
create(:survey_item_response, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: rand)
end
end end
it 'returns nil' do it 'returns nil' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_nil expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_nil
end
it 'affirms that the result does not meet the threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be false
end end
end end
context "and the average number of responses across the measure's survey items does not meet the teacher threshold of 17" do context "and the average number of responses across the measure's survey items does not meet the teacher threshold of 17" do
before :each do before :each do
18.times do create_list(:survey_item_response, 18, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: rand)
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: rand) create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: rand)
16.times do
create(:survey_item_response, survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end
16.times do
create(:survey_item_response, survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: rand)
end
end end
it 'returns nil' do it 'returns nil' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_nil expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_nil
end
it 'affirms that the result does not meet the threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be false
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(:student_survey_item, measure: measure) }
let(:student_survey_item_2) { create(:survey_item, survey_item_id: 's-question-2', measure: measure) } let(:student_survey_item_2) { create(:student_survey_item, measure: measure) }
let(:student_survey_item_3) { create(:survey_item, survey_item_id: 's-question-3', measure: measure) } let(:student_survey_item_3) { create(:student_survey_item, measure: measure) }
context "and the number of responses for each of the measure's survey items meets the student threshold of 196" do context "and the number of responses for each of the measure's survey items meets the student threshold of 196" do
before :each do before :each do
196.times do create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 3)
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 3) create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: 5)
196.times do
create(:survey_item_response, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end
196.times do
create(:survey_item_response, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: 5)
end
end end
it 'returns the average of the likert scores of the survey items' do it 'returns the average of the likert scores of the survey items' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to eq 4 expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to eq 4
end
it 'affirms that the result meets the threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be true
end end
end end
context "and the average number of responses across the measure's survey items meets the student threshold of 196" do context "and the average number of responses across the measure's survey items meets the student threshold of 196" do
before :each do before :each do
200.times do create_list(:survey_item_response, 200, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 3)
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 3) create_list(:survey_item_response, 195, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end create_list(:survey_item_response, 193, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: 5)
195.times do
create(:survey_item_response, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 4)
end
193.times do
create(:survey_item_response, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: 5)
end
end end
it 'returns the average of the likert scores of the survey items' do it 'returns the average of the likert scores of the survey items' do
average_score = 3.988 average_score = 3.988
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_within(0.001).of(average_score) expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_within(0.001).of(average_score)
end end
end end
context "and none of the measure's survey items meets the student threshold of 196" do context "and none of the measure's survey items meets the student threshold of 196" do
before :each do before :each do
195.times do create_list(:survey_item_response, 195, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: rand)
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: rand) create_list(:survey_item_response, 195, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end create_list(:survey_item_response, 195, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: rand)
195.times do
create(:survey_item_response, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end
195.times do
create(:survey_item_response, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: rand)
end
end end
it 'returns nil' do it 'returns nil' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_nil expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_nil
end
it 'affirms that the result does not meet the threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be false
end end
end end
context "and the average number of responses across the measure's survey items does not meet the student threshold of 196" do context "and the average number of responses across the measure's survey items does not meet the student threshold of 196" do
before :each do before :each do
200.times do create_list(:survey_item_response, 200, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: rand)
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: rand) create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end create_list(:survey_item_response, 191, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: rand)
196.times do
create(:survey_item_response, survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: rand)
end
191.times do
create(:survey_item_response, survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: rand)
end
end end
it 'returns nil' do it 'returns nil' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_nil expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_nil
end
it 'affirms that the result does not meet the threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be false
end end
end end
end end
context 'when the measure includes both teacher and student data' do context 'when the measure includes both teacher and student data' do
let(:teacher_survey_item_1) { create(:survey_item, survey_item_id: 't-question-1', measure: measure) } let(:teacher_survey_item_1) { create(:teacher_survey_item, measure: measure) }
let(:student_survey_item_1) { create(:survey_item, survey_item_id: 's-question-1', measure: measure) } let(:student_survey_item_1) { create(:student_survey_item, measure: measure) }
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 create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 5)
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 5) create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 5)
end
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 5)
end
end end
it 'returns the average of the likert scores of the survey items' do it 'returns the average of the likert scores of the survey items' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to eq 5 expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to eq 5
end
it 'affirms that the result does meet the thresholds' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be true
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be true
end end
end end
@ -191,7 +168,12 @@ describe SurveyItemResponse, type: :model do
end end
it 'returns the average of the likert scores of the teacher survey items' do it 'returns the average of the likert scores of the teacher survey items' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to eq 5 expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to eq 5
end
it 'affirms that the result meets the teacher threshold but not the student threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be true
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be false
end end
end end
@ -202,22 +184,28 @@ describe SurveyItemResponse, type: :model do
end end
it 'returns the average of the likert scores of the student survey items' do it 'returns the average of the likert scores of the student survey items' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to eq 5 expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to eq 5
end
it 'affirms that the result meets the student threshold but not the teacher threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be false
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be true
end end
end end
context 'and there is insufficient teacher data and insufficient student data' do context 'and there is insufficient teacher data and insufficient student data' do
before :each do before :each do
(SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1).times do create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, 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) create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_1, academic_year: ay, school: school)
end
(SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1).times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school)
end
end end
it 'returns nil' do it 'returns nil' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay)).to be_nil expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).average).to be_nil
end
it 'affirms that the result does not meet either threshold' do
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_teacher_threshold?).to be false
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school, academic_year: ay).meets_student_threshold?).to be false
end end
end end
end end
@ -228,22 +216,17 @@ describe SurveyItemResponse, type: :model do
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) } let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) } let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
let(:insufficient_measure) { create(:measure, subcategory: subcategory) } let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
let(:sufficient_teacher_survey_item) { create(:survey_item, survey_item_id: 't-question-1', measure: sufficient_measure_1) } let(:sufficient_teacher_survey_item) { create(:teacher_survey_item, measure: sufficient_measure_1) }
let(:insufficient_teacher_survey_item) { create(:survey_item, survey_item_id: 't-question-2', measure: insufficient_measure) } let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, measure: insufficient_measure) }
let(:sufficient_student_survey_item) { create(:survey_item, survey_item_id: 's-question-1', measure: sufficient_measure_2) } let(:sufficient_student_survey_item) { create(:student_survey_item, measure: sufficient_measure_2) }
let(:insufficient_student_survey_item) { create(:survey_item, survey_item_id: 's-question-2', measure: insufficient_measure) } let(:insufficient_student_survey_item) { create(:student_survey_item, measure: insufficient_measure) }
before :each do before :each do
[SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD].max.times do largest_threshold = [SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD].max
create(:survey_item_response, survey_item: sufficient_teacher_survey_item, academic_year: ay, school: school, likert_score: 1) create_list(:survey_item_response, largest_threshold, survey_item: sufficient_teacher_survey_item, academic_year: ay, school: school, likert_score: 1)
create(:survey_item_response, survey_item: sufficient_student_survey_item, academic_year: ay, school: school, likert_score: 4) create_list(:survey_item_response, largest_threshold, survey_item: sufficient_student_survey_item, academic_year: ay, school: school, likert_score: 4)
end create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, survey_item: insufficient_teacher_survey_item, academic_year: ay, school: school, likert_score: 1)
(SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1).times do create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: insufficient_student_survey_item, academic_year: ay, school: school, likert_score: 1)
create(:survey_item_response, survey_item: insufficient_teacher_survey_item, academic_year: ay, school: school, likert_score: 1)
end
(SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1).times do
create(:survey_item_response, survey_item: insufficient_student_survey_item, academic_year: ay, school: school, likert_score: 1)
end
end end
it 'returns the average score of all survey item responses for measures meeting their respective thresholds' do it 'returns the average score of all survey item responses for measures meeting their respective thresholds' do

@ -34,8 +34,8 @@ describe MeasurePresenter do
context 'when the measure contains both teacher data and admin data' do context 'when the measure contains both teacher data and admin data' do
before :each do before :each do
create(:survey_item, measure: measure, survey_item_id: 't-something', prompt: 'A teacher survey item prompt') create(:teacher_survey_item, measure: measure, prompt: 'A teacher survey item prompt')
create(:survey_item, measure: measure, survey_item_id: 't-something', prompt: 'Another teacher survey item prompt') create(:teacher_survey_item, measure: measure, prompt: 'Another teacher survey item prompt')
create(:admin_data_item, measure: measure, description: 'An admin data item description') create(:admin_data_item, measure: measure, description: 'An admin data item description')
create(:admin_data_item, measure: measure, description: 'Another admin data item description') create(:admin_data_item, measure: measure, description: 'Another admin data item description')
end end
@ -54,6 +54,24 @@ describe MeasurePresenter do
expect(second_data_item_presenter.title).to eq 'School admin data' expect(second_data_item_presenter.title).to eq 'School admin data'
expect(second_data_item_presenter.data_item_accordion_id).to eq 'data-item-accordion-measure-id' expect(second_data_item_presenter.data_item_accordion_id).to eq 'data-item-accordion-measure-id'
expect(second_data_item_presenter.item_descriptions).to eq ["An admin data item description", "Another admin data item description"] expect(second_data_item_presenter.item_descriptions).to eq ["An admin data item description", "Another admin data item description"]
expect(second_data_item_presenter.sufficient_data?).to be true
end
end
context 'when the measure has partial data for teachers and students' do
before :each do
teacher_survey_item = create(:teacher_survey_item, measure: measure)
student_survey_item = create(:student_survey_item, measure: measure)
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: teacher_survey_item, academic_year: academic_year, school: school)
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item, academic_year: academic_year, school: school)
end
it 'tracks which parts of the data are sufficient' do
teacher_data_item_presenter = measure_presenter.data_item_presenters.find { |presenter| presenter.title == 'Teacher survey' }
student_data_item_presenter = measure_presenter.data_item_presenters.find { |presenter| presenter.title == 'Student survey' }
expect(teacher_data_item_presenter.sufficient_data?).to be true
expect(student_data_item_presenter.sufficient_data?).to be false
end end
end end

Loading…
Cancel
Save