2024-10-24 10:59:15 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
require 'rails_helper'
|
|
|
|
|
|
2024-12-06 10:52:36 -05:00
|
|
|
RSpec.describe Stats::CalculateMonth do
|
2024-10-24 10:59:15 -04:00
|
|
|
describe '#call' do
|
2024-12-06 10:52:36 -05:00
|
|
|
subject(:calculate_stats) { described_class.new(user.id, year, month).call }
|
2024-10-24 10:59:15 -04:00
|
|
|
|
|
|
|
|
let(:user) { create(:user) }
|
2024-12-06 10:52:36 -05:00
|
|
|
let(:year) { 2021 }
|
|
|
|
|
let(:month) { 1 }
|
2024-10-24 10:59:15 -04:00
|
|
|
|
|
|
|
|
context 'when there are no points' do
|
|
|
|
|
it 'does not create stats' do
|
|
|
|
|
expect { calculate_stats }.not_to(change { Stat.count })
|
|
|
|
|
end
|
2025-05-17 18:15:25 -04:00
|
|
|
|
|
|
|
|
context 'when stats already exist for the month' do
|
|
|
|
|
before do
|
|
|
|
|
create(:stat, user: user, year: year, month: month)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'deletes existing stats for that month' do
|
|
|
|
|
expect { calculate_stats }.to change { Stat.count }.by(-1)
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-10-24 10:59:15 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when there are points' do
|
2024-12-06 10:52:36 -05:00
|
|
|
let(:timestamp1) { DateTime.new(year, month, 1, 12).to_i }
|
|
|
|
|
let(:timestamp2) { DateTime.new(year, month, 1, 13).to_i }
|
|
|
|
|
let(:timestamp3) { DateTime.new(year, month, 1, 14).to_i }
|
2024-10-24 10:59:15 -04:00
|
|
|
let!(:import) { create(:import, user:) }
|
|
|
|
|
let!(:point1) do
|
|
|
|
|
create(:point,
|
|
|
|
|
user:,
|
|
|
|
|
import:,
|
|
|
|
|
timestamp: timestamp1,
|
2025-02-21 17:45:36 -05:00
|
|
|
lonlat: 'POINT(14.452712811406352 52.107902115161316)')
|
2024-10-24 10:59:15 -04:00
|
|
|
end
|
|
|
|
|
let!(:point2) do
|
|
|
|
|
create(:point,
|
|
|
|
|
user:,
|
|
|
|
|
import:,
|
|
|
|
|
timestamp: timestamp2,
|
2025-02-21 17:45:36 -05:00
|
|
|
lonlat: 'POINT(12.291519487061901 51.9746598171507)')
|
2024-10-24 10:59:15 -04:00
|
|
|
end
|
|
|
|
|
let!(:point3) do
|
|
|
|
|
create(:point,
|
|
|
|
|
user:,
|
|
|
|
|
import:,
|
|
|
|
|
timestamp: timestamp3,
|
2025-02-21 17:45:36 -05:00
|
|
|
lonlat: 'POINT(9.77973105800526 52.72859111523629)')
|
2024-10-24 10:59:15 -04:00
|
|
|
end
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
context 'when calculating distance' do
|
2024-10-24 10:59:15 -04:00
|
|
|
it 'creates stats' do
|
|
|
|
|
expect { calculate_stats }.to change { Stat.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
it 'calculates distance in meters consistently' do
|
2024-10-24 10:59:15 -04:00
|
|
|
calculate_stats
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
# Distance should be calculated in meters regardless of user unit preference
|
|
|
|
|
# The actual distance between the test points is approximately 340 km = 340,000 meters
|
|
|
|
|
expect(user.stats.last.distance).to be_within(1000).of(340_000)
|
2024-10-24 10:59:15 -04:00
|
|
|
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 { calculate_stats }.not_to(change { Stat.count })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'creates a notification' do
|
|
|
|
|
expect { calculate_stats }.to change { Notification.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
context 'when user prefers miles' do
|
2025-05-17 14:35:38 -04:00
|
|
|
before do
|
2025-05-17 16:12:35 -04:00
|
|
|
user.update(settings: { maps: { distance_unit: 'mi' } })
|
2025-05-17 14:35:38 -04:00
|
|
|
end
|
2024-10-24 10:59:15 -04:00
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
it 'still stores distance in meters (same as km users)' do
|
2024-10-24 10:59:15 -04:00
|
|
|
calculate_stats
|
|
|
|
|
|
2025-07-08 12:10:10 -04:00
|
|
|
# Distance stored should be the same regardless of user preference (meters)
|
|
|
|
|
expect(user.stats.last.distance).to be_within(1000).of(340_000)
|
2024-10-24 10:59:15 -04:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|