Add benchmarks to survey and admin data items. Remove them from measures. Modify seeder

Calculate benchmarks for measures based on a weighted average of survey
and admin data items

Added architectural records
pull/1/head
Nelson Jovel 4 years ago
parent 1a6c81e240
commit ad03606d66

@ -1,19 +1,18 @@
source 'https://rubygems.org' source 'https://rubygems.org'
ruby "3.0.2" ruby '3.0.2'
git_source(:github) do |repo_name| git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
"https://github.com/#{repo_name}.git" "https://github.com/#{repo_name}.git"
end end
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.1.4.1' gem 'rails', '~> 6.1.4.1'
gem 'pg' gem 'pg'
# Use Puma as the app server # Use Puma as the app server
gem "puma", ">= 5.5.2" gem 'puma', '>= 5.5.2'
# Use SCSS for stylesheets # Use SCSS for stylesheets
gem 'sassc-rails', require: false gem 'sassc-rails', require: false
# Use Uglifier as compressor for JavaScript assets # Use Uglifier as compressor for JavaScript assets
@ -33,7 +32,7 @@ gem 'jbuilder', '~> 2.5'
# Use Capistrano for deployment # Use Capistrano for deployment
# gem 'capistrano-rails', group: :development # gem 'capistrano-rails', group: :development
gem "nokogiri", ">= 1.12.5" gem 'nokogiri', '>= 1.12.5'
gem 'bootsnap', require: false gem 'bootsnap', require: false
@ -64,24 +63,24 @@ end
group :development do group :development do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code. # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console'
gem 'listen', '~> 3.0.5' gem 'listen', '~> 3.0.5'
gem 'web-console'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'nested_scaffold'
gem 'seed_dump'
gem 'spring' gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0' gem 'spring-watcher-listen', '~> 2.0.0'
gem 'seed_dump'
gem 'nested_scaffold'
end end
group 'test' do group 'test' do
gem 'rspec-rails', '~> 4.1.2'
gem 'rails-controller-testing'
gem 'capybara'
gem 'apparition', github: 'twalpole/apparition', ref: 'ca86be4d54af835d531dbcd2b86e7b2c77f85f34' gem 'apparition', github: 'twalpole/apparition', ref: 'ca86be4d54af835d531dbcd2b86e7b2c77f85f34'
gem 'launchy' gem 'capybara'
gem 'database_cleaner' gem 'database_cleaner'
gem 'launchy'
gem 'rails-controller-testing'
gem 'rspec-rails', '~> 4.1.2'
gem 'timecop' gem 'timecop'
end end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

@ -1,9 +1,7 @@
class CategoriesController < SqmApplicationController class CategoriesController < SqmApplicationController
def show def show
@categories = Category.sorted.map { |category| CategoryPresenter.new(category: category) } @categories = Category.sorted.map { |category| CategoryPresenter.new(category: category) }
@category = CategoryPresenter.new(category: Category.find_by_slug(params[:id])) @category = CategoryPresenter.new(category: Category.find_by_slug(params[:id]))
end end
end end

@ -1,8 +1,5 @@
module Legacy module Legacy
class AdminController < Legacy::ApplicationController class AdminController < Legacy::ApplicationController
def index; end
def index
end
end end
end end

@ -2,21 +2,21 @@ module Legacy
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, prepend: true protect_from_forgery with: :exception, prepend: true
layout "legacy/application" layout 'legacy/application'
def verify_admin def verify_admin
return true #if current_user.admin?(@school) return true # if current_user.admin?(@school)
redirect_to root_path, notice: 'You must be logged in as an admin of that school to access that page.' redirect_to root_path, notice: 'You must be logged in as an admin of that school to access that page.'
return false false
end end
def authenticate(username, password) def authenticate(username, password)
return true if username == "boston" return true if username == 'boston'
authenticate_or_request_with_http_basic do |u, p| authenticate_or_request_with_http_basic do |u, p|
u == username && p == password u == username && p == password
end end
end end
end end
end end

@ -1,7 +1,7 @@
module Legacy module Legacy
class AttemptsController < Legacy::ApplicationController class AttemptsController < Legacy::ApplicationController
# before_action :set_attempt, only: [:edit, :update] # before_action :set_attempt, only: [:edit, :update]
protect_from_forgery :except => [:twilio] protect_from_forgery except: [:twilio]
def twilio def twilio
recipient = Recipient.where(phone: twilio_params['From']).first recipient = Recipient.where(phone: twilio_params['From']).first
@ -15,19 +15,19 @@ module Legacy
twilio_details: all_twilio_details.join('~!~') twilio_details: all_twilio_details.join('~!~')
) )
unless (['start', 'resume', 'restart', 'yes', 'go'].index(twilio_params[:Body].downcase).nil?) unless %w[start resume restart yes go].index(twilio_params[:Body].downcase).nil?
recipient.update(opted_out: false) recipient.update(opted_out: false)
render plain: 'Thank you, you will now begin receiving messages again.' render plain: 'Thank you, you will now begin receiving messages again.'
return return
end end
unless (['stop', 'cancel', 'quit', 'no'].index(twilio_params[:Body].downcase).nil?) unless %w[stop cancel quit no].index(twilio_params[:Body].downcase).nil?
recipient.update(opted_out: true) recipient.update(opted_out: true)
render plain: 'Thank you, you have been opted out of these messages and will no longer receive them.' render plain: 'Thank you, you have been opted out of these messages and will no longer receive them.'
return return
end end
unless (['skip', 'i dont know', "i don't know", 'next'].index(twilio_params[:Body].downcase).nil?) unless ['skip', 'i dont know', "i don't know", 'next'].index(twilio_params[:Body].downcase).nil?
render plain: 'Thank you, this question has been skipped.' render plain: 'Thank you, this question has been skipped.'
return return
end end
@ -90,8 +90,10 @@ module Legacy
# Never trust parameters from the scary internet, only allow the white list through. # Never trust parameters from the scary internet, only allow the white list through.
def twilio_params def twilio_params
{ "Body" => "5", "" => "US", "To" => "+16172023890", "ToZip" => "02135", "NumSegments" => "1", "MessageSid" => "SMe37977e625b7f0b429339e752dddefef", "AccountSid" => "AC57dc8a5a6d75addb9528e730e92f66b2", "From" => "+16502693205", "ApiVersion" => "2010-04-01" } { 'Body' => '5', '' => 'US', 'To' => '+16172023890', 'ToZip' => '02135', 'NumSegments' => '1',
params.permit(:FromCountry, :FromState, :FromZip, :FromCity, :ToCountry, :ToState, :SmsStatus, :SmsSid, :SmsMessageSid, :MessageSid, :AccountSid, :MessagingServiceSid, :From, :To, :Body, :NumMedia) 'MessageSid' => 'SMe37977e625b7f0b429339e752dddefef', 'AccountSid' => 'AC57dc8a5a6d75addb9528e730e92f66b2', 'From' => '+16502693205', 'ApiVersion' => '2010-04-01' }
params.permit(:FromCountry, :FromState, :FromZip, :FromCity, :ToCountry, :ToState, :SmsStatus, :SmsSid,
:SmsMessageSid, :MessageSid, :AccountSid, :MessagingServiceSid, :From, :To, :Body, :NumMedia)
end end
end end
end end

@ -1,7 +1,7 @@
module Legacy module Legacy
class CategoriesController < Legacy::ApplicationController class CategoriesController < Legacy::ApplicationController
before_action :set_school, only: [:show] before_action :set_school, only: [:show]
before_action :set_category, only: [:show, :edit, :update, :destroy] before_action :set_category, only: %i[show edit update destroy]
# GET /categories # GET /categories
# GET /categories.json # GET /categories.json
@ -17,7 +17,7 @@ module Legacy
school_categories = SchoolCategory.for(@school, @category) school_categories = SchoolCategory.for(@school, @category)
@years = school_categories.map(&:year).map(&:to_i).sort @years = school_categories.map(&:year).map(&:to_i).sort
@year = (params[:year] || @years.last || "2019").to_i @year = (params[:year] || @years.last || '2019').to_i
if school_categories.empty? if school_categories.empty?
school_categories = [SchoolCategory.new(school: @school, category: @category, year: @year)] school_categories = [SchoolCategory.new(school: @school, category: @category, year: @year)]
@ -28,12 +28,11 @@ module Legacy
missing_categories = Legacy::Category.for_parent(@category) - @child_school_categories.map(&:category) missing_categories = Legacy::Category.for_parent(@category) - @child_school_categories.map(&:category)
missing_categories.each do |category| missing_categories.each do |category|
next if category.benchmark.present? next if category.benchmark.present?
@child_school_categories << category.school_categories.new(school: @school) @child_school_categories << category.school_categories.new(school: @school)
end end
if district.name == "Boston" @child_school_categories = @child_school_categories.reject { |csc| csc.admin? } if district.name == 'Boston'
@child_school_categories = @child_school_categories.reject { |csc| csc.admin? }
end
@questions = @category.questions.created_in(@year) @questions = @category.questions.created_in(@year)
end end
@ -44,8 +43,7 @@ module Legacy
end end
# GET /categories/1/edit # GET /categories/1/edit
def edit def edit; end
end
# POST /categories # POST /categories
# POST /categories.json # POST /categories.json
@ -91,6 +89,7 @@ module Legacy
def set_school def set_school
redirect_to root_path and return false unless params.include?(:school_id) redirect_to root_path and return false unless params.include?(:school_id)
@school = Legacy::School.friendly.find(params[:school_id]) @school = Legacy::School.friendly.find(params[:school_id])
redirect_to root_path and return false if @school.nil? redirect_to root_path and return false if @school.nil?
end end

@ -1,6 +1,6 @@
module Legacy module Legacy
class DistrictsController < Legacy::ApplicationController class DistrictsController < Legacy::ApplicationController
before_action :set_district, only: [:show, :edit, :update, :destroy] before_action :set_district, only: %i[show edit update destroy]
# GET /districts # GET /districts
# GET /districts.json # GET /districts.json
@ -21,8 +21,7 @@ module Legacy
end end
# GET /districts/1/edit # GET /districts/1/edit
def edit def edit; end
end
# POST /districts # POST /districts
# POST /districts.json # POST /districts.json

@ -1,6 +1,6 @@
module Legacy module Legacy
class QuestionListsController < Legacy::ApplicationController class QuestionListsController < Legacy::ApplicationController
before_action :set_question_list, only: [:show, :edit, :update, :destroy] before_action :set_question_list, only: %i[show edit update destroy]
# GET /question_lists # GET /question_lists
# GET /question_lists.json # GET /question_lists.json
@ -10,8 +10,7 @@ module Legacy
# GET /question_lists/1 # GET /question_lists/1
# GET /question_lists/1.json # GET /question_lists/1.json
def show def show; end
end
# GET /question_lists/new # GET /question_lists/new
def new def new
@ -19,8 +18,7 @@ module Legacy
end end
# GET /question_lists/1/edit # GET /question_lists/1/edit
def edit def edit; end
end
# POST /question_lists # POST /question_lists
# POST /question_lists.json # POST /question_lists.json

@ -3,7 +3,7 @@ module Legacy
before_action :authenticate_user!, except: [:show] before_action :authenticate_user!, except: [:show]
before_action :verify_super_admin, except: [:show] before_action :verify_super_admin, except: [:show]
before_action :set_school, only: [:show] before_action :set_school, only: [:show]
before_action :set_question, only: [:show, :edit, :update, :destroy] before_action :set_question, only: %i[show edit update destroy]
# GET /questions # GET /questions
# GET /questions.json # GET /questions.json
@ -13,8 +13,7 @@ module Legacy
# GET /questions/1 # GET /questions/1
# GET /questions/1.json # GET /questions/1.json
def show def show; end
end
# GET /questions/new # GET /questions/new
def new def new
@ -22,8 +21,7 @@ module Legacy
end end
# GET /questions/1/edit # GET /questions/1/edit
def edit def edit; end
end
# POST /questions # POST /questions
# POST /questions.json # POST /questions.json
@ -69,6 +67,7 @@ module Legacy
def set_school def set_school
redirect_to root_path and return false unless params.include?(:school_id) redirect_to root_path and return false unless params.include?(:school_id)
@school = Legacy::School.friendly.find(params[:school_id]) @school = Legacy::School.friendly.find(params[:school_id])
redirect_to root_path and return false if @school.nil? redirect_to root_path and return false if @school.nil?
end end

@ -3,7 +3,7 @@ module Legacy
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_school before_action :set_school
before_action :verify_admin before_action :verify_admin
before_action :set_recipient_list, only: [:show, :edit, :update, :destroy] before_action :set_recipient_list, only: %i[show edit update destroy]
# GET schools/1/recipient_lists # GET schools/1/recipient_lists
def index def index
@ -11,8 +11,7 @@ module Legacy
end end
# GET schools/1/recipient_lists/1 # GET schools/1/recipient_lists/1
def show def show; end
end
# GET schools/1/recipient_lists/new # GET schools/1/recipient_lists/new
def new def new
@ -20,8 +19,7 @@ module Legacy
end end
# GET schools/1/recipient_lists/1/edit # GET schools/1/recipient_lists/1/edit
def edit def edit; end
end
# POST schools/1/recipient_lists # POST schools/1/recipient_lists
def create def create

@ -3,7 +3,7 @@ module Legacy
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_school before_action :set_school
before_action :verify_admin before_action :verify_admin
before_action :set_recipient, only: [:show, :edit, :update, :destroy] before_action :set_recipient, only: %i[show edit update destroy]
# GET /recipients # GET /recipients
# GET /recipients.json # GET /recipients.json
@ -13,8 +13,7 @@ module Legacy
# GET /recipients/1 # GET /recipients/1
# GET /recipients/1.json # GET /recipients/1.json
def show def show; end
end
# GET /recipients/new # GET /recipients/new
def new def new
@ -22,8 +21,7 @@ module Legacy
end end
# GET /recipients/1/edit # GET /recipients/1/edit
def edit def edit; end
end
# POST /recipients # POST /recipients
# POST /recipients.json # POST /recipients.json
@ -32,7 +30,10 @@ module Legacy
respond_to do |format| respond_to do |format|
if @recipient.save if @recipient.save
format.html { redirect_to legacy_school_legacy_recipient_path(@school, @recipient), notice: 'Recipient was successfully created.' } format.html do
redirect_to legacy_school_legacy_recipient_path(@school, @recipient),
notice: 'Recipient was successfully created.'
end
format.json { render :show, status: :created, location: @recipient } format.json { render :show, status: :created, location: @recipient }
else else
format.html { render :new } format.html { render :new }
@ -45,7 +46,7 @@ module Legacy
render and return if request.get? render and return if request.get?
Recipient.import(@school, params[:file]) Recipient.import(@school, params[:file])
redirect_to @school, notice: "Recipients imported." redirect_to @school, notice: 'Recipients imported.'
end end
# PATCH/PUT /recipients/1 # PATCH/PUT /recipients/1
@ -53,7 +54,10 @@ module Legacy
def update def update
respond_to do |format| respond_to do |format|
if @recipient.update(recipient_params) if @recipient.update(recipient_params)
format.html { redirect_to legacy_school_legacy_recipient_path(@school, @recipient), notice: 'Recipient was successfully updated.' } format.html do
redirect_to legacy_school_legacy_recipient_path(@school, @recipient),
notice: 'Recipient was successfully updated.'
end
format.json { render :show, status: :ok, location: @recipient } format.json { render :show, status: :ok, location: @recipient }
else else
format.html { render :edit } format.html { render :edit }
@ -86,7 +90,8 @@ module Legacy
# Never trust parameters from the scary internet, only allow the white list through. # Never trust parameters from the scary internet, only allow the white list through.
def recipient_params def recipient_params
params.require(:recipient).permit(:name, :phone, :birth_date, :gender, :race, :ethnicity, :home_language_id, :income, :opted_out, :school_id) params.require(:recipient).permit(:name, :phone, :birth_date, :gender, :race, :ethnicity, :home_language_id,
:income, :opted_out, :school_id)
end end
end end
end end

@ -3,12 +3,11 @@ module Legacy
before_action :authenticate_user!, except: [:show] before_action :authenticate_user!, except: [:show]
before_action :set_school before_action :set_school
before_action :verify_admin before_action :verify_admin
before_action :set_schedule, only: [:show, :edit, :update, :destroy] before_action :set_schedule, only: %i[show edit update destroy]
before_action :set_time, only: [:create, :update] before_action :set_time, only: %i[create update]
# GET schools/1/schedules/1 # GET schools/1/schedules/1
def show def show; end
end
# GET schools/1/schedules/new # GET schools/1/schedules/new
def new def new
@ -16,8 +15,7 @@ module Legacy
end end
# GET schools/1/schedules/1/edit # GET schools/1/schedules/1/edit
def edit def edit; end
end
# POST schools/1/schedules # POST schools/1/schedules
def create def create
@ -59,13 +57,14 @@ module Legacy
# Only allow a trusted parameter "white list" through. # Only allow a trusted parameter "white list" through.
def schedule_params def schedule_params
params.require(:schedule).permit(:name, :description, :school_id, :frequency_hours, :start_date, :end_date, :time, :active, :random, :recipient_list_id, :question_list_id) params.require(:schedule).permit(:name, :description, :school_id, :frequency_hours, :start_date, :end_date,
:time, :active, :random, :recipient_list_id, :question_list_id)
end end
def set_time def set_time
return unless schedule_params.include?(:time) return unless schedule_params.include?(:time)
params[:schedule][:time] = schedule_params[:time].to_i + (4 * 60) # Go from EST to UTC (NEEDS TO BETTER) params[:schedule][:time] = schedule_params[:time].to_i + (4 * 60) # Go from EST to UTC (NEEDS TO BETTER)
end end
end end
end end

@ -1,8 +1,8 @@
module Legacy module Legacy
class SchoolsController < Legacy::ApplicationController class SchoolsController < Legacy::ApplicationController
before_action :authenticate_user!, except: [:show] before_action :authenticate_user!, except: [:show]
before_action :set_school, only: [:admin, :show, :edit, :update, :destroy] before_action :set_school, only: %i[admin show edit update destroy]
before_action :verify_admin, except: [:show, :create, :new] before_action :verify_admin, except: %i[show create new]
# GET /schools/1 # GET /schools/1
# GET /schools/1.json # GET /schools/1.json
@ -13,7 +13,7 @@ module Legacy
@years = [2017, 2018, 2019] @years = [2017, 2018, 2019]
@year = (params[:year] || @years.last).to_i @year = (params[:year] || @years.last).to_i
if @district.name == "Boston" if @district.name == 'Boston'
@categories = Legacy::Category.joins(:questions) @categories = Legacy::Category.joins(:questions)
@school_categories = SchoolCategory.where(school: @school).where(category: @categories).in(@year).to_a @school_categories = SchoolCategory.where(school: @school).where(category: @categories).in(@year).to_a
else else
@ -29,8 +29,7 @@ module Legacy
@school_categories = @school_categories.select { |sc| sc.year.to_i == @year } @school_categories = @school_categories.select { |sc| sc.year.to_i == @year }
end end
def admin def admin; end
end
# GET /schools/new # GET /schools/new
def new def new
@ -38,8 +37,7 @@ module Legacy
end end
# GET /schools/1/edit # GET /schools/1/edit
def edit def edit; end
end
# POST /schools # POST /schools
# POST /schools.json # POST /schools.json
@ -92,6 +90,5 @@ module Legacy
def school_params def school_params
params.require(:school).permit(:name, :district_id) params.require(:school).permit(:name, :district_id)
end end
end end
end end

@ -1,10 +1,8 @@
module Legacy module Legacy
class WelcomeController < Legacy::ApplicationController class WelcomeController < Legacy::ApplicationController
def index def index
@districts = Legacy::District.all.alphabetic @districts = Legacy::District.all.alphabetic
@schools = Legacy::School.all.alphabetic @schools = Legacy::School.all.alphabetic
end end
end end
end end

@ -1,5 +1,4 @@
class OverviewController < SqmApplicationController class OverviewController < SqmApplicationController
def index def index
@variance_chart_row_presenters = Measure.all.map(&method(:presenter_for_measure)) @variance_chart_row_presenters = Measure.all.map(&method(:presenter_for_measure))
@category_presenters = Category.sorted.map { |category| CategoryPresenter.new(category: category) } @category_presenters = Category.sorted.map { |category| CategoryPresenter.new(category: category) }

@ -27,7 +27,8 @@ class SqmApplicationController < ApplicationController
end end
def authenticate(username, password) def authenticate(username, password)
return true if username == "boston" return true if username == 'boston'
authenticate_or_request_with_http_basic do |u, p| authenticate_or_request_with_http_basic do |u, p|
u == username && p == password u == username && p == password
end end

@ -21,8 +21,8 @@ module GaugeHelper
def viewbox def viewbox
x = arc_center.x - (outer_radius + stroke_width) x = arc_center.x - (outer_radius + stroke_width)
y = arc_center.y - (outer_radius + stroke_width) - key_benchmark_indicator_gutter y = arc_center.y - (outer_radius + stroke_width) - key_benchmark_indicator_gutter
width = 2*(outer_radius + stroke_width) width = 2 * (outer_radius + stroke_width)
height = outer_radius + 2*stroke_width + key_benchmark_indicator_gutter height = outer_radius + 2 * stroke_width + key_benchmark_indicator_gutter
Rect.new(x, y, width, height) Rect.new(x, y, width, height)
end end
@ -35,11 +35,13 @@ module GaugeHelper
end end
def indicator_right_corner def indicator_right_corner
Point.new(key_benchmark_indicator_gutter/Math.sqrt(3), arc_center.y - outer_radius - key_benchmark_indicator_gutter) Point.new(key_benchmark_indicator_gutter / Math.sqrt(3),
arc_center.y - outer_radius - key_benchmark_indicator_gutter)
end end
def indicator_left_corner def indicator_left_corner
Point.new(-key_benchmark_indicator_gutter/Math.sqrt(3), arc_center.y - outer_radius - key_benchmark_indicator_gutter) Point.new(-key_benchmark_indicator_gutter / Math.sqrt(3),
arc_center.y - outer_radius - key_benchmark_indicator_gutter)
end end
def arc_radius(radius) def arc_radius(radius)
@ -74,7 +76,8 @@ module GaugeHelper
def draw_arc(radius:, percentage:, clockwise:) def draw_arc(radius:, percentage:, clockwise:)
sweep_flag = clockwise ? 1 : 0 sweep_flag = clockwise ? 1 : 0
"A #{arc_radius(radius)} 0 0 #{sweep_flag} #{coordinates_for(arc_end_point_for(radius: radius, percentage: percentage))}" "A #{arc_radius(radius)} 0 0 #{sweep_flag} #{coordinates_for(arc_end_point_for(radius: radius,
percentage: percentage))}"
end end
def draw_line_to(point:) def draw_line_to(point:)
@ -82,8 +85,8 @@ module GaugeHelper
end end
def benchmark_line_point(radius, angle) def benchmark_line_point(radius, angle)
x = "#{radius * Math.cos(angle)}" x = (radius * Math.cos(angle)).to_s
y = "#{radius * Math.sin(angle) + arc_center.y}" y = (radius * Math.sin(angle) + arc_center.y).to_s
Point.new(x, y) Point.new(x, y)
end end

@ -1,5 +1,4 @@
module HeaderHelper module HeaderHelper
def link_to_overview(district:, school:, academic_year:) def link_to_overview(district:, school:, academic_year:)
"/districts/#{district.slug}/schools/#{school.slug}/overview?year=#{academic_year.range}" "/districts/#{district.slug}/schools/#{school.slug}/overview?year=#{academic_year.range}"
end end
@ -9,18 +8,20 @@ module HeaderHelper
end end
def district_url_for(district:, academic_year:) def district_url_for(district:, academic_year:)
overview_link(district_slug: district.slug, school_slug: district.schools.alphabetic.first.slug, academic_year_range: academic_year.range, uri_path: request.fullpath) overview_link(district_slug: district.slug, school_slug: district.schools.alphabetic.first.slug,
academic_year_range: academic_year.range, uri_path: request.fullpath)
end end
def school_url_for(school:, academic_year:) def school_url_for(school:, academic_year:)
overview_link(district_slug: school.district.slug, school_slug: school.slug, academic_year_range: academic_year.range, uri_path: request.fullpath) overview_link(district_slug: school.district.slug, school_slug: school.slug,
academic_year_range: academic_year.range, uri_path: request.fullpath)
end end
def school_mapper(school) def school_mapper(school)
{ {
name: school.name, name: school.name,
district_id: school.district_id, district_id: school.district_id,
url: district_school_overview_index_path(school.district, school, {year: AcademicYear.first.range}) url: district_school_overview_index_path(school.district, school, { year: AcademicYear.first.range })
} }
end end
@ -31,14 +32,14 @@ module HeaderHelper
private private
def overview_link(district_slug:, school_slug:, academic_year_range:, uri_path:) def overview_link(district_slug:, school_slug:, academic_year_range:, uri_path:)
if uri_path.include?("overview") if uri_path.include?('overview')
return "/districts/#{district_slug}/schools/#{school_slug}/overview?year=#{academic_year_range}" return "/districts/#{district_slug}/schools/#{school_slug}/overview?year=#{academic_year_range}"
end end
"/districts/#{district_slug}/schools/#{school_slug}/browse/teachers-and-leadership?year=#{academic_year_range}" "/districts/#{district_slug}/schools/#{school_slug}/browse/teachers-and-leadership?year=#{academic_year_range}"
end end
def active?(path:) def active?(path:)
request.fullpath.include? path request.fullpath.include? path
end end
end end

@ -1,5 +1,4 @@
module SchedulesHelper module SchedulesHelper
def options_for_frequency_hours def options_for_frequency_hours
[ [
['Once A Day', 24], ['Once A Day', 24],
@ -10,9 +9,9 @@ module SchedulesHelper
end end
def options_for_time def options_for_time
words = ['AM', 'PM'].map do |time| words = %w[AM PM].map do |time|
[12, *(1..11)].map do |hour| [12, *(1..11)].map do |hour|
['00', '30'].map do |minute| %w[00 30].map do |minute|
"#{hour}:#{minute} #{time}" "#{hour}:#{minute} #{time}"
end end
end end

@ -37,11 +37,11 @@ module VarianceHelper
end end
def zones def zones
%w(warning watch growth approval ideal) %w[warning watch growth approval ideal]
end end
def zone_width_percentage def zone_width_percentage
100.0/zones.size 100.0 / zones.size
end end
def availability_indicator_percentage def availability_indicator_percentage
@ -51,5 +51,4 @@ module VarianceHelper
def partial_data_indicator_size def partial_data_indicator_size
16 16
end end
end end

@ -7,7 +7,7 @@ class Seeder
end end
end end
def seed_districts_and_schools csv_file def seed_districts_and_schools(csv_file)
dese_ids = [] dese_ids = []
CSV.parse(File.read(csv_file), headers: true) do |row| CSV.parse(File.read(csv_file), headers: true) do |row|
district_name = row['District'].strip district_name = row['District'].strip
@ -29,7 +29,7 @@ class Seeder
School.where.not(dese_id: dese_ids).destroy_all School.where.not(dese_id: dese_ids).destroy_all
end end
def seed_sqm_framework csv_file def seed_sqm_framework(csv_file)
CSV.parse(File.read(csv_file), headers: true) do |row| CSV.parse(File.read(csv_file), headers: true) do |row|
category_id = row['Category ID'].strip category_id = row['Category ID'].strip
category = Category.find_or_create_by!(category_id: category_id) category = Category.find_or_create_by!(category_id: category_id)
@ -38,9 +38,10 @@ class Seeder
'2' => 'school-culture', '2' => 'school-culture',
'3' => 'resources', '3' => 'resources',
'4' => 'academic-learning', '4' => 'academic-learning',
'5' => 'community-and-wellbeing', '5' => 'community-and-wellbeing'
} }
category.update! name: row['Category'].strip, description: row['Category Description'].strip, short_description: row['Category Short Description'], slug: category_slugs[category_id], sort_index: category_slugs.keys.index(category_id) category.update! name: row['Category'].strip, description: row['Category Description'].strip,
short_description: row['Category Short Description'], slug: category_slugs[category_id], sort_index: category_slugs.keys.index(category_id)
subcategory_id = row['Subcategory ID'].strip subcategory_id = row['Subcategory ID'].strip
subcategory = Subcategory.find_or_create_by! subcategory_id: subcategory_id, category: category subcategory = Subcategory.find_or_create_by! subcategory_id: subcategory_id, category: category
@ -55,26 +56,28 @@ class Seeder
measure_description = row['Measure Description'].try(:strip) measure_description = row['Measure Description'].try(:strip)
next if row['Source'] == 'No source' next if row['Source'] == 'No source'
measure = Measure.find_or_create_by! measure_id: measure_id, subcategory: subcategory measure = Measure.find_or_create_by! measure_id: measure_id, subcategory: subcategory
measure.name = measure_name measure.name = measure_name
measure.description = measure_description measure.description = measure_description
if ['Teachers', 'Students'].include? row['Source']
measure.watch_low_benchmark = watch_low if watch_low
measure.growth_low_benchmark = growth_low if growth_low
measure.approval_low_benchmark = approval_low if approval_low
measure.ideal_low_benchmark = ideal_low if ideal_low
end
measure.save! measure.save!
data_item_id = row['Survey Item ID'].strip data_item_id = row['Survey Item ID'].strip
if ['Teachers', 'Students'].include? row['Source'] if %w[Teachers Students].include? row['Source']
survey_item = SurveyItem.find_or_create_by! survey_item_id: data_item_id, measure: measure survey_item = SurveyItem.find_or_create_by! survey_item_id: data_item_id, measure: measure
survey_item.watch_low_benchmark = watch_low if watch_low
survey_item.growth_low_benchmark = growth_low if growth_low
survey_item.approval_low_benchmark = approval_low if approval_low
survey_item.ideal_low_benchmark = ideal_low if ideal_low
survey_item.update! prompt: row['Question/item (20-21)'].strip survey_item.update! prompt: row['Question/item (20-21)'].strip
end end
if row['Source'] == 'Admin Data' if row['Source'] == 'Admin Data'
admin_data_item = AdminDataItem.find_or_create_by! admin_data_item_id: data_item_id, measure: measure admin_data_item = AdminDataItem.find_or_create_by! admin_data_item_id: data_item_id, measure: measure
admin_data_item.watch_low_benchmark = watch_low if watch_low
admin_data_item.growth_low_benchmark = growth_low if growth_low
admin_data_item.approval_low_benchmark = approval_low if approval_low
admin_data_item.ideal_low_benchmark = ideal_low if ideal_low
admin_data_item.update! description: row['Question/item (20-21)'].strip admin_data_item.update! description: row['Question/item (20-21)'].strip
end end
end end

@ -1,5 +1,4 @@
class AcademicYear < ActiveRecord::Base class AcademicYear < ActiveRecord::Base
def self.find_by_date(date) def self.find_by_date(date)
if date.month > 6 if date.month > 6
ay_range_start = date.year ay_range_start = date.year
@ -10,5 +9,4 @@ class AcademicYear < ActiveRecord::Base
end end
AcademicYear.find_by_range("#{ay_range_start}-#{ay_range_end.to_s[2, 3]}") AcademicYear.find_by_range("#{ay_range_start}-#{ay_range_end.to_s[2, 3]}")
end end
end end

@ -1,4 +1,4 @@
# TODO move this to legacy, probably? # TODO: move this to legacy, probably?
class ApplicationRecord < ActiveRecord::Base class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true self.abstract_class = true
end end

@ -2,7 +2,7 @@ class Category < ActiveRecord::Base
include FriendlyId include FriendlyId
friendly_id :name, use: [:slugged] friendly_id :name, use: [:slugged]
scope :sorted, ->() { order(:sort_index) } scope :sorted, -> { order(:sort_index) }
has_many :subcategories has_many :subcategories
has_many :measures, through: :subcategories has_many :measures, through: :subcategories

@ -2,7 +2,6 @@ require 'twilio-ruby'
module Legacy module Legacy
class Attempt < ApplicationRecord class Attempt < ApplicationRecord
belongs_to :schedule belongs_to :schedule
belongs_to :recipient belongs_to :recipient
belongs_to :recipient_schedule belongs_to :recipient_schedule
@ -12,16 +11,16 @@ module Legacy
after_save :update_school_categories after_save :update_school_categories
after_commit :update_counts after_commit :update_counts
scope :for_question, -> (question) { where(question_id: question.id) } scope :for_question, ->(question) { where(question_id: question.id) }
scope :for_recipient, -> (recipient) { where(recipient_id: recipient.id) } scope :for_recipient, ->(recipient) { where(recipient_id: recipient.id) }
scope :for_student, -> (student) { where(student_id: student.id) } scope :for_student, ->(student) { where(student_id: student.id) }
scope :for_category, -> (category) { joins(:question).merge(Question.for_category(category)) } scope :for_category, ->(category) { joins(:question).merge(Question.for_category(category)) }
scope :for_school, -> (school) { joins(:recipient).merge(Legacy::Recipient.for_school(school)) } scope :for_school, ->(school) { joins(:recipient).merge(Legacy::Recipient.for_school(school)) }
scope :with_answer, -> { where('answer_index is not null or open_response_id is not null') } scope :with_answer, -> { where('answer_index is not null or open_response_id is not null') }
scope :with_no_answer, -> { where('answer_index is null and open_response_id is null') } scope :with_no_answer, -> { where('answer_index is null and open_response_id is null') }
scope :not_yet_responded, -> { where(responded_at: nil) } scope :not_yet_responded, -> { where(responded_at: nil) }
scope :last_sent, -> { order(sent_at: :desc) } scope :last_sent, -> { order(sent_at: :desc) }
scope :created_in, -> (year) { where('extract(year from legacy_attempts.created_at) = ?', year) } scope :created_in, ->(year) { where('extract(year from legacy_attempts.created_at) = ?', year) }
def messages def messages
child_specific = student.present? ? " (for #{student.name})" : '' child_specific = student.present? ? " (for #{student.name})" : ''
@ -53,6 +52,7 @@ module Legacy
def response def response
return 'No Answer Yet' if answer_index.blank? return 'No Answer Yet' if answer_index.blank?
question.options[answer_index_with_reverse - 1] question.options[answer_index_with_reverse - 1]
end end
@ -63,20 +63,20 @@ module Legacy
responded_at: responded_at responded_at: responded_at
) )
if recipient_schedule.queued_question_ids.present? recipient_schedule.update(next_attempt_at: Time.new) if recipient_schedule.queued_question_ids.present?
recipient_schedule.update(next_attempt_at: Time.new)
end
end end
def answer_index_with_reverse def answer_index_with_reverse
return 6 - answer_index if question.reverse? return 6 - answer_index if question.reverse?
return answer_index
answer_index
end end
private private
def update_school_categories def update_school_categories
return if ENV['BULK_PROCESS'] return if ENV['BULK_PROCESS']
school_category = SchoolCategory.for(recipient.school, question.category).first school_category = SchoolCategory.for(recipient.school, question.category).first
if school_category.nil? if school_category.nil?
school_category = SchoolCategory.create(school: recipient.school, category: question.category) school_category = SchoolCategory.create(school: recipient.school, category: question.category)
@ -86,8 +86,8 @@ module Legacy
def update_counts def update_counts
return if ENV['BULK_PROCESS'] return if ENV['BULK_PROCESS']
recipient.update_counts recipient.update_counts
end end
end end
end end

@ -1,6 +1,5 @@
module Legacy module Legacy
class Category < ApplicationRecord class Category < ApplicationRecord
has_many :questions has_many :questions
belongs_to :parent_category, class_name: 'Legacy::Category', foreign_key: :parent_category_id belongs_to :parent_category, class_name: 'Legacy::Category', foreign_key: :parent_category_id
has_many :child_categories, class_name: 'Legacy::Category', foreign_key: :parent_category_id has_many :child_categories, class_name: 'Legacy::Category', foreign_key: :parent_category_id
@ -8,11 +7,11 @@ module Legacy
validates :name, presence: true validates :name, presence: true
scope :for_parent, -> (category = nil) { where(parent_category_id: category.try(:id)) } scope :for_parent, ->(category = nil) { where(parent_category_id: category.try(:id)) }
scope :likert, -> { where("benchmark is null") } scope :likert, -> { where('benchmark is null') }
include FriendlyId include FriendlyId
friendly_id :name, :use => [:slugged] friendly_id :name, use: [:slugged]
def path def path
p = self p = self
@ -30,23 +29,24 @@ module Legacy
end end
def self.root_identifiers def self.root_identifiers
[ %w[
"teachers-and-the-teaching-environment", teachers-and-the-teaching-environment
"school-culture", school-culture
"resources", resources
"academic-learning", academic-learning
"community-and-wellbeing", community-and-wellbeing
"pilot-family-questions" pilot-family-questions
] ]
end end
def self.root def self.root
Category.where(parent_category: nil).select { |c| self.root_identifiers.index(c.slug) } Category.where(parent_category: nil).select { |c| root_identifiers.index(c.slug) }
end end
def custom_zones def custom_zones
return [] if zones.nil? return [] if zones.nil?
zones.split(",").map(&:to_f)
zones.split(',').map(&:to_f)
end end
def zone_widths def zone_widths
@ -57,18 +57,17 @@ module Legacy
end end
widths[4] = widths[4] + (5 - widths.sum) widths[4] = widths[4] + (5 - widths.sum)
return widths widths
end end
def sync_child_zones def sync_child_zones
likert_child_categories = child_categories.likert likert_child_categories = child_categories.likert
return unless likert_child_categories.present? return unless likert_child_categories.present?
total_zones = [0, 0, 0, 0, 0] total_zones = [0, 0, 0, 0, 0]
valid_child_categories = 0 valid_child_categories = 0
likert_child_categories.each do |cc| likert_child_categories.each do |cc|
if cc.zones.nil? cc.sync_child_zones if cc.zones.nil?
cc.sync_child_zones
end
if cc.zones.nil? if cc.zones.nil?
puts "NO ZONES: #{name} -> #{cc.name}" puts "NO ZONES: #{name} -> #{cc.name}"
@ -87,9 +86,8 @@ module Legacy
if valid_child_categories > 0 if valid_child_categories > 0
average_zones = total_zones.map { |zone| zone / valid_child_categories } average_zones = total_zones.map { |zone| zone / valid_child_categories }
puts "TOTAL: #{name} | #{total_zones} | #{valid_child_categories} | #{average_zones} | #{zone_widths}" puts "TOTAL: #{name} | #{total_zones} | #{valid_child_categories} | #{average_zones} | #{zone_widths}"
update(zones: average_zones.join(",")) update(zones: average_zones.join(','))
end end
end end
end end
end end

@ -22,10 +22,10 @@ module Legacy
validates :option4, presence: true validates :option4, presence: true
validates :option5, presence: true validates :option5, presence: true
scope :for_category, -> (category) { where(category: category) } scope :for_category, ->(category) { where(category: category) }
scope :created_in, -> (year) { where("extract(year from #{self.table_name}.created_at) = ?", year) } scope :created_in, ->(year) { where("extract(year from #{table_name}.created_at) = ?", year) }
enum target_group: [:unknown, :for_students, :for_teachers, :for_parents] enum target_group: %i[unknown for_students for_teachers for_parents]
def source def source
target_group.gsub('for_', '') target_group.gsub('for_', '')
@ -37,6 +37,7 @@ module Legacy
def options_with_reverse def options_with_reverse
return options.reverse if reverse? return options.reverse if reverse?
options options
end end
@ -48,7 +49,9 @@ module Legacy
school_responses = attempts.for_school(school).with_answer.order(id: :asc) school_responses = attempts.for_school(school).with_answer.order(id: :asc)
return unless school_responses.present? return unless school_responses.present?
response_answer_total = school_responses.inject(0) { |total, response| total + response.answer_index_with_reverse } response_answer_total = school_responses.inject(0) do |total, response|
total + response.answer_index_with_reverse
end
histogram = school_responses.group_by(&:answer_index_with_reverse) histogram = school_responses.group_by(&:answer_index_with_reverse)
most_popular_answer_index = histogram.to_a.sort_by { |info| info[1].length }.last[0] most_popular_answer_index = histogram.to_a.sort_by { |info| info[1].length }.last[0]
@ -66,7 +69,7 @@ module Legacy
end end
def normalized_text def normalized_text
text.gsub("[science/math/English/social studies]", "") text.gsub('[science/math/English/social studies]', '')
end end
end end
end end

@ -1,10 +1,10 @@
module Legacy module Legacy
class QuestionList < ApplicationRecord class QuestionList < ApplicationRecord
validates :name, presence: true validates :name, presence: true
validates :question_ids, presence: true validates :question_ids, presence: true
attr_accessor :question_id_array attr_accessor :question_id_array
before_validation :convert_question_id_array before_validation :convert_question_id_array
after_initialize :set_question_id_array after_initialize :set_question_id_array
@ -16,13 +16,14 @@ module Legacy
def convert_question_id_array def convert_question_id_array
return if question_id_array.blank? return if question_id_array.blank?
self.question_ids = question_id_array.reject { |id| id.to_s.empty? }.join(',') self.question_ids = question_id_array.reject { |id| id.to_s.empty? }.join(',')
end end
def set_question_id_array def set_question_id_array
return if question_ids.blank? return if question_ids.blank?
self.question_id_array = question_ids.split(',').map(&:to_i) self.question_id_array = question_ids.split(',').map(&:to_i)
end end
end end
end end

@ -12,8 +12,8 @@ module Legacy
validates :name, presence: true validates :name, presence: true
scope :for_school, -> (school) { where(school: school) } scope :for_school, ->(school) { where(school: school) }
scope :created_in, -> (year) { where('extract(year from recipients.created_at) = ?', year) } scope :created_in, ->(year) { where('extract(year from recipients.created_at) = ?', year) }
before_destroy :sync_lists before_destroy :sync_lists
@ -43,10 +43,10 @@ module Legacy
def sync_lists def sync_lists
school.recipient_lists.each do |recipient_list| school.recipient_lists.each do |recipient_list|
next if recipient_list.recipient_id_array.index(id).nil? next if recipient_list.recipient_id_array.index(id).nil?
updated_ids = recipient_list.recipient_id_array - [id] updated_ids = recipient_list.recipient_id_array - [id]
recipient_list.update(recipient_id_array: updated_ids) recipient_list.update(recipient_id_array: updated_ids)
end end
end end
end end
end end

@ -7,6 +7,7 @@ module Legacy
validates :name, presence: true validates :name, presence: true
attr_accessor :recipient_id_array attr_accessor :recipient_id_array
before_validation :convert_recipient_id_array before_validation :convert_recipient_id_array
after_initialize :set_recipient_id_array after_initialize :set_recipient_id_array
@ -20,16 +21,19 @@ module Legacy
def convert_recipient_id_array def convert_recipient_id_array
return if recipient_id_array.blank? || (recipient_ids_was != recipient_ids) return if recipient_id_array.blank? || (recipient_ids_was != recipient_ids)
self.recipient_ids = recipient_id_array.reject { |id| id.to_s.empty? }.join(',') self.recipient_ids = recipient_id_array.reject { |id| id.to_s.empty? }.join(',')
end end
def set_recipient_id_array def set_recipient_id_array
return if recipient_id_array.present? return if recipient_id_array.present?
self.recipient_id_array = (recipient_ids || '').split(',').map(&:to_i) self.recipient_id_array = (recipient_ids || '').split(',').map(&:to_i)
end end
def sync_recipient_schedules def sync_recipient_schedules
return unless recipient_ids_before_last_save.present? && recipient_ids_before_last_save != recipient_ids return unless recipient_ids_before_last_save.present? && recipient_ids_before_last_save != recipient_ids
old_ids = recipient_ids_before_last_save.split(/,/) old_ids = recipient_ids_before_last_save.split(/,/)
new_ids = recipient_ids.split(/,/) new_ids = recipient_ids.split(/,/)
(old_ids - new_ids).each do |deleted_recipient| (old_ids - new_ids).each do |deleted_recipient|
@ -44,6 +48,5 @@ module Legacy
end end
end end
end end
end end
end end

@ -1,6 +1,5 @@
module Legacy module Legacy
class RecipientSchedule < ApplicationRecord class RecipientSchedule < ApplicationRecord
belongs_to :recipient belongs_to :recipient
belongs_to :schedule belongs_to :schedule
has_many :attempts has_many :attempts
@ -10,25 +9,29 @@ module Legacy
validates :next_attempt_at, presence: true validates :next_attempt_at, presence: true
scope :ready, -> { where('next_attempt_at <= ?', Time.new) } scope :ready, -> { where('next_attempt_at <= ?', Time.new) }
scope :for_recipient, -> (recipient_or_recipient_id) { scope :for_recipient, lambda { |recipient_or_recipient_id|
id = recipient_or_recipient_id.is_a?(Recipient) ? id = if recipient_or_recipient_id.is_a?(Recipient)
recipient_or_recipient_id.id : recipient_or_recipient_id.id
else
recipient_or_recipient_id recipient_or_recipient_id
end
where(recipient_id: id) where(recipient_id: id)
} }
scope :for_schedule, -> (schedule_or_schedule_id) { scope :for_schedule, lambda { |schedule_or_schedule_id|
id = schedule_or_schedule_id.is_a?(Schedule) ? id = if schedule_or_schedule_id.is_a?(Schedule)
schedule_or_schedule_id.id : schedule_or_schedule_id.id
else
schedule_or_schedule_id schedule_or_schedule_id
end
where(schedule_id: id) where(schedule_id: id)
} }
def next_question def next_question
if queued_question_ids.present? next_question_id = if queued_question_ids.present?
next_question_id = queued_question_ids.split(/,/).first queued_question_ids.split(/,/).first
else else
next_question_id = upcoming_question_ids.split(/,/).first upcoming_question_ids.split(/,/).first
end end
Question.where(id: next_question_id).first Question.where(id: next_question_id).first
end end
@ -48,16 +51,12 @@ module Legacy
return if recipient.opted_out? return if recipient.opted_out?
return if question.nil? return if question.nil?
if !question.for_recipient_students? return attempt_question(question: question) unless question.for_recipient_students?
return attempt_question(question: question)
end
missing_students = [] missing_students = []
recipient_attempts = attempts.for_recipient(recipient).for_question(question) recipient_attempts = attempts.for_recipient(recipient).for_question(question)
recipient.students.each do |student| recipient.students.each do |student|
if recipient_attempts.for_student(student).empty? missing_students << student if recipient_attempts.for_student(student).empty?
missing_students << student
end
end end
attempt = recipient.attempts.create( attempt = recipient.attempts.create(
@ -74,7 +73,7 @@ module Legacy
if question.present? if question.present?
question_id = [question.id.to_s] question_id = [question.id.to_s]
upcoming = upcoming - question_id upcoming -= question_id
if missing_students.length > 1 if missing_students.length > 1
queued += question_id queued += question_id
else else
@ -91,19 +90,18 @@ module Legacy
next_attempt_at: next_valid_attempt_time next_attempt_at: next_valid_attempt_time
) )
end end
return attempt attempt
end end
def attempt_question(send_message: true, question: next_question) def attempt_question(send_message: true, question: next_question)
return if recipient.opted_out? return if recipient.opted_out?
unanswered_attempt = recipient.attempts.not_yet_responded.last unanswered_attempt = recipient.attempts.not_yet_responded.last
return if question.nil? && unanswered_attempt.nil? return if question.nil? && unanswered_attempt.nil?
if unanswered_attempt.nil? if unanswered_attempt.nil?
if question.for_recipient_students? return attempt_question_for_recipient_students(question: question) if question.for_recipient_students?
return attempt_question_for_recipient_students(question: question)
end
attempt = recipient.attempts.create( attempt = recipient.attempts.create(
schedule: schedule, schedule: schedule,
@ -119,7 +117,7 @@ module Legacy
if question.present? if question.present?
question_id = [question.id.to_s] question_id = [question.id.to_s]
upcoming = upcoming - question_id upcoming -= question_id
if unanswered_attempt.nil? if unanswered_attempt.nil?
attempted += question_id attempted += question_id
queued -= question_id queued -= question_id
@ -136,13 +134,13 @@ module Legacy
next_attempt_at: next_valid_attempt_time next_attempt_at: next_valid_attempt_time
) )
end end
return (unanswered_attempt || attempt) (unanswered_attempt || attempt)
end end
def next_valid_attempt_time def next_valid_attempt_time
local_time = (next_attempt_at + (60 * 60 * schedule.frequency_hours)).in_time_zone('Eastern Time (US & Canada)') local_time = (next_attempt_at + (60 * 60 * schedule.frequency_hours)).in_time_zone('Eastern Time (US & Canada)')
local_time += 1.day while local_time.on_weekend? local_time += 1.day while local_time.on_weekend?
return local_time local_time
end end
def self.create_for_recipient(recipient_or_recipient_id, schedule, next_attempt_at = nil) def self.create_for_recipient(recipient_or_recipient_id, schedule, next_attempt_at = nil)
@ -154,9 +152,11 @@ module Legacy
question_ids = schedule.question_list.question_ids.split(/,/) question_ids = schedule.question_list.question_ids.split(/,/)
question_ids = question_ids.shuffle if schedule.random? question_ids = question_ids.shuffle if schedule.random?
recipient_id = recipient_or_recipient_id.is_a?(Recipient) ? recipient_id = if recipient_or_recipient_id.is_a?(Recipient)
recipient_or_recipient_id.id : recipient_or_recipient_id.id
else
recipient_or_recipient_id recipient_or_recipient_id
end
schedule.recipient_schedules.create( schedule.recipient_schedules.create(
recipient_id: recipient_id, recipient_id: recipient_id,
@ -164,6 +164,5 @@ module Legacy
next_attempt_at: next_attempt_at next_attempt_at: next_attempt_at
) )
end end
end end
end end

@ -12,14 +12,15 @@ module Legacy
before_validation :set_start_date before_validation :set_start_date
after_create :create_recipient_schedules after_create :create_recipient_schedules
scope :active, -> { scope :active, lambda {
where(active: true).where("start_date <= ? and end_date > ?", Date.today, Date.today) where(active: true).where('start_date <= ? and end_date > ?', Date.today, Date.today)
} }
private private
def set_start_date def set_start_date
return if start_date.present? return if start_date.present?
self.start_date = Date.today self.start_date = Date.today
end end
@ -28,6 +29,5 @@ module Legacy
RecipientSchedule.create_for_recipient(recipient, self) RecipientSchedule.create_for_recipient(recipient, self)
end end
end end
end end
end end

@ -1,6 +1,5 @@
module Legacy module Legacy
class SchoolQuestion < ApplicationRecord class SchoolQuestion < ApplicationRecord
belongs_to :school belongs_to :school
belongs_to :question belongs_to :question
belongs_to :school_category belongs_to :school_category
@ -9,17 +8,17 @@ module Legacy
validates_associated :question validates_associated :question
validates_associated :school_category validates_associated :school_category
scope :for, -> (school, question) { where(school_id: school.id, question_id: question.id) } scope :for, ->(school, question) { where(school_id: school.id, question_id: question.id) }
scope :in, -> (year) { where(year: year) } scope :in, ->(year) { where(year: year) }
def sync_attempts def sync_attempts
attempt_data = Attempt. attempt_data = Attempt
joins(:question). .joins(:question)
created_in(school_category.year). .created_in(school_category.year)
for_question(question). .for_question(question)
for_school(school). .for_school(school)
select('count(attempts.answer_index) as response_count'). .select('count(attempts.answer_index) as response_count')
select('sum(case when questions.reverse then 6 - attempts.answer_index else attempts.answer_index end) as answer_index_total')[0] .select('sum(case when questions.reverse then 6 - attempts.answer_index else attempts.answer_index end) as answer_index_total')[0]
available_responders = school.available_responders_for(question) available_responders = school.available_responders_for(question)
@ -30,6 +29,5 @@ module Legacy
response_total: attempt_data.answer_index_total response_total: attempt_data.answer_index_total
) )
end end
end end
end end

@ -1,9 +1,7 @@
module Legacy module Legacy
class UserSchool < ApplicationRecord class UserSchool < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :school belongs_to :school
belongs_to :district belongs_to :district
end end
end end

@ -22,15 +22,15 @@ class Measure < ActiveRecord::Base
end end
def includes_teacher_survey_items? def includes_teacher_survey_items?
teacher_survey_items.any? @includes_teacher_survey_items ||= teacher_survey_items.any?
end end
def includes_student_survey_items? def includes_student_survey_items?
student_survey_items.any? @includes_student_survey_items ||= student_survey_items.any?
end end
def includes_admin_data_items? def includes_admin_data_items?
admin_data_items.any? @includes_admin_data_items ||= admin_data_items.any?
end end
def sources def sources
@ -40,4 +40,45 @@ class Measure < ActiveRecord::Base
sources << :teacher_surveys if includes_teacher_survey_items? sources << :teacher_surveys if includes_teacher_survey_items?
sources sources
end end
def warning_low_benchmark
return @warning_low_benchmark unless @warning_low_benchmark.nil?
@warning_low_benchmark = benchmark(:warning_low_benchmark)
end
def watch_low_benchmark
return @watch_low_benchmark unless @watch_low_benchmark.nil?
@watch_low_benchmark = benchmark(:watch_low_benchmark)
end
def growth_low_benchmark
return @growth_low_benchmark unless @growth_low_benchmark.nil?
@growth_low_benchmark = benchmark(:growth_low_benchmark)
end
def approval_low_benchmark
return @approval_low_benchmark unless @approval_low_benchmark.nil?
@approval_low_benchmark = benchmark(:approval_low_benchmark)
end
def ideal_low_benchmark
return @ideal_low_benchmark unless @ideal_low_benchmark.nil?
@ideal_low_benchmark = benchmark(:ideal_low_benchmark)
end
private
def benchmark(name)
averages = []
averages << student_survey_items.first.send(name) if includes_student_survey_items?
averages << teacher_survey_items.first.send(name) if includes_teacher_survey_items?
(averages << admin_data_items.map(&name)).flatten! if includes_admin_data_items?
averages.average
end
end end

@ -7,7 +7,9 @@ class SurveyItemResponse < ActiveRecord::Base
belongs_to :survey_item belongs_to :survey_item
def self.score_for_subcategory(subcategory:, school:, academic_year:) def self.score_for_subcategory(subcategory:, school:, academic_year:)
measures = subcategory.measures.select { |measure| sufficient_data?(measure: measure, school: school, academic_year: academic_year) } measures = subcategory.measures.select do |measure|
sufficient_data?(measure: measure, school: school, academic_year: academic_year)
end
SurveyItemResponse.for_measures(measures) SurveyItemResponse.for_measures(measures)
.where(academic_year: academic_year, school: school) .where(academic_year: academic_year, school: school)
@ -27,9 +29,7 @@ class SurveyItemResponse < ActiveRecord::Base
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) unless survey_item_responses.nil?
score_for_measure = survey_item_responses.average(:likert_score)
end
Score.new(score_for_measure, meets_teacher_threshold, meets_student_threshold) Score.new(score_for_measure, meets_teacher_threshold, meets_student_threshold)
end end
@ -40,17 +40,20 @@ class SurveyItemResponse < ActiveRecord::Base
meets_teacher_threshold || meets_student_threshold meets_teacher_threshold || meets_student_threshold
end 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, lambda { |measure|
scope :student_responses_for_measure, ->(measure) { for_measure(measure).where("survey_items.survey_item_id LIKE 's-%'") } for_measure(measure).where("survey_items.survey_item_id LIKE 't-%'")
}
scope :student_responses_for_measure, lambda { |measure|
for_measure(measure).where("survey_items.survey_item_id LIKE 's-%'")
}
def self.student_sufficient_data?(measure:, school:, academic_year:) def self.student_sufficient_data?(measure:, school:, academic_year:)
if measure.includes_student_survey_items? if measure.includes_student_survey_items?
student_survey_item_responses = SurveyItemResponse.student_responses_for_measure(measure).where(academic_year: academic_year, school: school) student_survey_item_responses = SurveyItemResponse.student_responses_for_measure(measure).where(
academic_year: academic_year, school: school
)
average_number_of_survey_item_responses = student_survey_item_responses.count / measure.student_survey_items.count average_number_of_survey_item_responses = student_survey_item_responses.count / measure.student_survey_items.count
meets_student_threshold = average_number_of_survey_item_responses >= STUDENT_RESPONSE_THRESHOLD meets_student_threshold = average_number_of_survey_item_responses >= STUDENT_RESPONSE_THRESHOLD
@ -60,7 +63,9 @@ class SurveyItemResponse < ActiveRecord::Base
def self.teacher_sufficient_data?(measure:, school:, academic_year:) def self.teacher_sufficient_data?(measure:, school:, academic_year:)
if measure.includes_teacher_survey_items? if measure.includes_teacher_survey_items?
teacher_survey_item_responses = SurveyItemResponse.teacher_responses_for_measure(measure).where(academic_year: academic_year, school: school) teacher_survey_item_responses = SurveyItemResponse.teacher_responses_for_measure(measure).where(
academic_year: academic_year, school: school
)
average_number_of_survey_item_responses = teacher_survey_item_responses.count / measure.teacher_survey_items.count average_number_of_survey_item_responses = teacher_survey_item_responses.count / measure.teacher_survey_items.count
meets_teacher_threshold = average_number_of_survey_item_responses >= TEACHER_RESPONSE_THRESHOLD meets_teacher_threshold = average_number_of_survey_item_responses >= TEACHER_RESPONSE_THRESHOLD

@ -5,7 +5,7 @@ class AdminDataPresenter < DataItemPresenter
end end
def title def title
"School admin data" 'School admin data'
end end
def id def id
@ -17,6 +17,6 @@ class AdminDataPresenter < DataItemPresenter
end end
def reason_for_insufficiency def reason_for_insufficiency
"limited availability" 'limited availability'
end end
end end

@ -28,6 +28,7 @@ class GaugePresenter
def percentage_for(number) def percentage_for(number)
return nil if number.nil? return nil if number.nil?
scale_minimum = @scale.warning_zone.low_benchmark scale_minimum = @scale.warning_zone.low_benchmark
scale_maximum = @scale.ideal_zone.high_benchmark scale_maximum = @scale.ideal_zone.high_benchmark

@ -26,10 +26,19 @@ class MeasurePresenter
end end
def data_item_presenters def data_item_presenters
Array.new.tap do |array| [].tap do |array|
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? if @measure.student_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 << StudentSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.student_survey_items,
array << AdminDataPresenter.new(measure_id: @measure.measure_id, admin_data_items: @measure.admin_data_items) if @measure.admin_data_items.any? has_sufficient_data: score_for_measure.meets_student_threshold?)
end
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?)
end
if @measure.admin_data_items.any?
array << AdminDataPresenter.new(measure_id: @measure.measure_id,
admin_data_items: @measure.admin_data_items)
end
end end
end end
@ -44,7 +53,7 @@ class MeasurePresenter
watch_low_benchmark: @measure.watch_low_benchmark, watch_low_benchmark: @measure.watch_low_benchmark,
growth_low_benchmark: @measure.growth_low_benchmark, growth_low_benchmark: @measure.growth_low_benchmark,
approval_low_benchmark: @measure.approval_low_benchmark, approval_low_benchmark: @measure.approval_low_benchmark,
ideal_low_benchmark: @measure.ideal_low_benchmark, ideal_low_benchmark: @measure.ideal_low_benchmark
) )
end end
end end

@ -30,7 +30,7 @@ class Scale
end end
def insufficient_data def insufficient_data
Zone.new(0,@warning_low_benchmark,:insufficient_data) Zone.new(0, @warning_low_benchmark, :insufficient_data)
end end
def zone_for_score(score) def zone_for_score(score)

@ -5,7 +5,7 @@ class StudentSurveyPresenter < DataItemPresenter
end end
def title def title
"Student survey" 'Student survey'
end end
def id def id
@ -17,6 +17,6 @@ class StudentSurveyPresenter < DataItemPresenter
end end
def reason_for_insufficiency def reason_for_insufficiency
"low response rate" 'low response rate'
end end
end end

@ -31,7 +31,9 @@ class SubcategoryPresenter
end end
def measure_presenters def measure_presenters
@subcategory.measures.sort_by(&:measure_id).map { |measure| MeasurePresenter.new(measure: measure, academic_year: @academic_year, school: @school) } @subcategory.measures.sort_by(&:measure_id).map do |measure|
MeasurePresenter.new(measure: measure, academic_year: @academic_year, school: @school)
end
end end
private private

@ -5,7 +5,7 @@ class TeacherSurveyPresenter < DataItemPresenter
end end
def title def title
"Teacher survey" 'Teacher survey'
end end
def id def id
@ -17,6 +17,6 @@ class TeacherSurveyPresenter < DataItemPresenter
end end
def reason_for_insufficiency def reason_for_insufficiency
"low response rate" 'low response rate'
end end
end end

@ -59,7 +59,7 @@ class VarianceChartRowPresenter
end end
def partial_data_sources def partial_data_sources
Array.new.tap do |sources| [].tap do |sources|
sources << 'teacher survey results' if @measure.includes_teacher_survey_items? && !@meets_teacher_threshold sources << 'teacher survey results' if @measure.includes_teacher_survey_items? && !@meets_teacher_threshold
sources << 'student survey results' if @measure.includes_student_survey_items? && !@meets_student_threshold sources << 'student survey results' if @measure.includes_student_survey_items? && !@meets_student_threshold
sources << 'administrative data' if @measure.includes_admin_data_items? sources << 'administrative data' if @measure.includes_admin_data_items?

@ -1,14 +1,13 @@
require 'csv' require 'csv'
class SurveyResponsesDataLoader class SurveyResponsesDataLoader
def self.load_data(filepath:) def self.load_data(filepath:)
File.open(filepath) do |file| File.open(filepath) do |file|
headers = file.first headers = file.first
survey_item_ids = CSV.parse(headers, headers: true).headers survey_item_ids = CSV.parse(headers, headers: true).headers
.filter { |header| header.present? } .filter { |header| header.present? }
.filter { |header| header.start_with? 't-' or header.start_with? 's-' } .filter { |header| header.start_with? 't-' or header.start_with? 's-' }
survey_items = SurveyItem.where(survey_item_id: survey_item_ids) survey_items = SurveyItem.where(survey_item_id: survey_item_ids)
file.lazy.each_slice(1000) do |lines| file.lazy.each_slice(1000) do |lines|
@ -58,11 +57,11 @@ end
module StringMonkeyPatches module StringMonkeyPatches
def integer? def integer?
self.to_i.to_s == self to_i.to_s == self
end end
def valid_likert_score? def valid_likert_score?
self.integer? and self.to_i.between? 1, 5 integer? and to_i.between? 1, 5
end end
end end

@ -1 +1,2 @@
json.extract! @question, :id, :text, :option1, :option2, :option3, :option4, :option5, :category_id, :created_at, :updated_at json.extract! @question, :id, :text, :option1, :option2, :option3, :option4, :option5, :category_id, :created_at,
:updated_at

@ -1,4 +1,5 @@
json.array!(@recipients) do |recipient| json.array!(@recipients) do |recipient|
json.extract! recipient, :id, :name, :phone, :birth_date, :gender, :race, :ethnicity, :home_language_id, :income, :opted_out, :school_id json.extract! recipient, :id, :name, :phone, :birth_date, :gender, :race, :ethnicity, :home_language_id, :income,
:opted_out, :school_id
json.url recipient_url(recipient, format: :json) json.url recipient_url(recipient, format: :json)
end end

@ -1 +1,2 @@
json.extract! @recipient, :id, :name, :phone, :birth_date, :gender, :race, :ethnicity, :home_language_id, :income, :opted_out, :school_id, :created_at, :updated_at json.extract! @recipient, :id, :name, :phone, :birth_date, :gender, :race, :ethnicity, :home_language_id, :income,
:opted_out, :school_id, :created_at, :updated_at

@ -1,4 +1,5 @@
json.array!(@school_schedules) do |school_schedule| json.array!(@school_schedules) do |school_schedule|
json.extract! school_schedule, :id, :name, :description, :school_id, :frequency_hours, :start_date, :end_date, :active, :random, :recipient_list_id, :question_list_id json.extract! school_schedule, :id, :name, :description, :school_id, :frequency_hours, :start_date, :end_date,
:active, :random, :recipient_list_id, :question_list_id
json.url school_schedule_url(school_schedule, format: :json) json.url school_schedule_url(school_schedule, format: :json)
end end

@ -1 +1,2 @@
json.extract! @school_schedule, :id, :name, :description, :school_id, :frequency_hours, :start_date, :end_date, :active, :random, :recipient_list_id, :question_list_id, :created_at, :updated_at json.extract! @school_schedule, :id, :name, :description, :school_id, :frequency_hours, :start_date, :end_date,
:active, :random, :recipient_list_id, :question_list_id, :created_at, :updated_at

@ -8,7 +8,7 @@
# this file is here to facilitate running it. # this file is here to facilitate running it.
# #
require "rubygems" require 'rubygems'
m = Module.new do m = Module.new do
module_function module_function
@ -18,36 +18,36 @@ m = Module.new do
end end
def env_var_version def env_var_version
ENV["BUNDLER_VERSION"] ENV['BUNDLER_VERSION']
end end
def cli_arg_version def cli_arg_version
return unless invoked_as_script? # don't want to hijack other binstubs return unless invoked_as_script? # don't want to hijack other binstubs
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` return unless 'update'.start_with?(ARGV.first || ' ') # must be running `bundle update`
bundler_version = nil bundler_version = nil
update_index = nil update_index = nil
ARGV.each_with_index do |a, i| ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN bundler_version = a if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1
bundler_version = Regexp.last_match(1)
update_index = i update_index = i
end end
bundler_version bundler_version
end end
def gemfile def gemfile
gemfile = ENV["BUNDLE_GEMFILE"] gemfile = ENV['BUNDLE_GEMFILE']
return gemfile if gemfile && !gemfile.empty? return gemfile if gemfile && !gemfile.empty?
File.expand_path("../../Gemfile", __FILE__) File.expand_path('../Gemfile', __dir__)
end end
def lockfile def lockfile
lockfile = lockfile =
case File.basename(gemfile) case File.basename(gemfile)
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) when 'gems.rb' then gemfile.sub(/\.rb$/, gemfile)
else "#{gemfile}.lock" else "#{gemfile}.lock"
end end
File.expand_path(lockfile) File.expand_path(lockfile)
@ -55,15 +55,17 @@ m = Module.new do
def lockfile_version def lockfile_version
return unless File.file?(lockfile) return unless File.file?(lockfile)
lockfile_contents = File.read(lockfile) lockfile_contents = File.read(lockfile)
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
Regexp.last_match(1) Regexp.last_match(1)
end end
def bundler_requirement def bundler_requirement
@bundler_requirement ||= @bundler_requirement ||=
env_var_version || cli_arg_version || env_var_version || cli_arg_version ||
bundler_requirement_for(lockfile_version) bundler_requirement_for(lockfile_version)
end end
def bundler_requirement_for(version) def bundler_requirement_for(version)
@ -73,28 +75,32 @@ m = Module.new do
requirement = bundler_gem_version.approximate_recommendation requirement = bundler_gem_version.approximate_recommendation
return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0") return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new('2.7.0')
requirement += ".a" if bundler_gem_version.prerelease? requirement += '.a' if bundler_gem_version.prerelease?
requirement requirement
end end
def load_bundler! def load_bundler!
ENV["BUNDLE_GEMFILE"] ||= gemfile ENV['BUNDLE_GEMFILE'] ||= gemfile
activate_bundler activate_bundler
end end
def activate_bundler def activate_bundler
gem_error = activation_error_handling do gem_error = activation_error_handling do
gem "bundler", bundler_requirement gem 'bundler', bundler_requirement
end end
return if gem_error.nil? return if gem_error.nil?
require_error = activation_error_handling do require_error = activation_error_handling do
require "bundler/version" require 'bundler/version'
end
if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
return
end end
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
exit 42 exit 42
end end
@ -109,6 +115,4 @@ end
m.load_bundler! m.load_bundler!
if m.invoked_as_script? load Gem.bin_path('bundler', 'bundle') if m.invoked_as_script?
load Gem.bin_path("bundler", "bundle")
end

@ -1,5 +1,5 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
load File.expand_path("spring", __dir__) load File.expand_path('spring', __dir__)
APP_PATH = File.expand_path('../config/application', __dir__) APP_PATH = File.expand_path('../config/application', __dir__)
require_relative "../config/boot" require_relative '../config/boot'
require "rails/commands" require 'rails/commands'

@ -1,5 +1,5 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
load File.expand_path("spring", __dir__) load File.expand_path('spring', __dir__)
require_relative "../config/boot" require_relative '../config/boot'
require "rake" require 'rake'
Rake.application.run Rake.application.run

@ -8,11 +8,11 @@
# this file is here to facilitate running it. # this file is here to facilitate running it.
# #
require "pathname" require 'pathname'
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
Pathname.new(__FILE__).realpath) Pathname.new(__FILE__).realpath)
bundle_binstub = File.expand_path("../bundle", __FILE__) bundle_binstub = File.expand_path('bundle', __dir__)
if File.file?(bundle_binstub) if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
@ -23,7 +23,7 @@ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this
end end
end end
require "rubygems" require 'rubygems'
require "bundler/setup" require 'bundler/setup'
load Gem.bin_path("rspec-core", "rspec") load Gem.bin_path('rspec-core', 'rspec')

@ -1,5 +1,5 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require "fileutils" require 'fileutils'
# path to your application root. # path to your application root.
APP_ROOT = File.expand_path('..', __dir__) APP_ROOT = File.expand_path('..', __dir__)

@ -1,13 +1,13 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"]) if !defined?(Spring) && [nil, 'development', 'test'].include?(ENV['RAILS_ENV'])
gem "bundler" gem 'bundler'
require "bundler" require 'bundler'
# Load Spring without loading other gems in the Gemfile, for speed. # Load Spring without loading other gems in the Gemfile, for speed.
Bundler.locked_gems&.specs&.find { |spec| spec.name == "spring" }&.tap do |spring| Bundler.locked_gems&.specs&.find { |spec| spec.name == 'spring' }&.tap do |spring|
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
gem "spring", spring.version gem 'spring', spring.version
require "spring/binstub" require 'spring/binstub'
rescue Gem::LoadError rescue Gem::LoadError
# Ignore when Spring is not installed. # Ignore when Spring is not installed.
end end

@ -4,7 +4,7 @@ require 'fileutils'
include FileUtils include FileUtils
# path to your application root. # path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) APP_ROOT = Pathname.new File.expand_path('..', __dir__)
def system!(*args) def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==") system(*args) || abort("\n== Command #{args} failed ==")

@ -1,17 +1,17 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__) APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do Dir.chdir(APP_ROOT) do
yarn = ENV["PATH"].split(File::PATH_SEPARATOR). yarn = ENV['PATH'].split(File::PATH_SEPARATOR)
select { |dir| File.expand_path(dir) != __dir__ }. .select { |dir| File.expand_path(dir) != __dir__ }
product(["yarn", "yarn.cmd", "yarn.ps1"]). .product(['yarn', 'yarn.cmd', 'yarn.ps1'])
map { |dir, file| File.expand_path(file, dir) }. .map { |dir, file| File.expand_path(file, dir) }
find { |file| File.executable?(file) } .find { |file| File.executable?(file) }
if yarn if yarn
exec yarn, *ARGV exec yarn, *ARGV
else else
$stderr.puts "Yarn executable was not detected in the system." warn 'Yarn executable was not detected in the system.'
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" warn 'Download Yarn at https://yarnpkg.com/en/docs/install'
exit 1 exit 1
end end
end end

@ -51,7 +51,7 @@ Rails.application.configure do
config.log_level = :debug config.log_level = :debug
# Prepend all log lines with the following tags. # Prepend all log lines with the following tags.
config.log_tags = [ :request_id ] config.log_tags = [:request_id]
# Use a different cache store in production. # Use a different cache store in production.
# config.cache_store = :mem_cache_store # config.cache_store = :mem_cache_store
@ -80,7 +80,7 @@ Rails.application.configure do
# require 'syslog/logger' # require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present? if ENV['RAILS_LOG_TO_STDOUT'].present?
logger = ActiveSupport::Logger.new(STDOUT) logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger) config.logger = ActiveSupport::TaggedLogging.new(logger)

@ -1,6 +1,6 @@
module ArrayMonkeyPatches module ArrayMonkeyPatches
def average def average
self.sum.to_f / self.size sum.to_f / size
end end
end end

@ -16,8 +16,8 @@ FriendlyId.defaults do |config|
# undesirable to allow as slugs. Edit this list as needed for your app. # undesirable to allow as slugs. Edit this list as needed for your app.
config.use :reserved config.use :reserved
config.reserved_words = %w(new edit index session login logout users admin config.reserved_words = %w[new edit index session login logout users admin
stylesheets assets javascripts images) stylesheets assets javascripts images]
# ## Friendly Finders # ## Friendly Finders
# #

@ -4,20 +4,20 @@
# the maximum value specified for Puma. Default is set to 5 threads for minimum # the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record. # and maximum; this matches the default thread size of Active Record.
# #
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } max_threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
threads min_threads_count, max_threads_count threads min_threads_count, max_threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000. # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
# #
port ENV.fetch("PORT") { 3000 } port ENV.fetch('PORT') { 3000 }
# Specifies the `environment` that Puma will run in. # Specifies the `environment` that Puma will run in.
# #
environment ENV.fetch("RAILS_ENV") { "development" } environment ENV.fetch('RAILS_ENV') { 'development' }
# Specifies the `pidfile` that Puma will use. # Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } pidfile ENV.fetch('PIDFILE') { 'tmp/pids/server.pid' }
# Specifies the number of `workers` to boot in clustered mode. # Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together # Workers are forked web server processes. If using threads and workers together

@ -23,7 +23,7 @@ Rails.application.routes.draw do
end end
resources :districts do resources :districts do
resources :schools, only: [:index, :show] do resources :schools, only: %i[index show] do
resources :overview, only: [:index] resources :overview, only: [:index]
resources :categories, only: [:show], path: 'browse' resources :categories, only: [:show], path: 'browse'
end end
@ -31,10 +31,10 @@ Rails.application.routes.draw do
devise_for :users, class_name: 'Legacy::User' devise_for :users, class_name: 'Legacy::User'
as :user do as :user do
get 'users', :to => 'legacy/users#show', :as => :user_root # Rails 3 get 'users', to: 'legacy/users#show', as: :user_root # Rails 3
end end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
get '/welcome', to: 'home#index' get '/welcome', to: 'home#index'
root to: "legacy/welcome#index" root to: 'legacy/welcome#index'
end end

@ -1,6 +1,6 @@
Spring.watch( Spring.watch(
".ruby-version", '.ruby-version',
".rbenv-vars", '.rbenv-vars',
"tmp/restart.txt", 'tmp/restart.txt',
"tmp/caching-dev.txt" 'tmp/caching-dev.txt'
) )

@ -2,8 +2,8 @@ class DeviseCreateUsers < ActiveRecord::Migration[5.0]
def change def change
create_table :users do |t| create_table :users do |t|
## Database authenticatable ## Database authenticatable
t.string :email, null: false, default: "" t.string :email, null: false, default: ''
t.string :encrypted_password, null: false, default: "" t.string :encrypted_password, null: false, default: ''
## Recoverable ## Recoverable
t.string :reset_password_token t.string :reset_password_token
@ -30,7 +30,6 @@ class DeviseCreateUsers < ActiveRecord::Migration[5.0]
# t.string :unlock_token # Only if unlock strategy is :email or :both # t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at # t.datetime :locked_at
t.timestamps null: false t.timestamps null: false
end end

@ -2,11 +2,10 @@ class AddSlugToDistrict < ActiveRecord::Migration[5.0]
def up def up
add_column :districts, :slug, :string add_column :districts, :slug, :string
add_index :districts, :slug, unique: true add_index :districts, :slug, unique: true
District.all.each {|district| district.update(slug: district.slug ||= district.name.parameterize) } District.all.each { |district| district.update(slug: district.slug ||= district.name.parameterize) }
end end
def down def down
remove_column :districts, :slug remove_column :districts, :slug
end end
end end

@ -8,7 +8,6 @@ class RemoveNullConstraintsFromMeasureBenchmarks < ActiveRecord::Migration[6.1]
end end
end end
def down def down
change_table :measures do |t| change_table :measures do |t|
t.change :watch_low_benchmark, :float, null: false t.change :watch_low_benchmark, :float, null: false

@ -1,6 +1,6 @@
class UpdateForeignKeyBetweenSurveyItemResponseAndSchool < ActiveRecord::Migration[6.1] class UpdateForeignKeyBetweenSurveyItemResponseAndSchool < ActiveRecord::Migration[6.1]
def change def change
ActiveRecord::Base.connection.execute("DELETE FROM survey_item_responses") ActiveRecord::Base.connection.execute('DELETE FROM survey_item_responses')
remove_foreign_key :survey_item_responses, :legacy_schools, column: :school_id remove_foreign_key :survey_item_responses, :legacy_schools, column: :school_id
add_foreign_key :survey_item_responses, :schools add_foreign_key :survey_item_responses, :schools

@ -1,6 +1,6 @@
class MakeSchoolDeseIdUnique < ActiveRecord::Migration[6.1] class MakeSchoolDeseIdUnique < ActiveRecord::Migration[6.1]
def change def change
ActiveRecord::Base.connection.execute("UPDATE schools SET dese_id = id") ActiveRecord::Base.connection.execute('UPDATE schools SET dese_id = id')
add_index :schools, :dese_id, unique: true add_index :schools, :dese_id, unique: true
end end
end end

@ -0,0 +1,8 @@
class AddBenchmarksToSurveyItems < ActiveRecord::Migration[6.1]
def change
add_column :survey_items, :watch_low_benchmark, :float
add_column :survey_items, :growth_low_benchmark, :float
add_column :survey_items, :approval_low_benchmark, :float
add_column :survey_items, :ideal_low_benchmark, :float
end
end

@ -0,0 +1,8 @@
class AddBenchmarksToAdminDataItems < ActiveRecord::Migration[6.1]
def change
add_column :admin_data_items, :watch_low_benchmark, :float
add_column :admin_data_items, :growth_low_benchmark, :float
add_column :admin_data_items, :approval_low_benchmark, :float
add_column :admin_data_items, :ideal_low_benchmark, :float
end
end

@ -0,0 +1,8 @@
class RemoveBenchmarksFromMeasures < ActiveRecord::Migration[6.1]
def change
remove_column :measures, :watch_low_benchmark, :float
remove_column :measures, :growth_low_benchmark, :float
remove_column :measures, :approval_low_benchmark, :float
remove_column :measures, :ideal_low_benchmark, :float
end
end

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_12_10_142652) do ActiveRecord::Schema.define(version: 2021_12_17_164449) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements" enable_extension "pg_stat_statements"
@ -27,6 +27,10 @@ ActiveRecord::Schema.define(version: 2021_12_10_142652) do
t.string "description" t.string "description"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.float "watch_low_benchmark"
t.float "growth_low_benchmark"
t.float "approval_low_benchmark"
t.float "ideal_low_benchmark"
end end
create_table "categories", id: :serial, force: :cascade do |t| create_table "categories", id: :serial, force: :cascade do |t|
@ -260,10 +264,6 @@ ActiveRecord::Schema.define(version: 2021_12_10_142652) do
create_table "measures", id: :serial, force: :cascade do |t| create_table "measures", id: :serial, force: :cascade do |t|
t.string "measure_id", null: false t.string "measure_id", null: false
t.string "name" t.string "name"
t.float "watch_low_benchmark"
t.float "growth_low_benchmark"
t.float "approval_low_benchmark"
t.float "ideal_low_benchmark"
t.integer "subcategory_id", null: false t.integer "subcategory_id", null: false
t.text "description" t.text "description"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
@ -313,6 +313,10 @@ ActiveRecord::Schema.define(version: 2021_12_10_142652) do
t.string "prompt" t.string "prompt"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.float "watch_low_benchmark"
t.float "growth_low_benchmark"
t.float "approval_low_benchmark"
t.float "ideal_low_benchmark"
t.index ["measure_id"], name: "index_survey_items_on_measure_id" t.index ["measure_id"], name: "index_survey_items_on_measure_id"
t.index ["survey_item_id"], name: "index_survey_items_on_survey_item_id" t.index ["survey_item_id"], name: "index_survey_items_on_survey_item_id"
end end

@ -0,0 +1,31 @@
# Decision record 1
# Add zone boundaries to Items and change how benchmarks are calculated for Measures, and subcategories
## Status
Implemented
## Context
Story: https://www.pivotaltracker.com/n/projects/2529781/stories/179844090
Add new zone boundaries for Survey and Admin Data items. Measure zone boundaries become a weighted average of Survey and Admin Data items.
At the moment the measure table is has warning, watch, growth, approval, and ideal low benchmarks seeded from the source of truth. This change means the measure table will no longer be populated with that information. Instead, student and teacher survey items and admin data items will be seeded with benchmark information. Measure.rb will instead have methods for calculating the benchmarks.
## Decision
What is the change that we're proposing and/or doing?
Do we move benchmarks to admin data items and survey items directly or do we only populate admin data items with benchmarks and leave benchmarks on measures the way they are?
I've made the decision to move the benchmarks to the item level because it places the seed information on the correct model. Now that we know benchmarks belong to items, not measures, the data in the database and the corresponding models should reflect that fact.
## Consequences
What becomes easier or more difficult to do because of this change?
Also, instead of just getting the data we need from each measure directly, we must cycle through admin and survey items to calculate the benchmark.
This will also slow down the test suite because we must now create survey items or admin data items so the tests pass correctly.

@ -0,0 +1,24 @@
# Decision record template by Michael Nygard
This is the template in [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
You can use [adr-tools](https://github.com/npryce/adr-tools) for managing the ADR files.
In each ADR file, write these sections:
# Title
## Status
What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?
## Context
What is the issue that we're seeing that is motivating this decision or change?
## Decision
What is the change that we're proposing and/or doing?
## Consequences
What becomes easier or more difficult to do because of this change?

@ -1,6 +1,5 @@
# PSQL: /Applications/Postgres.app/Contents/Versions/9.6/bin/psql -h localhost # PSQL: /Applications/Postgres.app/Contents/Versions/9.6/bin/psql -h localhost
# aws s3 presign s3://irrationaldesign/beta-data-080719a.dump # aws s3 presign s3://irrationaldesign/beta-data-080719a.dump
# sudo heroku pg:backups:restore 'https://irrationaldesign.s3.amazonaws.com/beta-data-080719a.dump?AWSAccessKeyId=AKIAIDGE3EMQEWUQZUJA&Signature=KrabUOeggEd5wrjLQ4bvgd9eZGU%3D&Expires=1565267251' DATABASE_URL -a mciea-beta # sudo heroku pg:backups:restore 'https://irrationaldesign.s3.amazonaws.com/beta-data-080719a.dump?AWSAccessKeyId=AKIAIDGE3EMQEWUQZUJA&Signature=KrabUOeggEd5wrjLQ4bvgd9eZGU%3D&Expires=1565267251' DATABASE_URL -a mciea-beta
@ -36,7 +35,7 @@ require 'csv'
namespace :data do namespace :data do
@year = 2019 @year = 2019
desc "load survey responses" desc 'load survey responses'
task load_survey_responses: :environment do task load_survey_responses: :environment do
Dir.glob(Rails.root.join('data', 'survey_responses', '*.csv')).each do |filepath| Dir.glob(Rails.root.join('data', 'survey_responses', '*.csv')).each do |filepath|
puts "=====================> Loading data from csv at path: #{filepath}" puts "=====================> Loading data from csv at path: #{filepath}"
@ -45,30 +44,28 @@ namespace :data do
puts "=====================> Completed loading #{SurveyItemResponse.count} survey responses" puts "=====================> Completed loading #{SurveyItemResponse.count} survey responses"
end end
desc "Load in all data" desc 'Load in all data'
task load: :environment do task load: :environment do
# return if School.count > 0 # return if School.count > 0
Rake::Task["data:load_categories"].invoke Rake::Task['data:load_categories'].invoke
Rake::Task["data:load_questions"].invoke Rake::Task['data:load_questions'].invoke
Rake::Task["db:seed"].invoke Rake::Task['db:seed'].invoke
Rake::Task["data:load_responses"].invoke Rake::Task['data:load_responses'].invoke
Rake::Task["data:load_nonlikert_values"].invoke Rake::Task['data:load_nonlikert_values'].invoke
end end
desc 'Check question / category data against existing data' desc 'Check question / category data against existing data'
task check_questions: :environment do task check_questions: :environment do
csv_string = File.read(File.expand_path("../../../data/MeasureKey#{@year}.csv", __FILE__)) csv_string = File.read(File.expand_path("../../../data/MeasureKey#{@year}.csv", __FILE__))
csv = CSV.parse(csv_string, :headers => true) csv = CSV.parse(csv_string, headers: true)
t = Time.new t = Time.new
csv.each_with_index do |question, index| csv.each_with_index do |question, _index|
existing_question = Question.created_in(@year).find_by_external_id(question['qid']) existing_question = Question.created_in(@year).find_by_external_id(question['qid'])
if existing_question.blank? if existing_question.blank?
puts "NOT FOUND: #{question['qid']} -> #{question["Question Text"]}" puts "NOT FOUND: #{question['qid']} -> #{question['Question Text']}"
else else
if Question.where(external_id: question['qid']).count > 1 puts "MULTIPLE FOUND: #{question['qid']}" if Question.where(external_id: question['qid']).count > 1
puts "MULTIPLE FOUND: #{question['qid']}"
end
question_text = question['Question Text'].gsub(/[[:space:]]/, ' ').strip question_text = question['Question Text'].gsub(/[[:space:]]/, ' ').strip
if existing_question.text != question_text if existing_question.text != question_text
@ -92,10 +89,10 @@ namespace :data do
desc 'Sync questions / category data against existing data' desc 'Sync questions / category data against existing data'
task sync_questions: :environment do task sync_questions: :environment do
csv_string = File.read(File.expand_path("../../../data/MeasureKey#{@year}.csv", __FILE__)) csv_string = File.read(File.expand_path("../../../data/MeasureKey#{@year}.csv", __FILE__))
csv = CSV.parse(csv_string, :headers => true) csv = CSV.parse(csv_string, headers: true)
t = Time.new t = Time.new
csv.each_with_index do |question, index| csv.each_with_index do |question, _index|
existing_question = Question.created_in(@year).find_by_external_id(question['qid']) existing_question = Question.created_in(@year).find_by_external_id(question['qid'])
if existing_question.blank? if existing_question.blank?
categories = Category.where(name: question['Category Name'].titleize) categories = Category.where(name: question['Category Name'].titleize)
@ -114,7 +111,7 @@ namespace :data do
option4: question['R4'], option4: question['R4'],
option5: question['R5'], option5: question['R5'],
target_group: question['qid'].starts_with?('s') ? 'for_students' : 'for_teachers', target_group: question['qid'].starts_with?('s') ? 'for_students' : 'for_teachers',
reverse: question['Reverse'] == "1" reverse: question['Reverse'] == '1'
) )
end end
else else
@ -145,7 +142,7 @@ namespace :data do
desc 'Load in category data' desc 'Load in category data'
task load_categories: :environment do task load_categories: :environment do
measures = JSON.parse(File.read(File.expand_path('../../../data/measures.json', __FILE__))) measures = JSON.parse(File.read(File.expand_path('../../data/measures.json', __dir__)))
measures.each_with_index do |measure, index| measures.each_with_index do |measure, index|
category = Category.create_with( category = Category.create_with(
blurb: measure['blurb'], blurb: measure['blurb'],
@ -169,14 +166,14 @@ namespace :data do
external_id: subinfo_key external_id: subinfo_key
).find_or_create_by(name: subsubinfo['title']) ).find_or_create_by(name: subsubinfo['title'])
if subsubinfo['nonlikert'].present? next unless subsubinfo['nonlikert'].present?
subsubinfo['nonlikert'].each do |nonlikert_info|
puts("NONLIKERT FOUND: #{nonlikert_info['title']}") subsubinfo['nonlikert'].each do |nonlikert_info|
nonlikert = subsubcategory.child_categories.create_with( puts("NONLIKERT FOUND: #{nonlikert_info['title']}")
benchmark_description: nonlikert_info['benchmark_explanation'], nonlikert = subsubcategory.child_categories.create_with(
benchmark: nonlikert_info['benchmark'] benchmark_description: nonlikert_info['benchmark_explanation'],
).find_or_create_by(name: nonlikert_info['title']) benchmark: nonlikert_info['benchmark']
end ).find_or_create_by(name: nonlikert_info['title'])
end end
end end
end end
@ -190,18 +187,18 @@ namespace :data do
'teacher' 'teacher'
] ]
questions = JSON.parse(File.read(File.expand_path('../../../data/questions.json', __FILE__))) questions = JSON.parse(File.read(File.expand_path('../../data/questions.json', __dir__)))
questions.each do |question| questions.each do |question|
category = nil category = nil
question['category'].split('-').each do |external_id| question['category'].split('-').each do |external_id|
categories = category.present? ? category.child_categories : Category categories = category.present? ? category.child_categories : Category
category = categories.where(external_id: external_id).first category = categories.where(external_id: external_id).first
if category.nil? next unless category.nil?
puts 'NOTHING'
puts external_id puts 'NOTHING'
puts categories.inspect puts external_id
category = categories.create(name: question['Category Name'], external_id: external_id) puts categories.inspect
end category = categories.create(name: question['Category Name'], external_id: external_id)
end end
question_text = question['text'].gsub(/[[:space:]]/, ' ').strip question_text = question['text'].gsub(/[[:space:]]/, ' ').strip
if question_text.index('.* teacher').nil? if question_text.index('.* teacher').nil?
@ -213,7 +210,7 @@ namespace :data do
option4: question['answers'][3], option4: question['answers'][3],
option5: question['answers'][4], option5: question['answers'][4],
for_recipient_students: question['child'].present?, for_recipient_students: question['child'].present?,
reverse: question['Reverse'] == "1" reverse: question['Reverse'] == '1'
) )
else else
variations.each do |variation| variations.each do |variation|
@ -225,7 +222,7 @@ namespace :data do
option4: question['answers'][3], option4: question['answers'][3],
option5: question['answers'][4], option5: question['answers'][4],
for_recipient_students: question['child'].present?, for_recipient_students: question['child'].present?,
reverse: question['Reverse'] == "1" reverse: question['Reverse'] == '1'
) )
end end
end end
@ -240,21 +237,23 @@ namespace :data do
] ]
csv_string = File.read(File.expand_path("../../../data/MeasureKey#{@year}.csv", __FILE__)) csv_string = File.read(File.expand_path("../../../data/MeasureKey#{@year}.csv", __FILE__))
csv = CSV.parse(csv_string, :headers => true) csv = CSV.parse(csv_string, headers: true)
t = Time.new t = Time.new
csv.each_with_index do |question, index| csv.each_with_index do |question, _index|
category = nil category = nil
question['Category19'].split('-').each do |external_id_raw| question['Category19'].split('-').each do |external_id_raw|
external_id = external_id_raw.gsub(/[[:space:]]/, ' ').strip external_id = external_id_raw.gsub(/[[:space:]]/, ' ').strip
categories = category.present? ? category.child_categories : Category categories = category.present? ? category.child_categories : Category
category = categories.where(external_id: external_id).first category = categories.where(external_id: external_id).first
if category.nil? next unless category.nil?
puts 'NOTHING'
puts "#{question['Category']} -- #{external_id}" puts 'NOTHING'
puts categories.map { |c| "#{c.name} - |#{c.external_id}| == |#{external_id}|: - #{external_id == c.external_id}"}.join(" ---- ") puts "#{question['Category']} -- #{external_id}"
category = categories.create(name: question['Category Name'], external_id: external_id) puts categories.map { |c|
end "#{c.name} - |#{c.external_id}| == |#{external_id}|: - #{external_id == c.external_id}"
}.join(' ---- ')
category = categories.create(name: question['Category Name'], external_id: external_id)
end end
question_text = question['Question Text'].gsub(/[[:space:]]/, ' ').strip question_text = question['Question Text'].gsub(/[[:space:]]/, ' ').strip
if question_text.index('.* teacher').nil? if question_text.index('.* teacher').nil?
@ -265,9 +264,9 @@ namespace :data do
option3: question['R3'], option3: question['R3'],
option4: question['R4'], option4: question['R4'],
option5: question['R5'], option5: question['R5'],
for_recipient_students: question['Level'] == "Students", for_recipient_students: question['Level'] == 'Students',
external_id: question['qid'], external_id: question['qid'],
reverse: question['Reverse'] == "1" reverse: question['Reverse'] == '1'
) )
else else
variations.each do |variation| variations.each do |variation|
@ -278,9 +277,9 @@ namespace :data do
option3: question['R3'], option3: question['R3'],
option4: question['R4'], option4: question['R4'],
option5: question['R5'], option5: question['R5'],
for_recipient_students: question['Level'] == "Students", for_recipient_students: question['Level'] == 'Students',
external_id: question['qid'], external_id: question['qid'],
reverse: question['Reverse'] == "1" reverse: question['Reverse'] == '1'
) )
end end
end end
@ -310,17 +309,17 @@ namespace :data do
missing_questions = {} missing_questions = {}
bad_answers = {} bad_answers = {}
timeToRun = 120000 * 60 timeToRun = 120_000 * 60
startIndex = 0 startIndex = 0
stopIndex = 1000000 stopIndex = 1_000_000
startTime = Time.new startTime = Time.new
# ['teacher_responses'].each do |file| # ['teacher_responses'].each do |file|
['student_responses', 'teacher_responses'].each do |file| %w[student_responses teacher_responses].each do |file|
recipients = file.split('_')[0] recipients = file.split('_')[0]
target_group = Question.target_groups["for_#{recipients}s"] target_group = Question.target_groups["for_#{recipients}s"]
csv_string = File.read(File.expand_path("../../../data/#{file}_#{@year}.csv", __FILE__)) csv_string = File.read(File.expand_path("../../../data/#{file}_#{@year}.csv", __FILE__))
csv = CSV.parse(csv_string, :headers => true) csv = CSV.parse(csv_string, headers: true)
puts("LOADING CSV: #{csv.length} ROWS") puts("LOADING CSV: #{csv.length} ROWS")
t = Time.new t = Time.new
@ -338,16 +337,16 @@ namespace :data do
end end
district_name = row['Q111'].strip district_name = row['Q111'].strip
if district_name.blank? || district_name == "NA" if district_name.blank? || district_name == 'NA'
puts "DISTRICT NOT FOUND: #{district_name}" puts "DISTRICT NOT FOUND: #{district_name}"
next next
end end
# district_name = row['To begin, please select your district.'] if district_name.nil? # district_name = row['To begin, please select your district.'] if district_name.nil?
district = District.find_or_create_by(name: district_name, state_id: 1) district = District.find_or_create_by(name: district_name, state_id: 1)
school_name = row["SchoolName"].strip school_name = row['SchoolName'].strip
if school_name.blank? || school_name == "NA" if school_name.blank? || school_name == 'NA'
puts "BLANK SCHOOL NAME: #{district.name} - #{index}" puts "BLANK SCHOOL NAME: #{district.name} - #{index}"
next next
end end
@ -356,38 +355,36 @@ namespace :data do
if school.nil? if school.nil?
next if unknown_schools[school_name] next if unknown_schools[school_name]
puts "DATAERROR: Unable to find school: #{school_name} - #{index}" puts "DATAERROR: Unable to find school: #{school_name} - #{index}"
unknown_schools[school_name] = true unknown_schools[school_name] = true
next next
end end
respondent_id = "#{recipients}-#{index}-#{row["ResponseId"].strip}" respondent_id = "#{recipients}-#{index}-#{row['ResponseId'].strip}"
recipient_id = respondent_map["#{school.id}-#{@year}-#{respondent_id}"] recipient_id = respondent_map["#{school.id}-#{@year}-#{respondent_id}"]
if recipient_id.present? recipient = school.recipients.where(id: recipient_id).first if recipient_id.present?
recipient = school.recipients.where(id: recipient_id).first
end
if recipient.nil? if recipient.nil?
begin begin
recipient = school.recipients.create( recipient = school.recipients.create(
name: "Survey Respondent Id: #{respondent_id}" name: "Survey Respondent Id: #{respondent_id}"
) )
rescue rescue StandardError
puts "DATAERROR: INDEX: #{index} ERROR AT #{index} - #{district.name} - #{school_name} #{school}: #{respondent_id}" puts "DATAERROR: INDEX: #{index} ERROR AT #{index} - #{district.name} - #{school_name} #{school}: #{respondent_id}"
end end
respondent_map["#{school.id}-#{respondent_id}"] = recipient.id respondent_map["#{school.id}-#{respondent_id}"] = recipient.id
end end
recipient_list = school.recipient_lists.find_by_name("#{recipients.titleize} List") recipient_list = school.recipient_lists.find_by_name("#{recipients.titleize} List")
if recipient_list.nil? recipient_list = school.recipient_lists.create(name: "#{recipients.titleize} List") if recipient_list.nil?
recipient_list = school.recipient_lists.create(name: "#{recipients.titleize} List")
end
recipient_list.recipient_id_array << recipient.id recipient_list.recipient_id_array << recipient.id
recipient_list.save! recipient_list.save!
row.each do |key, value| row.each do |key, value|
t1 = Time.new t1 = Time.new
next if value.nil? or key.nil? or value.to_s == "-99" next if value.nil? or key.nil? or value.to_s == '-99'
key = key.gsub(/[[:space:]]/, ' ').gsub(/\./, '-').strip.gsub(/\s+/, ' ') key = key.gsub(/[[:space:]]/, ' ').gsub(/\./, '-').strip.gsub(/\s+/, ' ')
key = key.gsub(/-4-5/, '').gsub(/-6-12/, '') key = key.gsub(/-4-5/, '').gsub(/-6-12/, '')
value = value.gsub(/[[:space:]]/, ' ').strip.downcase value = value.gsub(/[[:space:]]/, ' ').strip.downcase
@ -400,23 +397,26 @@ namespace :data do
if question.nil? if question.nil?
next if missing_questions[key] next if missing_questions[key]
puts "DATAERROR: Unable to find question: #{key}" puts "DATAERROR: Unable to find question: #{key}"
missing_questions[key] = true missing_questions[key] = true
next next
else elsif question.unknown?
question.update_attributes(target_group: target_group) if question.unknown? question.update_attributes(target_group: target_group)
end end
if (value.to_i.blank?) if value.to_i.blank?
answer_index = question.option_index(value) answer_index = question.option_index(value)
answer_dictionary.each do |k, v| answer_dictionary.each do |k, v|
break if answer_index.present? break if answer_index.present?
answer_index = question.option_index(value.gsub(k.to_s, v.to_s)) answer_index = question.option_index(value.gsub(k.to_s, v.to_s))
answer_index = question.option_index(value.gsub(v.to_s, k.to_s)) if answer_index.nil? answer_index = question.option_index(value.gsub(v.to_s, k.to_s)) if answer_index.nil?
end end
if answer_index.nil? if answer_index.nil?
next if bad_answers[key] next if bad_answers[key]
puts "DATAERROR: Unable to find answer: #{key} = #{value.downcase.strip} - #{question.options.inspect}" puts "DATAERROR: Unable to find answer: #{key} = #{value.downcase.strip} - #{question.options.inspect}"
bad_answers[key] = true bad_answers[key] = true
next next
@ -429,7 +429,11 @@ namespace :data do
# answer_index = 6 - answer_index if question.reverse? # answer_index = 6 - answer_index if question.reverse?
responded_at = Date.strptime(row['recordedDate'], '%Y-%m-%d %H:%M:%S') rescue Date.today responded_at = begin
Date.strptime(row['recordedDate'], '%Y-%m-%d %H:%M:%S')
rescue StandardError
Date.today
end
begin begin
recipient.attempts.create(question: question, answer_index: answer_index, responded_at: responded_at) recipient.attempts.create(question: question, answer_index: answer_index, responded_at: responded_at)
rescue Exception => e rescue Exception => e
@ -448,65 +452,64 @@ namespace :data do
desc 'Load in nonlikert values for each school' desc 'Load in nonlikert values for each school'
task load_nonlikert_values: :environment do task load_nonlikert_values: :environment do
csv_string = File.read(File.expand_path("../../../data/MCIEA_18-19AdminData_Final.csv", __FILE__)) csv_string = File.read(File.expand_path('../../data/MCIEA_18-19AdminData_Final.csv', __dir__))
# csv_string = File.read(File.expand_path("../../../data/MCIEA_16-17_SGP.csv", __FILE__)) # csv_string = File.read(File.expand_path("../../../data/MCIEA_16-17_SGP.csv", __FILE__))
csv = CSV.parse(csv_string, :headers => true) csv = CSV.parse(csv_string, headers: true)
puts("LOADING NONLIKERT CSV: #{csv.length} ROWS") puts("LOADING NONLIKERT CSV: #{csv.length} ROWS")
errors = [] errors = []
csv.each_with_index do |row, index| csv.each_with_index do |row, _index|
next if row["Likert_Value"].blank? next if row['Likert_Value'].blank?
base = Category base = Category
category_ids = row["Category"].split("-") category_ids = row['Category'].split('-')
category_ids.each do |category_id| category_ids.each do |category_id|
category_id = category_id.downcase if category_id.downcase =~ /i/ category_id = category_id.downcase if category_id.downcase =~ /i/
base = base.find_by_external_id(category_id) base = base.find_by_external_id(category_id)
if base.nil? if base.nil?
row["reason"] = "Unable to find category_id #{category_id} for category #{row["Category"]}" row['reason'] = "Unable to find category_id #{category_id} for category #{row['Category']}"
errors << row errors << row
next next
end end
base = base.child_categories base = base.child_categories
end end
nonlikert_category = base.where(name: row["NonLikert Title"]).first nonlikert_category = base.where(name: row['NonLikert Title']).first
if nonlikert_category.nil? if nonlikert_category.nil?
row["reason"] = "Unable to find nonlikert category: #{row["NonLikert Title"]} in #{}" row['reason'] = "Unable to find nonlikert category: #{row['NonLikert Title']} in "
errors << row errors << row
next next
else elsif (benchmark = row['Benchmark']).present?
if (benchmark = row["Benchmark"]).present? nonlikert_category.update(benchmark: benchmark)
nonlikert_category.update(benchmark: benchmark)
end
end end
district = District.where(name: row["District"], state_id: 1).first district = District.where(name: row['District'], state_id: 1).first
if district.blank? if district.blank?
row["reason"] = "DISTRICT NOT FOUND: #{row["District"]}" row['reason'] = "DISTRICT NOT FOUND: #{row['District']}"
errors << row errors << row
next next
end end
school = district.schools.where(name: row["School"]).first school = district.schools.where(name: row['School']).first
if school.blank? if school.blank?
row["reason"] = "SCHOOL NOT FOUND: #{row["School"]} (#{district.name})" row['reason'] = "SCHOOL NOT FOUND: #{row['School']} (#{district.name})"
errors << row errors << row
next next
end end
school_category = school.school_categories.find_or_create_by(category: nonlikert_category, year: "#{@year}") school_category = school.school_categories.find_or_create_by(category: nonlikert_category, year: @year.to_s)
if school_category.blank? if school_category.blank?
row["reason"] = "SCHOOL CATEGORY NOT FOUND: #{school.name} (#{district.name}) #{nonlikert_category.name}" row['reason'] = "SCHOOL CATEGORY NOT FOUND: #{school.name} (#{district.name}) #{nonlikert_category.name}"
errors << row errors << row
next next
end end
zscore = (([-2,[row["Likert_Value"].to_f-3,2].min].max * 10).to_i).to_f / 10.0 zscore = ([-2, [row['Likert_Value'].to_f - 3, 2].min].max * 10).to_i.to_f / 10.0
school_category.update( school_category.update(
nonlikert: row["NL_Value"], nonlikert: row['NL_Value'],
zscore: zscore.to_f, zscore: zscore.to_f,
year: "#{@year}", year: @year.to_s,
valid_child_count: 1 valid_child_count: 1
) )
@ -514,40 +517,41 @@ namespace :data do
end end
errors.each do |error| errors.each do |error|
puts "#{error["reason"]}: #{error["NonLikert Title"]} -> #{error["Likert_Value"]}" puts "#{error['reason']}: #{error['NonLikert Title']} -> #{error['Likert_Value']}"
end end
puts "COUNT: #{SchoolCategory.where(attempt_count: 0, answer_index_total: 0).where("nonlikert is not null and zscore is null").count}" puts "COUNT: #{SchoolCategory.where(attempt_count: 0,
answer_index_total: 0).where('nonlikert is not null and zscore is null').count}"
end end
desc 'Load in custom zones for each category' desc 'Load in custom zones for each category'
task load_custom_zones: :environment do task load_custom_zones: :environment do
ENV['BULK_PROCESS'] = 'true' ENV['BULK_PROCESS'] = 'true'
csv_string = File.read(File.expand_path("../../../data/Benchmarks2016-2017.csv", __FILE__)) csv_string = File.read(File.expand_path('../../data/Benchmarks2016-2017.csv', __dir__))
csv = CSV.parse(csv_string, :headers => true) csv = CSV.parse(csv_string, headers: true)
csv.each_with_index do |row, index| csv.each_with_index do |row, _index|
next if row["Warning High"].blank? next if row['Warning High'].blank?
category = Category.find_by_name(row["Subcategory"]) category = Category.find_by_name(row['Subcategory'])
if category.nil? if category.nil?
puts "Unable to find category #{row["Subcategory"]}" puts "Unable to find category #{row['Subcategory']}"
next next
end end
custom_zones = [ custom_zones = [
row["Warning High"], row['Warning High'],
row["Watch High"], row['Watch High'],
row["Growth High"], row['Growth High'],
row["Approval High"], row['Approval High'],
5 5
] ]
puts "#{category.name} -> #{custom_zones.join(",")}" puts "#{category.name} -> #{custom_zones.join(',')}"
category.update(zones: custom_zones.join(",")) category.update(zones: custom_zones.join(','))
end end
ENV.delete('BULK_PROCESS') ENV.delete('BULK_PROCESS')
@ -559,7 +563,8 @@ namespace :data do
task move_likert_to_submeasures: :environment do task move_likert_to_submeasures: :environment do
Question.all.each do |q| Question.all.each do |q|
category = q.category category = q.category
next unless category.name.index("Scale").nil? next unless category.name.index('Scale').nil?
new_category_name = "#{category.name} Scale" new_category_name = "#{category.name} Scale"
new_category = category.child_categories.where(name: new_category_name).first new_category = category.child_categories.where(name: new_category_name).first
if new_category.nil? if new_category.nil?
@ -592,19 +597,19 @@ namespace :data do
new_school_questions = [] new_school_questions = []
category.questions.created_in(@year).each do |question| category.questions.created_in(@year).each do |question|
school = school_category.school school = school_category.school
next if school.district.name != "Boston" next if school.district.name != 'Boston'
school_question = school_category.school_questions.for(school, question).first school_question = school_category.school_questions.for(school, question).first
if school_question.present? if school_question.present?
school_questions << school_question school_questions << school_question
else else
attempt_data = Attempt. attempt_data = Attempt
joins(:question). .joins(:question)
created_in(school_category.year). .created_in(school_category.year)
for_question(question). .for_question(question)
for_school(school). .for_school(school)
select('count(attempts.answer_index) as response_count'). .select('count(attempts.answer_index) as response_count')
select('sum(case when questions.reverse then 6 - attempts.answer_index else attempts.answer_index end) as answer_index_total')[0] .select('sum(case when questions.reverse then 6 - attempts.answer_index else attempts.answer_index end) as answer_index_total')[0]
available_responders = school.available_responders_for(question) available_responders = school.available_responders_for(question)
@ -625,7 +630,6 @@ namespace :data do
SchoolQuestion.import new_school_questions SchoolQuestion.import new_school_questions
end end
end end
end end
end end
@ -634,17 +638,14 @@ namespace :data do
School.all.each do |school| School.all.each do |school|
Category.all.each do |category| Category.all.each do |category|
school_category = SchoolCategory.for(school, category).in(@year).first school_category = SchoolCategory.for(school, category).in(@year).first
if school_category.nil? school_category = school.school_categories.create(category: category, year: @year) if school_category.nil?
school_category = school.school_categories.create(category: category, year: @year)
end
school_category.sync_aggregated_responses school_category.sync_aggregated_responses
end end
end end
end end
end end
#<SchoolCategory id: 1, school_id: 1, category_id: 1, attempt_count: 277, response_count: 277, answer_index_total: 1073, created_at: "2017-10-17 00:21:52", updated_at: "2018-03-03 17:24:53", nonlikert: nil, zscore: 0.674396962759463, year: "2017"> # <SchoolCategory id: 1, school_id: 1, category_id: 1, attempt_count: 277, response_count: 277, answer_index_total: 1073, created_at: "2017-10-17 00:21:52", updated_at: "2018-03-03 17:24:53", nonlikert: nil, zscore: 0.674396962759463, year: "2017">
# require 'csv' # require 'csv'
# student_counts_string = File.read(File.expand_path("data/bps_student_counts.csv")) # student_counts_string = File.read(File.expand_path("data/bps_student_counts.csv"))
@ -691,8 +692,6 @@ end
# #
# #
# min_response_rate = 0.3 # min_response_rate = 0.3
# level = 1 # level = 1
# # categories = Category.joins(:questions).uniq.all # # categories = Category.joins(:questions).uniq.all
@ -796,7 +795,6 @@ end
# #
# puts "TOTAL: #{total}" # puts "TOTAL: #{total}"
# [ # [
# "next-wave-full-circle" # "next-wave-full-circle"
# ].each do |slug| # ].each do |slug|

@ -7,7 +7,7 @@ namespace :dupes do
# | Dist1 | Jefferson High | lincoln-high | created_at | updated_at | # | Dist1 | Jefferson High | lincoln-high | created_at | updated_at |
task record_csv: :environment do task record_csv: :environment do
csv_string = CSV.generate do |csv| csv_string = CSV.generate do |csv|
csv << [ 'District Name', 'School Name', 'School Slug', 'Creation Time', 'Updated Time' ] csv << ['District Name', 'School Name', 'School Slug', 'Creation Time', 'Updated Time']
School.all.order(:district_id, :name, :created_at).each do |school| School.all.order(:district_id, :name, :created_at).each do |school|
schools = School.where name: school.name, district: school.district schools = School.where name: school.name, district: school.district
@ -23,21 +23,21 @@ namespace :dupes do
task dedup_schools: :environment do task dedup_schools: :environment do
School.all.each do |school| School.all.each do |school|
schools = School.where(name: school.name, district: school.district).order(:created_at) schools = School.where(name: school.name, district: school.district).order(:created_at)
if schools.length > 1 next unless schools.length > 1
school_to_keep = schools.first
schools.each do |school_to_destroy|
next if school_to_destroy == school_to_keep
school_to_keep.update(qualtrics_code: school_to_destroy.qualtrics_code) school_to_keep = schools.first
schools.each do |school_to_destroy|
next if school_to_destroy == school_to_keep
SurveyItemResponse.where(school: school_to_destroy).each do |response| school_to_keep.update(qualtrics_code: school_to_destroy.qualtrics_code)
success = response.update(school: school_to_keep)
puts "Attempted to update survey item response with id #{response.id} to point to school with id #{school_to_keep.id}. Successful? #{success}"
puts response.reload.school_id
end
school_to_destroy.destroy SurveyItemResponse.where(school: school_to_destroy).each do |response|
success = response.update(school: school_to_keep)
puts "Attempted to update survey item response with id #{response.id} to point to school with id #{school_to_keep.id}. Successful? #{success}"
puts response.reload.school_id
end end
school_to_destroy.destroy
end end
end end
end end

@ -1,12 +1,10 @@
namespace :survey do namespace :survey do
desc 'Text all recipients ready for an attempt' desc 'Text all recipients ready for an attempt'
task :attempt_questions => :environment do task attempt_questions: :environment do
Legacy::Schedule.active.each do |schedule| Legacy::Schedule.active.each do |schedule|
schedule.recipient_schedules.ready.each do |recipient_schedule| schedule.recipient_schedules.ready.each do |recipient_schedule|
recipient_schedule.attempt_question recipient_schedule.attempt_question
end end
end end
end end
end end

@ -4,14 +4,14 @@ describe CategoriesController, type: :controller do
include BasicAuthHelper include BasicAuthHelper
let(:school) { create(:school) } let(:school) { create(:school) }
let(:district) { create(:district) } let(:district) { create(:district) }
let!(:categories) { let!(:categories) do
[create(:category, name: 'Second', sort_index: 2), create(:category, name: 'First', sort_index: 1)] [create(:category, name: 'Second', sort_index: 2), create(:category, name: 'First', sort_index: 1)]
} end
it 'fetches categories sorted by sort_index' do it 'fetches categories sorted by sort_index' do
login_as district login_as district
category = categories.first category = categories.first
get :show, params: { id: category.to_param, school_id: school.to_param, district_id: district.to_param } get :show, params: { id: category.to_param, school_id: school.to_param, district_id: district.to_param }
expect(assigns(:categories).map(&:name)).to eql ['First', 'Second'] expect(assigns(:categories).map(&:name)).to eql %w[First Second]
end end
end end

@ -1,12 +1,12 @@
require 'rails_helper' require 'rails_helper'
describe HomeController, type: :controller do describe HomeController, type: :controller do
let!(:categories) { let!(:categories) do
[create(:category, name: 'Second', sort_index: 2), create(:category, name: 'First', sort_index: 1)] [create(:category, name: 'Second', sort_index: 2), create(:category, name: 'First', sort_index: 1)]
} end
it 'fetches categories sorted by sort_index' do it 'fetches categories sorted by sort_index' do
get :index get :index
expect(assigns(:categories).map(&:name)).to eql ['First', 'Second'] expect(assigns(:categories).map(&:name)).to eql %w[First Second]
end end
end end

@ -2,7 +2,6 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe AttemptsController, type: :controller do RSpec.describe AttemptsController, type: :controller do
let(:valid_session) { {} } let(:valid_session) { {} }
let!(:recipients) { create_recipients(school, 2) } let!(:recipients) { create_recipients(school, 2) }
@ -16,13 +15,19 @@ module Legacy
QuestionList.create!(name: 'Parent Questions', question_ids: questions.map(&:id).join(',')) QuestionList.create!(name: 'Parent Questions', question_ids: questions.map(&:id).join(','))
end end
let(:schedule) { Schedule.create(name: 'Test Schedule', question_list: question_list, recipient_list: recipient_list) } let(:schedule) do
Schedule.create(name: 'Test Schedule', question_list: question_list, recipient_list: recipient_list)
end
let(:school) { Legacy::School.create!(name: 'School') } let(:school) { Legacy::School.create!(name: 'School') }
let(:recipient_schedule) { RecipientSchedule.create(recipient: recipients.first, schedule: schedule, next_attempt_at: Time.now) } let(:recipient_schedule) do
let(:recipient_schedule2) { RecipientSchedule.create(recipient: recipients.last, schedule: schedule, next_attempt_at: Time.now) } RecipientSchedule.create(recipient: recipients.first, schedule: schedule, next_attempt_at: Time.now)
end
let(:recipient_schedule2) do
RecipientSchedule.create(recipient: recipients.last, schedule: schedule, next_attempt_at: Time.now)
end
let!(:first_attempt) { let!(:first_attempt) do
Attempt.create( Attempt.create(
schedule: schedule, schedule: schedule,
recipient: recipients.first, recipient: recipients.first,
@ -30,8 +35,8 @@ module Legacy
question: questions.first, question: questions.first,
sent_at: Time.new sent_at: Time.new
) )
} end
let!(:attempt) { let!(:attempt) do
Attempt.create( Attempt.create(
schedule: schedule, schedule: schedule,
recipient: recipients.first, recipient: recipients.first,
@ -39,8 +44,8 @@ module Legacy
question: questions.first, question: questions.first,
sent_at: Time.new sent_at: Time.new
) )
} end
let!(:attempt2) { let!(:attempt2) do
Attempt.create( Attempt.create(
schedule: schedule, schedule: schedule,
recipient: recipients.last, recipient: recipients.last,
@ -48,13 +53,14 @@ module Legacy
question: questions.first, question: questions.first,
sent_at: Time.new sent_at: Time.new
) )
} end
describe "POST #twilio" do describe 'POST #twilio' do
context "with valid params" do context 'with valid params' do
let(:twilio_attributes) { let(:twilio_attributes) do
{ 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw', 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => '3', 'NumMedia' => '0' } { 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw',
} 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => '3', 'NumMedia' => '0' }
end
before :each do before :each do
post :twilio, params: twilio_attributes post :twilio, params: twilio_attributes
@ -64,7 +70,7 @@ module Legacy
expect(attempt.question.attempts.for_school(school).with_answer.count).to eq(1) expect(attempt.question.attempts.for_school(school).with_answer.count).to eq(1)
end end
it "updates the last attempt by recipient phone number" do it 'updates the last attempt by recipient phone number' do
attempt.reload attempt.reload
expect(attempt.answer_index).to eq(3) expect(attempt.answer_index).to eq(3)
expect(attempt.twilio_details).to eq(twilio_attributes.with_indifferent_access.to_yaml) expect(attempt.twilio_details).to eq(twilio_attributes.with_indifferent_access.to_yaml)
@ -75,14 +81,15 @@ module Legacy
expect(first_attempt.responded_at).to be_nil expect(first_attempt.responded_at).to be_nil
end end
it "sends back a message" do it 'sends back a message' do
expect(response.body).to eq "We've registered your response of \"Option 0:3 C\". You are the first person to respond to this question. Once more people have responded you will be able to see all responses at: http://test.host/schools/school/categories/test-category" expect(response.body).to eq "We've registered your response of \"Option 0:3 C\". You are the first person to respond to this question. Once more people have responded you will be able to see all responses at: http://test.host/schools/school/categories/test-category"
end end
context "with second response" do context 'with second response' do
let(:twilio_attributes2) { let(:twilio_attributes2) do
{ 'MessageSid' => 'fwefwefewfewfasfsdfdf', 'AccountSid' => 'wefwegdbvcbrtnrn', 'MessagingServiceSid' => 'dfvdfvegbdfb', 'From' => '+1111111111', 'To' => '2223334444', 'Body' => '4', 'NumMedia' => '0' } { 'MessageSid' => 'fwefwefewfewfasfsdfdf', 'AccountSid' => 'wefwegdbvcbrtnrn',
} 'MessagingServiceSid' => 'dfvdfvegbdfb', 'From' => '+1111111111', 'To' => '2223334444', 'Body' => '4', 'NumMedia' => '0' }
end
before :each do before :each do
post :twilio, params: twilio_attributes2 post :twilio, params: twilio_attributes2
@ -92,26 +99,27 @@ module Legacy
expect(attempt.question.attempts.for_school(school).with_answer.count).to eq(2) expect(attempt.question.attempts.for_school(school).with_answer.count).to eq(2)
end end
it "updates the attempt from the second recipient" do it 'updates the attempt from the second recipient' do
attempt2.reload attempt2.reload
expect(attempt2.answer_index).to eq(4) expect(attempt2.answer_index).to eq(4)
expect(attempt2.twilio_details).to eq(twilio_attributes2.with_indifferent_access.to_yaml) expect(attempt2.twilio_details).to eq(twilio_attributes2.with_indifferent_access.to_yaml)
expect(attempt2.responded_at).to be_present expect(attempt2.responded_at).to be_present
end end
it "sends back a message" do it 'sends back a message' do
expect(response.body).to eq "We've registered your response of \"Option 0:3 D\". 2 people have responded to this question so far. To see all responses visit: http://test.host/schools/school/categories/test-category" expect(response.body).to eq "We've registered your response of \"Option 0:3 D\". 2 people have responded to this question so far. To see all responses visit: http://test.host/schools/school/categories/test-category"
end end
end end
end end
['stOp', 'cANcel', 'QuIt', 'no'].each do |command| %w[stOp cANcel QuIt no].each do |command|
context "with #{command} command" do context "with #{command} command" do
let(:twilio_attributes) { let(:twilio_attributes) do
{ 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw', 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => command, 'NumMedia' => '0' } { 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw',
} 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => command, 'NumMedia' => '0' }
end
it "updates the last attempt by recipient phone number" do it 'updates the last attempt by recipient phone number' do
post :twilio, params: twilio_attributes post :twilio, params: twilio_attributes
attempt.reload attempt.reload
expect(attempt.answer_index).to be_nil expect(attempt.answer_index).to be_nil
@ -119,24 +127,25 @@ module Legacy
expect(attempt.recipient).to be_opted_out expect(attempt.recipient).to be_opted_out
end end
it "sends back a message" do it 'sends back a message' do
post :twilio, params: twilio_attributes post :twilio, params: twilio_attributes
expect(response.body).to eq('Thank you, you have been opted out of these messages and will no longer receive them.') expect(response.body).to eq('Thank you, you have been opted out of these messages and will no longer receive them.')
end end
end end
end end
['staRt', 'reSUme', 'rEstaRt', 'Yes', 'go'].each do |command| %w[staRt reSUme rEstaRt Yes go].each do |command|
context "with #{command} command" do context "with #{command} command" do
before :each do before :each do
attempt.recipient.update(opted_out: true) attempt.recipient.update(opted_out: true)
end end
let(:twilio_attributes) { let(:twilio_attributes) do
{ 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw', 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => command, 'NumMedia' => '0' } { 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw',
} 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => command, 'NumMedia' => '0' }
end
it "updates the last attempt by recipient phone number" do it 'updates the last attempt by recipient phone number' do
expect(attempt.recipient).to be_opted_out expect(attempt.recipient).to be_opted_out
post :twilio, params: twilio_attributes post :twilio, params: twilio_attributes
attempt.reload attempt.reload
@ -145,7 +154,7 @@ module Legacy
expect(attempt.recipient).to_not be_opted_out expect(attempt.recipient).to_not be_opted_out
end end
it "sends back a message" do it 'sends back a message' do
post :twilio, params: twilio_attributes post :twilio, params: twilio_attributes
expect(response.body).to eq('Thank you, you will now begin receiving messages again.') expect(response.body).to eq('Thank you, you will now begin receiving messages again.')
end end
@ -154,11 +163,12 @@ module Legacy
['skip', 'i dont know', "i don't know", 'next'].each do |command| ['skip', 'i dont know', "i don't know", 'next'].each do |command|
context "with #{command} command" do context "with #{command} command" do
let(:twilio_skip_attributes) { let(:twilio_skip_attributes) do
{ 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw', 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => command, 'NumMedia' => '0' } { 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw',
} 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => command, 'NumMedia' => '0' }
end
it "updates the last attempt by recipient phone number" do it 'updates the last attempt by recipient phone number' do
post :twilio, params: twilio_skip_attributes post :twilio, params: twilio_skip_attributes
attempt.reload attempt.reload
expect(attempt.answer_index).to be_nil expect(attempt.answer_index).to be_nil
@ -172,7 +182,7 @@ module Legacy
expect(school_attempts.not_yet_responded.count).to eq(2) expect(school_attempts.not_yet_responded.count).to eq(2)
end end
it "sends back a message" do it 'sends back a message' do
post :twilio, params: twilio_skip_attributes post :twilio, params: twilio_skip_attributes
expect(response.body).to eq('Thank you, this question has been skipped.') expect(response.body).to eq('Thank you, this question has been skipped.')
end end
@ -180,23 +190,23 @@ module Legacy
end end
end end
describe "POST #twilio with response to repeated question" do describe 'POST #twilio with response to repeated question' do
context "with valid params" do context 'with valid params' do
let!(:recent_first_attempt) do
let!(:recent_first_attempt) {
first_attempt.update(sent_at: Time.new) first_attempt.update(sent_at: Time.new)
return first_attempt return first_attempt
} end
let(:twilio_attributes) { let(:twilio_attributes) do
{ 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw', 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => '2', 'NumMedia' => '0' } { 'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf', 'AccountSid' => 'wefiuwhefuwehfuwefinwefw',
} 'MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf', 'From' => '+0000000000', 'To' => '2223334444', 'Body' => '2', 'NumMedia' => '0' }
end
before :each do before :each do
post :twilio, params: twilio_attributes post :twilio, params: twilio_attributes
end end
it "updates the first attempt (that now has the most recent sent_at)" do it 'updates the first attempt (that now has the most recent sent_at)' do
recent_first_attempt.reload recent_first_attempt.reload
expect(recent_first_attempt.answer_index).to eq(2) expect(recent_first_attempt.answer_index).to eq(2)
expect(recent_first_attempt.twilio_details).to eq(twilio_attributes.with_indifferent_access.to_yaml) expect(recent_first_attempt.twilio_details).to eq(twilio_attributes.with_indifferent_access.to_yaml)

@ -20,37 +20,36 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe Legacy::CategoriesController, type: :controller do RSpec.describe Legacy::CategoriesController, type: :controller do
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# Category. As you add validations to Category, be sure to # Category. As you add validations to Category, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{ name: 'Category', external_id: 'A' } { name: 'Category', external_id: 'A' }
} end
let(:invalid_attributes) { let(:invalid_attributes) do
{ name: '' } { name: '' }
} end
let(:district) { let(:district) do
Legacy::District.create! name: 'District' Legacy::District.create! name: 'District'
} end
# This should return the minimal set of values that should be in the session # This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in # in order to pass any filters (e.g. authentication) defined in
# CategoriesController. Be sure to keep this updated too. # CategoriesController. Be sure to keep this updated too.
let(:valid_session) { {} } let(:valid_session) { {} }
describe "GET #index" do describe 'GET #index' do
it "assigns all categories as @categories" do it 'assigns all categories as @categories' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
get :index, params: {}, session: valid_session get :index, params: {}, session: valid_session
expect(assigns(:categories)).to eq([category]) expect(assigns(:categories)).to eq([category])
end end
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested school and category as @school and @category" do it 'assigns the requested school and category as @school and @category' do
school = Legacy::School.create! name: 'School', district: district school = Legacy::School.create! name: 'School', district: district
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
get :show, params: { school_id: school.id, id: category.to_param }, session: valid_session get :show, params: { school_id: school.id, id: category.to_param }, session: valid_session
@ -58,89 +57,89 @@ module Legacy
expect(assigns(:school)).to eq(school) expect(assigns(:school)).to eq(school)
end end
it "redirects to root_path if school is not provided" do it 'redirects to root_path if school is not provided' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
get :show, params: { id: category.to_param }, session: valid_session get :show, params: { id: category.to_param }, session: valid_session
expect(response).to redirect_to(root_path) expect(response).to redirect_to(root_path)
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new category as @category" do it 'assigns a new category as @category' do
get :new, params: {}, session: valid_session get :new, params: {}, session: valid_session
expect(assigns(:category)).to be_a_new(Legacy::Category) expect(assigns(:category)).to be_a_new(Legacy::Category)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested category as @category" do it 'assigns the requested category as @category' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
get :edit, params: { id: category.to_param }, session: valid_session get :edit, params: { id: category.to_param }, session: valid_session
expect(assigns(:category)).to eq(category) expect(assigns(:category)).to eq(category)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new Category" do it 'creates a new Category' do
expect { expect do
post :create, params: { category: valid_attributes }, session: valid_session post :create, params: { category: valid_attributes }, session: valid_session
}.to change(Legacy::Category, :count).by(1) end.to change(Legacy::Category, :count).by(1)
end end
it "assigns a newly created category as @category" do it 'assigns a newly created category as @category' do
post :create, params: { category: valid_attributes }, session: valid_session post :create, params: { category: valid_attributes }, session: valid_session
expect(assigns(:category)).to be_a(Legacy::Category) expect(assigns(:category)).to be_a(Legacy::Category)
expect(assigns(:category)).to be_persisted expect(assigns(:category)).to be_persisted
end end
it "redirects to the created category" do it 'redirects to the created category' do
post :create, params: { category: valid_attributes }, session: valid_session post :create, params: { category: valid_attributes }, session: valid_session
expect(response).to redirect_to(Legacy::Category.last) expect(response).to redirect_to(Legacy::Category.last)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved category as @category" do it 'assigns a newly created but unsaved category as @category' do
post :create, params: { category: invalid_attributes }, session: valid_session post :create, params: { category: invalid_attributes }, session: valid_session
expect(assigns(:category)).to be_a_new(Legacy::Category) expect(assigns(:category)).to be_a_new(Legacy::Category)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { category: invalid_attributes }, session: valid_session post :create, params: { category: invalid_attributes }, session: valid_session
expect(response).to render_template("new") expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ name: 'Category 2' } { name: 'Category 2' }
} end
it "updates the requested category" do it 'updates the requested category' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
put :update, params: { id: category.to_param, category: new_attributes }, session: valid_session put :update, params: { id: category.to_param, category: new_attributes }, session: valid_session
category.reload category.reload
expect(category.name).to eq('Category 2') expect(category.name).to eq('Category 2')
end end
it "assigns the requested category as @category" do it 'assigns the requested category as @category' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
put :update, params: { id: category.to_param, category: valid_attributes }, session: valid_session put :update, params: { id: category.to_param, category: valid_attributes }, session: valid_session
expect(assigns(:category)).to eq(category) expect(assigns(:category)).to eq(category)
end end
it "redirects to the category" do it 'redirects to the category' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
put :update, params: { id: category.to_param, category: valid_attributes }, session: valid_session put :update, params: { id: category.to_param, category: valid_attributes }, session: valid_session
expect(response).to redirect_to(category) expect(response).to redirect_to(category)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the category as @category" do it 'assigns the category as @category' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
put :update, params: { id: category.to_param, category: invalid_attributes }, session: valid_session put :update, params: { id: category.to_param, category: invalid_attributes }, session: valid_session
expect(assigns(:category)).to eq(category) expect(assigns(:category)).to eq(category)
@ -149,25 +148,24 @@ module Legacy
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
put :update, params: { id: category.to_param, category: invalid_attributes }, session: valid_session put :update, params: { id: category.to_param, category: invalid_attributes }, session: valid_session
expect(response).to render_template("edit") expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested category" do it 'destroys the requested category' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
expect { expect do
delete :destroy, params: { id: category.to_param }, session: valid_session delete :destroy, params: { id: category.to_param }, session: valid_session
}.to change(Legacy::Category, :count).by(-1) end.to change(Legacy::Category, :count).by(-1)
end end
it "redirects to the categories list" do it 'redirects to the categories list' do
category = Legacy::Category.create! valid_attributes category = Legacy::Category.create! valid_attributes
delete :destroy, params: { id: category.to_param }, session: valid_session delete :destroy, params: { id: category.to_param }, session: valid_session
expect(response).to redirect_to(legacy_categories_url) expect(response).to redirect_to(legacy_categories_url)
end end
end end
end end
end end

@ -2,114 +2,113 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe DistrictsController, type: :controller do RSpec.describe DistrictsController, type: :controller do
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# District. As you add validations to District, be sure to # District. As you add validations to District, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{ name: 'Milford' } { name: 'Milford' }
} end
let(:invalid_attributes) { let(:invalid_attributes) do
{ name: '' } { name: '' }
} end
# This should return the minimal set of values that should be in the session # This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in # in order to pass any filters (e.g. authentication) defined in
# DistrictsController. Be sure to keep this updated too. # DistrictsController. Be sure to keep this updated too.
let(:valid_session) { {} } let(:valid_session) { {} }
describe "GET #index" do describe 'GET #index' do
it "assigns all districts as @districts" do it 'assigns all districts as @districts' do
get :index, params: {}, session: valid_session get :index, params: {}, session: valid_session
expect(assigns(:districts)).to eq(District.all.alphabetic) expect(assigns(:districts)).to eq(District.all.alphabetic)
end end
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested district as @district" do it 'assigns the requested district as @district' do
district = District.create! valid_attributes district = District.create! valid_attributes
get :show, params: { id: district.to_param }, session: valid_session get :show, params: { id: district.to_param }, session: valid_session
expect(assigns(:district)).to eq(district) expect(assigns(:district)).to eq(district)
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new district as @district" do it 'assigns a new district as @district' do
get :new, params: {}, session: valid_session get :new, params: {}, session: valid_session
expect(assigns(:district)).to be_a_new(District) expect(assigns(:district)).to be_a_new(District)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested district as @district" do it 'assigns the requested district as @district' do
district = District.create! valid_attributes district = District.create! valid_attributes
get :edit, params: { id: district.to_param }, session: valid_session get :edit, params: { id: district.to_param }, session: valid_session
expect(assigns(:district)).to eq(district) expect(assigns(:district)).to eq(district)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new District" do it 'creates a new District' do
expect { expect do
post :create, params: { district: valid_attributes }, session: valid_session post :create, params: { district: valid_attributes }, session: valid_session
}.to change(District, :count).by(1) end.to change(District, :count).by(1)
end end
it "assigns a newly created district as @district" do it 'assigns a newly created district as @district' do
post :create, params: { district: valid_attributes }, session: valid_session post :create, params: { district: valid_attributes }, session: valid_session
expect(assigns(:district)).to be_a(District) expect(assigns(:district)).to be_a(District)
expect(assigns(:district)).to be_persisted expect(assigns(:district)).to be_persisted
end end
it "redirects to the created district" do it 'redirects to the created district' do
post :create, params: { district: valid_attributes }, session: valid_session post :create, params: { district: valid_attributes }, session: valid_session
expect(response).to redirect_to(District.last) expect(response).to redirect_to(District.last)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved district as @district" do it 'assigns a newly created but unsaved district as @district' do
post :create, params: { district: invalid_attributes }, session: valid_session post :create, params: { district: invalid_attributes }, session: valid_session
expect(assigns(:district)).to be_a_new(District) expect(assigns(:district)).to be_a_new(District)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { district: invalid_attributes }, session: valid_session post :create, params: { district: invalid_attributes }, session: valid_session
expect(response).to render_template("new") expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ name: 'New District' } { name: 'New District' }
} end
it "updates the requested district" do it 'updates the requested district' do
district = District.create! valid_attributes district = District.create! valid_attributes
put :update, params: { id: district.to_param, district: new_attributes }, session: valid_session put :update, params: { id: district.to_param, district: new_attributes }, session: valid_session
district.reload district.reload
expect(district.name).to eq('New District') expect(district.name).to eq('New District')
end end
it "assigns the requested district as @district" do it 'assigns the requested district as @district' do
district = District.create! valid_attributes district = District.create! valid_attributes
put :update, params: { id: district.to_param, district: valid_attributes }, session: valid_session put :update, params: { id: district.to_param, district: valid_attributes }, session: valid_session
expect(assigns(:district)).to eq(district) expect(assigns(:district)).to eq(district)
end end
it "redirects to the district" do it 'redirects to the district' do
district = District.create! valid_attributes district = District.create! valid_attributes
put :update, params: { id: district.to_param, district: valid_attributes }, session: valid_session put :update, params: { id: district.to_param, district: valid_attributes }, session: valid_session
expect(response).to redirect_to(district) expect(response).to redirect_to(district)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the district as @district" do it 'assigns the district as @district' do
district = District.create! valid_attributes district = District.create! valid_attributes
put :update, params: { id: district.to_param, district: invalid_attributes }, session: valid_session put :update, params: { id: district.to_param, district: invalid_attributes }, session: valid_session
expect(assigns(:district)).to eq(district) expect(assigns(:district)).to eq(district)
@ -118,25 +117,24 @@ module Legacy
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
district = District.create! valid_attributes district = District.create! valid_attributes
put :update, params: { id: district.to_param, district: invalid_attributes }, session: valid_session put :update, params: { id: district.to_param, district: invalid_attributes }, session: valid_session
expect(response).to render_template("edit") expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested district" do it 'destroys the requested district' do
district = District.create! valid_attributes district = District.create! valid_attributes
expect { expect do
delete :destroy, params: { id: district.to_param }, session: valid_session delete :destroy, params: { id: district.to_param }, session: valid_session
}.to change(District, :count).by(-1) end.to change(District, :count).by(-1)
end end
it "redirects to the districts list" do it 'redirects to the districts list' do
district = District.create! valid_attributes district = District.create! valid_attributes
delete :destroy, params: { id: district.to_param }, session: valid_session delete :destroy, params: { id: district.to_param }, session: valid_session
expect(response).to redirect_to(districts_url) expect(response).to redirect_to(districts_url)
end end
end end
end end
end end

@ -20,115 +20,114 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe QuestionListsController, type: :controller do RSpec.describe QuestionListsController, type: :controller do
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# QuestionList. As you add validations to QuestionList, be sure to # QuestionList. As you add validations to QuestionList, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{ name: 'Questions for Parents', question_id_array: ['', '1', '2', '3'] } { name: 'Questions for Parents', question_id_array: ['', '1', '2', '3'] }
} end
let(:invalid_attributes) { let(:invalid_attributes) do
{ question_id_array: [''] } { question_id_array: [''] }
} end
# This should return the minimal set of values that should be in the session # This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in # in order to pass any filters (e.g. authentication) defined in
# QuestionListsController. Be sure to keep this updated too. # QuestionListsController. Be sure to keep this updated too.
let(:valid_session) { {} } let(:valid_session) { {} }
describe "GET #index" do describe 'GET #index' do
it "assigns all question_lists as @question_lists" do it 'assigns all question_lists as @question_lists' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
get :index, params: {}, session: valid_session get :index, params: {}, session: valid_session
expect(assigns(:question_lists)).to eq([question_list]) expect(assigns(:question_lists)).to eq([question_list])
end end
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested question_list as @question_list" do it 'assigns the requested question_list as @question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
get :show, params: { id: question_list.to_param }, session: valid_session get :show, params: { id: question_list.to_param }, session: valid_session
expect(assigns(:question_list)).to eq(question_list) expect(assigns(:question_list)).to eq(question_list)
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new question_list as @question_list" do it 'assigns a new question_list as @question_list' do
get :new, params: {}, session: valid_session get :new, params: {}, session: valid_session
expect(assigns(:question_list)).to be_a_new(QuestionList) expect(assigns(:question_list)).to be_a_new(QuestionList)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested question_list as @question_list" do it 'assigns the requested question_list as @question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
get :edit, params: { id: question_list.to_param }, session: valid_session get :edit, params: { id: question_list.to_param }, session: valid_session
expect(assigns(:question_list)).to eq(question_list) expect(assigns(:question_list)).to eq(question_list)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new QuestionList" do it 'creates a new QuestionList' do
expect { expect do
post :create, params: { question_list: valid_attributes }, session: valid_session post :create, params: { question_list: valid_attributes }, session: valid_session
}.to change(QuestionList, :count).by(1) end.to change(QuestionList, :count).by(1)
end end
it "assigns a newly created question_list as @question_list" do it 'assigns a newly created question_list as @question_list' do
post :create, params: { question_list: valid_attributes }, session: valid_session post :create, params: { question_list: valid_attributes }, session: valid_session
expect(assigns(:question_list)).to be_a(QuestionList) expect(assigns(:question_list)).to be_a(QuestionList)
expect(assigns(:question_list)).to be_persisted expect(assigns(:question_list)).to be_persisted
end end
it "redirects to the created question_list" do it 'redirects to the created question_list' do
post :create, params: { question_list: valid_attributes }, session: valid_session post :create, params: { question_list: valid_attributes }, session: valid_session
expect(response).to redirect_to(QuestionList.last) expect(response).to redirect_to(QuestionList.last)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved question_list as @question_list" do it 'assigns a newly created but unsaved question_list as @question_list' do
post :create, params: { question_list: invalid_attributes }, session: valid_session post :create, params: { question_list: invalid_attributes }, session: valid_session
expect(assigns(:question_list)).to be_a_new(QuestionList) expect(assigns(:question_list)).to be_a_new(QuestionList)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { question_list: invalid_attributes }, session: valid_session post :create, params: { question_list: invalid_attributes }, session: valid_session
expect(response).to render_template("new") expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ question_id_array: ['', '2', '3'] } { question_id_array: ['', '2', '3'] }
} end
it "updates the requested question_list" do it 'updates the requested question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
put :update, params: { id: question_list.to_param, question_list: new_attributes }, session: valid_session put :update, params: { id: question_list.to_param, question_list: new_attributes }, session: valid_session
question_list.reload question_list.reload
expect(question_list.question_ids).to eq('2,3') expect(question_list.question_ids).to eq('2,3')
end end
it "assigns the requested question_list as @question_list" do it 'assigns the requested question_list as @question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
put :update, params: { id: question_list.to_param, question_list: valid_attributes }, session: valid_session put :update, params: { id: question_list.to_param, question_list: valid_attributes }, session: valid_session
expect(assigns(:question_list)).to eq(question_list) expect(assigns(:question_list)).to eq(question_list)
end end
it "redirects to the question_list" do it 'redirects to the question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
put :update, params: { id: question_list.to_param, question_list: valid_attributes }, session: valid_session put :update, params: { id: question_list.to_param, question_list: valid_attributes }, session: valid_session
expect(response).to redirect_to(question_list) expect(response).to redirect_to(question_list)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the question_list as @question_list" do it 'assigns the question_list as @question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
put :update, params: { id: question_list.to_param, question_list: invalid_attributes }, session: valid_session put :update, params: { id: question_list.to_param, question_list: invalid_attributes }, session: valid_session
expect(assigns(:question_list)).to eq(question_list) expect(assigns(:question_list)).to eq(question_list)
@ -137,25 +136,24 @@ module Legacy
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
put :update, params: { id: question_list.to_param, question_list: invalid_attributes }, session: valid_session put :update, params: { id: question_list.to_param, question_list: invalid_attributes }, session: valid_session
expect(response).to render_template("edit") expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested question_list" do it 'destroys the requested question_list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
expect { expect do
delete :destroy, params: { id: question_list.to_param }, session: valid_session delete :destroy, params: { id: question_list.to_param }, session: valid_session
}.to change(QuestionList, :count).by(-1) end.to change(QuestionList, :count).by(-1)
end end
it "redirects to the question_lists list" do it 'redirects to the question_lists list' do
question_list = QuestionList.create! valid_attributes question_list = QuestionList.create! valid_attributes
delete :destroy, params: { id: question_list.to_param }, session: valid_session delete :destroy, params: { id: question_list.to_param }, session: valid_session
expect(response).to redirect_to(legacy_question_lists_url) expect(response).to redirect_to(legacy_question_lists_url)
end end
end end
end end
end end

@ -20,13 +20,12 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe QuestionsController, type: :controller do RSpec.describe QuestionsController, type: :controller do
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# Question. As you add validations to Question, be sure to # Question. As you add validations to Question, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let!(:user) { User.create(email: 'test@test.com', password: '123456') } let!(:user) { User.create(email: 'test@test.com', password: '123456') }
let (:category) { Legacy::Category.create!(name: 'Category') } let(:category) { Legacy::Category.create!(name: 'Category') }
let(:valid_attributes) { let(:valid_attributes) do
{ {
text: 'Question', text: 'Question',
option1: 'option1', option1: 'option1',
@ -36,11 +35,11 @@ module Legacy
option5: 'option5', option5: 'option5',
category_id: category.id category_id: category.id
} }
} end
let(:invalid_attributes) { let(:invalid_attributes) do
{ text: '' } { text: '' }
} end
# This should return the minimal set of values that should be in the session # This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in # in order to pass any filters (e.g. authentication) defined in
@ -51,16 +50,16 @@ module Legacy
sign_in user sign_in user
end end
describe "GET #index" do describe 'GET #index' do
it "assigns all questions as @questions" do it 'assigns all questions as @questions' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
get :index, params: {}, session: valid_session get :index, params: {}, session: valid_session
expect(assigns(:questions)).to eq([question]) expect(assigns(:questions)).to eq([question])
end end
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested question as @question" do it 'assigns the requested question as @question' do
school = School.create!(name: 'School') school = School.create!(name: 'School')
question = Question.create! valid_attributes question = Question.create! valid_attributes
get :show, params: { school_id: school.id, id: question.to_param }, session: valid_session get :show, params: { school_id: school.id, id: question.to_param }, session: valid_session
@ -69,82 +68,82 @@ module Legacy
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new question as @question" do it 'assigns a new question as @question' do
get :new, params: {}, session: valid_session get :new, params: {}, session: valid_session
expect(assigns(:question)).to be_a_new(Question) expect(assigns(:question)).to be_a_new(Question)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested question as @question" do it 'assigns the requested question as @question' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
get :edit, params: { id: question.to_param }, session: valid_session get :edit, params: { id: question.to_param }, session: valid_session
expect(assigns(:question)).to eq(question) expect(assigns(:question)).to eq(question)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new Question" do it 'creates a new Question' do
expect { expect do
post :create, params: { question: valid_attributes }, session: valid_session post :create, params: { question: valid_attributes }, session: valid_session
}.to change(Question, :count).by(1) end.to change(Question, :count).by(1)
end end
it "assigns a newly created question as @question" do it 'assigns a newly created question as @question' do
post :create, params: { question: valid_attributes }, session: valid_session post :create, params: { question: valid_attributes }, session: valid_session
expect(assigns(:question)).to be_a(Question) expect(assigns(:question)).to be_a(Question)
expect(assigns(:question)).to be_persisted expect(assigns(:question)).to be_persisted
end end
it "redirects to the created question" do it 'redirects to the created question' do
post :create, params: { question: valid_attributes }, session: valid_session post :create, params: { question: valid_attributes }, session: valid_session
expect(response).to redirect_to(Question.last) expect(response).to redirect_to(Question.last)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved question as @question" do it 'assigns a newly created but unsaved question as @question' do
post :create, params: { question: invalid_attributes }, session: valid_session post :create, params: { question: invalid_attributes }, session: valid_session
expect(assigns(:question)).to be_a_new(Question) expect(assigns(:question)).to be_a_new(Question)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { question: invalid_attributes }, session: valid_session post :create, params: { question: invalid_attributes }, session: valid_session
expect(response).to render_template("new") expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ text: 'Question2' } { text: 'Question2' }
} end
it "updates the requested question" do it 'updates the requested question' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
put :update, params: { id: question.to_param, question: new_attributes }, session: valid_session put :update, params: { id: question.to_param, question: new_attributes }, session: valid_session
question.reload question.reload
expect(question.text).to eq('Question2') expect(question.text).to eq('Question2')
end end
it "assigns the requested question as @question" do it 'assigns the requested question as @question' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
put :update, params: { id: question.to_param, question: valid_attributes }, session: valid_session put :update, params: { id: question.to_param, question: valid_attributes }, session: valid_session
expect(assigns(:question)).to eq(question) expect(assigns(:question)).to eq(question)
end end
it "redirects to the question" do it 'redirects to the question' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
put :update, params: { id: question.to_param, question: valid_attributes }, session: valid_session put :update, params: { id: question.to_param, question: valid_attributes }, session: valid_session
expect(response).to redirect_to(question) expect(response).to redirect_to(question)
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the question as @question" do it 'assigns the question as @question' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
put :update, params: { id: question.to_param, question: invalid_attributes }, session: valid_session put :update, params: { id: question.to_param, question: invalid_attributes }, session: valid_session
expect(assigns(:question)).to eq(question) expect(assigns(:question)).to eq(question)
@ -153,25 +152,24 @@ module Legacy
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
question = Question.create! valid_attributes question = Question.create! valid_attributes
put :update, params: { id: question.to_param, question: invalid_attributes }, session: valid_session put :update, params: { id: question.to_param, question: invalid_attributes }, session: valid_session
expect(response).to render_template("edit") expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested question" do it 'destroys the requested question' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
expect { expect do
delete :destroy, params: { id: question.to_param }, session: valid_session delete :destroy, params: { id: question.to_param }, session: valid_session
}.to change(Question, :count).by(-1) end.to change(Question, :count).by(-1)
end end
it "redirects to the questions list" do it 'redirects to the questions list' do
question = Question.create! valid_attributes question = Question.create! valid_attributes
delete :destroy, params: { id: question.to_param }, session: valid_session delete :destroy, params: { id: question.to_param }, session: valid_session
expect(response).to redirect_to(legacy_questions_url) expect(response).to redirect_to(legacy_questions_url)
end end
end end
end end
end end

@ -20,25 +20,24 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe RecipientListsController, type: :controller do RSpec.describe RecipientListsController, type: :controller do
let!(:user) { User.create(email: 'test@test.com', password: '123456') } let!(:user) { User.create(email: 'test@test.com', password: '123456') }
let(:school) { School.create!(name: 'School') } let(:school) { School.create!(name: 'School') }
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# RecipientList. As you add validations to RecipientList, be sure to # RecipientList. As you add validations to RecipientList, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{ {
school_id: school.id, school_id: school.id,
recipient_id_array: ['', '1', '2', '3'], recipient_id_array: ['', '1', '2', '3'],
name: 'Parents', name: 'Parents',
description: 'List of parents.' description: 'List of parents.'
} }
} end
let(:invalid_attributes) { let(:invalid_attributes) do
{ school_id: school.id, name: '' } { school_id: school.id, name: '' }
} end
# This should return the minimal set of values that should be in the session # This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in # in order to pass any filters (e.g. authentication) defined in
@ -50,46 +49,47 @@ module Legacy
sign_in user sign_in user
end end
describe "GET #index" do describe 'GET #index' do
it "assigns all recipient_lists as @recipient_lists" do it 'assigns all recipient_lists as @recipient_lists' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
get :index, params: { school_id: school.to_param }, session: valid_session get :index, params: { school_id: school.to_param }, session: valid_session
expect(assigns(:recipient_lists)).to eq([recipient_list]) expect(assigns(:recipient_lists)).to eq([recipient_list])
end end
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested recipient_list as @recipient_list" do it 'assigns the requested recipient_list as @recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
get :show, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session get :show, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session
expect(assigns(:recipient_list)).to eq(recipient_list) expect(assigns(:recipient_list)).to eq(recipient_list)
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new recipient_list as @recipient_list" do it 'assigns a new recipient_list as @recipient_list' do
get :new, params: { school_id: school.to_param }, session: valid_session get :new, params: { school_id: school.to_param }, session: valid_session
expect(assigns(:recipient_list)).to be_a_new(RecipientList) expect(assigns(:recipient_list)).to be_a_new(RecipientList)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested recipient_list as @recipient_list" do it 'assigns the requested recipient_list as @recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
get :edit, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session get :edit, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session
expect(assigns(:recipient_list)).to eq(recipient_list) expect(assigns(:recipient_list)).to eq(recipient_list)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new RecipientList" do it 'creates a new RecipientList' do
expect { expect do
post :create, params: { school_id: school.to_param, recipient_list: valid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient_list: valid_attributes },
}.to change(RecipientList, :count).by(1) session: valid_session
end.to change(RecipientList, :count).by(1)
end end
it "assigns a newly created recipient_list as @recipient_list" do it 'assigns a newly created recipient_list as @recipient_list' do
post :create, params: { school_id: school.to_param, recipient_list: valid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient_list: valid_attributes }, session: valid_session
expect(assigns(:recipient_list)).to be_a(RecipientList) expect(assigns(:recipient_list)).to be_a(RecipientList)
expect(assigns(:recipient_list)).to be_persisted expect(assigns(:recipient_list)).to be_persisted
@ -100,80 +100,86 @@ module Legacy
expect(assigns(:recipient_list).recipient_ids).to eq('1,2,3') expect(assigns(:recipient_list).recipient_ids).to eq('1,2,3')
end end
it "redirects to the created recipient_list" do it 'redirects to the created recipient_list' do
post :create, params: { school_id: school.to_param, recipient_list: valid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient_list: valid_attributes }, session: valid_session
expect(response).to redirect_to(legacy_school_legacy_recipient_list_path(school, RecipientList.last)) expect(response).to redirect_to(legacy_school_legacy_recipient_list_path(school, RecipientList.last))
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved recipient_list as @recipient_list" do it 'assigns a newly created but unsaved recipient_list as @recipient_list' do
post :create, params: { school_id: school.to_param, recipient_list: invalid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient_list: invalid_attributes },
session: valid_session
expect(assigns(:recipient_list)).to be_a_new(RecipientList) expect(assigns(:recipient_list)).to be_a_new(RecipientList)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { school_id: school.to_param, recipient_list: invalid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient_list: invalid_attributes },
expect(response).to render_template("new") session: valid_session
expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ recipient_id_array: ['', '3', '4', '5'] } { recipient_id_array: ['', '3', '4', '5'] }
} end
it "updates the requested recipient_list" do it 'updates the requested recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: new_attributes }, session: valid_session put :update,
params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: new_attributes }, session: valid_session
recipient_list.reload recipient_list.reload
expect(recipient_list.recipient_ids).to eq('3,4,5') expect(recipient_list.recipient_ids).to eq('3,4,5')
end end
it "assigns the requested recipient_list as @recipient_list" do it 'assigns the requested recipient_list as @recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: valid_attributes }, session: valid_session put :update,
params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: valid_attributes }, session: valid_session
expect(assigns(:recipient_list)).to eq(recipient_list) expect(assigns(:recipient_list)).to eq(recipient_list)
end end
it "redirects to the recipient_list" do it 'redirects to the recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: valid_attributes }, session: valid_session put :update,
params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: valid_attributes }, session: valid_session
expect(response).to redirect_to(legacy_school_legacy_recipient_list_url(school, recipient_list)) expect(response).to redirect_to(legacy_school_legacy_recipient_list_url(school, recipient_list))
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the recipient_list as @recipient_list" do it 'assigns the recipient_list as @recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: invalid_attributes }, session: valid_session put :update,
params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: invalid_attributes }, session: valid_session
expect(assigns(:recipient_list)).to eq(recipient_list) expect(assigns(:recipient_list)).to eq(recipient_list)
end end
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: invalid_attributes }, session: valid_session put :update,
expect(response).to render_template("edit") params: { school_id: school.to_param, id: recipient_list.to_param, recipient_list: invalid_attributes }, session: valid_session
expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested recipient_list" do it 'destroys the requested recipient_list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
expect { expect do
delete :destroy, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session delete :destroy, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session
}.to change(RecipientList, :count).by(-1) end.to change(RecipientList, :count).by(-1)
end end
it "redirects to the recipient_lists list" do it 'redirects to the recipient_lists list' do
recipient_list = RecipientList.create! valid_attributes recipient_list = RecipientList.create! valid_attributes
delete :destroy, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session delete :destroy, params: { school_id: school.to_param, id: recipient_list.to_param }, session: valid_session
expect(response).to redirect_to(school) expect(response).to redirect_to(school)
end end
end end
end end
end end

@ -20,20 +20,19 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe RecipientsController, type: :controller do RSpec.describe RecipientsController, type: :controller do
let!(:user) { User.create(email: 'test@test.com', password: '123456') } let!(:user) { User.create(email: 'test@test.com', password: '123456') }
let(:school) { School.create!(name: 'School') } let(:school) { School.create!(name: 'School') }
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# Recipient. As you add validations to Recipient, be sure to # Recipient. As you add validations to Recipient, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{ {
name: 'Recipient Name', name: 'Recipient Name',
phone: '111-222-3333', phone: '111-222-3333',
school_id: school.id school_id: school.id
} }
} end
let(:invalid_attributes) { { name: '', phone: '111-222-3333' } } let(:invalid_attributes) { { name: '', phone: '111-222-3333' } }
@ -47,126 +46,130 @@ module Legacy
sign_in user sign_in user
end end
describe "GET #index" do describe 'GET #index' do
it "assigns all recipients as @recipients" do it 'assigns all recipients as @recipients' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
get :index, params: { school_id: school.to_param }, session: valid_session get :index, params: { school_id: school.to_param }, session: valid_session
expect(assigns(:recipients)).to eq([recipient]) expect(assigns(:recipients)).to eq([recipient])
end end
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested recipient as @recipient" do it 'assigns the requested recipient as @recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
get :show, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session get :show, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session
expect(assigns(:recipient)).to eq(recipient) expect(assigns(:recipient)).to eq(recipient)
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new recipient as @recipient" do it 'assigns a new recipient as @recipient' do
get :new, params: { school_id: school.id }, session: valid_session get :new, params: { school_id: school.id }, session: valid_session
expect(assigns(:recipient)).to be_a_new(Recipient) expect(assigns(:recipient)).to be_a_new(Recipient)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested recipient as @recipient" do it 'assigns the requested recipient as @recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
get :edit, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session get :edit, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session
expect(assigns(:recipient)).to eq(recipient) expect(assigns(:recipient)).to eq(recipient)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new Recipient" do it 'creates a new Recipient' do
expect { expect do
post :create, params: { school_id: school.to_param, recipient: valid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient: valid_attributes }, session: valid_session
}.to change(Recipient, :count).by(1) end.to change(Recipient, :count).by(1)
end end
it "assigns a newly created recipient as @recipient" do it 'assigns a newly created recipient as @recipient' do
post :create, params: { school_id: school.to_param, recipient: valid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient: valid_attributes }, session: valid_session
expect(assigns(:recipient)).to be_a(Recipient) expect(assigns(:recipient)).to be_a(Recipient)
expect(assigns(:recipient)).to be_persisted expect(assigns(:recipient)).to be_persisted
end end
it "redirects to the created recipient" do it 'redirects to the created recipient' do
post :create, params: { school_id: school.to_param, recipient: valid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient: valid_attributes }, session: valid_session
expect(response).to redirect_to(legacy_school_legacy_recipient_path(school, Recipient.last)) expect(response).to redirect_to(legacy_school_legacy_recipient_path(school, Recipient.last))
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved recipient as @recipient" do it 'assigns a newly created but unsaved recipient as @recipient' do
post :create, params: { school_id: school.to_param, recipient: invalid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient: invalid_attributes }, session: valid_session
expect(assigns(:recipient)).to be_a_new(Recipient) expect(assigns(:recipient)).to be_a_new(Recipient)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { school_id: school.to_param, recipient: invalid_attributes }, session: valid_session post :create, params: { school_id: school.to_param, recipient: invalid_attributes }, session: valid_session
expect(response).to render_template("new") expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ name: 'New Name' } { name: 'New Name' }
} end
it "updates the requested recipient" do it 'updates the requested recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: new_attributes }, session: valid_session put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: new_attributes },
session: valid_session
recipient.reload recipient.reload
expect(recipient.name).to eq('New Name') expect(recipient.name).to eq('New Name')
expect(recipient.phone).to eq('111-222-3333') expect(recipient.phone).to eq('111-222-3333')
end end
it "assigns the requested recipient as @recipient" do it 'assigns the requested recipient as @recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: valid_attributes }, session: valid_session put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: valid_attributes },
session: valid_session
expect(assigns(:recipient)).to eq(recipient) expect(assigns(:recipient)).to eq(recipient)
end end
it "redirects to the recipient" do it 'redirects to the recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: valid_attributes }, session: valid_session put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: valid_attributes },
session: valid_session
expect(response).to redirect_to(legacy_school_legacy_recipient_url(school, recipient)) expect(response).to redirect_to(legacy_school_legacy_recipient_url(school, recipient))
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the recipient as @recipient" do it 'assigns the recipient as @recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: invalid_attributes }, session: valid_session put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: invalid_attributes },
session: valid_session
expect(assigns(:recipient)).to eq(recipient) expect(assigns(:recipient)).to eq(recipient)
end end
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: invalid_attributes }, session: valid_session put :update, params: { school_id: school.to_param, id: recipient.to_param, recipient: invalid_attributes },
expect(response).to render_template("edit") session: valid_session
expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested recipient" do it 'destroys the requested recipient' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
expect { expect do
delete :destroy, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session delete :destroy, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session
}.to change(Recipient, :count).by(-1) end.to change(Recipient, :count).by(-1)
end end
it "redirects to the recipients list" do it 'redirects to the recipients list' do
recipient = Recipient.create! valid_attributes recipient = Recipient.create! valid_attributes
delete :destroy, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session delete :destroy, params: { school_id: school.to_param, id: recipient.to_param }, session: valid_session
expect(response).to redirect_to(school) expect(response).to redirect_to(school)
end end
end end
end end
end end

@ -20,7 +20,6 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe SchedulesController, type: :controller do RSpec.describe SchedulesController, type: :controller do
let!(:user) { User.create(email: 'test@test.com', password: '123456') } let!(:user) { User.create(email: 'test@test.com', password: '123456') }
let!(:school) { School.create!(name: 'School') } let!(:school) { School.create!(name: 'School') }
@ -37,7 +36,7 @@ module Legacy
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# Schedule. As you add validations to Schedule, be sure to # Schedule. As you add validations to Schedule, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{ {
school_id: school.id, school_id: school.id,
recipient_list_id: recipient_list.id, recipient_list_id: recipient_list.id,
@ -46,11 +45,11 @@ module Legacy
description: 'Schedule for parent questions', description: 'Schedule for parent questions',
time: (8 * 60) time: (8 * 60)
} }
} end
let(:invalid_attributes) { let(:invalid_attributes) do
{ name: '' } { name: '' }
} end
# This should return the minimal set of values that should be in the session # This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in # in order to pass any filters (e.g. authentication) defined in
@ -62,38 +61,38 @@ module Legacy
sign_in user sign_in user
end end
describe "GET #show" do describe 'GET #show' do
it "assigns the requested schedule as @schedule" do it 'assigns the requested schedule as @schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
get :show, params: { school_id: school.id, id: schedule.to_param }, session: valid_session get :show, params: { school_id: school.id, id: schedule.to_param }, session: valid_session
expect(assigns(:schedule)).to eq(schedule) expect(assigns(:schedule)).to eq(schedule)
end end
end end
describe "GET #new" do describe 'GET #new' do
it "assigns a new schedule as @schedule" do it 'assigns a new schedule as @schedule' do
get :new, params: { school_id: school.id }, session: valid_session get :new, params: { school_id: school.id }, session: valid_session
expect(assigns(:schedule)).to be_a_new(Schedule) expect(assigns(:schedule)).to be_a_new(Schedule)
end end
end end
describe "GET #edit" do describe 'GET #edit' do
it "assigns the requested schedule as @schedule" do it 'assigns the requested schedule as @schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
get :edit, params: { school_id: school.id, id: schedule.to_param }, session: valid_session get :edit, params: { school_id: school.id, id: schedule.to_param }, session: valid_session
expect(assigns(:schedule)).to eq(schedule) expect(assigns(:schedule)).to eq(schedule)
end end
end end
describe "POST #create" do describe 'POST #create' do
context "with valid params" do context 'with valid params' do
it "creates a new Schedule" do it 'creates a new Schedule' do
expect { expect do
post :create, params: { school_id: school.id, schedule: valid_attributes }, session: valid_session post :create, params: { school_id: school.id, schedule: valid_attributes }, session: valid_session
}.to change(Schedule, :count).by(1) end.to change(Schedule, :count).by(1)
end end
it "assigns a newly created schedule as @schedule" do it 'assigns a newly created schedule as @schedule' do
post :create, params: { school_id: school.id, schedule: valid_attributes }, session: valid_session post :create, params: { school_id: school.id, schedule: valid_attributes }, session: valid_session
expect(assigns(:schedule)).to be_a(Schedule) expect(assigns(:schedule)).to be_a(Schedule)
expect(assigns(:schedule)).to be_persisted expect(assigns(:schedule)).to be_persisted
@ -105,80 +104,84 @@ module Legacy
expect(assigns(:schedule).time).to eq(60 * 12) expect(assigns(:schedule).time).to eq(60 * 12)
end end
it "redirects to the created schedule" do it 'redirects to the created schedule' do
post :create, params: { school_id: school.id, schedule: valid_attributes }, session: valid_session post :create, params: { school_id: school.id, schedule: valid_attributes }, session: valid_session
expect(response).to redirect_to([school, Schedule.last]) expect(response).to redirect_to([school, Schedule.last])
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns a newly created but unsaved schedule as @schedule" do it 'assigns a newly created but unsaved schedule as @schedule' do
post :create, params: { school_id: school.id, schedule: invalid_attributes }, session: valid_session post :create, params: { school_id: school.id, schedule: invalid_attributes }, session: valid_session
expect(assigns(:schedule)).to be_a_new(Schedule) expect(assigns(:schedule)).to be_a_new(Schedule)
end end
it "re-renders the 'new' template" do it "re-renders the 'new' template" do
post :create, params: { school_id: school.id, schedule: invalid_attributes }, session: valid_session post :create, params: { school_id: school.id, schedule: invalid_attributes }, session: valid_session
expect(response).to render_template("new") expect(response).to render_template('new')
end end
end end
end end
describe "PUT #update" do describe 'PUT #update' do
context "with valid params" do context 'with valid params' do
let(:new_attributes) { let(:new_attributes) do
{ name: 'New Name' } { name: 'New Name' }
} end
it "updates the requested schedule" do it 'updates the requested schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
put :update, params: { school_id: school.id, id: schedule.to_param, schedule: new_attributes }, session: valid_session put :update, params: { school_id: school.id, id: schedule.to_param, schedule: new_attributes },
session: valid_session
schedule.reload schedule.reload
expect(schedule.name).to eq('New Name') expect(schedule.name).to eq('New Name')
end end
it "assigns the requested schedule as @schedule" do it 'assigns the requested schedule as @schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
put :update, params: { school_id: school.id, id: schedule.to_param, schedule: valid_attributes }, session: valid_session put :update, params: { school_id: school.id, id: schedule.to_param, schedule: valid_attributes },
session: valid_session
expect(assigns(:schedule)).to eq(schedule) expect(assigns(:schedule)).to eq(schedule)
end end
it "redirects to the schedule" do it 'redirects to the schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
put :update, params: { school_id: school.id, id: schedule.to_param, schedule: valid_attributes }, session: valid_session put :update, params: { school_id: school.id, id: schedule.to_param, schedule: valid_attributes },
session: valid_session
expect(response).to redirect_to([school, schedule]) expect(response).to redirect_to([school, schedule])
end end
end end
context "with invalid params" do context 'with invalid params' do
it "assigns the schedule as @schedule" do it 'assigns the schedule as @schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
put :update, params: { school_id: school.id, id: schedule.to_param, schedule: invalid_attributes }, session: valid_session put :update, params: { school_id: school.id, id: schedule.to_param, schedule: invalid_attributes },
session: valid_session
expect(assigns(:schedule)).to eq(schedule) expect(assigns(:schedule)).to eq(schedule)
end end
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
put :update, params: { school_id: school.id, id: schedule.to_param, schedule: invalid_attributes }, session: valid_session put :update, params: { school_id: school.id, id: schedule.to_param, schedule: invalid_attributes },
expect(response).to render_template("edit") session: valid_session
expect(response).to render_template('edit')
end end
end end
end end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
it "destroys the requested schedule" do it 'destroys the requested schedule' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
expect { expect do
delete :destroy, params: { school_id: school.id, id: schedule.to_param }, session: valid_session delete :destroy, params: { school_id: school.id, id: schedule.to_param }, session: valid_session
}.to change(Schedule, :count).by(-1) end.to change(Schedule, :count).by(-1)
end end
it "redirects to the schedules list" do it 'redirects to the schedules list' do
schedule = Schedule.create! valid_attributes schedule = Schedule.create! valid_attributes
delete :destroy, params: { school_id: school.id, id: schedule.to_param }, session: valid_session delete :destroy, params: { school_id: school.id, id: schedule.to_param }, session: valid_session
expect(response).to redirect_to(school) expect(response).to redirect_to(school)
end end
end end
end end
end end

@ -20,7 +20,6 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe SchoolsController, type: :controller do RSpec.describe SchoolsController, type: :controller do
let(:district) { District.create! name: 'District' } let(:district) { District.create! name: 'District' }
let!(:school) { School.create! name: 'school', district: district } let!(:school) { School.create! name: 'school', district: district }
let!(:user) { User.create(email: 'test@example.com', password: '123456') } let!(:user) { User.create(email: 'test@example.com', password: '123456') }
@ -29,157 +28,156 @@ module Legacy
# This should return the minimal set of attributes required to create a valid # This should return the minimal set of attributes required to create a valid
# School. As you add validations to School, be sure to # School. As you add validations to School, be sure to
# adjust the attributes here as well. # adjust the attributes here as well.
let(:valid_attributes) { let(:valid_attributes) do
{name: 'School', district: district} { name: 'School', district: district }
}
let(:invalid_attributes) {
{name: ''}
}
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# SchoolsController. Be sure to keep this updated too.
let(:valid_session) { {} }
describe "GET #show" do
it "assigns the requested school as @school" do
get :show, params: {id: school.to_param}, session: valid_session
expect(assigns(:school)).to eq(school)
end end
end
describe "GET #new" do let(:invalid_attributes) do
it "assigns a new school as @school" do { name: '' }
sign_in user
get :new, params: {}
expect(assigns(:school)).to be_a_new(School)
end end
end
describe "GET #edit" do # This should return the minimal set of values that should be in the session
it "assigns the requested school as @school" do # in order to pass any filters (e.g. authentication) defined in
sign_in user # SchoolsController. Be sure to keep this updated too.
school = School.create! valid_attributes let(:valid_session) { {} }
get :edit, params: {id: school.to_param}
expect(assigns(:school)).to eq(school)
end
end
describe "GET #admin" do describe 'GET #show' do
it "assigns the requested school as @school" do it 'assigns the requested school as @school' do
sign_in user get :show, params: { id: school.to_param }, session: valid_session
get :admin, params: {school_id: school.to_param} expect(assigns(:school)).to eq(school)
expect(assigns(:school)).to eq(school) end
end
it "redirects if not logged in" do
get :admin, params: {school_id: school.to_param}
expect(response).to redirect_to(new_user_session_path)
end end
xit "redirects if user is not associated with school" do describe 'GET #new' do
another_user = User.create(email: 'test2@test.com', password: '123456') it 'assigns a new school as @school' do
sign_in another_user sign_in user
get :new, params: {}
get :admin, params: {school_id: school.to_param} expect(assigns(:school)).to be_a_new(School)
expect(response).to redirect_to(root_path) end
end end
end
describe "POST #create" do describe 'GET #edit' do
before :each do it 'assigns the requested school as @school' do
sign_in user sign_in user
school = School.create! valid_attributes
get :edit, params: { id: school.to_param }
expect(assigns(:school)).to eq(school)
end
end end
context "with valid params" do describe 'GET #admin' do
it "creates a new School" do it 'assigns the requested school as @school' do
expect { sign_in user
post :create, params: {school: valid_attributes} get :admin, params: { school_id: school.to_param }
}.to change(School, :count).by(1) expect(assigns(:school)).to eq(school)
end end
it "assigns a newly created school as @school" do it 'redirects if not logged in' do
post :create, params: {school: valid_attributes} get :admin, params: { school_id: school.to_param }
expect(assigns(:school)).to be_a(School) expect(response).to redirect_to(new_user_session_path)
expect(assigns(:school)).to be_persisted
end end
it "redirects to the created school" do xit 'redirects if user is not associated with school' do
post :create, params: {school: valid_attributes} another_user = User.create(email: 'test2@test.com', password: '123456')
expect(response).to redirect_to(School.last) sign_in another_user
get :admin, params: { school_id: school.to_param }
expect(response).to redirect_to(root_path)
end end
end end
context "with invalid params" do describe 'POST #create' do
it "assigns a newly created but unsaved school as @school" do before :each do
post :create, params: {school: invalid_attributes} sign_in user
expect(assigns(:school)).to be_a_new(School)
end end
it "re-renders the 'new' template" do context 'with valid params' do
post :create, params: {school: invalid_attributes} it 'creates a new School' do
expect(response).to render_template("new") expect do
post :create, params: { school: valid_attributes }
end.to change(School, :count).by(1)
end
it 'assigns a newly created school as @school' do
post :create, params: { school: valid_attributes }
expect(assigns(:school)).to be_a(School)
expect(assigns(:school)).to be_persisted
end
it 'redirects to the created school' do
post :create, params: { school: valid_attributes }
expect(response).to redirect_to(School.last)
end
end end
end
end
describe "PUT #update" do context 'with invalid params' do
before :each do it 'assigns a newly created but unsaved school as @school' do
sign_in user post :create, params: { school: invalid_attributes }
end expect(assigns(:school)).to be_a_new(School)
end
context "with valid params" do it "re-renders the 'new' template" do
let(:new_attributes) { post :create, params: { school: invalid_attributes }
{name: 'New School'} expect(response).to render_template('new')
} end
it "updates the requested school" do
put :update, params: {id: school.to_param, school: new_attributes}
school.reload
expect(school.name).to eq('New School')
end end
end
it "assigns the requested school as @school" do describe 'PUT #update' do
put :update, params: {id: school.to_param, school: valid_attributes} before :each do
expect(assigns(:school)).to eq(school) sign_in user
end end
it "redirects to the school" do context 'with valid params' do
put :update, params: {id: school.to_param, school: valid_attributes} let(:new_attributes) do
expect(response).to redirect_to(school) { name: 'New School' }
end
it 'updates the requested school' do
put :update, params: { id: school.to_param, school: new_attributes }
school.reload
expect(school.name).to eq('New School')
end
it 'assigns the requested school as @school' do
put :update, params: { id: school.to_param, school: valid_attributes }
expect(assigns(:school)).to eq(school)
end
it 'redirects to the school' do
put :update, params: { id: school.to_param, school: valid_attributes }
expect(response).to redirect_to(school)
end
end end
end
context "with invalid params" do context 'with invalid params' do
it "assigns the school as @school" do it 'assigns the school as @school' do
put :update, params: {id: school.to_param, school: invalid_attributes} put :update, params: { id: school.to_param, school: invalid_attributes }
expect(assigns(:school)).to eq(school) expect(assigns(:school)).to eq(school)
end end
it "re-renders the 'edit' template" do it "re-renders the 'edit' template" do
put :update, params: {id: school.to_param, school: invalid_attributes} put :update, params: { id: school.to_param, school: invalid_attributes }
expect(response).to render_template("edit") expect(response).to render_template('edit')
end
end end
end end
end
describe "DELETE #destroy" do describe 'DELETE #destroy' do
before :each do before :each do
sign_in user sign_in user
end end
it "destroys the requested school" do it 'destroys the requested school' do
expect { expect do
delete :destroy, params: {id: school.to_param} delete :destroy, params: { id: school.to_param }
}.to change(School, :count).by(-1) end.to change(School, :count).by(-1)
end end
it "redirects to the schools list" do it 'redirects to the schools list' do
delete :destroy, params: {id: school.to_param} delete :destroy, params: { id: school.to_param }
expect(response).to redirect_to(legacy_schools_url) expect(response).to redirect_to(legacy_schools_url)
end
end end
end end
end
end end

@ -2,12 +2,10 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe WelcomeController, type: :controller do RSpec.describe WelcomeController, type: :controller do
describe 'GET #index' do
describe "GET #index" do it 'works' do
it "works" do
get :index get :index
end end
end end
end end
end end

@ -4,13 +4,13 @@ describe OverviewController, type: :controller do
include BasicAuthHelper include BasicAuthHelper
let(:school) { create(:school) } let(:school) { create(:school) }
let(:district) { create(:district) } let(:district) { create(:district) }
let!(:categories) { let!(:categories) do
[create(:category, name: 'Second', sort_index: 2), create(:category, name: 'First', sort_index: 1)] [create(:category, name: 'Second', sort_index: 2), create(:category, name: 'First', sort_index: 1)]
} end
it 'fetches categories sorted by sort_index' do it 'fetches categories sorted by sort_index' do
login_as district login_as district
get :index, params: { school_id: school.to_param, district_id: district.to_param } get :index, params: { school_id: school.to_param, district_id: district.to_param }
expect(assigns(:category_presenters).map(&:name)).to eql ['First', 'Second'] expect(assigns(:category_presenters).map(&:name)).to eql %w[First Second]
end end
end end

@ -1,5 +1,4 @@
FactoryBot.define do FactoryBot.define do
factory :district do factory :district do
name { "#{rand} District" } name { "#{rand} District" }
slug { name.parameterize } slug { name.parameterize }
@ -20,15 +19,15 @@ FactoryBot.define do
factory :category, class: 'Category' do factory :category, class: 'Category' do
name { "A #{rand} category" } name { "A #{rand} category" }
category_id { rand.to_s } category_id { rand.to_s }
description { "A description of a category" } description { 'A description of a category' }
slug { name.parameterize } slug { name.parameterize }
sort_index { 1 } sort_index { 1 }
end end
factory :subcategory do factory :subcategory do
name { "A subcategory" } name { 'A subcategory' }
subcategory_id { rand.to_s } subcategory_id { rand.to_s }
description { "A description of a subcategory" } description { 'A description of a subcategory' }
category category
factory :subcategory_with_measures do factory :subcategory_with_measures do
@ -36,7 +35,7 @@ FactoryBot.define do
measures_count { 2 } measures_count { 2 }
end end
after(:create) do |subcategory, evaluator| after(:create) do |subcategory, evaluator|
create_list(:measure, evaluator.measures_count, subcategory: subcategory). each do |measure| create_list(:measure, evaluator.measures_count, subcategory: subcategory).each do |measure|
survey_item = create(:teacher_survey_item, measure: measure) survey_item = create(:teacher_survey_item, measure: measure)
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item) create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item)
end end
@ -47,25 +46,33 @@ FactoryBot.define do
factory :measure do factory :measure do
measure_id { rand.to_s } measure_id { rand.to_s }
name { 'A Measure' } name { 'A Measure' }
watch_low_benchmark { 2.0 }
growth_low_benchmark { 3.0 }
approval_low_benchmark { 4.0 }
ideal_low_benchmark { 4.5 }
subcategory subcategory
# trait :with_student_survey_items do
# after(:create) do |measure|
# measure.survey_items << build_list(:student_survey_item, 2)
# end
# end
end end
factory :survey_item do factory :survey_item do
prompt { 'What do YOU think?' } prompt { 'What do YOU think?' }
measure measure
factory :teacher_survey_item do factory :teacher_survey_item do
survey_item_id { "t-#{rand.to_s}" } survey_item_id { "t-#{rand}" }
watch_low_benchmark { 2.0 }
growth_low_benchmark { 3.0 }
approval_low_benchmark { 4.0 }
ideal_low_benchmark { 4.5 }
end end
factory :student_survey_item do factory :student_survey_item do
survey_item_id { "s-#{rand.to_s}" } survey_item_id { "s-#{rand}" }
watch_low_benchmark { 2.0 }
growth_low_benchmark { 3.0 }
approval_low_benchmark { 4.0 }
ideal_low_benchmark { 4.5 }
end end
end end
factory :survey_item_response do factory :survey_item_response do
likert_score { 3 } likert_score { 3 }
response_id { rand.to_s } response_id { rand.to_s }

@ -8,19 +8,19 @@ describe Seeder do
before { AcademicYear.delete_all } before { AcademicYear.delete_all }
it 'seeds new academic years' do it 'seeds new academic years' do
expect { expect do
seeder.seed_academic_years '2020-21', '2021-22', '2022-23' seeder.seed_academic_years '2020-21', '2021-22', '2022-23'
}.to change { AcademicYear.count }.by(3) end.to change { AcademicYear.count }.by(3)
expect(AcademicYear.all.map(&:range)).to eq ['2020-21', '2021-22', '2022-23'] expect(AcademicYear.all.map(&:range)).to eq %w[2020-21 2021-22 2022-23]
end end
context 'when partial data already exists' do context 'when partial data already exists' do
before { create(:academic_year, range: '2020-21') } before { create(:academic_year, range: '2020-21') }
it 'only creates new data' do it 'only creates new data' do
expect { expect do
seeder.seed_academic_years '2020-21', '2021-22' seeder.seed_academic_years '2020-21', '2021-22'
}.to change { AcademicYear.count }.by(1) end.to change { AcademicYear.count }.by(1)
end end
end end
end end
@ -32,30 +32,35 @@ describe Seeder do
end end
it 'seeds new districts and schools' do it 'seeds new districts and schools' do
expect { expect do
seeder.seed_districts_and_schools sample_districts_and_schools_csv seeder.seed_districts_and_schools sample_districts_and_schools_csv
}.to change { District.count }.by(2) end.to change { District.count }.by(2)
.and change { School.count }.by(2) .and change { School.count }.by(2)
end end
context 'when partial data already exists' do context 'when partial data already exists' do
let!(:existing_district) { create(:district, name: 'Boston') } let!(:existing_district) { create(:district, name: 'Boston') }
let!(:removed_school) { create(:school, name: 'John Oldes Academy', dese_id: 12345, district: existing_district) } let!(:removed_school) do
create(:school, name: 'John Oldes Academy', dese_id: 12_345, district: existing_district)
end
let!(:removed_survey_item_response) { create(:survey_item_response, school: removed_school) } let!(:removed_survey_item_response) { create(:survey_item_response, school: removed_school) }
let!(:existing_school) { create(:school, name: 'Sam Adams Elementary School', dese_id: 350302, slug: 'some-slug-for-sam-adams', district: existing_district) } let!(:existing_school) do
create(:school, name: 'Sam Adams Elementary School', dese_id: 350_302, slug: 'some-slug-for-sam-adams',
district: existing_district)
end
it 'only creates new districts and schools' do it 'only creates new districts and schools' do
expect { expect do
seeder.seed_districts_and_schools sample_districts_and_schools_csv seeder.seed_districts_and_schools sample_districts_and_schools_csv
}.to change { District.count }.by(1) end.to change { District.count }.by(1)
.and change { School.count }.by(0) # +1 for new school, -1 for old school .and change { School.count }.by(0) # +1 for new school, -1 for old school
new_district = District.find_by_name 'Attleboro' new_district = District.find_by_name 'Attleboro'
expect(new_district.qualtrics_code).to eq 1 expect(new_district.qualtrics_code).to eq 1
expect(new_district.slug).to eq 'attleboro' expect(new_district.slug).to eq 'attleboro'
new_school = School.find_by_name 'Attleboro High School' new_school = School.find_by_name 'Attleboro High School'
expect(new_school.dese_id).to eq 160505 expect(new_school.dese_id).to eq 160_505
expect(new_school.qualtrics_code).to eq 1 expect(new_school.qualtrics_code).to eq 1
expect(new_school.slug).to eq 'attleboro-high-school' expect(new_school.slug).to eq 'attleboro-high-school'
end end
@ -92,13 +97,17 @@ describe Seeder do
end end
it 'creates new objects as necessary' do it 'creates new objects as necessary' do
expect { expect do
seeder.seed_sqm_framework sample_sqm_framework_csv seeder.seed_sqm_framework sample_sqm_framework_csv
}.to change { Category.count }.by(4) end.to change { Category.count }.by(4)
.and change { Subcategory.count }.by(15) .and change { Subcategory.count }.by(15)
.and change { Measure.count }.by(31) .and change { Measure.count }.by(31)
.and change { SurveyItem.count }.by(136) .and change {
.and change { AdminDataItem.count }.by(32) SurveyItem.count
}.by(136)
.and change {
AdminDataItem.count
}.by(32)
end end
context 'updates records to match given data' do context 'updates records to match given data' do
@ -110,8 +119,8 @@ describe Seeder do
teachers_leadership = Category.find_by_name 'Teachers & Leadership' teachers_leadership = Category.find_by_name 'Teachers & Leadership'
expect(teachers_leadership.slug).to eq 'teachers-and-leadership' expect(teachers_leadership.slug).to eq 'teachers-and-leadership'
expect(teachers_leadership.description).to eq "This is a category description." expect(teachers_leadership.description).to eq 'This is a category description.'
expect(teachers_leadership.short_description).to eq "This is a category short description." expect(teachers_leadership.short_description).to eq 'This is a category short description.'
end end
it 'updates category sort index to match a predefined order' do it 'updates category sort index to match a predefined order' do
@ -124,31 +133,35 @@ describe Seeder do
it 'updates subcategory data' do it 'updates subcategory data' do
subcategory = Subcategory.find_by_name 'Safety' subcategory = Subcategory.find_by_name 'Safety'
expect(subcategory.description).to eq "This is a subcategory description." expect(subcategory.description).to eq 'This is a subcategory description.'
end end
it 'updates measure data' do it 'updates measure data' do
measure = Measure.find_by_measure_id '2A-i' measure = Measure.find_by_measure_id '2A-i'
expect(measure.name).to eq 'Student Physical Safety' expect(measure.name).to eq 'Student Physical Safety'
expect(measure.description).to eq 'This is a measure description.' expect(measure.description).to eq 'This is a measure description.'
expect(measure.watch_low_benchmark).to eq 2.79
expect(measure.growth_low_benchmark).to eq 3.3
expect(measure.approval_low_benchmark).to eq 3.8
expect(measure.ideal_low_benchmark).to eq 4.51
end end
it 'does not overwrite the measure benchmarks with admin data benchmarks' do it 'does not overwrite the survey item benchmarks with admin data benchmarks' do
measure = Measure.find_by_measure_id '1A-i' survey_item = SurveyItem.find_by_survey_item_id 't-prep-q1'
expect(measure.approval_low_benchmark).to eq 3.5 expect(survey_item.approval_low_benchmark).to eq 3.5
end end
it 'updates survey item data' do it 'updates survey item data' do
survey_item = SurveyItem.find_by_survey_item_id 's-phys-q1' survey_item = SurveyItem.find_by_survey_item_id 's-phys-q1'
expect(survey_item.prompt).to eq 'How often do you worry about violence at your school?' expect(survey_item.prompt).to eq 'How often do you worry about violence at your school?'
expect(survey_item.watch_low_benchmark).to eq 2.79
expect(survey_item.growth_low_benchmark).to eq 3.3
expect(survey_item.approval_low_benchmark).to eq 3.8
expect(survey_item.ideal_low_benchmark).to eq 4.51
end end
it 'updates admin data item data' do it 'updates admin data item data' do
admin_data_item = AdminDataItem.find_by_admin_data_item_id 'a-phys-i1' admin_data_item = AdminDataItem.find_by_admin_data_item_id 'a-phys-i1'
expect(admin_data_item.watch_low_benchmark).to eq 2.99
expect(admin_data_item.growth_low_benchmark).to eq 3.5
expect(admin_data_item.approval_low_benchmark).to eq 4
expect(admin_data_item.ideal_low_benchmark).to eq 4.71
expect(admin_data_item.description).to eq 'Student to suspensions ratio' expect(admin_data_item.description).to eq 'Student to suspensions ratio'
end end
end end

@ -1,26 +1,26 @@
require 'rails_helper' require 'rails_helper'
module Legacy module Legacy
describe "survey:attempt_questions" do describe 'survey:attempt_questions' do
include_context "rake" include_context 'rake'
it 'should have environment as a prerequisite' do it 'should have environment as a prerequisite' do
expect(subject.prerequisites).to include("environment") expect(subject.prerequisites).to include('environment')
end end
describe "basic flow" do describe 'basic flow' do
let(:now) { let(:now) do
n = DateTime.now n = DateTime.now
n += 1.day until n.on_weekday? n += 1.day until n.on_weekday?
return n return n
} end
let(:ready_recipient_schedule) { double('ready recipient schedule', attempt_question: nil) } let(:ready_recipient_schedule) { double('ready recipient schedule', attempt_question: nil) }
let(:recipient_schedules) { double("recipient schedules", ready: [ready_recipient_schedule]) } let(:recipient_schedules) { double('recipient schedules', ready: [ready_recipient_schedule]) }
let(:active_schedule) { double("active schedule", recipient_schedules: recipient_schedules) } let(:active_schedule) { double('active schedule', recipient_schedules: recipient_schedules) }
it "finds all active schedules" do it 'finds all active schedules' do
date = ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
Timecop.freeze(date) Timecop.freeze(date)
expect(ready_recipient_schedule).to receive(:attempt_question) expect(ready_recipient_schedule).to receive(:attempt_question)
@ -29,10 +29,10 @@ module Legacy
subject.invoke subject.invoke
end end
it "works only on weekdays" do it 'works only on weekdays' do
now = DateTime.now now = DateTime.now
now += 1.day until now.on_weekend? now += 1.day until now.on_weekend?
date = ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
Timecop.freeze(date) Timecop.freeze(date)
expect(ready_recipient_schedule).to_not receive(:attempt_question) expect(ready_recipient_schedule).to_not receive(:attempt_question)
@ -40,12 +40,12 @@ module Legacy
end end
end end
xdescribe "complex flow" do xdescribe 'complex flow' do
let(:now) { let(:now) do
n = DateTime.now n = DateTime.now
n += 1.day until n.on_weekday? n += 1.day until n.on_weekday?
return n return n
} end
let!(:school) { School.create!(name: 'School') } let!(:school) { School.create!(name: 'School') }
@ -76,7 +76,7 @@ module Legacy
before :each do before :each do
now = DateTime.new now = DateTime.new
now += 1.day until now.on_weekend? now += 1.day until now.on_weekend?
date = ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT19:00:00%z")) date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT19:00:00%z'))
Timecop.freeze(date) { subject.invoke } Timecop.freeze(date) { subject.invoke }
end end
@ -87,7 +87,7 @@ module Legacy
describe 'First attempt at specified time' do describe 'First attempt at specified time' do
before :each do before :each do
date = ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
Timecop.freeze(date) { subject.invoke } Timecop.freeze(date) { subject.invoke }
end end
@ -193,7 +193,6 @@ module Legacy
end end
describe 'Multiple Students In A Family' do describe 'Multiple Students In A Family' do
before :each do before :each do
3.times do |i| 3.times do |i|
recipients[1].students.create(name: "Student#{i}") recipients[1].students.create(name: "Student#{i}")
@ -201,12 +200,12 @@ module Legacy
end end
let(:students_recipient) { recipients[1] } let(:students_recipient) { recipients[1] }
let(:students_recipient_schedule) { let(:students_recipient_schedule) do
students_recipient.recipient_schedules.for_schedule(schedule).first students_recipient.recipient_schedules.for_schedule(schedule).first
} end
describe 'With A FOR_CHILD Question Is Asked' do describe 'With A FOR_CHILD Question Is Asked' do
let!(:date) { ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) } let!(:date) { ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z')) }
before :each do before :each do
questions.first.update(for_recipient_students: true) questions.first.update(for_recipient_students: true)
@ -224,7 +223,7 @@ module Legacy
expect(students_recipient_schedule.queued_question_ids).to be_present expect(students_recipient_schedule.queued_question_ids).to be_present
queued_question_ids = students_recipient_schedule.queued_question_ids.split(/,/) queued_question_ids = students_recipient_schedule.queued_question_ids.split(/,/)
expect(queued_question_ids.length).to eq(1) expect(queued_question_ids.length).to eq(1)
expect(queued_question_ids.first).to eq("#{questions[0].id}") expect(queued_question_ids.first).to eq(questions[0].id.to_s)
end end
it 'should set the next_attempt_at to now when attempt is made on first student' do it 'should set the next_attempt_at to now when attempt is made on first student' do
@ -234,7 +233,9 @@ module Legacy
it 'should set the next_attempt_at in the future when an attempts are made on each student' do it 'should set the next_attempt_at in the future when an attempts are made on each student' do
students_recipient.attempts.last.save_response(answer_index: 3) students_recipient.attempts.last.save_response(answer_index: 3)
expect { students_recipient_schedule.attempt_question }.to change { students_recipient.attempts.count }.by(1) expect { students_recipient_schedule.attempt_question }.to change {
students_recipient.attempts.count
}.by(1)
expect(students_recipient_schedule.reload.queued_question_ids).to be_present expect(students_recipient_schedule.reload.queued_question_ids).to be_present
attempt = students_recipient.attempts.last attempt = students_recipient.attempts.last
@ -244,7 +245,9 @@ module Legacy
attempt.save_response(answer_index: 4) attempt.save_response(answer_index: 4)
expect(students_recipient_schedule.reload.next_attempt_at).to eq(date + 1.day) expect(students_recipient_schedule.reload.next_attempt_at).to eq(date + 1.day)
expect { students_recipient_schedule.attempt_question }.to change { students_recipient.attempts.count }.by(1) expect { students_recipient_schedule.attempt_question }.to change {
students_recipient.attempts.count
}.by(1)
expect(students_recipient_schedule.reload.queued_question_ids).to be_nil expect(students_recipient_schedule.reload.queued_question_ids).to be_nil
expect(students_recipient_schedule.reload.next_attempt_at).to_not eq(date + (60 * 60 * schedule.frequency_hours)) expect(students_recipient_schedule.reload.next_attempt_at).to_not eq(date + (60 * 60 * schedule.frequency_hours))
@ -266,7 +269,9 @@ module Legacy
it 'resends the question about the same student if not responded to' do it 'resends the question about the same student if not responded to' do
message_count = FakeSMS.messages.length message_count = FakeSMS.messages.length
expect { students_recipient_schedule.attempt_question }.to change { students_recipient.attempts.count }.by(0) expect { students_recipient_schedule.attempt_question }.to change {
students_recipient.attempts.count
}.by(0)
expect(FakeSMS.messages.length).to eq(message_count + 2) expect(FakeSMS.messages.length).to eq(message_count + 2)
expect(FakeSMS.messages[message_count].body).to match(questions.first.text) expect(FakeSMS.messages[message_count].body).to match(questions.first.text)
expect(FakeSMS.messages[message_count].body).to match(/\(for Student0\)/) expect(FakeSMS.messages[message_count].body).to match(/\(for Student0\)/)
@ -276,7 +281,6 @@ module Legacy
recipient_schedule = recipients[0].recipient_schedules.for_schedule(schedule).first recipient_schedule = recipients[0].recipient_schedules.for_schedule(schedule).first
expect(recipient_schedule.queued_question_ids).to be_nil expect(recipient_schedule.queued_question_ids).to be_nil
end end
end end
describe 'With A General Question Is Asked' do describe 'With A General Question Is Asked' do
@ -293,23 +297,21 @@ module Legacy
expect(message.body).to_not match(/\(for .*\)/) expect(message.body).to_not match(/\(for .*\)/)
end end
end end
end end
end end
describe 'One Student In A Family' do describe 'One Student In A Family' do
before :each do before :each do
recipients[1].students.create(name: "Only Student") recipients[1].students.create(name: 'Only Student')
end end
let(:students_recipient) { recipients[1] } let(:students_recipient) { recipients[1] }
let(:students_recipient_schedule) { let(:students_recipient_schedule) do
students_recipient.recipient_schedules.for_schedule(schedule).first students_recipient.recipient_schedules.for_schedule(schedule).first
} end
describe 'With A FOR_CHILD Question Is Asked' do describe 'With A FOR_CHILD Question Is Asked' do
let!(:date) { ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) } let!(:date) { ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z')) }
before :each do before :each do
questions.first.update(for_recipient_students: true) questions.first.update(for_recipient_students: true)
@ -330,11 +332,10 @@ module Legacy
end end
describe 'Opted Out Recipient' do describe 'Opted Out Recipient' do
before :each do before :each do
recipients[1].update(opted_out: true) recipients[1].update(opted_out: true)
date = ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
Timecop.freeze(date) { subject.invoke } Timecop.freeze(date) { subject.invoke }
end end
@ -353,7 +354,6 @@ module Legacy
end end
end end
end end
end end
end end
end end

@ -2,21 +2,22 @@ require 'rails_helper'
module Legacy module Legacy
describe Attempt, type: :model do describe Attempt, type: :model do
let!(:school) { School.create!(name: 'School') } let!(:school) { School.create!(name: 'School') }
let!(:recipient) { school.recipients.create(name: 'name', phone: "#{1}" * 9) } let!(:recipient) { school.recipients.create(name: 'name', phone: '1' * 9) }
let!(:recipient_list) do let!(:recipient_list) do
school.recipient_lists.create!(name: 'Parents', recipient_ids: "#{recipient.id}") school.recipient_lists.create!(name: 'Parents', recipient_ids: recipient.id.to_s)
end end
let!(:category) { Category.create(name: 'Category') } let!(:category) { Category.create(name: 'Category') }
let!(:question) { create_questions(1, category).first } let!(:question) { create_questions(1, category).first }
let!(:question_list) do let!(:question_list) do
QuestionList.create!(name: 'Parent Questions', question_ids: "#{question.id}") QuestionList.create!(name: 'Parent Questions', question_ids: question.id.to_s)
end end
let(:schedule) { Schedule.create!(name: 'Parent Schedule', recipient_list_id: recipient_list.id, question_list: question_list) } let(:schedule) do
Schedule.create!(name: 'Parent Schedule', recipient_list_id: recipient_list.id, question_list: question_list)
end
let(:recipient_schedule) do let(:recipient_schedule) do
RecipientSchedule.create!( RecipientSchedule.create!(
@ -96,7 +97,7 @@ module Legacy
expect(FakeSMS.messages.length).to eq(2) expect(FakeSMS.messages.length).to eq(2)
expect(FakeSMS.messages.first.to).to eq('111111111') expect(FakeSMS.messages.first.to).to eq('111111111')
expect(FakeSMS.messages.first.body).to eq("Question 0:1") expect(FakeSMS.messages.first.body).to eq('Question 0:1')
expect(FakeSMS.messages.last.to).to eq('111111111') expect(FakeSMS.messages.last.to).to eq('111111111')
expect(FakeSMS.messages.last.body).to eq("Option 0:1 A: Reply 1\nOption 0:1 B: 2\nOption 0:1 C: 3\nOption 0:1 D: 4\nOption 0:1 E: 5") expect(FakeSMS.messages.last.body).to eq("Option 0:1 A: Reply 1\nOption 0:1 B: 2\nOption 0:1 C: 3\nOption 0:1 D: 4\nOption 0:1 E: 5")

@ -5,7 +5,7 @@ module Legacy
let(:district1) { District.create(name: 'District one', state_id: 32) } let(:district1) { District.create(name: 'District one', state_id: 32) }
let(:district2) { District.new(name: 'District two', state_id: 32) } let(:district2) { District.new(name: 'District two', state_id: 32) }
context "when saving or creating" do context 'when saving or creating' do
it 'should return a slug' do it 'should return a slug' do
expect(district1.slug).to eq 'district-one' expect(district1.slug).to eq 'district-one'
@ -17,5 +17,4 @@ module Legacy
end end
end end
end end
end end

@ -2,7 +2,6 @@ require 'rails_helper'
module Legacy module Legacy
RSpec.describe Question, type: :model do RSpec.describe Question, type: :model do
let!(:school1) { School.create!(name: 'School 1') } let!(:school1) { School.create!(name: 'School 1') }
let!(:school2) { School.create!(name: 'School 2') } let!(:school2) { School.create!(name: 'School 2') }
@ -16,18 +15,33 @@ module Legacy
let!(:category2questions) { create_questions(3, category2) } let!(:category2questions) { create_questions(3, category2) }
let(:question) { category1questions.first } let(:question) { category1questions.first }
let!(:attempt1) { Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[0], answer_index: 3) } let!(:attempt1) do
let!(:attempt2) { Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[1], answer_index: 2) } Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[0], answer_index: 3)
end
let!(:attempt2) do
Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[1], answer_index: 2)
end
let!(:attempt3) { Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[2]) } let!(:attempt3) { Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[2]) }
let!(:attempt4) { Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[3], answer_index: 3) } let!(:attempt4) do
let!(:attempt5) { Legacy::Attempt.create!(question: category1questions[0], recipient: school2recipients[0], answer_index: 4) } Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[3], answer_index: 3)
let!(:attempt6) { Legacy::Attempt.create!(question: category1questions[1], recipient: school1recipients[0], answer_index: 5) } end
let!(:attempt7) { Legacy::Attempt.create!(question: category1questions[2], recipient: school1recipients[0], answer_index: 5) } let!(:attempt5) do
let!(:attempt8) { Legacy::Attempt.create!(question: category2questions[0], recipient: school1recipients[0], answer_index: 3) } Legacy::Attempt.create!(question: category1questions[0], recipient: school2recipients[0], answer_index: 4)
let!(:attempt9) { Legacy::Attempt.create!(question: category2questions[1], recipient: school1recipients[1], answer_index: 1) } end
let!(:attempt6) do
Legacy::Attempt.create!(question: category1questions[1], recipient: school1recipients[0], answer_index: 5)
end
let!(:attempt7) do
Legacy::Attempt.create!(question: category1questions[2], recipient: school1recipients[0], answer_index: 5)
end
let!(:attempt8) do
Legacy::Attempt.create!(question: category2questions[0], recipient: school1recipients[0], answer_index: 3)
end
let!(:attempt9) do
Legacy::Attempt.create!(question: category2questions[1], recipient: school1recipients[1], answer_index: 1)
end
describe 'aggregated_responses_for_school' do describe 'aggregated_responses_for_school' do
let(:aggregated_responses) { question.aggregated_responses_for_school(school1) } let(:aggregated_responses) { question.aggregated_responses_for_school(school1) }
it 'aggregates all attempts with responses for the question for a given school' do it 'aggregates all attempts with responses for the question for a given school' do
@ -48,8 +62,6 @@ module Legacy
expect(aggregated_responses.question).to eq(question) expect(aggregated_responses.question).to eq(question)
expect(aggregated_responses.category).to eq(question.category) expect(aggregated_responses.category).to eq(question.category)
end end
end end
end end
end end

@ -2,8 +2,8 @@ require 'rails_helper'
module Legacy module Legacy
describe RecipientList do describe RecipientList do
describe "Save" do describe 'Save' do
it "should convert the recipient_id_array into the recipient_ids attribute" do it 'should convert the recipient_id_array into the recipient_ids attribute' do
recipient_list = RecipientList.create(name: 'Name', recipient_id_array: ['', '1', '2', '3']) recipient_list = RecipientList.create(name: 'Name', recipient_id_array: ['', '1', '2', '3'])
expect(recipient_list).to be_a(RecipientList) expect(recipient_list).to be_a(RecipientList)
expect(recipient_list).to be_persisted expect(recipient_list).to be_persisted
@ -14,7 +14,7 @@ module Legacy
end end
end end
describe "when edited" do describe 'when edited' do
let!(:school) { School.create!(name: 'School') } let!(:school) { School.create!(name: 'School') }
let!(:recipients) { create_recipients(school, 3) } let!(:recipients) { create_recipients(school, 3) }

@ -2,21 +2,21 @@ require 'rails_helper'
module Legacy module Legacy
describe Recipient do describe Recipient do
describe "Import" do describe 'Import' do
let(:school) { School.create!(name: 'School') } let(:school) { School.create!(name: 'School') }
let(:data) { "name,phone\rJared,111-222-333\rLauren,222-333-4444\rAbby,333-444-5555\r" } let(:data) { "name,phone\rJared,111-222-333\rLauren,222-333-4444\rAbby,333-444-5555\r" }
let(:file) { instance_double('File', path: 'path') } let(:file) { instance_double('File', path: 'path') }
xit "should parse file contents and return a result" do xit 'should parse file contents and return a result' do
expect(File).to receive(:open).with('path', universal_newline: false, headers: true) { StringIO.new(data) } expect(File).to receive(:open).with('path', universal_newline: false, headers: true) { StringIO.new(data) }
Recipient.import(school, file) Recipient.import(school, file)
expect(Recipient.count).to eq(3) expect(Recipient.count).to eq(3)
expect(Recipient.all.map(&:name)).to eq(['Jared', 'Lauren', 'Abby']) expect(Recipient.all.map(&:name)).to eq(%w[Jared Lauren Abby])
expect(Recipient.all.map(&:school).uniq).to eq([school]) expect(Recipient.all.map(&:school).uniq).to eq([school])
end end
end end
describe "When Deleted" do describe 'When Deleted' do
let!(:school) { School.create!(name: 'School') } let!(:school) { School.create!(name: 'School') }
let!(:recipients) { create_recipients(school, 3) } let!(:recipients) { create_recipients(school, 3) }
@ -45,7 +45,6 @@ module Legacy
end.to change { schedule.recipient_schedules.count }.from(3).to(2) end.to change { schedule.recipient_schedules.count }.from(3).to(2)
expect(recipient_list.recipient_ids).to eq("#{recipients[0].id},#{recipients[2].id}") expect(recipient_list.recipient_ids).to eq("#{recipients[0].id},#{recipients[2].id}")
end end
end end
end end

@ -2,7 +2,6 @@ require 'rails_helper'
module Legacy module Legacy
describe Schedule do describe Schedule do
let!(:school) { School.create!(name: 'School') } let!(:school) { School.create!(name: 'School') }
let!(:recipients) { create_recipients(school, 3) } let!(:recipients) { create_recipients(school, 3) }
@ -20,7 +19,7 @@ module Legacy
QuestionList.create!(name: 'Questions', question_ids: questions.map(&:id).join(',')) QuestionList.create!(name: 'Questions', question_ids: questions.map(&:id).join(','))
end end
let(:default_schedule_params) { let(:default_schedule_params) do
{ {
school: school, school: school,
recipient_list: recipient_list, recipient_list: recipient_list,
@ -31,7 +30,7 @@ module Legacy
end_date: 11.months.from_now, end_date: 11.months.from_now,
active: true active: true
} }
} end
let!(:active_schedule) do let!(:active_schedule) do
Schedule.create!(default_schedule_params) Schedule.create!(default_schedule_params)
@ -41,15 +40,15 @@ module Legacy
Schedule.create!(default_schedule_params.merge!(name: 'Kids Schedule', recipient_list: kids_recipient_list)) Schedule.create!(default_schedule_params.merge!(name: 'Kids Schedule', recipient_list: kids_recipient_list))
end end
let!(:old_schedule) { let!(:old_schedule) do
Schedule.create!(default_schedule_params.merge!(start_date: 13.month.ago, end_date: 1.months.ago)) Schedule.create!(default_schedule_params.merge!(start_date: 13.month.ago, end_date: 1.months.ago))
} end
let!(:paused_schedule) { let!(:paused_schedule) do
Schedule.create!(default_schedule_params.merge!(active: false)) Schedule.create!(default_schedule_params.merge!(active: false))
} end
describe "active" do describe 'active' do
it 'finds active schedules' do it 'finds active schedules' do
active = Schedule.active active = Schedule.active
expect(active.length).to eq(2) expect(active.length).to eq(2)
@ -59,6 +58,5 @@ module Legacy
it 'creates a recipient_schedule for every recipient when created' do it 'creates a recipient_schedule for every recipient when created' do
expect(active_schedule.recipient_schedules.length).to eq(3) expect(active_schedule.recipient_schedules.length).to eq(3)
end end
end end
end end

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save