From 9d8543afaeac8d68cf330679f5a41877b3253df2 Mon Sep 17 00:00:00 2001 From: rebuilt Date: Fri, 23 May 2025 16:35:12 -0700 Subject: [PATCH] feat: Update cleaner and uploader to load gender data from parent surveys Implement graph views for parent gender data --- app/models/parent.rb | 1 + app/models/survey_item_response.rb | 15 +++- .../analyze/graph/column/parent/base.rb | 78 +++++++++++++++++++ .../analyze/graph/column/parent/gender.rb | 39 ++++++++++ .../analyze/graph/column/parent/language.rb | 37 +-------- .../analyze/graph/column/parent/race.rb | 37 +-------- .../analyze/graph/parents_by_gender.rb | 42 ++++++++++ app/presenters/analyze/presenter.rb | 6 +- app/services/cleaner.rb | 2 +- app/services/survey_item_values.rb | 20 +++++ app/services/survey_responses_data_loader.rb | 4 + .../20250523222834_create_parent_genders.rb | 10 +++ db/schema.rb | 13 +++- .../test_2020-21_parent_survey_responses.csv | 12 +-- spec/services/cleaner_spec.rb | 2 +- .../survey_responses_data_loader_spec.rb | 42 +++++++--- 16 files changed, 262 insertions(+), 98 deletions(-) create mode 100644 app/presenters/analyze/graph/column/parent/base.rb create mode 100644 app/presenters/analyze/graph/column/parent/gender.rb create mode 100644 app/presenters/analyze/graph/parents_by_gender.rb create mode 100644 db/migrate/20250523222834_create_parent_genders.rb diff --git a/app/models/parent.rb b/app/models/parent.rb index 87b87d5e..0c535dff 100644 --- a/app/models/parent.rb +++ b/app/models/parent.rb @@ -3,4 +3,5 @@ class Parent < ApplicationRecord has_many :parent_languages has_and_belongs_to_many :languages, join_table: :parent_languages has_and_belongs_to_many :races, join_table: :parent_races + has_and_belongs_to_many :genders, join_table: :parent_genders end diff --git a/app/models/survey_item_response.rb b/app/models/survey_item_response.rb index 96bfdadc..278bbe2b 100644 --- a/app/models/survey_item_response.rb +++ b/app/models/survey_item_response.rb @@ -57,9 +57,18 @@ class SurveyItemResponse < ActiveRecord::Base else race.map(&:id) end - SurveyItemResponse.joins("JOIN parent_races on survey_item_responses.parent_id = parent_races.parent_id JOIN parents on parents.id = parent_races.parent_id").where( - school:, academic_year:, survey_item: survey_items - ).where("parent_races.race_id": id).group(:survey_item).having("count(*) >= 10").average(:likert_score) + + SurveyItemResponse.joins([parent: :races]).where(races: { id: }, survey_item: survey_items, school:, academic_year:).group(:survey_item).having("count(*) >= 10").average(:likert_score) + } + + scope :averages_for_parent_gender, lambda { |survey_items, school, academic_year, gender| + id = if gender.instance_of? ::Gender + gender.id + else + gender.map(&:id) + end + + SurveyItemResponse.joins([parent: :genders]).where(genders: { id: }, survey_item: survey_items, school:, academic_year:).group(:survey_item).having("count(*) >= 10").where.not(parent: nil).average(:likert_score) } scope :averages_for_language, lambda { |survey_items, school, academic_year, designations| diff --git a/app/presenters/analyze/graph/column/parent/base.rb b/app/presenters/analyze/graph/column/parent/base.rb new file mode 100644 index 00000000..593b6a4c --- /dev/null +++ b/app/presenters/analyze/graph/column/parent/base.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + module Parent + class Base + def label + raise NotImplementedError + end + + def basis + raise NotImplementedError + end + + def show_irrelevancy_message?(construct:) + raise NotImplementedError + end + + def show_insufficient_data_message?(construct:, school:, academic_years:) + raise NotImplementedError + end + + def insufficiency_message + raise NotImplementedError + end + + def score(construct:, school:, academic_year:) + raise NotImplementedError + end + + def type + raise NotImplementedError + end + + def n_size(construct:, school:, academic_year:) + raise NotImplementedError + end + + def show_insufficient_data_message?(construct:, school:, academic_years:) + false + end + + def basis + "parent surveys" + end + + def type + :parent + end + + def bubble_up_averages(construct:, averages:) + name = construct.class.name.downcase + send("#{name}_bubble_up_averages", construct:, averages:) + end + + def measure_bubble_up_averages(construct:, averages:) + construct.parent_scales.map do |scale| + scale_bubble_up_averages(construct: scale, averages:) + end.remove_blanks.average + end + + def scale_bubble_up_averages(construct:, averages:) + construct.survey_items.map do |survey_item| + averages[survey_item] + end.remove_blanks.average + end + + def show_irrelevancy_message?(construct:) + return false if @show_irrelevancy_message == false + + construct.survey_items.parent_survey_items.count.zero? + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/parent/gender.rb b/app/presenters/analyze/graph/column/parent/gender.rb new file mode 100644 index 00000000..abd00311 --- /dev/null +++ b/app/presenters/analyze/graph/column/parent/gender.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + module Parent + class Gender < Base + attr_reader :genders, :label + + def initialize(genders:, label:, show_irrelevancy_message:) + @genders = genders + @label = label + @show_irrelevancy_message = show_irrelevancy_message + end + + def n_size(construct:, school:, academic_year:) + id = if genders.instance_of? ::Gender + genders.id + else + genders.map(&:id) + end + SurveyItemResponse.joins([parent: :genders]).where(genders: { id: }, survey_item: construct.parent_survey_items, school:, academic_year:).select(:parent_id).distinct.count + end + + def score(construct:, school:, academic_year:) + return Score::NIL_SCORE if n_size(construct:, school:, academic_year:) < 10 + + averages = SurveyItemResponse.averages_for_parent_gender(construct.parent_survey_items, school, academic_year, genders) + average = bubble_up_averages(construct:, averages:).round(2) + Score.new(average:, + meets_teacher_threshold: false, + meets_student_threshold: true, + meets_admin_data_threshold: false) + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/parent/language.rb b/app/presenters/analyze/graph/column/parent/language.rb index d959a0b1..75d586af 100644 --- a/app/presenters/analyze/graph/column/parent/language.rb +++ b/app/presenters/analyze/graph/column/parent/language.rb @@ -4,7 +4,7 @@ module Analyze module Graph module Column module Parent - class Language < ColumnBase + class Language < Base attr_reader :language, :label def initialize(languages:, label:, show_irrelevancy_message:) @@ -13,18 +13,6 @@ module Analyze @show_irrelevancy_message = show_irrelevancy_message end - def basis - "parent surveys" - end - - def show_insufficient_data_message?(construct:, school:, academic_years:) - false - end - - def type - :parent - end - def n_size(construct:, school:, academic_year:) SurveyItemResponse.joins([parent: :languages]).where(languages: { designation: designations }, survey_item: construct.parent_survey_items, school:, academic_year:).select(:parent_id).distinct.count end @@ -44,29 +32,6 @@ module Analyze def designations language.map(&:designation) end - - def bubble_up_averages(construct:, averages:) - name = construct.class.name.downcase - send("#{name}_bubble_up_averages", construct:, averages:) - end - - def measure_bubble_up_averages(construct:, averages:) - construct.parent_scales.map do |scale| - scale_bubble_up_averages(construct: scale, averages:) - end.remove_blanks.average - end - - def scale_bubble_up_averages(construct:, averages:) - construct.survey_items.map do |survey_item| - averages[survey_item] - end.remove_blanks.average - end - - def show_irrelevancy_message?(construct:) - return false if @show_irrelevancy_message == false - - construct.survey_items.parent_survey_items.count.zero? - end end end end diff --git a/app/presenters/analyze/graph/column/parent/race.rb b/app/presenters/analyze/graph/column/parent/race.rb index 9cc23d98..ccad530a 100644 --- a/app/presenters/analyze/graph/column/parent/race.rb +++ b/app/presenters/analyze/graph/column/parent/race.rb @@ -4,7 +4,7 @@ module Analyze module Graph module Column module Parent - class Race < ColumnBase + class Race < Base attr_reader :race, :label def initialize(races:, label:, show_irrelevancy_message:) @@ -13,18 +13,6 @@ module Analyze @show_irrelevancy_message = show_irrelevancy_message end - def basis - "parent surveys" - end - - def show_insufficient_data_message?(construct:, school:, academic_years:) - false - end - - def type - :parent - end - def n_size(construct:, school:, academic_year:) designation = if race.instance_of? ::Race race.designation @@ -44,29 +32,6 @@ module Analyze meets_student_threshold: true, meets_admin_data_threshold: false) end - - def bubble_up_averages(construct:, averages:) - name = construct.class.name.downcase - send("#{name}_bubble_up_averages", construct:, averages:) - end - - def measure_bubble_up_averages(construct:, averages:) - construct.parent_scales.map do |scale| - scale_bubble_up_averages(construct: scale, averages:) - end.remove_blanks.average - end - - def scale_bubble_up_averages(construct:, averages:) - construct.survey_items.map do |survey_item| - averages[survey_item] - end.remove_blanks.average - end - - def show_irrelevancy_message?(construct:) - return false if @show_irrelevancy_message == false - - construct.survey_items.parent_survey_items.count.zero? - end end end end diff --git a/app/presenters/analyze/graph/parents_by_gender.rb b/app/presenters/analyze/graph/parents_by_gender.rb new file mode 100644 index 00000000..a3025463 --- /dev/null +++ b/app/presenters/analyze/graph/parents_by_gender.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Analyze + module Graph + class ParentsByGender + def to_s + "Parents by Gender" + end + + def slug + "parents-by-gender" + end + + def columns + [].tap do |array| + Gender.all.each do |gender| + label = if gender.designation.match(/\or\s/i) + [gender.designation.split("or").first.squish] + else + gender.designation.split(" ", 2).compact + end + + array << Analyze::Graph::Column::Parent::Gender.new(genders: gender, label:, show_irrelevancy_message: false) + end + array << Analyze::Graph::Column::Parent::Gender.new(genders: Gender.all, label: ["All Parent"], show_irrelevancy_message: true) + end + end + + def source + Analyze::Source::SurveyData.new(slices: nil, graph: self) + end + + def slice + Analyze::Slice::ParentsByGroup.new(graph: self) + end + + def group + Analyze::Group::Base.new(name: "Student Gender", slug: "student-gender", graph: self) + end + end + end +end diff --git a/app/presenters/analyze/presenter.rb b/app/presenters/analyze/presenter.rb index ac86ec38..f573596b 100644 --- a/app/presenters/analyze/presenter.rb +++ b/app/presenters/analyze/presenter.rb @@ -166,7 +166,8 @@ module Analyze "students-by-sped" => Analyze::Graph::StudentsBySped.new(speds: selected_speds), "students-by-ell" => Analyze::Graph::StudentsByEll.new(ells: selected_ells), "parents-by-race" => Analyze::Graph::ParentsByRace.new, - "parents-by-language" => Analyze::Graph::ParentsByLanguage.new } + "parents-by-language" => Analyze::Graph::ParentsByLanguage.new, + "parents-by-gender" => Analyze::Graph::ParentsByGender.new } end # The last item will per slice type will be selected as the default slice @@ -183,7 +184,8 @@ module Analyze "students-by-sped" => nil, "students-by-ell" => nil, "parents-by-race" => Analyze::Graph::ParentsByRace.new, - "parents-by-language" => Analyze::Graph::ParentsByLanguage.new } + "parents-by-language" => Analyze::Graph::ParentsByLanguage.new, + "parents-by-gender" => Analyze::Graph::ParentsByGender.new } end def graphs diff --git a/app/services/cleaner.rb b/app/services/cleaner.rb index e376445c..176a6421 100644 --- a/app/services/cleaner.rb +++ b/app/services/cleaner.rb @@ -79,7 +79,7 @@ class Cleaner headers = headers.to_set headers = headers.merge(Set.new(["Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", - "Race", "Gender", "Raw Housing Status", "Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents"])).to_a + "Race", "Gender", "Raw Housing Status", "Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents", "Declared Genders of Children from Parents"])).to_a filtered_headers = include_all_headers(headers:) filtered_headers = remove_unwanted_headers(headers: filtered_headers) log_headers = (filtered_headers + ["Valid Duration?", "Valid Progress?", "Valid Grade?", diff --git a/app/services/survey_item_values.rb b/app/services/survey_item_values.rb index 3853c910..001645e7 100644 --- a/app/services/survey_item_values.rb +++ b/app/services/survey_item_values.rb @@ -31,6 +31,7 @@ class SurveyItemValues row["Housing Status"] = housing row["Home Languages"] = languages.join(",") row["Declared Races of Children from Parents"] = races_of_children.join(",") + row["Declared Genders of Children from Parents"] = genders_of_children.join(",") end def normalize_headers(headers:) @@ -146,6 +147,25 @@ class SurveyItemValues end end + def genders_of_children + @genders_of_children ||= [].tap do |gender_codes| + matches = headers.select do |header| + # Explanation: + # ^: Start of the string. + # (?!.*text): Negative lookahead — ensures that the word text does not appear anywhere in the string. + # .*?: Lazily match any characters (to get to the word gender). + # gender: Match the word gender + header.match(/^(?!.*text).*?gender/i) + end + + matches.each do |match| + code = row[match]&.strip + gender_codes << Gender.qualtrics_code_from(code).to_i unless code.nil? + end + gender_codes << 99 if gender_codes.empty? + end.uniq.sort + end + def races @races ||= begin race_codes ||= self_report = value_from(pattern: /Race\s*self\s*report/i) diff --git a/app/services/survey_responses_data_loader.rb b/app/services/survey_responses_data_loader.rb index dadf943c..b9b3461d 100644 --- a/app/services/survey_responses_data_loader.rb +++ b/app/services/survey_responses_data_loader.rb @@ -118,6 +118,10 @@ class SurveyResponsesDataLoader tmp_races = row.races_of_children.map { |race| races[race] }.reject(&:nil?) parent.races.concat(tmp_races) + parent.genders.delete_all + tmp_genders = row.genders_of_children.map { |race| genders[race] }.reject(&:nil?) + parent.genders.concat(tmp_genders) + parent.housing = housings[row.housing] if row.housing.present? parent.save end diff --git a/db/migrate/20250523222834_create_parent_genders.rb b/db/migrate/20250523222834_create_parent_genders.rb new file mode 100644 index 00000000..a4e0f26d --- /dev/null +++ b/db/migrate/20250523222834_create_parent_genders.rb @@ -0,0 +1,10 @@ +class CreateParentGenders < ActiveRecord::Migration[8.0] + def change + create_table :parent_genders do |t| + t.references :parent, null: false, foreign_key: true + t.references :gender, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 1a36b311..8d0351f3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_05_15_205734) do +ActiveRecord::Schema[8.0].define(version: 2025_05_23_222834) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -330,6 +330,15 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_15_205734) do t.index ["subcategory_id"], name: "index_measures_on_subcategory_id" end + create_table "parent_genders", force: :cascade do |t| + t.bigint "parent_id", null: false + t.bigint "gender_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["gender_id"], name: "index_parent_genders_on_gender_id" + t.index ["parent_id"], name: "index_parent_genders_on_parent_id" + end + create_table "parent_languages", force: :cascade do |t| t.bigint "parent_id", null: false t.bigint "language_id", null: false @@ -543,6 +552,8 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_15_205734) do add_foreign_key "legacy_school_categories", "legacy_categories", column: "category_id" add_foreign_key "legacy_school_categories", "legacy_schools", column: "school_id" add_foreign_key "measures", "subcategories" + add_foreign_key "parent_genders", "genders" + add_foreign_key "parent_genders", "parents" add_foreign_key "parent_languages", "languages" add_foreign_key "parent_languages", "parents" add_foreign_key "parent_races", "parents" diff --git a/spec/fixtures/test_2020-21_parent_survey_responses.csv b/spec/fixtures/test_2020-21_parent_survey_responses.csv index 2c14d476..6b0507d9 100644 --- a/spec/fixtures/test_2020-21_parent_survey_responses.csv +++ b/spec/fixtures/test_2020-21_parent_survey_responses.csv @@ -1,9 +1,9 @@ StartDate,EndDate,Status,IPAddress,Progress,Duration (in seconds),Finished,RecordedDate,ResponseId,DistributionChannel,UserLanguage,DESE ID,Number of Children,Gender-1,Gender-1_7_TEXT,Race-1,Race-1_7_TEXT,Gender-2,Gender-2_7_TEXT,Race-2,Race-2_7_TEXT,Gender-3,Gender-3_7_TEXT,Race-3,Race-3_7_TEXT,Gender-4,Gender-4_7_TEXT,Race-4,Race-4_7_TEXT,Gender-5,Gender-5_7_TEXT,Race-5,Race-5_7_TEXT,Gender,Gender_7_TEXT,p-scrp-q3,p-scrp-q2,p-valm-q1,p-valm-q2,p-valm-q3,p-valm-q4,p-comm-q1,p-comm-q2,p-comm-q3,p-tcom-q1,P-tcom-q2,p-tcom-q3,p-evnt-q4,p-comm-q4,p-evnt-q3,p-evnt-q1,p-evnt-q2,p-socx-q3,p-socx-q4,p-scrp-q1,p-socx-q1,p-sosu-q1,p-sosu-q2,p-sosu-q3,p-socx-q2,p-sosu-q4,p-phys-q3,p-acpr-q1,p-acpr-q2,p-acpr-q3,p-acpr-q4,p-cure-q1,p-cure-q2,p-cure-q3,p-cure-q4,Housing,Housing_100_TEXT,Employment,Employment_100_TEXT,Caregivers,Caregivers_100_TEXT,Education,Education_100_TEXT,Benefits,Benefits_100_TEXT,Language,Language_100_TEXT,Raw Income,Income,Raw ELL,ELL,Raw SpEd,SpEd,Progress Count 5/1/2024 10:04:34,5/1/2024 10:10:49,0,72.93.86.98,100,374,1,2021-03-31T10:01:36,parent_survey_response_1,email,EN,1500025,1,,,1,,,,,,,,,,,,,,,,,,2,,4,5,5,4,5,5,5,5,5,4,4,5,4,5,3,4,5,4,4,5,5,5,5,5,5,5,1,2,2,2,1,4,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 5/1/2024 10:03:52,5/1/2024 10:14:42,0,73.69.182.58,100,649,1,2021-04-01T10:01:36,parent_survey_response_2,email,EN,1500025,1,,,,,,,,,,,6,,,,7,,,,,,1,,4,4,5,5,5,5,5,5,5,5,5,5,3,5,4,5,5,5,5,5,4,4,4,4,5,5,1,5,4,5,5,5,5,5,5,1,,99,,2,,3,,1,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 -5/1/2024 10:06:44,5/1/2024 10:15:41,0,50.235.109.170,100,537,1,2021-04-02T10:01:36,parent_survey_response_3,email,EN,1500025,2,2,,4,,2,,"1,5",,,,,,,,,,,,,,2,,5,5,5,4,5,5,5,5,5,4,4,5,4,4,3,4,4,4,4,5,4,4,5,5,2,5,3,4,4,4,4,5,5,5,5,1,,1,,3,,6,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 -5/1/2024 10:14:23,5/1/2024 10:22:22,0,73.38.238.192,100,478,1,2021-04-03T10:01:36,parent_survey_response_4,email,EN,1500025,1,,,,,,,,,,,,,,,,,,,,,1,,5,5,5,5,5,5,5,4,5,4,4,4,2,5,4,5,4,5,5,5,3,5,5,5,2,5,1,5,5,5,5,5,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 -5/1/2024 10:18:39,5/1/2024 10:23:49,0,73.69.158.255,100,310,1,2021-04-04T10:01:36,parent_survey_response_5,email,EN,1500025,2,2,,"1,2,3",,1,,"4,5,8",,,,,,,,,,,,,,2,,5,4,5,5,5,5,1,1,1,1,1,1,3,1,4,4,5,1,1,1,4,1,1,1,4,5,1,5,5,5,5,1,5,1,1,1,,"2,4",,3,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 -5/1/2024 10:20:30,5/1/2024 10:25:16,0,73.182.146.201,100,285,1,2021-04-05T10:01:36,parent_survey_response_6,email,EN,1500025,1,,,,,,,,,,,,,,,1,,,,"2,3,4,5,8",,1,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,2,,2,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 -5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_7,email,EN,1500025,2,1,,5,,1,,5,,,,,,,,,,,,,,1,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 -5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_8,email,EN,1500025,2,1,,5,,1,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +5/1/2024 10:06:44,5/1/2024 10:15:41,0,50.235.109.170,100,537,1,2021-04-02T10:01:36,parent_survey_response_3,email,EN,1500025,2,1,,4,,2,,"1,5",,,,,,,,,,,,,,2,,5,5,5,4,5,5,5,5,5,4,4,5,4,4,3,4,4,4,4,5,4,4,5,5,2,5,3,4,4,4,4,5,5,5,5,1,,1,,3,,6,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 +5/1/2024 10:14:23,5/1/2024 10:22:22,0,73.38.238.192,100,478,1,2021-04-03T10:01:36,parent_survey_response_4,email,EN,1500025,1,3,,7,,,,,,,,,,,,,,,,,,4,,5,5,5,5,5,5,5,4,5,4,4,4,2,5,4,5,4,5,5,5,3,5,5,5,2,5,1,5,5,5,5,5,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 +5/1/2024 10:18:39,5/1/2024 10:23:49,0,73.69.158.255,100,310,1,2021-04-04T10:01:36,parent_survey_response_5,email,EN,1500025,2,2,,"1,2,3",,,,"4,5,8",,,,,,,,,,,,,,2,,5,4,5,5,5,5,1,1,1,1,1,1,3,1,4,4,5,1,1,1,4,1,1,1,4,5,1,5,5,5,5,1,5,1,1,1,,"2,4",,3,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 +5/1/2024 10:20:30,5/1/2024 10:25:16,0,73.182.146.201,100,285,1,2021-04-05T10:01:36,parent_survey_response_6,email,EN,1500025,1,,,,,,,,,,,,,,,1,,,,"2,3,4,5,8",,,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,2,,2,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 +5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_7,email,EN,1500025,2,6,,5,,,,5,,,,,,,,,,,,,,,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34 +5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_8,email,EN,1500025,2,Prefer not to disclose,,5,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/spec/services/cleaner_spec.rb b/spec/services/cleaner_spec.rb index 12851edd..7e563b39 100644 --- a/spec/services/cleaner_spec.rb +++ b/spec/services/cleaner_spec.rb @@ -315,7 +315,7 @@ def reads_headers_from_raw_csv(processed_data) "s-grit-q1", "s-grit-q2", "s-grit-q3", "s-grit-q4", "s-expa-q1", "s-poaf-q1", "s-poaf-q2", "s-poaf-q3", "s-poaf-q4", "s-tint-q1-1", "s-tint-q2-1", "s-tint-q3-1", "s-tint-q4-1", "s-tint-q5-1", "s-acpr-q1-1", "s-acpr-q2-1", "s-acpr-q3-1", "s-acpr-q4-1", "s-peff-q1-1", "s-peff-q2-1", "s-peff-q3-1", "s-peff-q4-1", - "s-peff-q5-1", "s-peff-q6-1", "Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", "Housing Status", "Raw Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents"].to_set.sort + "s-peff-q5-1", "s-peff-q6-1", "Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", "Housing Status", "Raw Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents", "Declared Genders of Children from Parents"].to_set.sort end def invalid_rows_are_rejected_for_the_correct_reasons(data) diff --git a/spec/services/survey_responses_data_loader_spec.rb b/spec/services/survey_responses_data_loader_spec.rb index e3b5a1bb..3655c30d 100644 --- a/spec/services/survey_responses_data_loader_spec.rb +++ b/spec/services/survey_responses_data_loader_spec.rb @@ -129,12 +129,12 @@ describe SurveyResponsesDataLoader do let(:unknown_race) { create(:race, qualtrics_code: 99, designation: "Race/Ethnicity Not Listed") } let(:multiracial) { create(:race, qualtrics_code: 100, designation: "Multiracial") } - let(:languages){ + let(:languages) do create(:language, designation: "English") create(:language, designation: "Spanish") create(:language, designation: "Portuguese") create(:language, designation: "Unknown") - } + end let(:setup) do ay_2020_21 @@ -277,6 +277,10 @@ describe SurveyResponsesDataLoader do it "loads the correct set of races for parents" do assigns_races_to_parents end + + it "loads the correct set of genders for parents" do + assigns_genders_to_parents + end end end @@ -470,18 +474,18 @@ def assigns_races_to_students end end - def assigns_races_to_parents results = { - "parent_survey_response_1" => [american_indian], - "parent_survey_response_2" => [unknown_race], - "parent_survey_response_3" => [american_indian, latinx, white, multiracial], - "parent_survey_response_4" => [unknown_race], - "parent_survey_response_5" => [american_indian, asian, black, latinx, white, middle_eastern, - multiracial], - "parent_survey_response_6" => [american_indian, asian, black, latinx, white, middle_eastern, - multiracial], - "parent_survey_response_7" => [white] } + "parent_survey_response_1" => [american_indian], + "parent_survey_response_2" => [unknown_race], + "parent_survey_response_3" => [american_indian, latinx, white, multiracial], + "parent_survey_response_4" => [unknown_race], + "parent_survey_response_5" => [american_indian, asian, black, latinx, white, middle_eastern, + multiracial], + "parent_survey_response_6" => [american_indian, asian, black, latinx, white, middle_eastern, + multiracial], + "parent_survey_response_7" => [white] + } results.each do |key, value| race = SurveyItemResponse.find_by_response_id(key).parent.races.to_a @@ -489,3 +493,17 @@ def assigns_races_to_parents expect(race).to eq value end end + +def assigns_genders_to_parents + results = { "parent_survey_response_1" => [male], + "parent_survey_response_2" => [female], + "parent_survey_response_3" => [female, male], + "parent_survey_response_4" => [non_binary], + "parent_survey_response_5" => [male], + "parent_survey_response_6" => [unknown_gender] } + # "parent_survey_response_7" => [non_binary] } + + results.each do |key, value| + expect(SurveyItemResponse.where(response_id: key).first.parent.genders).to eq value + end +end