mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
Update demographics table with lanugage options Create a lanugage table to hold the new languages Update the demographic loader to input languages into the database Update the cleaner to read the language column Update the parent table to hold a reference to a language Update the data uploader script to read the language from the csv and update the language information for any parent items that already exist (or create database entries if none already exist) update the analyze interface to add controls for selecting ‘parents by group’ and a dropdown for ‘parent by language’ Update the analyze controller to read the parent-by-group parameter Create a graph for the parent-by-group view Bubble up averages for language calculations. Make sure n-size only counts responses for a given measure.
467 lines
18 KiB
Ruby
467 lines
18 KiB
Ruby
require "rails_helper"
|
||
|
||
describe SurveyResponsesDataLoader do
|
||
let(:path_to_teacher_responses) { Rails.root.join("spec", "fixtures", "test_2020-21_teacher_survey_responses.csv") }
|
||
let(:path_to_student_responses) { Rails.root.join("spec", "fixtures", "test_2020-21_student_survey_responses.csv") }
|
||
let(:path_to_parent_responses) { Rails.root.join("spec", "fixtures", "test_2020-21_parent_survey_responses.csv") }
|
||
let(:path_to_butler_student_responses) do
|
||
Rails.root.join("spec", "fixtures", "test_2022-23_butler_student_survey_responses.csv")
|
||
end
|
||
|
||
let(:ay_2020_21) { create(:academic_year, range: "2020-21") }
|
||
let(:ay_2022_23) { create(:academic_year, range: "2022-23") }
|
||
|
||
let(:school) { create(:school, name: "Lee Elementary School", slug: "lee-elementary-school", dese_id: 1_500_025) }
|
||
let(:lowell) { create(:district, name: "Lowell", slug: "lowell") }
|
||
let(:second_school) do
|
||
create(:school, name: "Lee Middle High School", slug: "lee-middle-high-school", dese_id: 1_500_505,
|
||
district: lowell)
|
||
end
|
||
let(:butler_school) do
|
||
create(:school, name: "Butler Elementary School", slug: "butler-elementary-school", dese_id: 1_600_310,
|
||
district: lowell)
|
||
end
|
||
|
||
let(:student_survey_items) do
|
||
ids = %w[ s-emsa-q1 s-emsa-q2 s-emsa-q3
|
||
s-tint-q1 s-tint-q2 s-tint-q4 s-tint-q5
|
||
s-acpr-q1 s-acpr-q2 s-acpr-q3 s-acpr-q4
|
||
s-cure-q3 s-cure-q4 s-sten-q2 s-sten-q3
|
||
s-sper-q1 s-sper-q2 s-sper-q3 s-sper-q4
|
||
s-civp-q1 s-civp-q2 s-civp-q3 s-civp-q4 s-grmi-q1
|
||
s-grmi-q4 s-appa-q1
|
||
s-appa-q2 s-peff-q1
|
||
s-peff-q2 s-peff-q3 s-peff-q4 s-peff-q5 s-peff-q6
|
||
s-sbel-q1 s-sbel-q2 s-sbel-q3 s-sbel-q4 s-sbel-q5
|
||
s-phys-q1 s-phys-q2 s-phys-q3 s-phys-q4
|
||
s-vale-q1 s-vale-q2 s-vale-q3 s-vale-q4
|
||
s-acst-q1 s-acst-q2 s-acst-q3 s-acst-q4 s-acst-q5
|
||
s-grit-q1 s-grit-q2 s-grit-q3 s-grit-q4]
|
||
|
||
ids.each do |id|
|
||
create(:survey_item, survey_item_id: id)
|
||
end
|
||
end
|
||
let(:parent_survey_items) do
|
||
ids = %w[
|
||
p-socx-q1
|
||
p-socx-q2
|
||
p-socx-q3
|
||
p-socx-q4
|
||
p-sosu-q1
|
||
p-sosu-q2
|
||
p-sosu-q3
|
||
p-sosu-q4
|
||
p-tcom-q1
|
||
p-tcom-q2
|
||
p-tcom-q3
|
||
p-comm-q1
|
||
p-comm-q2
|
||
p-comm-q3
|
||
p-comm-q4
|
||
p-valm-q1
|
||
p-valm-q2
|
||
p-valm-q3
|
||
p-valm-q4
|
||
p-acpr-q1
|
||
p-acpr-q2
|
||
p-acpr-q3
|
||
p-acpr-q4
|
||
]
|
||
|
||
ids.each do |id|
|
||
create(:survey_item, survey_item_id: id)
|
||
end
|
||
end
|
||
|
||
let(:vestigial_parent_ids) do
|
||
%w[
|
||
p-scrp-q3
|
||
p-cure-q1
|
||
p-cure-q2
|
||
p-cure-q3
|
||
p-cure-q4
|
||
p-evnt-q1
|
||
p-evnt-q2
|
||
p-evnt-q3
|
||
p-evnt-q4
|
||
p-phys-q3
|
||
p-scrp-q1
|
||
p-scrp-q2
|
||
]
|
||
end
|
||
|
||
let(:housings) do
|
||
create(:housing, designation: "Own")
|
||
create(:housing, designation: "Rent")
|
||
create(:housing, designation: "Unknown")
|
||
end
|
||
|
||
let(:t_pcom_q3) { create(:survey_item, survey_item_id: "t-pcom-q3") }
|
||
let(:t_pcom_q2) { create(:survey_item, survey_item_id: "t-pcom-q2") }
|
||
let(:t_coll_q1) { create(:survey_item, survey_item_id: "t-coll-q1") }
|
||
let(:t_coll_q2) { create(:survey_item, survey_item_id: "t-coll-q2") }
|
||
let(:t_coll_q3) { create(:survey_item, survey_item_id: "t-coll-q3") }
|
||
let(:t_sach_q1) { create(:survey_item, survey_item_id: "t-sach-q1") }
|
||
let(:t_sach_q2) { create(:survey_item, survey_item_id: "t-sach-q2") }
|
||
let(:t_sach_q3) { create(:survey_item, survey_item_id: "t-sach-q3") }
|
||
|
||
let(:female) { create(:gender, qualtrics_code: 1) }
|
||
let(:male) { create(:gender, qualtrics_code: 2) }
|
||
let(:another_gender) { create(:gender, qualtrics_code: 3) }
|
||
let(:non_binary) { create(:gender, qualtrics_code: 4) }
|
||
let(:unknown_gender) { create(:gender, qualtrics_code: 99) }
|
||
|
||
let(:low_income) { create(:income, designation: "Economically Disadvantaged – Y") }
|
||
let(:high_income) { create(:income, designation: "Economically Disadvantaged – N") }
|
||
let(:unknown_income) { create(:income, designation: "Unknown") }
|
||
|
||
let(:yes_ell) { create(:ell, designation: "ELL") }
|
||
let(:not_ell) { create(:ell, designation: "Not ELL") }
|
||
let(:unknown_ell) { create(:ell, designation: "Unknown") }
|
||
|
||
let(:american_indian) { create(:race, qualtrics_code: 1) }
|
||
let(:asian) { create(:race, qualtrics_code: 2) }
|
||
let(:black) { create(:race, qualtrics_code: 3) }
|
||
let(:latinx) { create(:race, qualtrics_code: 4) }
|
||
let(:white) { create(:race, qualtrics_code: 5) }
|
||
let(:middle_eastern) { create(:race, qualtrics_code: 8) }
|
||
let(:unknown_race) { create(:race, qualtrics_code: 99) }
|
||
let(:multiracial) { create(:race, qualtrics_code: 100) }
|
||
|
||
let(:languages){
|
||
create(:language, designation: "English")
|
||
create(:language, designation: "Spanish")
|
||
create(:language, designation: "Portuguese")
|
||
create(:language, designation: "Unknown")
|
||
}
|
||
|
||
let(:setup) do
|
||
ay_2020_21
|
||
ay_2022_23
|
||
school
|
||
second_school
|
||
butler_school
|
||
housings
|
||
t_pcom_q3
|
||
t_pcom_q2
|
||
t_coll_q1
|
||
t_coll_q2
|
||
t_coll_q3
|
||
t_sach_q1
|
||
t_sach_q2
|
||
t_sach_q3
|
||
student_survey_items
|
||
|
||
female
|
||
male
|
||
another_gender
|
||
non_binary
|
||
unknown_gender
|
||
|
||
low_income
|
||
high_income
|
||
unknown_income
|
||
|
||
yes_ell
|
||
not_ell
|
||
unknown_ell
|
||
|
||
american_indian
|
||
asian
|
||
black
|
||
latinx
|
||
white
|
||
middle_eastern
|
||
unknown_race
|
||
multiracial
|
||
|
||
languages
|
||
end
|
||
|
||
before :each do
|
||
setup
|
||
end
|
||
|
||
describe "loading teacher survey responses" do
|
||
before do
|
||
SurveyResponsesDataLoader.new.load_data filepath: path_to_teacher_responses
|
||
end
|
||
|
||
it "ensures teacher responses load correctly" do
|
||
assigns_academic_year_to_survey_item_responses
|
||
assigns_school_to_the_survey_item_responses
|
||
assigns_recorded_date_to_teacher_responses
|
||
loads_survey_item_responses_for_a_given_survey_response
|
||
loads_all_survey_item_responses_for_a_given_survey_item
|
||
captures_likert_scores_for_survey_item_responses
|
||
is_idempotent
|
||
end
|
||
end
|
||
|
||
describe "student survey responses" do
|
||
before do
|
||
SurveyResponsesDataLoader.new.load_data filepath: path_to_student_responses
|
||
end
|
||
|
||
it "ensures student responses load correctly" do
|
||
assigns_academic_year_to_student_survey_item_responses
|
||
assigns_school_to_student_survey_item_responses
|
||
assigns_recorded_date_to_student_responses
|
||
loads_student_survey_item_response_values
|
||
student_survey_item_response_count_matches_expected
|
||
captures_likert_scores_for_student_survey_item_responses
|
||
assigns_grade_level_to_responses
|
||
assigns_gender_to_responses
|
||
assigns_income_to_responses
|
||
assigns_ell_to_responses
|
||
assigns_races_to_students
|
||
is_idempotent_for_students
|
||
end
|
||
|
||
context "when updating student survey responses from another csv file" do
|
||
before :each do
|
||
SurveyResponsesDataLoader.new.load_data filepath: Rails.root.join("spec", "fixtures",
|
||
"secondary_test_2020-21_student_survey_responses.csv")
|
||
end
|
||
it "updates the likert score to the score on the new csv file" do
|
||
s_emsa_q1 = SurveyItem.find_by_survey_item_id "s-emsa-q1"
|
||
s_acst_q3 = SurveyItem.find_by_survey_item_id "s-acst-q3"
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_3",
|
||
survey_item: s_emsa_q1).first.likert_score).to eq 1
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_4",
|
||
survey_item: s_emsa_q1).first.likert_score).to eq 1
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_5",
|
||
survey_item: s_emsa_q1).first.likert_score).to eq 1
|
||
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_5",
|
||
survey_item: s_acst_q3).first.likert_score).to eq 4
|
||
end
|
||
end
|
||
end
|
||
|
||
describe "parent survey responses" do
|
||
before do
|
||
school
|
||
ay_2020_21
|
||
parent_survey_items
|
||
SurveyResponsesDataLoader.new.load_data filepath: path_to_parent_responses
|
||
end
|
||
|
||
it "adds only the surveyitems that exist in source of truth" do
|
||
si = (SurveyItemResponse.where(school:, response_id: "parent_survey_response_1").map do |response|
|
||
response.survey_item.survey_item_id
|
||
end)
|
||
response_ids = %w[
|
||
parent_survey_response_1
|
||
parent_survey_response_2
|
||
parent_survey_response_3
|
||
parent_survey_response_4
|
||
parent_survey_response_5
|
||
parent_survey_response_6
|
||
]
|
||
response_ids.each do |id|
|
||
expect(SurveyItemResponse.where(response_id: id,
|
||
survey_item: SurveyItem.parent_survey_items).count).to eq 23
|
||
end
|
||
|
||
expect(SurveyItemResponse.where(response_id: "parent_survey_response_7").count).to eq 0
|
||
end
|
||
|
||
it "does not add surveyitems from questions that have been disabled" do
|
||
vestigial_parent_ids.each do |id|
|
||
expect(SurveyItemResponse.where(school:, survey_item: id).count).to eq 0
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
def assigns_academic_year_to_survey_item_responses
|
||
expect(SurveyItemResponse.find_by_response_id("teacher_survey_response_1").academic_year).to eq ay_2020_21
|
||
end
|
||
|
||
def assigns_school_to_the_survey_item_responses
|
||
expect(SurveyItemResponse.find_by_response_id("teacher_survey_response_1").school).to eq school
|
||
end
|
||
|
||
def loads_survey_item_responses_for_a_given_survey_response
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_1").count).to eq 5
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_2").count).to eq 0
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_3").count).to eq 8
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_4").count).to eq 8
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_5").count).to eq 8
|
||
end
|
||
|
||
def loads_all_survey_item_responses_for_a_given_survey_item
|
||
expect(SurveyItemResponse.where(survey_item: t_pcom_q2).count).to eq 3
|
||
expect(SurveyItemResponse.where(survey_item: t_pcom_q3).count).to eq 4
|
||
end
|
||
|
||
def captures_likert_scores_for_survey_item_responses
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_1").where(survey_item: t_pcom_q2)).to be_empty
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_1").where(survey_item: t_pcom_q3).first.likert_score).to eq 3
|
||
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_2").where(survey_item: t_pcom_q2)).to be_empty
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_2").where(survey_item: t_pcom_q3)).to be_empty
|
||
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_3").where(survey_item: t_pcom_q2).first.likert_score).to eq 5
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_3").where(survey_item: t_pcom_q3).first.likert_score).to eq 5
|
||
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_4").where(survey_item: t_pcom_q2).first.likert_score).to eq 4
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_4").where(survey_item: t_pcom_q3).first.likert_score).to eq 4
|
||
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_5").where(survey_item: t_pcom_q2).first.likert_score).to eq 2
|
||
expect(SurveyItemResponse.where(response_id: "teacher_survey_response_5").where(survey_item: t_pcom_q3).first.likert_score).to eq 4
|
||
end
|
||
|
||
def is_idempotent
|
||
number_of_survey_item_responses = SurveyItemResponse.count
|
||
|
||
SurveyResponsesDataLoader.new.load_data filepath: path_to_teacher_responses
|
||
|
||
expect(SurveyItemResponse.count).to eq number_of_survey_item_responses
|
||
end
|
||
|
||
def assigns_academic_year_to_student_survey_item_responses
|
||
expect(SurveyItemResponse.find_by_response_id("student_survey_response_3").academic_year).to eq ay_2020_21
|
||
end
|
||
|
||
def assigns_school_to_student_survey_item_responses
|
||
expect(SurveyItemResponse.find_by_response_id("student_survey_response_3").school).to eq second_school
|
||
end
|
||
|
||
def loads_student_survey_item_response_values
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_1").count).to eq 3
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_2").count).to eq 0
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_3").count).to eq 30
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_4").count).to eq 27
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_5").count).to eq 30
|
||
end
|
||
|
||
def student_survey_item_response_count_matches_expected
|
||
s_phys_q1 = SurveyItem.where(survey_item_id: "s-phys-q1")
|
||
s_phys_q2 = SurveyItem.where(survey_item_id: "s-phys-q2")
|
||
expect(SurveyItemResponse.where(survey_item: s_phys_q1).count).to eq 6
|
||
expect(SurveyItemResponse.where(survey_item: s_phys_q2).count).to eq 5
|
||
end
|
||
|
||
def captures_likert_scores_for_student_survey_item_responses
|
||
s_phys_q1 = SurveyItem.where(survey_item_id: "s-phys-q1")
|
||
s_phys_q2 = SurveyItem.where(survey_item_id: "s-phys-q2")
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_1").where(survey_item: s_phys_q1).first.likert_score).to eq 3
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_1").where(survey_item: s_phys_q2)).to be_empty
|
||
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_2").where(survey_item: s_phys_q1)).to be_empty
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_2").where(survey_item: s_phys_q2)).to be_empty
|
||
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_3").where(survey_item: s_phys_q1).first.likert_score).to eq 1
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_3").where(survey_item: s_phys_q2).first.likert_score).to eq 3
|
||
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_4").where(survey_item: s_phys_q1).first.likert_score).to eq 1
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_4").where(survey_item: s_phys_q2).first.likert_score).to eq 1
|
||
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_5").where(survey_item: s_phys_q1).first.likert_score).to eq 1
|
||
expect(SurveyItemResponse.where(response_id: "student_survey_response_5").where(survey_item: s_phys_q2).first.likert_score).to eq 2
|
||
end
|
||
|
||
def is_idempotent_for_students
|
||
number_of_survey_item_responses = SurveyItemResponse.count
|
||
|
||
SurveyResponsesDataLoader.new.load_data filepath: path_to_student_responses
|
||
|
||
expect(SurveyItemResponse.count).to eq number_of_survey_item_responses
|
||
end
|
||
|
||
def assigns_grade_level_to_responses
|
||
results = { "student_survey_response_1" => 11,
|
||
"student_survey_response_3" => 8,
|
||
"student_survey_response_4" => 8,
|
||
"student_survey_response_5" => 7,
|
||
"student_survey_response_6" => 3,
|
||
"student_survey_response_7" => 4 }
|
||
results.each do |key, value|
|
||
expect(SurveyItemResponse.where(response_id: key).all? do |response|
|
||
response.grade == value
|
||
end).to eq true
|
||
end
|
||
end
|
||
|
||
def assigns_gender_to_responses
|
||
results = { "student_survey_response_1" => female,
|
||
"student_survey_response_3" => male,
|
||
"student_survey_response_4" => non_binary,
|
||
"student_survey_response_5" => non_binary,
|
||
"student_survey_response_6" => unknown_gender,
|
||
"student_survey_response_7" => non_binary }
|
||
|
||
results.each do |key, value|
|
||
expect(SurveyItemResponse.where(response_id: key).first.gender).to eq value
|
||
end
|
||
end
|
||
|
||
def assigns_recorded_date_to_student_responses
|
||
results = { "student_survey_response_1" => "2020-09-30T18:48:50",
|
||
"student_survey_response_3" => "2021-03-31T09:59:02",
|
||
"student_survey_response_4" => "2021-03-31T10:00:17",
|
||
"student_survey_response_5" => "2021-03-31T10:01:36",
|
||
"student_survey_response_6" => "2021-03-31T10:01:37",
|
||
"student_survey_response_7" => "2021-03-31T10:01:38" }
|
||
results.each do |key, value|
|
||
expect(SurveyItemResponse.find_by_response_id(key).recorded_date).to eq Date.parse(value)
|
||
end
|
||
end
|
||
|
||
def assigns_recorded_date_to_teacher_responses
|
||
results = { "teacher_survey_response_1" => "2020-10-16T11:09:03",
|
||
"teacher_survey_response_3" => "2020-12-06T8:36:52",
|
||
"teacher_survey_response_4" => "2020-12-06T8:51:25",
|
||
"teacher_survey_response_5" => "2020-12-06T8:55:58" }
|
||
results.each do |key, value|
|
||
expect(SurveyItemResponse.find_by_response_id(key).recorded_date).to eq Date.parse(value)
|
||
end
|
||
end
|
||
|
||
def assigns_income_to_responses
|
||
results = { "student_survey_response_1" => low_income,
|
||
"student_survey_response_3" => low_income,
|
||
"student_survey_response_4" => high_income,
|
||
"student_survey_response_5" => low_income,
|
||
"student_survey_response_6" => high_income,
|
||
"student_survey_response_7" => low_income }
|
||
|
||
results.each do |key, value|
|
||
income = SurveyItemResponse.find_by_response_id(key).income
|
||
expect(income).to eq value
|
||
end
|
||
end
|
||
|
||
def assigns_ell_to_responses
|
||
results = { "student_survey_response_1" => not_ell,
|
||
"student_survey_response_3" => not_ell,
|
||
"student_survey_response_4" => yes_ell,
|
||
"student_survey_response_5" => yes_ell,
|
||
"student_survey_response_6" => unknown_ell,
|
||
"student_survey_response_7" => unknown_ell }
|
||
|
||
results.each do |key, value|
|
||
ell = SurveyItemResponse.find_by_response_id(key).ell
|
||
expect(ell).to eq value
|
||
end
|
||
end
|
||
|
||
def assigns_races_to_students
|
||
results = { "student_survey_response_1" => [american_indian],
|
||
"student_survey_response_3" => [asian, black, latinx, multiracial],
|
||
"student_survey_response_4" => [unknown_race],
|
||
"student_survey_response_5" => [american_indian, asian, black, latinx, white, middle_eastern,
|
||
multiracial],
|
||
"student_survey_response_6" => [american_indian, asian, black, latinx, white, middle_eastern,
|
||
multiracial],
|
||
"student_survey_response_7" => [white] }
|
||
|
||
results.each do |key, value|
|
||
race = SurveyItemResponse.find_by_response_id(key).student.races.to_a
|
||
qualtrics = race.map(&:qualtrics_code)
|
||
expect(race).to eq value
|
||
end
|
||
end
|