to survey table. We no longer check or keep track of the survey type. Instead we look in the database to see if a survey item has at least 10 responses. If it does, that survey item was presented to the respondent and we count it, and all responses when calculating the response rate. Remove response rate timestamp from caching logic because we no longer add the response rate to the database. All response rates are calculated on the fly Update three_b_two scraper to use teacher only numbers swap over to using https://profiles.doe.mass.edu/statereport/gradesubjectstaffing.aspx as the source of staffing informationmciea-main
parent
0bfde2805a
commit
07ed8dd259
@ -1,37 +1,54 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class StudentResponseRateCalculator < ResponseRateCalculator
|
||||
private
|
||||
|
||||
def survey_item_count
|
||||
@survey_item_count ||= begin
|
||||
survey_items = SurveyItem.includes(%i[scale
|
||||
measure]).student_survey_items.where("scale.measure": @subcategory.measures)
|
||||
survey_items = survey_items.where(on_short_form: true) if survey.form == 'short'
|
||||
survey_items = survey_items.reject do |survey_item|
|
||||
survey_item.survey_item_responses.where(school:, academic_year:).none?
|
||||
def raw_response_rate
|
||||
rates_by_grade.length.positive? ? rates_by_grade.average : 0
|
||||
end
|
||||
|
||||
def rates_by_grade
|
||||
@rates_by_grade ||= counts_by_grade.map do |grade, num_of_students_in_grade|
|
||||
sufficient_survey_items = survey_items_with_sufficient_responses(grade:).keys
|
||||
actual_response_count_for_grade = SurveyItemResponse.where(school:, academic_year:, grade:,
|
||||
survey_item: sufficient_survey_items).count.to_f
|
||||
count_of_survey_items_with_sufficient_responses = survey_item_count(grade:)
|
||||
if count_of_survey_items_with_sufficient_responses.nil? || count_of_survey_items_with_sufficient_responses.zero? || num_of_students_in_grade.nil? || num_of_students_in_grade.zero?
|
||||
next nil
|
||||
end
|
||||
survey_items.count
|
||||
end
|
||||
|
||||
actual_response_count_for_grade / count_of_survey_items_with_sufficient_responses / num_of_students_in_grade * 100
|
||||
end.compact
|
||||
end
|
||||
|
||||
def counts_by_grade
|
||||
@counts_by_grade ||= respondents.counts_by_grade
|
||||
end
|
||||
|
||||
def response_count
|
||||
@response_count ||= @subcategory.measures.map do |measure|
|
||||
measure.student_survey_items.map do |survey_item|
|
||||
next 0 if survey.form == 'short' && survey_item.on_short_form == false
|
||||
def survey_items_have_sufficient_responses?
|
||||
rates_by_grade.length.positive?
|
||||
end
|
||||
|
||||
def survey_items_with_sufficient_responses(grade:)
|
||||
SurveyItem.joins('inner join survey_item_responses on survey_item_responses.survey_item_id = survey_items.id')
|
||||
.student_survey_items
|
||||
.where("survey_item_responses.school": school, "survey_item_responses.academic_year": academic_year, "survey_item_responses.grade": grade, "survey_item_responses.survey_item_id": subcategory.survey_items.student_survey_items)
|
||||
.group('survey_items.id')
|
||||
.having('count(*) >= 10')
|
||||
.count
|
||||
end
|
||||
|
||||
def survey_item_count(grade:)
|
||||
survey_items_with_sufficient_responses(grade:).count
|
||||
end
|
||||
|
||||
survey_item.survey_item_responses.where(school:,
|
||||
academic_year:).exclude_boston.count
|
||||
end.sum
|
||||
end.sum
|
||||
def respondents
|
||||
@respondents ||= Respondent.find_by(school:, academic_year:)
|
||||
end
|
||||
|
||||
def total_possible_responses
|
||||
@total_possible_responses ||= begin
|
||||
total_responses = Respondent.find_by(school:, academic_year:)
|
||||
return 0 unless total_responses.present?
|
||||
return 0 unless respondents.present?
|
||||
|
||||
total_responses.total_students
|
||||
respondents.total_students
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
require 'watir'
|
||||
|
||||
module Dese
|
||||
class Staffing
|
||||
include Dese::Scraper
|
||||
attr_reader :filepath
|
||||
|
||||
def initialize(filepath: Rails.root.join('data', 'staffing', 'staffing.csv'))
|
||||
@filepath = filepath
|
||||
end
|
||||
|
||||
def run_all
|
||||
scrape_staffing(filepath:)
|
||||
end
|
||||
|
||||
def scrape_staffing(filepath:)
|
||||
headers = ['Raw likert calculation', 'Likert Score', 'Admin Data Item', 'Academic Year',
|
||||
'School Name', 'DESE ID',
|
||||
'PK-2 (#)', '3-5 (#)', '6-8 (#)', '9-12 (#)', 'Multiple Grades (#)',
|
||||
'All Grades (#)', 'FTE Count']
|
||||
write_headers(filepath:, headers:)
|
||||
run do |academic_year|
|
||||
admin_data_item_id = 'NA'
|
||||
url = 'https://profiles.doe.mass.edu/statereport/gradesubjectstaffing.aspx'
|
||||
range = academic_year.range
|
||||
selectors = { 'ctl00_ContentPlaceHolder1_ddReportType' => 'School',
|
||||
'ctl00_ContentPlaceHolder1_ddYear' => range,
|
||||
'ctl00_ContentPlaceHolder1_ddDisplay' => 'Full-time Equivalents' }
|
||||
submit_id = 'btnViewReport'
|
||||
calculation = ->(_headers, _items) { 'NA' }
|
||||
Prerequisites.new(filepath, url, selectors, submit_id, admin_data_item_id, calculation)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,108 +1,94 @@
|
||||
<% content_for :navigation do %>
|
||||
<h2 class="sub-header-2 color-white m-0">Areas Of Interest</h2>
|
||||
|
||||
<select id="select-academic-year" class="form-select" name="academic-year">
|
||||
<% @academic_years.each do |year| %>
|
||||
<option value="<%= district_school_overview_index_path(@district, @school, {year: year.range}) %>" <%= @academic_year == year ? "selected" : nil %>><%= year.formatted_range %></option>
|
||||
<h2 class="sub-header-2 color-white m-0">Areas Of Interest</h2>
|
||||
<select id="select-academic-year" class="form-select" name="academic-year">
|
||||
<% @academic_years.each do |year| %>
|
||||
<option value="<%= district_school_overview_index_path(@district, @school, {year: year.range}) %>" <%= @academic_year == year ? "selected" : nil %>><%= year.formatted_range %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
<% end %>
|
||||
|
||||
<% cache do %>
|
||||
<svg class="d-none">
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="warning-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" fill="white" stroke="none" />
|
||||
<path d="
|
||||
<% end %>
|
||||
<% cache do %>
|
||||
<svg class="d-none">
|
||||
<symbol viewBox="0 0 24 24" id="warning-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" fill="white" stroke="none" />
|
||||
<path d="
|
||||
M 12 0
|
||||
A 12 12 0 0 1 24 12
|
||||
L 12 12
|
||||
L 12 0"
|
||||
stroke="none"
|
||||
/>
|
||||
<circle cx="12" cy="12" r="11.5" fill="none" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="watch-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" fill="white" stroke="none" />
|
||||
<path d="
|
||||
<circle cx="12" cy="12" r="11.5" fill="none" />
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" id="watch-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" fill="white" stroke="none" />
|
||||
<path d="
|
||||
M 12 0
|
||||
A 12 12 0 1 1 12 24
|
||||
L 12 12
|
||||
L 12 0"
|
||||
stroke="none"
|
||||
/>
|
||||
<circle cx="12" cy="12" r="11.5" fill="none" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="growth-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" fill="white" stroke="none" />
|
||||
<path d="
|
||||
<circle cx="12" cy="12" r="11.5" fill="none" />
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" id="growth-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" fill="white" stroke="none" />
|
||||
<path d="
|
||||
M 12 0
|
||||
A 12 12 0 1 1 0 12
|
||||
L 12 12
|
||||
L 12 0"
|
||||
stroke="none"
|
||||
/>
|
||||
<circle cx="12" cy="12" r="11.5" fill="none" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="approval-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" />
|
||||
<path d="M19 8C19 8.28125 18.875 8.53125 18.6875 8.71875L10.6875 16.7188C10.5 16.9062 10.25 17 10 17C9.71875 17 9.46875 16.9062 9.28125 16.7188L5.28125 12.7188C5.09375 12.5312 5 12.2812 5 12C5 11.4375 5.4375 11 6 11C6.25 11 6.5 11.125 6.6875 11.3125L10 14.5938L17.2812 7.3125C17.4688 7.125 17.7188 7 18 7C18.5312 7 19 7.4375 19 8Z"
|
||||
<circle cx="12" cy="12" r="11.5" fill="none" />
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" id="approval-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" />
|
||||
<path d="M19 8C19 8.28125 18.875 8.53125 18.6875 8.71875L10.6875 16.7188C10.5 16.9062 10.25 17 10 17C9.71875 17 9.46875 16.9062 9.28125 16.7188L5.28125 12.7188C5.09375 12.5312 5 12.2812 5 12C5 11.4375 5.4375 11 6 11C6.25 11 6.5 11.125 6.6875 11.3125L10 14.5938L17.2812 7.3125C17.4688 7.125 17.7188 7 18 7C18.5312 7 19 7.4375 19 8Z"
|
||||
stroke-width=".5" stroke="white" fill="white" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="ideal-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" />
|
||||
<path d="M9.28125 11.7188C9.46875 11.9062 9.71875 12 10 12C10.25 12 10.5 11.9062 10.6875 11.7188L15.6875 6.71875C15.875 6.53125 16 6.28125 16 6C16 5.4375 15.5312 5 15 5C14.7188 5 14.4688 5.125 14.2812 5.3125L10 9.59375L8.1875 7.8125C8 7.625 7.75 7.5 7.5 7.5C6.9375 7.5 6.5 7.9375 6.5 8.5C6.5 8.78125 6.59375 9.03125 6.78125 9.21875L9.28125 11.7188ZM19 10C19 9.4375 18.5312 9 18 9C17.7188 9 17.4688 9.125 17.2812 9.3125L10 16.5938L6.6875 13.3125C6.5 13.125 6.25 13 6 13C5.4375 13 5 13.4375 5 14C5 14.2812 5.09375 14.5312 5.28125 14.7188L9.28125 18.7188C9.46875 18.9062 9.71875 19 10 19C10.25 19 10.5 18.9062 10.6875 18.7188L18.6875 10.7188C18.875 10.5312 19 10.2812 19 10Z"
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" id="ideal-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" />
|
||||
<path d="M9.28125 11.7188C9.46875 11.9062 9.71875 12 10 12C10.25 12 10.5 11.9062 10.6875 11.7188L15.6875 6.71875C15.875 6.53125 16 6.28125 16 6C16 5.4375 15.5312 5 15 5C14.7188 5 14.4688 5.125 14.2812 5.3125L10 9.59375L8.1875 7.8125C8 7.625 7.75 7.5 7.5 7.5C6.9375 7.5 6.5 7.9375 6.5 8.5C6.5 8.78125 6.59375 9.03125 6.78125 9.21875L9.28125 11.7188ZM19 10C19 9.4375 18.5312 9 18 9C17.7188 9 17.4688 9.125 17.2812 9.3125L10 16.5938L6.6875 13.3125C6.5 13.125 6.25 13 6 13C5.4375 13 5 13.4375 5 14C5 14.2812 5.09375 14.5312 5.28125 14.7188L9.28125 18.7188C9.46875 18.9062 9.71875 19 10 19C10.25 19 10.5 18.9062 10.6875 18.7188L18.6875 10.7188C18.875 10.5312 19 10.2812 19 10Z"
|
||||
stroke-width=".5" stroke="white" fill="white" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="insufficient_data-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" />
|
||||
</symbol>
|
||||
</svg>
|
||||
<% end %>
|
||||
|
||||
<% cache [@school, @academic_year, @response_rate_timestamp] do %>
|
||||
<div class="card">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h2 class="sub-header-2">School Quality Framework Indicators</h2>
|
||||
|
||||
<div class="harvey-ball-legend">
|
||||
<div class="font-size-14">Warning</div>
|
||||
<svg class="ms-3 me-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--warning" xlink:href="#warning-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="mx-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--watch" xlink:href="#watch-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="mx-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--growth" xlink:href="#growth-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="mx-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--approval" xlink:href="#approval-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="ms-1 me-3" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--ideal" xlink:href="#ideal-harvey-ball"></use>
|
||||
</svg>
|
||||
<div class="font-size-14">Ideal</div>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" id="insufficient_data-harvey-ball">
|
||||
<circle cx="12" cy="12" r="11.5" />
|
||||
</symbol>
|
||||
</svg>
|
||||
<% end %>
|
||||
<% cache [@school, @academic_year] do %>
|
||||
<div class="card">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h2 class="sub-header-2">School Quality Framework Indicators</h2>
|
||||
<div class="harvey-ball-legend">
|
||||
<div class="font-size-14">Warning</div>
|
||||
<svg class="ms-3 me-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--warning" xlink:href="#warning-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="mx-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--watch" xlink:href="#watch-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="mx-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--growth" xlink:href="#growth-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="mx-1" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--approval" xlink:href="#approval-harvey-ball"></use>
|
||||
</svg>
|
||||
<svg class="ms-1 me-3" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<use class="harvey-ball harvey-ball--ideal" xlink:href="#ideal-harvey-ball"></use>
|
||||
</svg>
|
||||
<div class="font-size-14">Ideal</div>
|
||||
</div>
|
||||
</div>
|
||||
<%= render partial: "quality_framework_indicators", locals: { category_presenters: @category_presenters }, cached: true %>
|
||||
</div>
|
||||
|
||||
<%= render partial: "quality_framework_indicators", locals: { category_presenters: @category_presenters }, cached: true %>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2 class="sub-header-2 mb-4">Distance From Benchmark</h2>
|
||||
|
||||
<%= render partial: "variance_chart", locals: { presenters: @variance_chart_row_presenters } , cached: true %>
|
||||
</div>
|
||||
|
||||
<% if @district == District.find_by_name("Boston") %>
|
||||
<%= render partial: 'layouts/boston_modal' %>
|
||||
<% elsif @has_empty_dataset %>
|
||||
<%= render partial: 'layouts/empty_dataset_modal' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<div class="card">
|
||||
<h2 class="sub-header-2 mb-4">Distance From Benchmark</h2>
|
||||
<%= render partial: "variance_chart", locals: { presenters: @variance_chart_row_presenters } , cached: true %>
|
||||
</div>
|
||||
<% if @district == District.find_by_name("Boston") %>
|
||||
<%= render partial: 'layouts/boston_modal' %>
|
||||
<% elsif @has_empty_dataset %>
|
||||
<%= render partial: 'layouts/empty_dataset_modal' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@
|
||||
class AddGradesToRespondent < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :respondents, :pk, :integer
|
||||
add_column :respondents, :k, :integer
|
||||
add_column :respondents, :one, :integer
|
||||
add_column :respondents, :two, :integer
|
||||
add_column :respondents, :three, :integer
|
||||
add_column :respondents, :four, :integer
|
||||
add_column :respondents, :five, :integer
|
||||
add_column :respondents, :six, :integer
|
||||
add_column :respondents, :seven, :integer
|
||||
add_column :respondents, :eight, :integer
|
||||
add_column :respondents, :nine, :integer
|
||||
add_column :respondents, :ten, :integer
|
||||
add_column :respondents, :eleven, :integer
|
||||
add_column :respondents, :twelve, :integer
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,5 @@
|
||||
class AddUniqueIndextoRespondent < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_index :respondents, %i[school_id academic_year_id], unique: true
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,5 @@
|
||||
class RemoveSchoolIndexFromRespondents < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
remove_index :respondents, name: 'index_respondents_on_school_id'
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,21 @@
|
||||
namespace :scrape do
|
||||
desc 'scrape dese site for admin data'
|
||||
task admin: :environment do
|
||||
puts 'scraping data from dese'
|
||||
scrapers = [Dese::OneAOne, Dese::OneAThree, Dese::TwoAOne, Dese::TwoCOne, Dese::ThreeAOne, Dese::ThreeATwo,
|
||||
Dese::ThreeBOne, Dese::ThreeBTwo, Dese::FourAOne, Dese::FourBTwo, Dese::FourDOne, Dese::FiveCOne, Dese::FiveDTwo]
|
||||
scrapers.each do |scraper|
|
||||
scraper.new.run_all
|
||||
end
|
||||
end
|
||||
|
||||
desc 'scrape dese site for teacher staffing information'
|
||||
task enrollment: :environment do
|
||||
Dese::ThreeATwo.new.scrape_enrollments(filepath: Rails.root.join('data', 'enrollment', 'enrollment.csv'))
|
||||
end
|
||||
|
||||
desc 'scrape dese site for student staffing information'
|
||||
task staffing: :environment do
|
||||
Dese::Staffing.new.run_all
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,76 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Report::Pillar, type: :model do
|
||||
let(:school) { create(:school, name: 'Abraham Lincoln Elementary School') }
|
||||
let(:subcategory) { create(:subcategory, subcategory_id: '1A') }
|
||||
let(:measure_1) { create(:measure, measure_id: '1A-iii', subcategory:) }
|
||||
let(:measure_2) { create(:measure, measure_id: '1B-ii', subcategory:) }
|
||||
let(:scale_1) { create(:scale, measure: measure_1) }
|
||||
let(:scale_2) { create(:scale, measure: measure_2) }
|
||||
let(:survey_item_1) { create(:student_survey_item, scale: scale_1) }
|
||||
let(:survey_item_2) do
|
||||
create(:student_survey_item, scale: scale_2, ideal_low_benchmark: 5)
|
||||
end
|
||||
let(:measures) do
|
||||
subcategory.measures
|
||||
end
|
||||
let(:academic_year_1) { create(:academic_year, range: '2017-2018') }
|
||||
let(:academic_year_2) { create(:academic_year, range: '2018-2019') }
|
||||
let(:academic_years) { [academic_year_1, academic_year_2] }
|
||||
|
||||
before :each do
|
||||
create(:respondent, school:, academic_year: academic_year_1)
|
||||
create(:survey, school:, academic_year: academic_year_1)
|
||||
measures
|
||||
end
|
||||
|
||||
context '.pillar' do
|
||||
it 'returns the GPS pillar' do
|
||||
pillar = Report::Pillar.new(school:, measures:, indicator: 'Teaching Environment',
|
||||
period: 'Current', academic_year: academic_year_1)
|
||||
expect(pillar.pillar).to eq('Operational Efficiency')
|
||||
end
|
||||
end
|
||||
|
||||
context '.school' do
|
||||
it 'returns the name of the school' do
|
||||
pillar = Report::Pillar.new(school:, measures:, indicator: 'The Teaching Environment', period: 'Current',
|
||||
academic_year: academic_year_1)
|
||||
expect(pillar.school_name).to eq('Abraham Lincoln Elementary School')
|
||||
end
|
||||
end
|
||||
|
||||
context '.score' do
|
||||
before do
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item_1, school:, academic_year: academic_year_1,
|
||||
likert_score: 3)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item_1, school:, academic_year: academic_year_1,
|
||||
likert_score: 5)
|
||||
end
|
||||
it 'returns the average score for all the measures in the pillar' do
|
||||
pillar = Report::Pillar.new(school:, measures:, indicator: 'The Teaching Environment', period: 'Current',
|
||||
academic_year: academic_year_1)
|
||||
expect(pillar.score).to eq 4
|
||||
end
|
||||
end
|
||||
|
||||
context '.zone' do
|
||||
before do
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item_1, school:, academic_year: academic_year_1,
|
||||
likert_score: 4)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item_1, school:, academic_year: academic_year_1,
|
||||
likert_score: 5)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item_2, school:, academic_year: academic_year_1,
|
||||
likert_score: 4)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item_2, school:, academic_year: academic_year_1,
|
||||
likert_score: 5)
|
||||
end
|
||||
|
||||
it 'returns the zone for the average score for all the measures in the pillar' do
|
||||
pillar = Report::Pillar.new(school:, measures:, indicator: 'The Teaching Environment', period: 'Current',
|
||||
academic_year: academic_year_1)
|
||||
expect(pillar.score).to eq 4.5
|
||||
expect(pillar.zone).to eq 'Approval'
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,17 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Respondent, type: :model do
|
||||
describe 'grade_counts' do
|
||||
let(:single_grade_of_respondents) { create(:respondent, one: 10) }
|
||||
let(:two_grades_of_respondents) { create(:respondent, pk: 10, k: 5, one: 0, two: 0, three: 0) }
|
||||
let(:three_grades_of_respondents) { create(:respondent, one: 10, two: 5, twelve: 6, eleven: 0) }
|
||||
context 'when the student respondents include one or more counts for the number of respondents' do
|
||||
it 'returns a hash with only the grades that have a non-zero count of students' do
|
||||
expect(single_grade_of_respondents.one).to eq(10)
|
||||
expect(single_grade_of_respondents.counts_by_grade).to eq({ 1 => 10 })
|
||||
expect(two_grades_of_respondents.counts_by_grade).to eq({ -1 => 10, 0 => 5 })
|
||||
expect(three_grades_of_respondents.counts_by_grade).to eq({ 1 => 10, 2 => 5, 12 => 6 })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in new issue