Display insufficient data note. TODO: remove measures from variance chart

pull/1/head
Alex Basson 4 years ago
parent c423fcc014
commit 10e70557bd

@ -23,6 +23,15 @@ class DashboardController < SqmApplicationController
end
def presenter_for_measure(measure)
sufficient_data = SurveyItemResponse.sufficient_data?(measure: measure, academic_year: academic_year, school: school)
unless sufficient_data
return MeasureGraphRowPresenter.new(
measure: measure,
sufficient_data: false
)
end
score = SurveyItemResponse.for_measure(measure)
.where(academic_year: academic_year, school: school)
.average(:likert_score)

@ -42,4 +42,8 @@ module VarianceHelper
def zone_width_percentage
100.0/zones.size
end
def measures_with_insufficient_data(presenters:)
presenters.filter { |presenter| !presenter.sufficient_data? }
end
end

@ -3,4 +3,12 @@ class Measure < ActiveRecord::Base
has_many :survey_items
has_many :survey_item_responses, through: :survey_items
def includes_teacher_survey_items?
survey_items.where("survey_item_id LIKE 't-%'").any?
end
def includes_student_survey_items?
survey_items.where("survey_item_id LIKE 's-%'").any?
end
end

@ -1,8 +1,26 @@
class SurveyItemResponse < ActiveRecord::Base
TEACHER_RESPONSE_THRESHOLD = 17
STUDENT_RESPONSE_THRESHOLD = 196
belongs_to :academic_year
belongs_to :school
belongs_to :survey_item
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) }
def self.sufficient_data?(measure:, academic_year:, school:)
meets_teacher_threshold = true
meets_student_threshold = true
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
end
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
end
meets_teacher_threshold and meets_student_threshold
end
end

@ -1,8 +1,13 @@
class MeasureGraphRowPresenter
include Comparable
def initialize(measure:, score:)
def initialize(measure:, score: 0, sufficient_data: true)
@measure = measure
@score = score
@sufficient_data = sufficient_data
end
def sufficient_data?
@sufficient_data
end
def measure_name

@ -1,3 +1,8 @@
<% unless measures_with_insufficient_data(presenters: presenters).empty? %>
<p>Note: The following measures are not displayed due to limited availability of school admin data and/or low survey response rates: <%= measures_with_insufficient_data(presenters: presenters).map(&:measure_name).join('; ') %>.</p>
<% end %>
<svg width="100%" height=<%= graph_height(presenters.size) %> xmlns="http://www.w3.org/2000/svg">
<filter id="inset-shadow" x="-50%" y="-50%" width="200%" height="200%">

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

@ -16,9 +16,9 @@ FactoryBot.define do
end
factory :sqm_category do
name { "A category" }
name { "A #{rand} category" }
description { "A description of a category" }
slug { 'a-category' }
slug { "a-#{rand}-category" }
sort_index { 1 }
end

@ -0,0 +1,131 @@
require 'rails_helper'
describe SurveyItemResponse, type: :model do
describe '.sufficient_data?' do
let(:measure) { create(:measure) }
let(:school) { create(:school) }
let(:ay) { create(:academic_year) }
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) }
context 'and there is sufficient teacher data' do
before :each do
SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school)
end
end
it 'is truthy' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_truthy
end
end
context 'and there is insufficient teacher data' do
before :each do
(SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1).times do
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school)
end
end
it 'is falsey' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey
end
end
end
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) }
context 'and there is sufficient student data' do
before :each do
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school)
end
end
it 'is truthy' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_truthy
end
end
context 'and there insufficient student data' do
before :each do
(SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1).times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school)
end
end
it 'is falsey' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey
end
end
end
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(:student_survey_item_1) { create(:survey_item, survey_item_id: 's-question-1', measure: measure) }
context 'and there is sufficient teacher data and sufficient student data' do
before :each do
SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school)
end
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school)
end
end
it 'is truthy' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_truthy
end
end
context 'and there is sufficient teacher data and insufficient student data' do
before :each do
SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: teacher_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
it 'is falsey' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey
end
end
context 'and there is insufficient teacher data and sufficient student data' do
before :each do
(SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1).times do
create(:survey_item_response, survey_item: teacher_survey_item_1, academic_year: ay, school: school)
end
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do
create(:survey_item_response, survey_item: student_survey_item_1, academic_year: ay, school: school)
end
end
it 'is falsey' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey
end
end
context 'and there is insufficient teacher data and insufficient student data' do
before :each do
(SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1).times do
create(:survey_item_response, survey_item: teacher_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
it 'is falsey' do
expect(SurveyItemResponse.sufficient_data?(measure: measure, academic_year: ay, school: school)).to be_falsey
end
end
end
end
end

@ -0,0 +1,42 @@
require 'rails_helper'
describe 'dashboard/index.html.erb' do
let(:support_for_teaching) { create(:measure, name: 'Support For Teaching Development & Growth') }
let(:effective_leadership) { create(:measure, name: 'Effective Leadership') }
let(:professional_qualifications) { create(:measure, name: 'Professional Qualifications') }
before :each do
assign :category_presenters, []
assign :measure_graph_row_presenters, measure_graph_row_presenters
render
end
context 'when there are measures for which, in the given academic year, the school has insufficient responses' do
let(:measure_graph_row_presenters) {
[
MeasureGraphRowPresenter.new(measure: support_for_teaching, score: 0, sufficient_data: false),
MeasureGraphRowPresenter.new(measure: create(:measure), score: 0, sufficient_data: true),
MeasureGraphRowPresenter.new(measure: effective_leadership, score: 0, sufficient_data: false),
MeasureGraphRowPresenter.new(measure: professional_qualifications, score: 0, sufficient_data: false)
]
}
it 'displays a note detailing which measures have insufficient responses for the given school & academic year' do
expect(rendered).to match /Note: The following measures are not displayed due to limited availability of school admin data and\/or low survey response rates: Support For Teaching Development &amp; Growth; Effective Leadership; Professional Qualifications./
end
end
context 'when there are no measures for which, in the given academic year, the school has insufficient responses' do
let(:measure_graph_row_presenters) {
[
MeasureGraphRowPresenter.new(measure: create(:measure), score: 0, sufficient_data: true)
]
}
it 'does not display a note detailing which measures have insufficient responses for the given school & academic year' do
expect(rendered).not_to match /Note: The following measures are not displayed due to limited availability of school admin data and\/or low survey response rates/
end
end
end
Loading…
Cancel
Save