diff --git a/Gemfile b/Gemfile
index 9d6fd3a6..30c68795 100644
--- a/Gemfile
+++ b/Gemfile
@@ -71,6 +71,7 @@ group 'test' do
gem 'rspec-rails', '~> 4.1.2'
gem 'rails-controller-testing'
gem 'capybara'
+ gem 'apparition', github: 'twalpole/apparition', ref: 'ca86be4d54af835d531dbcd2b86e7b2c77f85f34'
gem 'launchy'
gem 'database_cleaner'
gem 'timecop'
diff --git a/Gemfile.lock b/Gemfile.lock
index 8f25f087..54780e0f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,12 @@
+GIT
+ remote: https://github.com/twalpole/apparition.git
+ revision: ca86be4d54af835d531dbcd2b86e7b2c77f85f34
+ ref: ca86be4d54af835d531dbcd2b86e7b2c77f85f34
+ specs:
+ apparition (0.6.0)
+ capybara (~> 3.13, < 4)
+ websocket-driver (>= 0.6.5)
+
GEM
remote: https://rubygems.org/
specs:
@@ -112,19 +121,19 @@ GEM
mail (2.7.1)
mini_mime (>= 0.1.1)
method_source (1.0.0)
- mini_mime (1.1.1)
+ mini_mime (1.1.2)
mini_portile2 (2.6.1)
minitest (5.14.4)
multi_json (1.15.0)
nested_scaffold (1.1.0)
newrelic_rpm (8.0.0)
nio4r (2.5.8)
- nokogiri (1.12.4)
+ nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
- nokogiri (1.12.4-x86_64-darwin)
+ nokogiri (1.12.5-x86_64-darwin)
racc (~> 1.4)
- nokogiri (1.12.4-x86_64-linux)
+ nokogiri (1.12.5-x86_64-linux)
racc (~> 1.4)
omniauth (2.0.4)
hashie (>= 3.4.6)
@@ -251,6 +260,7 @@ PLATFORMS
DEPENDENCIES
activerecord-import
+ apparition!
bootstrap
byebug
capybara
diff --git a/app/assets/javascripts/dashboard.js b/app/assets/javascripts/dashboard.js
index 82f4985a..dbcad599 100644
--- a/app/assets/javascripts/dashboard.js
+++ b/app/assets/javascripts/dashboard.js
@@ -1,9 +1,12 @@
-document.addEventListener("DOMContentLoaded", function() {
- document.querySelector('#select-school').addEventListener('change', (event) => {
- window.location = event.target.value;
- });
+document.addEventListener("turbolinks:load", function() {
+ const schoolDropdown = document.querySelector('#select-school');
+ if (schoolDropdown) {
+ document.querySelector('#select-school').addEventListener('change', (event) => {
+ window.location = event.target.value;
+ });
- document.querySelector('#select-district').addEventListener('change', (event) => {
- window.location = event.target.value;
- });
+ document.querySelector('#select-district').addEventListener('change', (event) => {
+ window.location = event.target.value;
+ });
+ }
});
diff --git a/app/assets/javascripts/home.js b/app/assets/javascripts/home.js
new file mode 100644
index 00000000..47d80f08
--- /dev/null
+++ b/app/assets/javascripts/home.js
@@ -0,0 +1,25 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const districtDropdown = document.querySelector('#district-dropdown');
+ if (districtDropdown) {
+ districtDropdown.addEventListener('change', event => {
+ const schoolDropdown = document.querySelector('#school-dropdown');
+
+ const districtId = Number(event.target.value);
+
+ const schoolsInDistrict = window.schools.filter(school => school.district_id === districtId);
+
+ schoolsInDistrict.forEach(school => {
+ const optionElem = document.createElement('option');
+ optionElem.setAttribute('value', school.url);
+ const schoolNameNode = document.createTextNode(school.name);
+ optionElem.appendChild(schoolNameNode);
+ schoolDropdown.appendChild(optionElem);
+ });
+ });
+
+ document.querySelector('button[data-id="go-to-school"]').addEventListener('click', event => {
+ const selectedSchoolURL = document.querySelector('#school-dropdown').value;
+ window.location = selectedSchoolURL;
+ });
+ }
+});
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
new file mode 100644
index 00000000..d53a1e76
--- /dev/null
+++ b/app/controllers/home_controller.rb
@@ -0,0 +1,6 @@
+class HomeController < ActionController::Base
+ def index
+ @districts = District.all.order(:name)
+ @schools = School.all
+ end
+end
diff --git a/app/helpers/header_helper.rb b/app/helpers/header_helper.rb
index e9bd6192..3fa8a1e9 100644
--- a/app/helpers/header_helper.rb
+++ b/app/helpers/header_helper.rb
@@ -16,6 +16,14 @@ module HeaderHelper
dashboard_link(district_slug: school.district.slug, school_slug: school.slug, academic_year_range: academic_year.range, uri_path: request.fullpath)
end
+ def school_mapper(school)
+ {
+ name: school.name,
+ district_id: school.district_id,
+ url: district_school_dashboard_index_path(school.district, school, {year: AcademicYear.first.range})
+ }
+ end
+
def link_weight(path:)
active?(path: path) ? 'weight-700' : 'weight-400'
end
diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb
new file mode 100644
index 00000000..d4eb7ff3
--- /dev/null
+++ b/app/views/home/index.html.erb
@@ -0,0 +1,6 @@
+<%= collection_select(:district, :id, @districts, :id, :name, {}, {id: 'district-dropdown'}) %>
+
+
+
+
diff --git a/app/views/layouts/home.html.erb b/app/views/layouts/home.html.erb
new file mode 100644
index 00000000..8266f150
--- /dev/null
+++ b/app/views/layouts/home.html.erb
@@ -0,0 +1,12 @@
+
+
+ Our new layout
+ <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
+
+
+ <%= yield %>
+
+
+
diff --git a/config/routes.rb b/config/routes.rb
index a9d8f7b4..6b5c6ea6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -34,5 +34,6 @@ Rails.application.routes.draw do
get '/admin', to: 'admin#index', as: 'admin'
post '/twilio', to: 'attempts#twilio'
+ get '/welcome', to: 'home#index'
root to: "welcome#index"
end
diff --git a/spec/features/school_dashboard_feature_spec.rb b/spec/features/school_dashboard_feature_spec.rb
index 3dc82535..b7dab844 100644
--- a/spec/features/school_dashboard_feature_spec.rb
+++ b/spec/features/school_dashboard_feature_spec.rb
@@ -1,7 +1,85 @@
require 'rails_helper'
+# include Rails.application.routes.url_helpers
+
+def district_admin_sees_student_physical_safety
+ expect(page).to have_text('Student Physical Safety')
+ student_physical_safety_row = measure_row_bars.find { |item| item['data-for-measure-id'] == '2A-i' }
+ expect(student_physical_safety_row['width']).to eq '40.0%'
+ expect(student_physical_safety_row['x']).to eq '60%'
+end
+
+def district_admin_sees_problem_solving_emphasis
+ expect(page).to have_text('Problem Solving Emphasis')
+ problem_solving_emphasis_row = measure_row_bars.find { |item| item['data-for-measure-id'] == '4C-i' }
+ expect(problem_solving_emphasis_row['width']).to eq '60.0%'
+ expect(problem_solving_emphasis_row['x']).to eq '0.0%'
+end
+
+def district_admin_sees_professional_qualifications
+ expect(page).to have_text('Professional Qualifications')
+ professional_qualifications_row = measure_row_bars.find { |item| item['data-for-measure-id'] == '1A-i' }
+ expect(professional_qualifications_row['width']).to eq '8.26%'
+ expect(professional_qualifications_row['x']).to eq '60%'
+end
+
+def go_to_school_dashboard_from_welcome_page(district, school)
+ select district.name, from: 'district-dropdown'
+ select school.name, from: 'school-dropdown'
+ click_on 'Go'
+end
+
+def go_to_different_school_in_same_district(school)
+ select school.name, from: 'select-school'
+end
+
+def go_to_different_district(district)
+ select district.name, from: 'select-district'
+end
+
+def district_admin_sees_schools_change
+ expected_path = "/districts/#{school_in_same_district.district.slug}/schools/#{school_in_same_district.slug}/browse/#{SqmCategory.first.slug}?year=2020-21"
+ expect(page).to have_current_path(expected_path)
+end
+
+def district_admin_sees_district_change
+ expected_path = "/districts/#{different_district.slug}/schools/#{different_district.schools.alphabetic.first.slug}/browse/#{SqmCategory.first.slug}?year=2020-21"
+ expect(page).to have_current_path(expected_path)
+end
+
+def district_admin_sees_measures_in_correct_order
+ professional_qualifications_row_index = measure_row_bars.find_index { |item| item['data-for-measure-id'] == '1A-i' }
+ student_physical_safety_row_index = measure_row_bars.find_index { |item| item['data-for-measure-id'] == '2A-i' }
+ problem_solving_emphasis_row_index = measure_row_bars.find_index { |item| item['data-for-measure-id'] == '4C-i' }
+ expect(student_physical_safety_row_index).to be < professional_qualifications_row_index
+ expect(professional_qualifications_row_index).to be < problem_solving_emphasis_row_index
+end
+
+def district_admin_sees_dashboard_content
+ expect(page).to have_select('academic-year', selected: '2020 – 2021')
+ expect(page).to have_select('district', selected: 'Winchester')
+ expect(page).to have_select('school', selected: 'Winchester High School')
+ expect(page).to have_text(school.name)
+
+ district_admin_sees_professional_qualifications
+ district_admin_sees_student_physical_safety
+ district_admin_sees_problem_solving_emphasis
+
+ measure_row_bar_with_no_responses = measure_row_bars.find { |item| item['data-for-measure-id'] == '3A-i' }
+ expect(measure_row_bar_with_no_responses['width']).to eq '0.0%'
+
+ page.assert_selector('.measure-row-bar', count: Measure.count)
+
+ district_admin_sees_measures_in_correct_order
+end
+
+def district_admin_sees_browse_content
+ expect(page).to have_text('Teachers & Leadership')
+ expect(page).to have_text('Approval')
+end
feature 'School dashboard', type: feature do
let(:district) { District.find_by_slug 'winchester' }
+ let(:different_district) { District.find_by_slug 'boston' }
let(:school) { School.find_by_slug 'winchester-high-school' }
let(:school_in_same_district) { School.find_by_slug 'muraco-elementary-school' }
@@ -31,19 +109,23 @@ feature 'School dashboard', type: feature do
before :each do
survey_items_for_measure_1A_i.each do |survey_item|
- SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, survey_item: survey_item, likert_score: 4
+ SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
+ survey_item: survey_item, likert_score: 4
end
survey_items_for_measure_2A_i.each do |survey_item|
- SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, survey_item: survey_item, likert_score: 5
+ SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
+ survey_item: survey_item, likert_score: 5
end
survey_items_for_measure_4C_i.each do |survey_item|
- SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, survey_item: survey_item, likert_score: 1
+ SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
+ survey_item: survey_item, likert_score: 1
end
survey_items_for_subcategory.each do |survey_item|
- SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school, survey_item: survey_item, likert_score: 4
+ SurveyItemResponse.create response_id: rand.to_s, academic_year: ay_2020_21, school: school,
+ survey_item: survey_item, likert_score: 4
end
end
@@ -55,58 +137,25 @@ feature 'School dashboard', type: feature do
expect(page).not_to have_text(school.name)
end
- scenario 'User views a school dashboard' do
- page.driver.browser.basic_authorize(username, password)
+ scenario 'District Admin views a school dashboard', js: true do
+ page.driver.basic_authorize(username, password)
- visit "/districts/#{district.slug}/schools/#{school.slug}/dashboard?year=#{ay_2020_21.range}"
+ visit '/welcome'
+ go_to_school_dashboard_from_welcome_page(district, school)
- expect(page).to have_select('academic-year', selected: '2020 – 2021')
- expect(page).to have_select('district', selected: 'Winchester')
- expect(page).to have_select('school', selected: 'Winchester High School')
-
- expect(page).to have_text(school.name)
-
- expect(page).to have_text('Professional Qualifications')
- professional_qualifications_row = measure_row_bars.find { |item| item['data-for-measure-id'] == '1A-i' }
- expect(professional_qualifications_row['width']).to eq '8.26%'
- expect(professional_qualifications_row['x']).to eq '60%'
-
- expect(page).to have_text('Student Physical Safety')
- student_physical_safety_row = measure_row_bars.find { |item| item['data-for-measure-id'] == '2A-i' }
- expect(student_physical_safety_row['width']).to eq '40.0%'
- expect(student_physical_safety_row['x']).to eq '60%'
-
- expect(page).to have_text('Problem Solving Emphasis')
- problem_solving_emphasis_row = measure_row_bars.find { |item| item['data-for-measure-id'] == '4C-i' }
- expect(problem_solving_emphasis_row['width']).to eq '60.0%'
- expect(problem_solving_emphasis_row['x']).to eq '0.0%'
-
- measure_row_bar_with_no_responses = measure_row_bars.find { |item| item['data-for-measure-id'] == '3A-i' }
-
- # puts measure_with_no_survey_responses.id
- # puts measure_with_no_survey_responses.measure_id
- # survey_item_responses = SurveyItemResponse.for_measure(measure_with_no_survey_responses)
- # responses_count = SurveyItemResponse.count
-
- # expect(responses_count).to eq survey_item_responses.count
- # expect(survey_item_responses.count).to eq 0
- expect(measure_row_bar_with_no_responses['width']).to eq '0.0%'
-
- page.assert_selector('.measure-row-bar', count: Measure.count)
- professional_qualifications_row_index = measure_row_bars.find_index { |item| item['data-for-measure-id'] == '1A-i' }
- student_physical_safety_row_index = measure_row_bars.find_index { |item| item['data-for-measure-id'] == '2A-i' }
- problem_solving_emphasis_row_index = measure_row_bars.find_index { |item| item['data-for-measure-id'] == '4C-i' }
- expect(student_physical_safety_row_index).to be < professional_qualifications_row_index
- expect(professional_qualifications_row_index).to be < problem_solving_emphasis_row_index
+ district_admin_sees_dashboard_content
click_on 'Browse'
-
- expect(page).to have_text('Teachers & Leadership')
- expect(page).to have_text('Approval')
+ district_admin_sees_browse_content
click_on 'School Culture'
-
expect(page).to have_text('This category measures the degree to which the school environment is safe, caring, and academically-oriented.')
+
+ go_to_different_school_in_same_district(school_in_same_district)
+ district_admin_sees_schools_change
+
+ go_to_different_district(different_district)
+ district_admin_sees_district_change
end
scenario 'user sees schools in the same district' do
@@ -120,9 +169,10 @@ feature 'School dashboard', type: feature do
expect(page.all('.school-options[selected]')[0].value).to eq "/districts/#{district.slug}/schools/#{school.slug}/dashboard?year=#{ay_2020_21.range}"
school_options = page.all('.school-options')
- school_options.each_with_index do |school , index|
- break if index == school_options.length-1
- expect(school.text).to be < school_options[index+1].text
+ school_options.each_with_index do |school, index|
+ break if index == school_options.length - 1
+
+ expect(school.text).to be < school_options[index + 1].text
end
visit "/districts/#{district.slug}/schools/#{school.slug}/browse/teachers-and-leadership?year=#{ay_2020_21.range}"
@@ -134,13 +184,14 @@ feature 'School dashboard', type: feature do
expect(page.all('.school-options[selected]')[0].value).to eq "/districts/#{district.slug}/schools/#{school.slug}/browse/teachers-and-leadership?year=#{ay_2020_21.range}"
school_options = page.all('.school-options')
- school_options.each_with_index do |school , index|
- break if index == school_options.length-1
- expect(school.text).to be < school_options[index+1].text
+ school_options.each_with_index do |school, index|
+ break if index == school_options.length - 1
+
+ expect(school.text).to be < school_options[index + 1].text
end
end
- scenario 'user sees all districts in dropdown menu' do
+ scenario 'user sees all districts in dropdown menu' do
page.driver.browser.basic_authorize(username, password)
visit "/districts/#{district.slug}/schools/#{school.slug}/dashboard?year=#{ay_2020_21.range}"
@@ -151,9 +202,10 @@ feature 'School dashboard', type: feature do
expect(page.all('.district-options[selected]')[0].value).to eq "/districts/#{district.slug}/schools/#{district.schools.alphabetic.first.slug}/dashboard?year=#{ay_2020_21.range}"
district_options = page.all('.district-options')
- district_options.each_with_index do |district , index|
- break if index == district_options.length-1
- expect(district.text).to be < district_options[index+1].text
+ district_options.each_with_index do |district, index|
+ break if index == district_options.length - 1
+
+ expect(district.text).to be < district_options[index + 1].text
end
visit "/districts/#{district.slug}/schools/#{school.slug}/browse/teachers-and-leadership?year=#{ay_2020_21.range}"
@@ -165,10 +217,10 @@ feature 'School dashboard', type: feature do
expect(page.all('.district-options[selected]')[0].value).to eq "/districts/#{district.slug}/schools/#{district.schools.alphabetic.first.slug}/browse/teachers-and-leadership?year=#{ay_2020_21.range}"
district_options = page.all('.district-options')
- district_options.each_with_index do |district , index|
- break if index == district_options.length-1
- expect(district.text).to be < district_options[index+1].text
+ district_options.each_with_index do |district, index|
+ break if index == district_options.length - 1
+
+ expect(district.text).to be < district_options[index + 1].text
end
end
-
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index b173bec3..8dc7f1f4 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,4 +1,5 @@
require 'capybara/rspec'
+require 'capybara/apparition'
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
@@ -17,6 +18,9 @@ require 'capybara/rspec'
# users commonly want.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+
+Capybara.javascript_driver = :apparition
+
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
diff --git a/spec/views/home/index.html.erb_spec.rb b/spec/views/home/index.html.erb_spec.rb
new file mode 100644
index 00000000..e7881547
--- /dev/null
+++ b/spec/views/home/index.html.erb_spec.rb
@@ -0,0 +1,17 @@
+require 'rails_helper'
+
+describe 'home/index.html.erb' do
+ subject { Nokogiri::HTML(rendered) }
+
+ before :each do
+ assign :districts, [create(:district), create(:district)]
+ # assign :schools, [create(:school), create(:school), create(:school)]
+
+ render
+ end
+
+ it 'renders a dropdown with districts' do
+ expect(subject.css('#district-dropdown option').count).to eq 2
+ end
+
+end