Fix tests

This commit is contained in:
Eugene Burmakin 2025-07-04 20:55:05 +02:00
parent 1468f1f9dc
commit 15be46b604
13 changed files with 54 additions and 36 deletions

View file

@ -44,7 +44,15 @@ class MapController < ApplicationController
) )
end end
distance.round(1) # Convert distance to meters for consistent storage
distance_in_meters = case current_user.safe_settings.distance_unit.to_s
when 'miles', 'mi'
distance * 1609.344 # miles to meters
else
distance * 1000 # km to meters
end
distance_in_meters.round # Return as integer meters
end end
def parsed_start_at def parsed_start_at

View file

@ -69,9 +69,9 @@ module Calculateable
# For Track model - convert to meters for storage (Track expects distance in meters) # For Track model - convert to meters for storage (Track expects distance in meters)
case user_distance_unit.to_s case user_distance_unit.to_s
when 'mi' when 'mi'
(calculated_distance * 1609.344).round(2) # miles to meters (calculated_distance * 1609.344).round # miles to meters
else else
(calculated_distance * 1000).round(2) # km to meters (calculated_distance * 1000).round # km to meters
end end
end end

View file

@ -38,7 +38,7 @@ class Stat < ApplicationRecord
timespan.to_a.map.with_index(1) do |day, index| timespan.to_a.map.with_index(1) do |day, index|
daily_points = filter_points_for_day(monthly_points, day) daily_points = filter_points_for_day(monthly_points, day)
distance = Point.total_distance(daily_points, user.safe_settings.distance_unit) distance = Point.total_distance(daily_points, user.safe_settings.distance_unit)
[index, distance.round(2)] [index, distance.round]
end end
end end

View file

@ -7,7 +7,7 @@ class Track < ApplicationRecord
has_many :points, dependent: :nullify has_many :points, dependent: :nullify
validates :start_at, :end_at, :original_path, presence: true validates :start_at, :end_at, :original_path, presence: true
validates :distance, :avg_speed, :duration, numericality: { greater_than: 0 } validates :distance, :avg_speed, :duration, numericality: { greater_than_or_equal_to: 0 }
after_update :recalculate_path_and_distance!, if: -> { points.exists? && (saved_change_to_start_at? || saved_change_to_end_at?) } after_update :recalculate_path_and_distance!, if: -> { points.exists? && (saved_change_to_start_at? || saved_change_to_end_at?) }
end end

View file

@ -38,7 +38,7 @@ class TrackSerializer
id: id, id: id,
start_at: start_at.iso8601, start_at: start_at.iso8601,
end_at: end_at.iso8601, end_at: end_at.iso8601,
distance: distance.to_f, distance: distance.to_i,
avg_speed: avg_speed.to_f, avg_speed: avg_speed.to_f,
duration: duration, duration: duration,
elevation_gain: elevation_gain, elevation_gain: elevation_gain,

View file

@ -154,9 +154,9 @@ class Tracks::CreateFromPoints
# Convert to meters for storage (Track model expects distance in meters) # Convert to meters for storage (Track model expects distance in meters)
case user.safe_settings.distance_unit case user.safe_settings.distance_unit
when 'miles', 'mi' when 'miles', 'mi'
(distance_in_user_unit * 1609.344).round(2) # miles to meters (distance_in_user_unit * 1609.344).round # miles to meters
else else
(distance_in_user_unit * 1000).round(2) # km to meters (distance_in_user_unit * 1000).round # km to meters
end end
end end

File diff suppressed because one or more lines are too long

View file

@ -54,28 +54,35 @@ RSpec.describe Tracks::CreateJob, type: :job do
expect(notification_service).to have_received(:call) expect(notification_service).to have_received(:call)
end end
it 'logs the error' do it 'reports the error using ExceptionReporter' do
allow(Rails.logger).to receive(:error) allow(ExceptionReporter).to receive(:call)
allow(Notifications::Create).to receive(:new).and_return(instance_double(Notifications::Create, call: nil))
described_class.new.perform(user.id) described_class.new.perform(user.id)
expect(Rails.logger).to have_received(:error).with("Failed to create tracks for user #{user.id}: #{error_message}") expect(ExceptionReporter).to have_received(:call).with(
kind_of(StandardError),
'Failed to create tracks for user'
)
end end
end end
context 'when user does not exist' do context 'when user does not exist' do
it 'raises ActiveRecord::RecordNotFound' do it 'handles the error gracefully and creates error notification' do
expect { allow(User).to receive(:find).with(999).and_raise(ActiveRecord::RecordNotFound)
described_class.new.perform(999) allow(ExceptionReporter).to receive(:call)
}.to raise_error(ActiveRecord::RecordNotFound) allow(Notifications::Create).to receive(:new).and_return(instance_double(Notifications::Create, call: nil))
# Should not raise an error because it's caught by the rescue block
expect { described_class.new.perform(999) }.not_to raise_error
expect(ExceptionReporter).to have_received(:call)
end end
end end
end end
describe 'queue' do describe 'queue' do
it 'is queued on default queue' do it 'is queued on default queue' do
expect(described_class.new.queue_name).to eq('tracks') expect(described_class.new.queue_name).to eq('default')
end end
end end
end end

View file

@ -29,7 +29,7 @@ RSpec.describe Stat, type: :model do
create(:point, user:, lonlat: 'POINT(2 2)', timestamp: DateTime.new(year, 1, 1, 2)) create(:point, user:, lonlat: 'POINT(2 2)', timestamp: DateTime.new(year, 1, 1, 2))
end end
before { expected_distance[0][1] = 156.88 } before { expected_distance[0][1] = 157 }
it 'returns distance by day' do it 'returns distance by day' do
expect(subject).to eq(expected_distance) expect(subject).to eq(expected_distance)

View file

@ -7,12 +7,14 @@ RSpec.describe Track, type: :model do
end end
describe 'validations' do describe 'validations' do
subject { build(:track) }
it { is_expected.to validate_presence_of(:start_at) } it { is_expected.to validate_presence_of(:start_at) }
it { is_expected.to validate_presence_of(:end_at) } it { is_expected.to validate_presence_of(:end_at) }
it { is_expected.to validate_presence_of(:original_path) } it { is_expected.to validate_presence_of(:original_path) }
it { is_expected.to validate_numericality_of(:distance).is_greater_than(0) } it { is_expected.to validate_numericality_of(:distance).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:avg_speed).is_greater_than(0) } it { is_expected.to validate_numericality_of(:avg_speed).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:duration).is_greater_than(0) } it { is_expected.to validate_numericality_of(:duration).is_greater_than_or_equal_to(0) }
end end
describe 'Calculateable concern' do describe 'Calculateable concern' do
@ -21,8 +23,8 @@ RSpec.describe Track, type: :model do
let!(:points) do let!(:points) do
[ [
create(:point, user: user, track: track, lonlat: 'POINT(13.404954 52.520008)', timestamp: 1.hour.ago.to_i), create(:point, user: user, track: track, lonlat: 'POINT(13.404954 52.520008)', timestamp: 1.hour.ago.to_i),
create(:point, user: user, track: track, lonlat: 'POINT(13.404955 52.520009)', timestamp: 30.minutes.ago.to_i), create(:point, user: user, track: track, lonlat: 'POINT(13.405954 52.521008)', timestamp: 30.minutes.ago.to_i),
create(:point, user: user, track: track, lonlat: 'POINT(13.404956 52.520010)', timestamp: Time.current.to_i) create(:point, user: user, track: track, lonlat: 'POINT(13.406954 52.522008)', timestamp: Time.current.to_i)
] ]
end end
@ -41,7 +43,7 @@ RSpec.describe Track, type: :model do
track.calculate_distance track.calculate_distance
expect(track.distance).to be > 0 expect(track.distance).to be > 0
expect(track.distance).to be_a(Float) expect(track.distance).to be_a(Integer)
end end
it 'stores distance in meters for Track model' do it 'stores distance in meters for Track model' do
@ -50,7 +52,7 @@ RSpec.describe Track, type: :model do
track.calculate_distance track.calculate_distance
expect(track.distance).to eq(1500.0) # Should be in meters expect(track.distance).to eq(1500) # Should be in meters as integer
end end
end end

View file

@ -33,7 +33,8 @@ RSpec.describe PointSerializer do
'geodata' => point.geodata, 'geodata' => point.geodata,
'course' => point.course, 'course' => point.course,
'course_accuracy' => point.course_accuracy, 'course_accuracy' => point.course_accuracy,
'external_track_id' => point.external_track_id 'external_track_id' => point.external_track_id,
'track_id' => point.track_id
} }
end end

View file

@ -61,7 +61,7 @@ RSpec.describe Stats::CalculateMonth do
it 'calculates distance' do it 'calculates distance' do
calculate_stats calculate_stats
expect(user.stats.last.distance).to eq(339) expect(user.stats.last.distance).to eq(340)
end end
context 'when there is an error' do context 'when there is an error' do

View file

@ -9,8 +9,8 @@ RSpec.describe Tracks::CreateFromPoints do
describe '#initialize' do describe '#initialize' do
it 'sets user and thresholds from user settings' do it 'sets user and thresholds from user settings' do
expect(service.user).to eq(user) expect(service.user).to eq(user)
expect(service.distance_threshold_meters).to eq(user.safe_settings.meters_between_routes) expect(service.distance_threshold_meters).to eq(user.safe_settings.meters_between_routes.to_i)
expect(service.time_threshold_minutes).to eq(user.safe_settings.minutes_between_routes) expect(service.time_threshold_minutes).to eq(user.safe_settings.minutes_between_routes.to_i)
end end
context 'with custom user settings' do context 'with custom user settings' do
@ -233,14 +233,14 @@ RSpec.describe Tracks::CreateFromPoints do
end end
end end
describe '#calculate_distance_meters' do describe '#calculate_distance_kilometers' do
let(:point1) { build(:point, lonlat: 'POINT(-74.0060 40.7128)') } let(:point1) { build(:point, lonlat: 'POINT(-74.0060 40.7128)') }
let(:point2) { build(:point, lonlat: 'POINT(-74.0070 40.7130)') } let(:point2) { build(:point, lonlat: 'POINT(-74.0070 40.7130)') }
it 'calculates distance between two points in meters' do it 'calculates distance between two points in kilometers' do
distance = service.send(:calculate_distance_meters, point1, point2) distance = service.send(:calculate_distance_kilometers, point1, point2)
expect(distance).to be > 0 expect(distance).to be > 0
expect(distance).to be < 200 # Should be small distance for close points expect(distance).to be < 0.2 # Should be small distance for close points (in km)
end end
end end
@ -276,7 +276,7 @@ RSpec.describe Tracks::CreateFromPoints do
it 'converts km to meters by default' do it 'converts km to meters by default' do
distance = service.send(:calculate_track_distance, points) distance = service.send(:calculate_track_distance, points)
expect(distance).to eq(1500.0) # 1.5 km = 1500 meters expect(distance).to eq(1500) # 1.5 km = 1500 meters
end end
context 'with miles unit' do context 'with miles unit' do
@ -286,7 +286,7 @@ RSpec.describe Tracks::CreateFromPoints do
it 'converts miles to meters' do it 'converts miles to meters' do
distance = service.send(:calculate_track_distance, points) distance = service.send(:calculate_track_distance, points)
expect(distance).to eq(2414.02) # 1.5 miles ≈ 2414 meters expect(distance).to eq(2414) # 1.5 miles ≈ 2414 meters (rounded)
end end
end end
end end