From 3b92fe93fc671a5b5a4389c9ebbb9a08e528136e Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 9 Jan 2019 14:48:56 +0100 Subject: [PATCH 1/3] stats: make groupdate week start on Monday --- config/initializers/groupdate.rb | 1 + 1 file changed, 1 insertion(+) create mode 100644 config/initializers/groupdate.rb diff --git a/config/initializers/groupdate.rb b/config/initializers/groupdate.rb new file mode 100644 index 000000000..847d6fc41 --- /dev/null +++ b/config/initializers/groupdate.rb @@ -0,0 +1 @@ +Groupdate.week_start = :mon From 908771e172109c7566117eb621cc02e84a97ed4d Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 9 Jan 2019 14:48:45 +0100 Subject: [PATCH 2/3] stats: use group_by_week to compute the week range Fix #3242 --- app/controllers/stats_controller.rb | 11 ++--- spec/controllers/stats_controller_spec.rb | 57 +++++++++++++++++++++++ spec/factories/feedback.rb | 12 +++++ 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 73d68e8be..ec3fd4ae1 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -133,17 +133,16 @@ class StatsController < ApplicationController Feedback.ratings.fetch(:neutral) => "Neutres", Feedback.ratings.fetch(:unhappy) => "Mécontents" } - interval = 6.weeks.ago.beginning_of_week..1.week.ago.beginning_of_week + number_of_weeks = 6 totals = Feedback - .where(created_at: interval) - .group_by_week(:created_at) + .group_by_week(:created_at, last: number_of_weeks, current: false) .count Feedback.ratings.values.map do |rating| data = Feedback - .where(created_at: interval, rating: rating) - .group_by_week(:created_at) + .where(rating: rating) + .group_by_week(:created_at, last: number_of_weeks, current: false) .count .map do |week, count| total = totals[week] @@ -151,7 +150,7 @@ class StatsController < ApplicationController if total > 0 [week, (count.to_f / total * 100).round(2)] else - 0 + [week, 0] end end.to_h diff --git a/spec/controllers/stats_controller_spec.rb b/spec/controllers/stats_controller_spec.rb index 6fd3f5c2c..27d9ceb26 100644 --- a/spec/controllers/stats_controller_spec.rb +++ b/spec/controllers/stats_controller_spec.rb @@ -229,6 +229,63 @@ describe StatsController, type: :controller do it { expect(subject).to eq(@expected_hash) } end + describe "#satisfaction_usagers" do + before do + # Test the stats on October 2018 – where the 1st, 8th, 15th, 22th and 29th are conveniently Mondays + # Current week: 1 negative feedback + Timecop.freeze(Time.zone.local(2018, 10, 22, 12, 00)) { create(:feedback, :unhappy) } + # Last week: 3 positive, 1 negative + Timecop.freeze(Time.zone.local(2018, 10, 21, 12, 00)) { create(:feedback, :unhappy) } + Timecop.freeze(Time.zone.local(2018, 10, 19, 12, 00)) { create(:feedback, :happy) } + Timecop.freeze(Time.zone.local(2018, 10, 17, 12, 00)) { create(:feedback, :happy) } + Timecop.freeze(Time.zone.local(2018, 10, 15, 12, 00)) { create(:feedback, :happy) } + # N-2 week: 2 positive, 2 negative + Timecop.freeze(Time.zone.local(2018, 10, 14, 12, 00)) { create(:feedback, :unhappy) } + Timecop.freeze(Time.zone.local(2018, 10, 12, 12, 00)) { create(:feedback, :happy) } + Timecop.freeze(Time.zone.local(2018, 10, 10, 12, 00)) { create(:feedback, :unhappy) } + Timecop.freeze(Time.zone.local(2018, 10, 8, 12, 00)) { create(:feedback, :happy) } + # N-3 week: 1 positive, 3 negative + Timecop.freeze(Time.zone.local(2018, 10, 1, 12, 00)) { create(:feedback, :unhappy) } + Timecop.freeze(Time.zone.local(2018, 10, 3, 12, 00)) { create(:feedback, :happy) } + Timecop.freeze(Time.zone.local(2018, 10, 5, 12, 00)) { create(:feedback, :unhappy) } + Timecop.freeze(Time.zone.local(2018, 10, 7, 12, 00)) { create(:feedback, :unhappy) } + end + + subject(:stats) do + Timecop.freeze(Time.zone.local(2018, 10, 28, 12, 00)) { + StatsController.new.send(:satisfaction_usagers) + } + end + + it 'returns one set of values for each kind of feedback' do + expect(stats.count).to eq 3 + expect(stats.map { |g| g[:name] }).to contain_exactly('Satisfaits', 'Neutres', 'Mécontents') + end + + it 'returns weekly ratios between a given feedback and all feedback' do + happy_data = stats.find { |g| g[:name] == 'Satisfaits' }[:data] + expect(happy_data.values[0]).to eq 0 + expect(happy_data.values[1]).to eq 0 + expect(happy_data.values[2]).to eq 0 + expect(happy_data.values[3]).to eq 25.0 + expect(happy_data.values[4]).to eq 50.0 + expect(happy_data.values[5]).to eq 75.0 + + unhappy_data = stats.find { |g| g[:name] == 'Mécontents' }[:data] + expect(unhappy_data.values[0]).to eq 0 + expect(unhappy_data.values[1]).to eq 0 + expect(unhappy_data.values[2]).to eq 0 + expect(unhappy_data.values[3]).to eq 75.0 + expect(unhappy_data.values[4]).to eq 50.0 + expect(unhappy_data.values[5]).to eq 25.0 + end + + it 'excludes values still in the current week' do + unhappy_data = stats.find { |g| g[:name] == 'Mécontents' }[:data] + expect(unhappy_data.values).not_to include(100.0) + end + end + describe '#avis_usage' do let!(:dossier) { create(:dossier) } let!(:avis_with_dossier) { create(:avis) } diff --git a/spec/factories/feedback.rb b/spec/factories/feedback.rb index 6c12442bc..402eb8973 100644 --- a/spec/factories/feedback.rb +++ b/spec/factories/feedback.rb @@ -1,5 +1,17 @@ FactoryBot.define do factory :feedback do rating { Feedback.ratings.fetch(:happy) } + + trait :happy do + rating { Feedback.ratings.fetch(:happy) } + end + + trait :neutral do + rating { Feedback.ratings.fetch(:neutral) } + end + + trait :unhappy do + rating { Feedback.ratings.fetch(:unhappy) } + end end end From ac88d1cc1da5ae9f3dae0135b66854d1056bc463 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 9 Jan 2019 13:53:54 +0000 Subject: [PATCH 3/3] stats: display the last day of the range (instead of the first day) --- app/controllers/stats_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index ec3fd4ae1..196c292d6 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -146,11 +146,13 @@ class StatsController < ApplicationController .count .map do |week, count| total = totals[week] + # By default a week is displayed by the first day of the week – but we'd rather display the last day + label = week.next_week if total > 0 - [week, (count.to_f / total * 100).round(2)] + [label, (count.to_f / total * 100).round(2)] else - [week, 0] + [label, 0] end end.to_h