Add miles tests and refactor CreateStats service a bit

This commit is contained in:
Eugene Burmakin 2024-09-06 21:22:13 +02:00
parent 88de60517e
commit 662eae81fd
3 changed files with 87 additions and 40 deletions

View file

@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.13.0] — 2024-08-28
## [0.13.3] — 2024-09-6
### Added

View file

@ -12,29 +12,12 @@ class CreateStats
def call
users.each do |user|
years.each do |year|
months.each do |month|
beginning_of_month_timestamp = DateTime.new(year, month).beginning_of_month.to_i
end_of_month_timestamp = DateTime.new(year, month).end_of_month.to_i
points = points(user, beginning_of_month_timestamp, end_of_month_timestamp)
next if points.empty?
stat = Stat.find_or_initialize_by(year:, month:, user:)
stat.distance = distance(points)
stat.toponyms = toponyms(points)
stat.daily_distance = stat.distance_by_day
stat.save
end
months.each { |month| update_month_stats(user, year, month) }
end
Notifications::Create.new(user:, kind: :info, title: 'Stats updated', content: 'Stats updated').call
create_stats_updated_notification(user)
rescue StandardError => e
Notifications::Create.new(
user:,
kind: :error,
title: 'Stats update failed',
content: "#{e.message}, stacktrace: #{e.backtrace.join("\n")}"
).call
create_stats_update_failed_notification(user, e)
end
end
@ -49,6 +32,21 @@ class CreateStats
.select(:latitude, :longitude, :timestamp, :city, :country)
end
def update_month_stats(user, year, month)
beginning_of_month_timestamp = DateTime.new(year, month).beginning_of_month.to_i
end_of_month_timestamp = DateTime.new(year, month).end_of_month.to_i
points = points(user, beginning_of_month_timestamp, end_of_month_timestamp)
return if points.empty?
stat = Stat.find_or_initialize_by(year:, month:, user:)
stat.distance = distance(points)
stat.toponyms = toponyms(points)
stat.daily_distance = stat.distance_by_day
stat.save
end
def distance(points)
distance = 0
@ -64,4 +62,19 @@ class CreateStats
def toponyms(points)
CountriesAndCities.new(points).call
end
def create_stats_updated_notification(user)
Notifications::Create.new(
user:, kind: :info, title: 'Stats updated', content: 'Stats updated'
).call
end
def create_stats_update_failed_notification(user, error)
Notifications::Create.new(
user:,
kind: :error,
title: 'Stats update failed',
content: "#{error.message}, stacktrace: #{error.backtrace.join("\n")}"
).call
end
end

View file

@ -21,6 +21,7 @@ RSpec.describe CreateStats do
let!(:point2) { create(:point, user:, import:, latitude: 1, longitude: 2) }
let!(:point3) { create(:point, user:, import:, latitude: 3, longitude: 4) }
context 'when units are kilometers' do
it 'creates stats' do
expect { create_stats }.to change { Stat.count }.by(1)
end
@ -49,5 +50,38 @@ RSpec.describe CreateStats do
end
end
end
context 'when units are miles' do
before { stub_const('DISTANCE_UNIT', 'mi') }
it 'creates stats' do
expect { create_stats }.to change { Stat.count }.by(1)
end
it 'calculates distance' do
create_stats
expect(Stat.last.distance).to eq(349)
end
it 'created notifications' do
expect { create_stats }.to change { Notification.count }.by(1)
end
context 'when there is an error' do
before do
allow(Stat).to receive(:find_or_initialize_by).and_raise(StandardError)
end
it 'does not create stats' do
expect { create_stats }.not_to(change { Stat.count })
end
it 'created notifications' do
expect { create_stats }.to change { Notification.count }.by(1)
end
end
end
end
end
end