stats: use group_by_week to compute the week range

Fix #3242
This commit is contained in:
Pierre de La Morinerie 2019-01-09 14:48:45 +01:00
parent 3b92fe93fc
commit 908771e172
3 changed files with 74 additions and 6 deletions

View file

@ -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

View file

@ -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) }

View file

@ -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