parent
5d6c1000f4
commit
25578a896f
@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
trim_trailing_whitespace = true
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
class BrowseController < ApplicationController
|
||||||
|
def show
|
||||||
|
@category = CategoryPresenter.new(
|
||||||
|
category: SqmCategory.find_by_name('Teachers & Leadership'),
|
||||||
|
academic_year: academic_year,
|
||||||
|
school: school,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def school
|
||||||
|
@school ||= School.find_by_slug school_slug
|
||||||
|
end
|
||||||
|
|
||||||
|
def school_slug
|
||||||
|
params[:school_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def academic_year
|
||||||
|
@academic_year ||= AcademicYear.find_by_range params[:year]
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,44 +1,6 @@
|
|||||||
class Measure < ActiveRecord::Base
|
class Measure < ActiveRecord::Base
|
||||||
belongs_to :subcategory
|
belongs_to :subcategory
|
||||||
|
has_many :survey_items
|
||||||
|
|
||||||
Zone = Struct.new(:low_benchmark, :high_benchmark, :type) do
|
has_many :survey_item_responses, through: :survey_items
|
||||||
def includes_score?(score)
|
|
||||||
score > low_benchmark and score < high_benchmark
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def warning_zone
|
|
||||||
Zone.new(1, watch_low_benchmark, :warning)
|
|
||||||
end
|
|
||||||
|
|
||||||
def watch_zone
|
|
||||||
Zone.new(watch_low_benchmark, growth_low_benchmark, :watch)
|
|
||||||
end
|
|
||||||
|
|
||||||
def growth_zone
|
|
||||||
Zone.new(growth_low_benchmark, approval_low_benchmark, :growth)
|
|
||||||
end
|
|
||||||
|
|
||||||
def approval_zone
|
|
||||||
Zone.new(approval_low_benchmark, ideal_low_benchmark, :approval)
|
|
||||||
end
|
|
||||||
|
|
||||||
def ideal_zone
|
|
||||||
Zone.new(ideal_low_benchmark, 5.0, :ideal)
|
|
||||||
end
|
|
||||||
|
|
||||||
def zone_for_score(score)
|
|
||||||
case score
|
|
||||||
when ideal_zone.low_benchmark..ideal_zone.high_benchmark
|
|
||||||
ideal_zone
|
|
||||||
when approval_zone.low_benchmark..approval_zone.high_benchmark
|
|
||||||
approval_zone
|
|
||||||
when growth_zone.low_benchmark..growth_zone.high_benchmark
|
|
||||||
growth_zone
|
|
||||||
when watch_zone.low_benchmark..watch_zone.high_benchmark
|
|
||||||
watch_zone
|
|
||||||
else
|
|
||||||
warning_zone
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
class SqmCategory < ActiveRecord::Base
|
class SqmCategory < ActiveRecord::Base
|
||||||
|
has_many :subcategories
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
class Subcategory < ActiveRecord::Base
|
class Subcategory < ActiveRecord::Base
|
||||||
belongs_to :sqm_category
|
belongs_to :sqm_category
|
||||||
|
|
||||||
|
has_many :measures
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
class SurveyItem < ActiveRecord::Base
|
class SurveyItem < ActiveRecord::Base
|
||||||
belongs_to :measure
|
belongs_to :measure
|
||||||
|
has_many :survey_item_responses
|
||||||
end
|
end
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
class CategoryPresenter
|
||||||
|
def initialize(category:, academic_year:, school:)
|
||||||
|
@category = category
|
||||||
|
@academic_year = academic_year
|
||||||
|
@school = school
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
@category.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def subcategories
|
||||||
|
@category.subcategories.map do |subcategory|
|
||||||
|
SubcategoryPresenter.new(
|
||||||
|
subcategory: subcategory,
|
||||||
|
academic_year: @academic_year,
|
||||||
|
school: @school,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
class GaugePresenter
|
||||||
|
def initialize(scale:, score:)
|
||||||
|
@scale = scale
|
||||||
|
@score = score
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
zone.type.to_s.capitalize
|
||||||
|
end
|
||||||
|
|
||||||
|
def color_class
|
||||||
|
"fill-#{zone.type}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def score_percentage
|
||||||
|
percentage_for @score
|
||||||
|
end
|
||||||
|
|
||||||
|
def key_benchmark_percentage
|
||||||
|
percentage_for @scale.approval_zone.low_benchmark
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def zone
|
||||||
|
@scale.zone_for_score(@score)
|
||||||
|
end
|
||||||
|
|
||||||
|
def percentage_for(number)
|
||||||
|
scale_minimum = @scale.warning_zone.low_benchmark
|
||||||
|
scale_maximum = @scale.ideal_zone.high_benchmark
|
||||||
|
(number - scale_minimum) / (scale_maximum - scale_minimum)
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
class Scale
|
||||||
|
def initialize(watch_low_benchmark:, growth_low_benchmark:, approval_low_benchmark:, ideal_low_benchmark:)
|
||||||
|
@watch_low_benchmark = watch_low_benchmark
|
||||||
|
@growth_low_benchmark = growth_low_benchmark
|
||||||
|
@approval_low_benchmark = approval_low_benchmark
|
||||||
|
@ideal_low_benchmark = ideal_low_benchmark
|
||||||
|
end
|
||||||
|
|
||||||
|
Zone = Struct.new(:low_benchmark, :high_benchmark, :type)
|
||||||
|
|
||||||
|
def warning_zone
|
||||||
|
Zone.new(1, @watch_low_benchmark, :warning)
|
||||||
|
end
|
||||||
|
|
||||||
|
def watch_zone
|
||||||
|
Zone.new(@watch_low_benchmark, @growth_low_benchmark, :watch)
|
||||||
|
end
|
||||||
|
|
||||||
|
def growth_zone
|
||||||
|
Zone.new(@growth_low_benchmark, @approval_low_benchmark, :growth)
|
||||||
|
end
|
||||||
|
|
||||||
|
def approval_zone
|
||||||
|
Zone.new(@approval_low_benchmark, @ideal_low_benchmark, :approval)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ideal_zone
|
||||||
|
Zone.new(@ideal_low_benchmark, 5.0, :ideal)
|
||||||
|
end
|
||||||
|
|
||||||
|
def zone_for_score(score)
|
||||||
|
case score
|
||||||
|
when ideal_zone.low_benchmark..ideal_zone.high_benchmark
|
||||||
|
ideal_zone
|
||||||
|
when approval_zone.low_benchmark..approval_zone.high_benchmark
|
||||||
|
approval_zone
|
||||||
|
when growth_zone.low_benchmark..growth_zone.high_benchmark
|
||||||
|
growth_zone
|
||||||
|
when watch_zone.low_benchmark..watch_zone.high_benchmark
|
||||||
|
watch_zone
|
||||||
|
else
|
||||||
|
warning_zone
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
class SubcategoryPresenter
|
||||||
|
def initialize(subcategory:, academic_year:, school:)
|
||||||
|
@subcategory = subcategory
|
||||||
|
@academic_year = academic_year
|
||||||
|
@school = school
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
@subcategory.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def gauge_presenter
|
||||||
|
average_score = SurveyItemResponse.for_measures(measures)
|
||||||
|
.where(academic_year: @academic_year, school: @school)
|
||||||
|
.average(:likert_score)
|
||||||
|
|
||||||
|
GaugePresenter.new(scale: scale, score: average_score)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def scale
|
||||||
|
Scale.new(
|
||||||
|
watch_low_benchmark: measures.map(&:watch_low_benchmark).average,
|
||||||
|
growth_low_benchmark: measures.map(&:growth_low_benchmark).average,
|
||||||
|
approval_low_benchmark: measures.map(&:approval_low_benchmark).average,
|
||||||
|
ideal_low_benchmark: measures.map(&:ideal_low_benchmark).average,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def measures
|
||||||
|
@measures ||= @subcategory.measures
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
<% outer_radius = 100 %>
|
||||||
|
<% inner_radius = 50 %>
|
||||||
|
<% stroke_width = 1 %>
|
||||||
|
<% key_benchmark_indicator_height = 10 %>
|
||||||
|
<% scale = -Math::PI %>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
viewBox="<%= -(outer_radius + stroke_width) %> <%= -(outer_radius + stroke_width) %> <%= 2*(outer_radius + stroke_width) %> <%= outer_radius + 2*stroke_width + key_benchmark_indicator_height %>"
|
||||||
|
width="400"
|
||||||
|
height="200"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
class="gauge-fill <%= gauge.color_class %>"
|
||||||
|
d="M <%= -outer_radius %> <%= key_benchmark_indicator_height %>
|
||||||
|
A <%= outer_radius %> <%= outer_radius %> 0 0 1 <%= outer_radius * Math.cos((1 - gauge.score_percentage) * scale) %> <%= outer_radius * Math.sin((1 - gauge.score_percentage) * scale) + key_benchmark_indicator_height %>
|
||||||
|
L <%= inner_radius * Math.cos((1 - gauge.score_percentage) * scale) %> <%= inner_radius * Math.sin((1 - gauge.score_percentage) * scale) + key_benchmark_indicator_height %>
|
||||||
|
A <%= inner_radius %> <%= inner_radius %> 0 0 0 <%= -inner_radius %> <%= key_benchmark_indicator_height %>
|
||||||
|
L <%= -outer_radius %> <%= key_benchmark_indicator_height %>"
|
||||||
|
fill="none"
|
||||||
|
stroke="none"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<text
|
||||||
|
class="gauge-title font-bitter fill-black"
|
||||||
|
x="0"
|
||||||
|
y="<% -10 + key_benchmark_indicator_height %>"
|
||||||
|
text-anchor="middle"
|
||||||
|
dominant-baseline="middle"
|
||||||
|
>
|
||||||
|
<%= gauge.title %>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<path
|
||||||
|
class="gauge-outline stroke-gray-2"
|
||||||
|
d="M <%= -outer_radius %> <%= key_benchmark_indicator_height %>
|
||||||
|
A <%= outer_radius %> <%= outer_radius %> 0 0 1 <%= outer_radius * Math.cos(0) %> <%= outer_radius * Math.sin(0) + key_benchmark_indicator_height %>
|
||||||
|
L <%= inner_radius * Math.cos(0) %> <%= inner_radius * Math.sin(0) + key_benchmark_indicator_height %>
|
||||||
|
A <%= inner_radius %> <%= inner_radius %> 0 0 0 <%= -inner_radius %> <%= key_benchmark_indicator_height %>
|
||||||
|
L <%= -outer_radius %> <%= key_benchmark_indicator_height %>"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="<%= stroke_width %>"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<line
|
||||||
|
class="zone-benchmark stroke-gray-2"
|
||||||
|
x1="<%= outer_radius * Math.cos((1 - gauge.key_benchmark_percentage) * scale) %>" y1="<%= outer_radius * Math.sin((1 - gauge.key_benchmark_percentage) * scale) + key_benchmark_indicator_height %>"
|
||||||
|
x2="<%= inner_radius * Math.cos((1 - gauge.key_benchmark_percentage) * scale) %>" y2="<%= inner_radius * Math.sin((1 - gauge.key_benchmark_percentage) * scale) + key_benchmark_indicator_height %>"
|
||||||
|
stroke-width="<%= stroke_width %>"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<path
|
||||||
|
class="key-benchmark-indicator fill-black"
|
||||||
|
d="M 0 <%= -(outer_radius - key_benchmark_indicator_height + 2) %>
|
||||||
|
L <%= key_benchmark_indicator_height/Math.sqrt(3) %> <%= -outer_radius %>
|
||||||
|
L <%= -key_benchmark_indicator_height/Math.sqrt(3) %> <%= -outer_radius %>
|
||||||
|
L 0 <%= -(outer_radius - key_benchmark_indicator_height + 2) %>"
|
||||||
|
transform="rotate(<%= 180.0 * gauge.key_benchmark_percentage - 90 %> 0 <%= key_benchmark_indicator_height %>)"
|
||||||
|
stroke="none"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<h1><%= @category.name %></h1>
|
||||||
|
|
||||||
|
<% @category.subcategories.each do |subcategory| %>
|
||||||
|
<h2><%= subcategory.name %></h2>
|
||||||
|
<%= render partial: "gauge_graph", locals: { gauge: subcategory.gauge_presenter } %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :sqm_category do
|
||||||
|
name { "A category" }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :subcategory do
|
||||||
|
name { "A subcategory" }
|
||||||
|
sqm_category
|
||||||
|
|
||||||
|
factory :subcategory_with_measures do
|
||||||
|
transient do
|
||||||
|
measures_count { 2 }
|
||||||
|
end
|
||||||
|
after(:create) do |subcategory, evaluator|
|
||||||
|
create_list(:measure, evaluator.measures_count, subcategory: subcategory)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :measure do
|
||||||
|
measure_id { rand.to_s }
|
||||||
|
name { 'A Measure' }
|
||||||
|
watch_low_benchmark { 2.0 }
|
||||||
|
growth_low_benchmark { 3.0 }
|
||||||
|
approval_low_benchmark { 4.0 }
|
||||||
|
ideal_low_benchmark { 4.5 }
|
||||||
|
subcategory
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :survey_item do
|
||||||
|
survey_item_id { rand.to_s }
|
||||||
|
measure
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :academic_year do
|
||||||
|
range { '2050-51' }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :school do
|
||||||
|
name { "#{rand} School" }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :survey_item_response do
|
||||||
|
likert_score { 3 }
|
||||||
|
response_id { rand.to_s }
|
||||||
|
academic_year
|
||||||
|
school
|
||||||
|
survey_item
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,45 +0,0 @@
|
|||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
describe Measure, type: :model do
|
|
||||||
it('has all the measures') do
|
|
||||||
expect(Measure.count).to eq 30
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the measure for the given measure id' do
|
|
||||||
measure = Measure.find_by_measure_id('1A-i')
|
|
||||||
|
|
||||||
expect(measure.name).to eq 'Professional Qualifications'
|
|
||||||
expect(measure.warning_zone).to eq Measure::Zone.new(1.0, 2.49, :warning)
|
|
||||||
expect(measure.watch_zone).to eq Measure::Zone.new(2.49, 3.0, :watch)
|
|
||||||
expect(measure.growth_zone).to eq Measure::Zone.new(3.0, 3.5, :growth)
|
|
||||||
expect(measure.approval_zone).to eq Measure::Zone.new(3.5, 4.71, :approval)
|
|
||||||
expect(measure.ideal_zone).to eq Measure::Zone.new(4.71, 5.0, :ideal)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#zone_for_score' do
|
|
||||||
let(:measure) {
|
|
||||||
Measure.new watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5
|
|
||||||
}
|
|
||||||
|
|
||||||
context 'when the score is 1.0' do
|
|
||||||
it 'returns the warning zone' do
|
|
||||||
expect(measure.zone_for_score(1.0)).to eq measure.warning_zone
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the score is 5.0' do
|
|
||||||
it 'returns the ideal zone' do
|
|
||||||
expect(measure.zone_for_score(5.0)).to eq measure.ideal_zone
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the score is right on the benchmark' do
|
|
||||||
it 'returns the higher zone' do
|
|
||||||
expect(measure.zone_for_score(1.5)).to eq measure.watch_zone
|
|
||||||
expect(measure.zone_for_score(2.5)).to eq measure.growth_zone
|
|
||||||
expect(measure.zone_for_score(3.5)).to eq measure.approval_zone
|
|
||||||
expect(measure.zone_for_score(4.5)).to eq measure.ideal_zone
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe CategoryPresenter do
|
||||||
|
let(:category_presenter) do
|
||||||
|
subcategory1 = Subcategory.new(name: 'A subcategory')
|
||||||
|
subcategory2 = Subcategory.new(name: 'Another subcategory')
|
||||||
|
|
||||||
|
category = SqmCategory.new(name: 'Some Category', subcategories: [subcategory1, subcategory2])
|
||||||
|
return CategoryPresenter.new(category: category, academic_year: AcademicYear.new, school: School.new)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the name of the category' do
|
||||||
|
expect(category_presenter.name).to eq 'Some Category'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'maps subcategories to subcategory presenters' do
|
||||||
|
expect(category_presenter.subcategories.map(&:name)).to eq ['A subcategory', 'Another subcategory']
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe GaugePresenter do
|
||||||
|
# let(:academic_year) { create(:academic_year, range: '1989-90') }
|
||||||
|
# let(:school) { create(:school, name: 'Best School') }
|
||||||
|
# let(:subcategory_presenter) do
|
||||||
|
# subcategory = create(:subcategory, name: 'A great subcategory')
|
||||||
|
|
||||||
|
# measure1 = create(:measure, watch_low_benchmark: 4, growth_low_benchmark: 4.25, approval_low_benchmark: 4.5, ideal_low_benchmark: 4.75, subcategory: subcategory)
|
||||||
|
# survey_item1 = create(:survey_item, measure: measure1)
|
||||||
|
# create(:survey_item_response, survey_item: survey_item1, academic_year: academic_year, school: school, likert_score: 1)
|
||||||
|
# create(:survey_item_response, survey_item: survey_item1, academic_year: academic_year, school: school, likert_score: 5)
|
||||||
|
|
||||||
|
# measure2 = create(:measure, watch_low_benchmark: 1.25, growth_low_benchmark: 1.5, approval_low_benchmark: 1.75, ideal_low_benchmark: 2.0, subcategory: subcategory)
|
||||||
|
# survey_item2 = create(:survey_item, measure: measure2)
|
||||||
|
# create(:survey_item_response, survey_item: survey_item2, academic_year: academic_year, school: school, likert_score: 1)
|
||||||
|
# create(:survey_item_response, survey_item: survey_item2, academic_year: academic_year, school: school, likert_score: 5)
|
||||||
|
|
||||||
|
# create_survey_item_responses_for_different_years_and_schools(survey_item1)
|
||||||
|
|
||||||
|
# return SubcategoryPresenter.new(subcategory: subcategory, academic_year: academic_year, school: school)
|
||||||
|
# end
|
||||||
|
let(:scale) do
|
||||||
|
Scale.new(
|
||||||
|
watch_low_benchmark: 1.5,
|
||||||
|
growth_low_benchmark: 2.5,
|
||||||
|
approval_low_benchmark: 3.5,
|
||||||
|
ideal_low_benchmark: 4.5,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
let(:score) { 3 }
|
||||||
|
|
||||||
|
|
||||||
|
let(:gauge_presenter) { GaugePresenter.new(scale: scale, score: score) }
|
||||||
|
|
||||||
|
it 'returns the key benchmark percentage for the gauge' do
|
||||||
|
expect(gauge_presenter.key_benchmark_percentage).to eq 0.625
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the given score is in the Warning zone for the given scale' do
|
||||||
|
let(:score) { 1 }
|
||||||
|
|
||||||
|
it 'returns the title of the zone' do
|
||||||
|
expect(gauge_presenter.title).to eq 'Warning'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the color class for the gauge' do
|
||||||
|
expect(gauge_presenter.color_class).to eq 'fill-warning'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the score percentage for the gauge' do
|
||||||
|
expect(gauge_presenter.score_percentage).to eq 0.0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the given score is in the Watch zone for the given scale' do
|
||||||
|
let(:score) { 2 }
|
||||||
|
|
||||||
|
it 'returns the title of the zone' do
|
||||||
|
expect(gauge_presenter.title).to eq 'Watch'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the color class for the gauge' do
|
||||||
|
expect(gauge_presenter.color_class).to eq 'fill-watch'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the score percentage for the gauge' do
|
||||||
|
expect(gauge_presenter.score_percentage).to eq 0.25
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the given score is in the Growth zone for the given scale' do
|
||||||
|
let(:score) { 3 }
|
||||||
|
|
||||||
|
it 'returns the title of the zone' do
|
||||||
|
expect(gauge_presenter.title).to eq 'Growth'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the color class for the gauge' do
|
||||||
|
expect(gauge_presenter.color_class).to eq 'fill-growth'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the score percentage for the gauge' do
|
||||||
|
expect(gauge_presenter.score_percentage).to eq 0.5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the given score is in the Approval zone for the given scale' do
|
||||||
|
let(:score) { 4 }
|
||||||
|
|
||||||
|
it 'returns the title of the zone' do
|
||||||
|
expect(gauge_presenter.title).to eq 'Approval'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the color class for the gauge' do
|
||||||
|
expect(gauge_presenter.color_class).to eq 'fill-approval'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the score percentage for the gauge' do
|
||||||
|
expect(gauge_presenter.score_percentage).to eq 0.75
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the given score is in the Ideal zone for the given scale' do
|
||||||
|
let(:score) { 5 }
|
||||||
|
|
||||||
|
it 'returns the title of the zone' do
|
||||||
|
expect(gauge_presenter.title).to eq 'Ideal'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the color class for the gauge' do
|
||||||
|
expect(gauge_presenter.color_class).to eq 'fill-ideal'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the score percentage for the gauge' do
|
||||||
|
expect(gauge_presenter.score_percentage).to eq 1.0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Scale do
|
||||||
|
describe '#zone_for_score' do
|
||||||
|
let(:scale) {
|
||||||
|
Scale.new watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'when the score is 1.0' do
|
||||||
|
it 'returns the warning zone' do
|
||||||
|
expect(scale.zone_for_score(1.0)).to eq scale.warning_zone
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the score is 5.0' do
|
||||||
|
it 'returns the ideal zone' do
|
||||||
|
expect(scale.zone_for_score(5.0)).to eq scale.ideal_zone
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the score is right on the benchmark' do
|
||||||
|
it 'returns the higher zone' do
|
||||||
|
expect(scale.zone_for_score(1.5)).to eq scale.watch_zone
|
||||||
|
expect(scale.zone_for_score(2.5)).to eq scale.growth_zone
|
||||||
|
expect(scale.zone_for_score(3.5)).to eq scale.approval_zone
|
||||||
|
expect(scale.zone_for_score(4.5)).to eq scale.ideal_zone
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe SubcategoryPresenter do
|
||||||
|
let(:academic_year) { create(:academic_year, range: '1989-90') }
|
||||||
|
let(:school) { create(:school, name: 'Best School') }
|
||||||
|
let(:subcategory_presenter) do
|
||||||
|
subcategory = create(:subcategory, name: 'A great subcategory')
|
||||||
|
|
||||||
|
measure1 = create(:measure, watch_low_benchmark: 4, growth_low_benchmark: 4.25, approval_low_benchmark: 4.5, ideal_low_benchmark: 4.75, subcategory: subcategory)
|
||||||
|
survey_item1 = create(:survey_item, measure: measure1)
|
||||||
|
create(:survey_item_response, survey_item: survey_item1, academic_year: academic_year, school: school, likert_score: 1)
|
||||||
|
create(:survey_item_response, survey_item: survey_item1, academic_year: academic_year, school: school, likert_score: 5)
|
||||||
|
|
||||||
|
measure2 = create(:measure, watch_low_benchmark: 1.25, growth_low_benchmark: 1.5, approval_low_benchmark: 1.75, ideal_low_benchmark: 2.0, subcategory: subcategory)
|
||||||
|
survey_item2 = create(:survey_item, measure: measure2)
|
||||||
|
create(:survey_item_response, survey_item: survey_item2, academic_year: academic_year, school: school, likert_score: 1)
|
||||||
|
create(:survey_item_response, survey_item: survey_item2, academic_year: academic_year, school: school, likert_score: 5)
|
||||||
|
|
||||||
|
create_survey_item_responses_for_different_years_and_schools(survey_item1)
|
||||||
|
|
||||||
|
return SubcategoryPresenter.new(subcategory: subcategory, academic_year: academic_year, school: school)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the name of the subcategory' do
|
||||||
|
expect(subcategory_presenter.name).to eq 'A great subcategory'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns a gauge presenter responsible for the aggregate survey item response likert scores' do
|
||||||
|
expect(subcategory_presenter.gauge_presenter.title).to eq 'Growth'
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_survey_item_responses_for_different_years_and_schools(survey_item)
|
||||||
|
create(:survey_item_response, survey_item: survey_item, school: school, likert_score: 1)
|
||||||
|
create(:survey_item_response, survey_item: survey_item, academic_year: academic_year, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
RSpec.configure do |config|
|
||||||
|
config.include FactoryBot::Syntax::Methods
|
||||||
|
end
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe 'browse/show.html.erb' do
|
||||||
|
before :each do
|
||||||
|
academic_year = create(:academic_year, range: '1989-90')
|
||||||
|
school = create(:school, name: 'Best School')
|
||||||
|
|
||||||
|
category = create(:sqm_category, name: 'Some Category')
|
||||||
|
|
||||||
|
subcategory1 = create(:subcategory, sqm_category: category, name: 'A subcategory')
|
||||||
|
subcategory2 = create(:subcategory_with_measures, sqm_category: category, name: 'Another subcategory')
|
||||||
|
|
||||||
|
measure1 = create(:measure, subcategory: subcategory1, watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
||||||
|
|
||||||
|
survey_item1 = create(:survey_item, measure: measure1)
|
||||||
|
|
||||||
|
survey_item_response1 = create(:survey_item_response, survey_item: survey_item1, academic_year: academic_year, school: school, likert_score: 3)
|
||||||
|
|
||||||
|
assign :category, CategoryPresenter.new(category: category, academic_year: academic_year, school: school)
|
||||||
|
|
||||||
|
render
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders the category name' do
|
||||||
|
expect(rendered).to match /Some Category/
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for each subcategory' do
|
||||||
|
it 'renders the subcategory name' do
|
||||||
|
expect(rendered).to match /A subcategory/
|
||||||
|
expect(rendered).to match /Another subcategory/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders the zone title and fill color for the gauge graph' do
|
||||||
|
expect(rendered).to match /Growth/
|
||||||
|
expect(rendered).to match /fill-growth/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in new issue