diff --git a/app/helpers/analyze_helper.rb b/app/helpers/analyze_helper.rb index 9a6968af..5ec40629 100644 --- a/app/helpers/analyze_helper.rb +++ b/app/helpers/analyze_helper.rb @@ -27,20 +27,20 @@ module AnalyzeHelper 1 end - def grouped_chart_width + def grouped_chart_column_width graph_width / data_sources end - def grouped_chart_divider_x(position) - zone_label_width + (grouped_chart_width * position) + def column_end_x(position) + zone_label_width + (grouped_chart_column_width * position) end - def bar_label_height - (100 - ((100 - analyze_graph_height) / 2)) + def column_start_x(position) + column_end_x(position - 1) end - def bar_label_x(position) - zone_label_width + (grouped_chart_width * position) - (grouped_chart_width / 2) + def bar_label_height + (100 - ((100 - analyze_graph_height) / 2)) end def analyze_zone_height @@ -66,4 +66,8 @@ module AnalyzeHelper def analyze_subcategory_link(district:, school:, academic_year:, category:, subcategory:) "/districts/#{district.slug}/schools/#{school.slug}/analyze?year=#{academic_year.range}&category=#{category.category_id}&subcategory=#{subcategory.subcategory_id}" end + + def colors + @colors ||= ['#49416D', '#FFC857', '#920020', '#00B0B3', '#B2D236', '#595959'] + end end diff --git a/app/helpers/color_helper.rb b/app/helpers/color_helper.rb new file mode 100644 index 00000000..8acffe49 --- /dev/null +++ b/app/helpers/color_helper.rb @@ -0,0 +1,2 @@ +module ColorHelper +end diff --git a/app/models/measure.rb b/app/models/measure.rb index 5eb54800..6a0da1b5 100644 --- a/app/models/measure.rb +++ b/app/models/measure.rb @@ -47,7 +47,7 @@ class Measure < ActiveRecord::Base end def score(school:, academic_year:) - @score ||= Hash.new do |memo| + @score ||= Hash.new do |memo, (school, academic_year)| meets_student_threshold = sufficient_student_data?(school:, academic_year:) meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:) meets_admin_data_threshold = all_admin_data_collected?(school:, academic_year:) @@ -73,23 +73,27 @@ class Measure < ActiveRecord::Base end def student_score(school:, academic_year:) - @student_score ||= begin + @student_score ||= Hash.new do |memo, (school, academic_year)| meets_student_threshold = sufficient_student_data?(school:, academic_year:) meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:) meets_admin_data_threshold = all_admin_data_collected?(school:, academic_year:) average = collect_survey_scale_average(student_scales, school, academic_year) if meets_student_threshold - Score.new(average, meets_teacher_threshold, meets_student_threshold, meets_admin_data_threshold) + memo[[school, academic_year]] = Score.new(average, meets_teacher_threshold, meets_student_threshold, meets_admin_data_threshold) end + + @student_score[[school, academic_year]] end def teacher_score(school:, academic_year:) - @teacher_score ||= begin + @teacher_score ||= Hash.new do |memo, (school, academic_year)| meets_student_threshold = sufficient_student_data?(school:, academic_year:) meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:) meets_admin_data_threshold = all_admin_data_collected?(school:, academic_year:) average = collect_survey_scale_average(teacher_scales, school, academic_year) if meets_teacher_threshold - Score.new(average, meets_teacher_threshold, meets_student_threshold, meets_admin_data_threshold) + memo[[school, academic_year]] = Score.new(average, meets_teacher_threshold, meets_student_threshold, meets_admin_data_threshold) end + + @teacher_score[[school, academic_year]] end def warning_low_benchmark diff --git a/app/models/scale.rb b/app/models/scale.rb index 98a2d596..7a6415d3 100644 --- a/app/models/scale.rb +++ b/app/models/scale.rb @@ -5,7 +5,7 @@ class Scale < ApplicationRecord has_many :admin_data_items def score(school:, academic_year:) - @score ||= Hash.new do |memo| + @score ||= Hash.new do |memo, (school, academic_year)| memo[[school, academic_year]] = begin items = [] items << collect_survey_item_average(student_survey_items(school:, academic_year:), school, academic_year) diff --git a/app/models/subcategory.rb b/app/models/subcategory.rb index 975e9607..0fcb44d0 100644 --- a/app/models/subcategory.rb +++ b/app/models/subcategory.rb @@ -12,7 +12,7 @@ class Subcategory < ActiveRecord::Base end def student_response_rate(school:, academic_year:) - @student_response_rate ||= Hash.new do |memo| + @student_response_rate ||= Hash.new do |memo, (school, academic_year)| memo[[school, academic_year]] = StudentResponseRate.new(subcategory: self, school:, academic_year:) end @@ -20,7 +20,7 @@ class Subcategory < ActiveRecord::Base end def teacher_response_rate(school:, academic_year:) - @teacher_response_rate ||= Hash.new do |memo| + @teacher_response_rate ||= Hash.new do |memo, (school, academic_year)| memo[[school, academic_year]] = TeacherResponseRate.new(subcategory: self, school:, academic_year:) end diff --git a/app/models/survey_item.rb b/app/models/survey_item.rb index 243b83ce..944d35a9 100644 --- a/app/models/survey_item.rb +++ b/app/models/survey_item.rb @@ -6,11 +6,10 @@ class SurveyItem < ActiveRecord::Base has_many :survey_item_responses def score(school:, academic_year:) - @score ||= Hash.new do |memo| - memo[[school, academic_year]] = survey_item_responses.where(school:, - academic_year:).exclude_boston.average(:likert_score).to_f + @score ||= Hash.new do |memo, (school, academic_year)| + memo[[school, academic_year]] = + survey_item_responses.exclude_boston.where(school:, academic_year:).average(:likert_score).to_f end - @score[[school, academic_year]] end diff --git a/app/presenters/analyze_bar_presenter.rb b/app/presenters/analyze_bar_presenter.rb new file mode 100644 index 00000000..aeef2908 --- /dev/null +++ b/app/presenters/analyze_bar_presenter.rb @@ -0,0 +1,63 @@ +class AnalyzeBarPresenter + include AnalyzeHelper + attr_reader :score, :x_position, :academic_year, :measure_id, :measure, :color + + def initialize(measure:, academic_year:, score:, x_position:, color:) + @score = score + @x_position = x_position + @academic_year = academic_year + @measure = measure + @measure_id = measure.measure_id + @color = color + end + + def y_offset + case zone.type + when :ideal, :approval + (analyze_zone_height * 2) - bar_height_percentage + else + (analyze_zone_height * 2) + end + end + + def bar_color + "fill-#{zone.type}" + end + + def bar_height_percentage + case zone.type + when :ideal + (percentage * zone_height_percentage + zone_height_percentage) * 100 + when :approval + (percentage * zone_height_percentage) * 100 + when :growth + ((1 - percentage) * zone_height_percentage) * 100 + when :watch + ((1 - percentage) * zone_height_percentage + zone_height_percentage) * 100 + when :warning + ((1 - percentage) * zone_height_percentage + zone_height_percentage + zone_height_percentage) * 100 + else + 0.0 + end + end + + def percentage + (score.average - zone.low_benchmark) / (zone.high_benchmark - zone.low_benchmark) + end + + def zone + zones = Zones.new( + watch_low_benchmark: measure.watch_low_benchmark, + growth_low_benchmark: measure.growth_low_benchmark, + approval_low_benchmark: measure.approval_low_benchmark, + ideal_low_benchmark: measure.ideal_low_benchmark + ) + zones.zone_for_score(score.average) + end + + def average + return 0 if score.average.nil? + + score.average.round(2) + end +end diff --git a/app/presenters/grouped_bar_column_presenter.rb b/app/presenters/grouped_bar_column_presenter.rb index d3e94346..e75795b8 100644 --- a/app/presenters/grouped_bar_column_presenter.rb +++ b/app/presenters/grouped_bar_column_presenter.rb @@ -1,78 +1,102 @@ class GroupedBarColumnPresenter include AnalyzeHelper - attr_reader :score, :measure_name, :measure_id, :category, :position, :measure, :school, :academic_year + include ColorHelper - def initialize(measure:, school:, academic_year:, position:) + attr_reader :measure_name, :measure_id, :category, :position, :measure, :school, :academic_years + + def initialize(measure:, school:, academic_years:, position:) @measure = measure @measure_name = @measure.name @measure_id = @measure.measure_id @category = @measure.subcategory.category @school = school - @academic_year = academic_year + @academic_years = academic_years @position = position end - def score - measure.score(school:, academic_year:) + def score(year_index) + measure.score(school:, academic_year: academic_years[year_index]) end - def y_offset - case zone.type - when :ideal, :approval - (analyze_zone_height * 2) - bar_height_percentage - else - (analyze_zone_height * 2) + def bars + @bars ||= yearly_scores.map.each_with_index do |item, index| + year = item[0] + score = item[1] + AnalyzeBarPresenter.new(measure:, academic_year: year, score:, x_position: bar_x(index), + color: bar_color(year)) end end - def bar_color - "fill-#{zone.type}" - end - - def bar_height_percentage - case zone.type - when :ideal - (percentage * zone_height_percentage + zone_height_percentage) * 100 - when :approval - (percentage * zone_height_percentage) * 100 - when :growth - ((1 - percentage) * zone_height_percentage) * 100 - when :watch - ((1 - percentage) * zone_height_percentage + zone_height_percentage) * 100 - when :warning - ((1 - percentage) * zone_height_percentage + zone_height_percentage + zone_height_percentage) * 100 - else - 0.0 + def label + 'All Survey Data' + end + + def basis + '' + end + + def show_irrelevancy_message? + !measure.includes_teacher_survey_items? && !measure.includes_student_survey_items? + end + + def show_insufficient_data_message? + scores = academic_years.map do |year| + measure.score(school:, academic_year: year) end + + scores.all? { |score| !score.meets_teacher_threshold? && !score.meets_student_threshold? } end - def percentage - (score.average - zone.low_benchmark) / (zone.high_benchmark - zone.low_benchmark) + def column_midpoint + zone_label_width + (grouped_chart_column_width * (position + 1)) - (grouped_chart_column_width / 2) end - def zone - zones = Zones.new( - watch_low_benchmark: @measure.watch_low_benchmark, - growth_low_benchmark: @measure.growth_low_benchmark, - approval_low_benchmark: @measure.approval_low_benchmark, - ideal_low_benchmark: @measure.ideal_low_benchmark - ) - zones.zone_for_score(score.average) + def bar_width + 3.5 end - def label - 'All Survey Data' + def message_x + column_midpoint - message_width / 2 end - def basis - '' + def message_y + 17 end - def show_irrelevancy_message? - !@measure.includes_teacher_survey_items? && !@measure.includes_student_survey_items? + def message_width + 20 end - def show_insufficient_data_message? - !score.meets_teacher_threshold? && !score.meets_student_threshold? + def message_height + 34 + end + + def column_end_x + zone_label_width + (grouped_chart_column_width * (position + 1)) + end + + def column_start_x + zone_label_width + (grouped_chart_column_width * position) + end + + private + + def yearly_scores + yearly_scores = academic_years.each_with_index.map do |year, index| + [year, score(index)] + end + yearly_scores.reject do |yearly_score| + score = yearly_score[1] + score.average.nil? || score.average.zero? || score.average.nan? + end + end + + def bar_color(year) + @available_academic_years ||= AcademicYear.order(:range).all + colors[@available_academic_years.find_index(year)] + end + + def bar_x(index) + column_start_x + (index * bar_width * 1.2) + ((column_end_x - column_start_x) - (yearly_scores.size * bar_width * 1.2)) / 2 end end diff --git a/app/presenters/student_grouped_bar_column_presenter.rb b/app/presenters/student_grouped_bar_column_presenter.rb index edf3267e..1d4f3a94 100644 --- a/app/presenters/student_grouped_bar_column_presenter.rb +++ b/app/presenters/student_grouped_bar_column_presenter.rb @@ -8,14 +8,18 @@ class StudentGroupedBarColumnPresenter < GroupedBarColumnPresenter end def show_irrelevancy_message? - !@measure.includes_student_survey_items? + !measure.includes_student_survey_items? end def show_insufficient_data_message? - !score.meets_student_threshold? + scores = academic_years.map do |year| + measure.score(school:, academic_year: year) + end + + scores.all? { |score| !score.meets_student_threshold? } end - def score - measure.student_score(school:, academic_year:) + def score(year_index) + measure.student_score(school:, academic_year: academic_years[year_index]) end end diff --git a/app/presenters/teacher_grouped_bar_column_presenter.rb b/app/presenters/teacher_grouped_bar_column_presenter.rb index c43883f4..85f1f40b 100644 --- a/app/presenters/teacher_grouped_bar_column_presenter.rb +++ b/app/presenters/teacher_grouped_bar_column_presenter.rb @@ -8,14 +8,18 @@ class TeacherGroupedBarColumnPresenter < GroupedBarColumnPresenter end def show_irrelevancy_message? - !@measure.includes_teacher_survey_items? + !measure.includes_teacher_survey_items? end def show_insufficient_data_message? - !score.meets_teacher_threshold? + scores = academic_years.map do |year| + measure.score(school:, academic_year: year) + end + + scores.all? { |score| !score.meets_teacher_threshold? } end - def score - measure.teacher_score(school:, academic_year:) + def score(year_index) + measure.teacher_score(school:, academic_year: academic_years[year_index]) end end diff --git a/app/views/analyze/_grouped_bar_chart.html.erb b/app/views/analyze/_grouped_bar_chart.html.erb index 79643a86..acfe5e10 100644 --- a/app/views/analyze/_grouped_bar_chart.html.erb +++ b/app/views/analyze/_grouped_bar_chart.html.erb @@ -3,8 +3,8 @@ - - + + @@ -31,11 +31,10 @@ -<% presenter = StudentGroupedBarColumnPresenter.new(measure: measure, school: @school, academic_year: @academic_year, position: 1) %> - <%= render partial: "grouped_bar_column", locals: {presenter: presenter} %> -<% presenter = TeacherGroupedBarColumnPresenter.new(measure: measure, school: @school, academic_year: @academic_year, position: 2) %> - <%= render partial: "grouped_bar_column", locals: {presenter: presenter} %> -<% presenter = GroupedBarColumnPresenter.new(measure: measure, school: @school, academic_year: @academic_year, position: 3) %> - <%= render partial: "grouped_bar_column", locals: {presenter: presenter} %> + <% presenters = [StudentGroupedBarColumnPresenter, TeacherGroupedBarColumnPresenter, GroupedBarColumnPresenter] %> + <% presenters.each_with_index do |presenter, index| %> + <% p = presenter.new(measure: measure, school: @school, academic_years: @selected_academic_years, position: index ) %> + <%= render partial: "grouped_bar_column", locals: {presenter: p} %> + <% end %> diff --git a/app/views/analyze/_grouped_bar_column.html.erb b/app/views/analyze/_grouped_bar_column.html.erb index 4b3666e9..63d0f00e 100644 --- a/app/views/analyze/_grouped_bar_column.html.erb +++ b/app/views/analyze/_grouped_bar_column.html.erb @@ -1,30 +1,33 @@ - - + + <% presenter.bars.each_with_index do |bar, index| %> + - <% if ENV["SCORES"].present? && ENV["SCORES"].upcase == "SHOW" %> - - <%= presenter.score.average %> - + <% if ENV["SCORES"].present? && ENV["SCORES"].upcase == "SHOW" %> + + <%= bar.average %> + + <% end %> <% end %> - + + <%= presenter.label %> <% if presenter.show_irrelevancy_message? %> - + - - measure not - based on - <%= presenter.basis %> surveys + + measure not + based on + <%= presenter.basis %> surveys <% elsif presenter.show_insufficient_data_message? %> - + - - survey response - rate below 25% + + survey response + rate below 25% <% end %> diff --git a/app/views/analyze/index.html.erb b/app/views/analyze/index.html.erb index 1581fdcf..4a408894 100644 --- a/app/views/analyze/index.html.erb +++ b/app/views/analyze/index.html.erb @@ -25,11 +25,11 @@

School Years

- <% @available_academic_years.each do | year | %> + <% @available_academic_years.each_with_index do | year, index | %>
data-action="click->analyze#refresh">
-
+
<% end %> diff --git a/spec/presenters/grouped_bar_column_presenter_spec.rb b/spec/presenters/grouped_bar_column_presenter_spec.rb index de690588..23d02572 100644 --- a/spec/presenters/grouped_bar_column_presenter_spec.rb +++ b/spec/presenters/grouped_bar_column_presenter_spec.rb @@ -1,8 +1,12 @@ require 'rails_helper' +include AnalyzeHelper describe GroupedBarColumnPresenter do let(:school) { create(:school) } - let(:academic_year) { create(:academic_year) } + let(:academic_year) { create(:academic_year, range: '1900-01') } + let(:another_academic_year) { create(:academic_year, range: '2000-01') } + let(:academic_years) { [academic_year, another_academic_year] } + let(:year_index) { academic_years.find_index(academic_year) } let(:watch_low_benchmark) { 2 } let(:growth_low_benchmark) { 3 } let(:approval_low_benchmark) { 4 } @@ -58,18 +62,18 @@ describe GroupedBarColumnPresenter do end let(:student_presenter) do - StudentGroupedBarColumnPresenter.new measure: measure_with_student_survey_items, school:, academic_year:, - position: 1 + StudentGroupedBarColumnPresenter.new measure: measure_with_student_survey_items, school:, academic_years:, + position: 0 end let(:teacher_presenter) do - TeacherGroupedBarColumnPresenter.new measure: measure_with_teacher_survey_items, school:, academic_year:, - position: 1 + TeacherGroupedBarColumnPresenter.new measure: measure_with_teacher_survey_items, school:, academic_years:, + position: 0 end let(:all_data_presenter) do - GroupedBarColumnPresenter.new measure: measure_composed_of_student_and_teacher_items, school:, academic_year:, - position: 1 + GroupedBarColumnPresenter.new measure: measure_composed_of_student_and_teacher_items, school:, academic_years:, + position: 0 end before do @@ -83,132 +87,198 @@ describe GroupedBarColumnPresenter do end end - context 'when a measure is based on student survey items' do - context 'when the score is in the Ideal zone' do + shared_examples_for 'column_midpoint' do + it 'return an x position centered in the width of the column' do + expect(student_presenter.column_midpoint).to eq 29 + end + end + + shared_examples_for 'bar_color' do + it 'returns the correct color' do + expect(student_presenter.bars[year_index].color).to eq colors[year_index] + end + end + + shared_examples_for 'y_offset' do + it 'bar will be based on the approval low benchmark boundary' do + expect(student_presenter.bars[year_index].y_offset).to be_within(0.01).of(34) + end + end + + context 'for a grouped column presenter with both student and teacher responses' do + context 'with a single year' + before do + create(:survey_item_response, survey_item: student_survey_item_for_composite_measure, school:, + academic_year:, likert_score: 4) + create(:survey_item_response, survey_item: student_survey_item_for_composite_measure, school:, + academic_year:, likert_score: 5) + end + + it 'returns a score that is an average of the likert scores ' do + expect(all_data_presenter.score(0).average).to eq 4.5 + expect(all_data_presenter.score(1).average).to eq nil + expect(all_data_presenter.academic_years[0].range).to be academic_year.range + expect(all_data_presenter.academic_years[1].range).to be another_academic_year.range + end + context 'when more than one year exists' do before do - create(:survey_item_response, survey_item: student_survey_item, school:, - academic_year:, likert_score: 5) - create(:survey_item_response, survey_item: student_survey_item, school:, - academic_year:, likert_score: 4) + create(:survey_item_response, survey_item: student_survey_item_for_composite_measure, school:, + academic_year: another_academic_year, likert_score: 5) + create(:survey_item_response, survey_item: student_survey_item_for_composite_measure, school:, + academic_year: another_academic_year, likert_score: 3) + end + it 'returns independent scores for each year of data' do + expect(all_data_presenter.score(0).average).to eq 4.5 + expect(all_data_presenter.score(1).average).to eq 4 end + end + end + context 'when a measure is based on student survey items' do + before do + year_index = academic_years.find_index(academic_year) + end + + context 'when there is insufficient data to show a score' do it_behaves_like 'measure_name' + it_behaves_like 'column_midpoint' - it 'returns the correct color' do - expect(student_presenter.bar_color).to eq 'fill-ideal' + it 'returns an emtpy set of bars' do + expect(student_presenter.bars).to eq [] end - it 'returns a bar width equal to the approval zone width plus the proportionate ideal zone width' do - expect(student_presenter.bar_height_percentage).to be_within(0.01).of(17) + it 'returns an emty score' do + expect(student_presenter.score(year_index).average).to eq nil end - it 'returns a y_offset equal to the ' do - expect(student_presenter.y_offset).to be_within(0.01).of(17) + it 'shows the irrelevancy message ' do + expect(student_presenter.show_irrelevancy_message?).to eq true + end + + it 'shows the insufficient data message' do + expect(student_presenter.show_insufficient_data_message?).to eq true end end - context 'when the score is in the Approval zone' do + context 'when the score is in the Ideal zone' do before do + create(:survey_item_response, survey_item: student_survey_item, school:, + academic_year:, likert_score: 5) create(:survey_item_response, survey_item: student_survey_item, school:, academic_year:, likert_score: 4) end it_behaves_like 'measure_name' + it_behaves_like 'column_midpoint' + it_behaves_like 'bar_color' - it 'returns the correct color' do - expect(student_presenter.bar_color).to eq 'fill-approval' + it 'returns a bar width equal to the approval zone width plus the proportionate ideal zone width' do + expect(student_presenter.bars[year_index].bar_height_percentage).to be_within(0.01).of(17) end - it 'returns a bar width equal to the proportionate approval zone width' do - expect(student_presenter.bar_height_percentage).to be_within(0.01).of(0) + it 'returns a y_offset equal to the ' do + expect(student_presenter.bars[0].y_offset).to be_within(0.01).of(17) end - it 'returns an x-offset of 60%' do - expect(student_presenter.y_offset).to be_within(0.01).of(34) + it 'returns a text representation of the type of survey the bars are based on' do + expect(student_presenter.basis).to eq 'student' end - end - context 'when the score is in the Growth zone' do - before do - create(:survey_item_response, survey_item: student_survey_item, school:, - academic_year:, likert_score: 3) + it 'returns only bars that have a numeric score' do + expect(student_presenter.bars.count).to be 1 end - it_behaves_like 'measure_name' + it 'returns an explanatory bar label' do + expect(student_presenter.label).to eq 'All Students' + end - it 'returns the correct color' do - expect(student_presenter.bar_color).to eq 'fill-growth' + it 'does not show a message that the data source is irrelevant for this measure' do + expect(student_presenter.show_irrelevancy_message?).to be false end - it 'returns a bar width equal to the proportionate growth zone width' do - expect(student_presenter.bar_height_percentage).to be_within(0.01).of(17) + it 'does not show a message about insufficient responses' do + expect(student_presenter.show_insufficient_data_message?).to be false end - context 'in order to achieve the visual effect' do - it 'returns an x-offset equal to 60% minus the bar width' do - expect(student_presenter.y_offset).to eq 34 + context 'when there is more than one years worth of data to show' do + before do + create(:survey_item_response, survey_item: student_survey_item, school:, + academic_year: another_academic_year, likert_score: 3) + create(:survey_item_response, survey_item: student_survey_item, school:, + academic_year: another_academic_year, likert_score: 4) + end + + it 'returns only bars that have a numeric score' do + expect(student_presenter.bars.count).to be 2 end end end - context 'when the score is in the Watch zone' do + context 'when the score is in the Approval zone' do before do create(:survey_item_response, survey_item: student_survey_item, school:, - academic_year:, likert_score: 2) + academic_year:, likert_score: 4) end it_behaves_like 'measure_name' + it_behaves_like 'column_midpoint' + it_behaves_like 'bar_color' + it_behaves_like 'y_offset' - it 'returns the correct color' do - expect(student_presenter.bar_color).to eq 'fill-watch' - end - - it 'returns a bar width equal to the proportionate watch zone width plus the growth zone width' do - expect(student_presenter.bar_height_percentage).to eq 34 - end + context 'and the score is right at the approval low benchmark' do + it 'bar will have a height of 0' do + expect(student_presenter.bars[year_index].bar_height_percentage).to be_within(0.01).of(0) + end - context 'in order to achieve the visual effect' do - it 'returns an x-offset equal to 60% minus the bar width' do - expect(student_presenter.y_offset).to eq 34 + it 'bar will be based on the approval low benchmark boundary' do + expect(student_presenter.bars[year_index].y_offset).to be_within(0.01).of(34) end end end - - context 'when the score is in the Warning zone' do + context 'when the score is in the Growth zone' do before do create(:survey_item_response, survey_item: student_survey_item, school:, - academic_year:, likert_score: 1) + academic_year:, likert_score: 3) end it_behaves_like 'measure_name' + it_behaves_like 'column_midpoint' + it_behaves_like 'bar_color' + it_behaves_like 'y_offset' - it 'returns the correct color' do - expect(student_presenter.bar_color).to eq 'fill-warning' + it 'returns a bar width equal to the proportionate growth zone width' do + expect(student_presenter.bars[year_index].bar_height_percentage).to be_within(0.01).of(17) end + end - it 'returns a bar width equal to the proportionate warning zone width plus the watch & growth zone widths' do - expect(student_presenter.bar_height_percentage).to eq 51 + context 'when the score is in the Watch zone' do + before do + create(:survey_item_response, survey_item: student_survey_item, school:, + academic_year:, likert_score: 2) end - context 'in order to achieve the visual effect' do - it 'returns an y-offset equal to 60% minus the bar width' do - expect(student_presenter.y_offset).to eq 34 - end - end - end + it_behaves_like 'measure_name' + it_behaves_like 'column_midpoint' + it_behaves_like 'bar_color' + it_behaves_like 'y_offset' - context 'when there are insufficient responses to calculate a score' do - it 'indicates it should show the insufficient data message' do - expect(student_presenter.show_insufficient_data_message?).to eq true + it 'returns a bar width equal to the proportionate watch zone width plus the growth zone width' do + expect(student_presenter.bars[year_index].bar_height_percentage).to eq 34 end end - context 'when there are enough responses to calculate a score' do + context 'when the score is in the Warning zone' do before do create(:survey_item_response, survey_item: student_survey_item, school:, - academic_year:) + academic_year:, likert_score: 1) end - it 'indicates it should show the insufficient data message' do - expect(student_presenter.show_insufficient_data_message?).to eq false + + it_behaves_like 'measure_name' + it_behaves_like 'column_midpoint' + it_behaves_like 'bar_color' + it_behaves_like 'y_offset' + + it 'returns a bar width equal to the proportionate warning zone width plus the watch & growth zone widths' do + expect(student_presenter.bars[year_index].bar_height_percentage).to eq 51 end end end diff --git a/spec/views/analyze/index.html.erb_spec.rb b/spec/views/analyze/index.html.erb_spec.rb index 6d5a1902..8b37c00c 100644 --- a/spec/views/analyze/index.html.erb_spec.rb +++ b/spec/views/analyze/index.html.erb_spec.rb @@ -78,10 +78,15 @@ describe 'analyze/index' do # end it 'displays a set of grouped bars for each presenter' do + displayed_variance_columns = subject.css('.grouped-bar-column') + expect(displayed_variance_columns.count).to eq 9 + displayed_variance_rows = subject.css('[data-for-measure-id]') - expect(displayed_variance_rows.count).to eq 9 expect(displayed_variance_rows.first.attribute('data-for-measure-id').value).to eq '1A-I' + # displayed_variance_rows = subject.css('data-for-academic-year') + # expect(displayed_variance_rows.count).to eq 9 + displayed_variance_labels = subject.css('[data-grouped-bar-label]') expect(displayed_variance_labels.count).to eq 9 expect(displayed_variance_labels.first.inner_text).to include 'All Students'