diff --git a/app/services/tracks/track_builder.rb b/app/services/tracks/track_builder.rb index 0ccd82b0..a988f3bf 100644 --- a/app/services/tracks/track_builder.rb +++ b/app/services/tracks/track_builder.rb @@ -59,7 +59,8 @@ module Tracks::TrackBuilder 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.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_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 def calculate_elevation_stats(points) diff --git a/spec/serializers/track_serializer_spec.rb b/spec/serializers/track_serializer_spec.rb index 6622b23d..cfda4e5c 100644 --- a/spec/serializers/track_serializer_spec.rb +++ b/spec/serializers/track_serializer_spec.rb @@ -123,7 +123,7 @@ RSpec.describe TrackSerializer do context 'with very large values' do let(:track) do create(:track, user: user, - distance: 1_000_000.0, + distance: 999_999.99, avg_speed: 999.99, duration: 86_400, # 24 hours in seconds elevation_gain: 10_000, @@ -133,7 +133,7 @@ RSpec.describe TrackSerializer do end 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[:duration]).to eq(86_400) expect(serialized_track[:elevation_gain]).to eq(10_000) diff --git a/spec/services/points_limit_exceeded_spec.rb b/spec/services/points_limit_exceeded_spec.rb index 534192ee..293c7a27 100644 --- a/spec/services/points_limit_exceeded_spec.rb +++ b/spec/services/points_limit_exceeded_spec.rb @@ -24,20 +24,20 @@ RSpec.describe PointsLimitExceeded do context 'when user points count is equal to the limit' do before do - allow(user.points).to receive(:count).and_return(10) + allow(user).to receive(:points_count).and_return(10) end it { is_expected.to be true } 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 } end end context 'when user points count exceeds the limit' do before do - allow(user.points).to receive(:count).and_return(11) + allow(user).to receive(:points_count).and_return(11) end it { is_expected.to be true } @@ -45,7 +45,7 @@ RSpec.describe PointsLimitExceeded do context 'when user points count is below the limit' do before do - allow(user.points).to receive(:count).and_return(9) + allow(user).to receive(:points_count).and_return(9) end it { is_expected.to be false } diff --git a/spec/services/users/export_data_spec.rb b/spec/services/users/export_data_spec.rb index 4db0acd0..b2c600d2 100644 --- a/spec/services/users/export_data_spec.rb +++ b/spec/services/users/export_data_spec.rb @@ -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(:stats).and_return(double(count: 24)) 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(: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(:stats).and_return(double(count: 24)) 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(: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(:stats).and_return(double(count: 24)) 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(: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(:stats).and_return(double(count: 24)) 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(:places).and_return(double(count: 20)) allow(Rails.logger).to receive(:info)