Fix range issue

This commit is contained in:
Eugene Burmakin 2025-08-22 21:27:50 +02:00
parent 7b122f2780
commit 76a7c12133
4 changed files with 15 additions and 12 deletions

View file

@ -59,7 +59,8 @@ module Tracks::TrackBuilder
original_path: build_path(points) original_path: build_path(points)
) )
track.distance = pre_calculated_distance.round # TODO: Move trips attrs to columns with more precision and range
track.distance = [[pre_calculated_distance.round, 999999.99].min, 0].max
track.duration = calculate_duration(points) track.duration = calculate_duration(points)
track.avg_speed = calculate_average_speed(track.distance, track.duration) track.avg_speed = calculate_average_speed(track.distance, track.duration)
@ -99,8 +100,10 @@ module Tracks::TrackBuilder
# Speed in meters per second, then convert to km/h for storage # Speed in meters per second, then convert to km/h for storage
speed_mps = distance_in_meters.to_f / duration_seconds speed_mps = distance_in_meters.to_f / duration_seconds
speed_kmh = (speed_mps * 3.6).round(2) # m/s to km/h
(speed_mps * 3.6).round(2) # m/s to km/h # Cap the speed to prevent database precision overflow (max 999999.99)
[speed_kmh, 999999.99].min
end end
def calculate_elevation_stats(points) def calculate_elevation_stats(points)

View file

@ -123,7 +123,7 @@ RSpec.describe TrackSerializer do
context 'with very large values' do context 'with very large values' do
let(:track) do let(:track) do
create(:track, user: user, create(:track, user: user,
distance: 1_000_000.0, distance: 999_999.99,
avg_speed: 999.99, avg_speed: 999.99,
duration: 86_400, # 24 hours in seconds duration: 86_400, # 24 hours in seconds
elevation_gain: 10_000, elevation_gain: 10_000,
@ -133,7 +133,7 @@ RSpec.describe TrackSerializer do
end end
it 'handles large values correctly' do it 'handles large values correctly' do
expect(serialized_track[:distance]).to eq(1_000_000) expect(serialized_track[:distance]).to eq(999_999)
expect(serialized_track[:avg_speed]).to eq(999.99) expect(serialized_track[:avg_speed]).to eq(999.99)
expect(serialized_track[:duration]).to eq(86_400) expect(serialized_track[:duration]).to eq(86_400)
expect(serialized_track[:elevation_gain]).to eq(10_000) expect(serialized_track[:elevation_gain]).to eq(10_000)

View file

@ -24,20 +24,20 @@ RSpec.describe PointsLimitExceeded do
context 'when user points count is equal to the limit' do context 'when user points count is equal to the limit' do
before do before do
allow(user.points).to receive(:count).and_return(10) allow(user).to receive(:points_count).and_return(10)
end end
it { is_expected.to be true } it { is_expected.to be true }
it 'caches the result' do it 'caches the result' do
expect(user.points).to receive(:count).once expect(user).to receive(:points_count).once
2.times { described_class.new(user).call } 2.times { described_class.new(user).call }
end end
end end
context 'when user points count exceeds the limit' do context 'when user points count exceeds the limit' do
before do before do
allow(user.points).to receive(:count).and_return(11) allow(user).to receive(:points_count).and_return(11)
end end
it { is_expected.to be true } it { is_expected.to be true }
@ -45,7 +45,7 @@ RSpec.describe PointsLimitExceeded do
context 'when user points count is below the limit' do context 'when user points count is below the limit' do
before do before do
allow(user.points).to receive(:count).and_return(9) allow(user).to receive(:points_count).and_return(9)
end end
it { is_expected.to be false } it { is_expected.to be false }

View file

@ -45,7 +45,7 @@ RSpec.describe Users::ExportData, type: :service do
allow(user).to receive(:trips).and_return(double(count: 8)) allow(user).to receive(:trips).and_return(double(count: 8))
allow(user).to receive(:stats).and_return(double(count: 24)) allow(user).to receive(:stats).and_return(double(count: 24))
allow(user).to receive(:notifications).and_return(double(count: 10)) allow(user).to receive(:notifications).and_return(double(count: 10))
allow(user).to receive(:points).and_return(double(count: 15000)) allow(user).to receive(:points_count).and_return(15000)
allow(user).to receive(:visits).and_return(double(count: 45)) allow(user).to receive(:visits).and_return(double(count: 45))
allow(user).to receive(:places).and_return(double(count: 20)) allow(user).to receive(:places).and_return(double(count: 20))
@ -187,7 +187,7 @@ RSpec.describe Users::ExportData, type: :service do
allow(user).to receive(:trips).and_return(double(count: 8)) allow(user).to receive(:trips).and_return(double(count: 8))
allow(user).to receive(:stats).and_return(double(count: 24)) allow(user).to receive(:stats).and_return(double(count: 24))
allow(user).to receive(:notifications).and_return(double(count: 10)) allow(user).to receive(:notifications).and_return(double(count: 10))
allow(user).to receive(:points).and_return(double(count: 15000)) allow(user).to receive(:points_count).and_return(15000)
allow(user).to receive(:visits).and_return(double(count: 45)) allow(user).to receive(:visits).and_return(double(count: 45))
allow(user).to receive(:places).and_return(double(count: 20)) allow(user).to receive(:places).and_return(double(count: 20))
@ -267,7 +267,7 @@ RSpec.describe Users::ExportData, type: :service do
allow(user).to receive(:trips).and_return(double(count: 8)) allow(user).to receive(:trips).and_return(double(count: 8))
allow(user).to receive(:stats).and_return(double(count: 24)) allow(user).to receive(:stats).and_return(double(count: 24))
allow(user).to receive(:notifications).and_return(double(count: 10)) allow(user).to receive(:notifications).and_return(double(count: 10))
allow(user).to receive(:points).and_return(double(count: 15000)) allow(user).to receive(:points_count).and_return(15000)
allow(user).to receive(:visits).and_return(double(count: 45)) allow(user).to receive(:visits).and_return(double(count: 45))
allow(user).to receive(:places).and_return(double(count: 20)) allow(user).to receive(:places).and_return(double(count: 20))
@ -374,7 +374,7 @@ RSpec.describe Users::ExportData, type: :service do
allow(user).to receive(:trips).and_return(double(count: 8)) allow(user).to receive(:trips).and_return(double(count: 8))
allow(user).to receive(:stats).and_return(double(count: 24)) allow(user).to receive(:stats).and_return(double(count: 24))
allow(user).to receive(:notifications).and_return(double(count: 10)) allow(user).to receive(:notifications).and_return(double(count: 10))
allow(user).to receive(:points).and_return(double(count: 15000)) allow(user).to receive(:points_count).and_return(15000)
allow(user).to receive(:visits).and_return(double(count: 45)) allow(user).to receive(:visits).and_return(double(count: 45))
allow(user).to receive(:places).and_return(double(count: 20)) allow(user).to receive(:places).and_return(double(count: 20))
allow(Rails.logger).to receive(:info) allow(Rails.logger).to receive(:info)