diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d661d1f..e35e26e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Prometheus exporter is now not being started when console is being run. - Stats will now properly reflect countries and cities visited after importing new points. - `GET /api/v1/points will now return correct latitude and longitude values. #1502 +- Deleting an import will now trigger stats recalculation for affected months. #1789 ## Changed diff --git a/app/models/import.rb b/app/models/import.rb index 8635f2a9..b1abde92 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -11,6 +11,7 @@ class Import < ApplicationRecord after_commit -> { Import::ProcessJob.perform_later(id) unless skip_background_processing }, on: :create after_commit :remove_attached_file, on: :destroy + before_commit :recalculate_stats, on: :destroy, if: -> { points.exists? } validates :name, presence: true, uniqueness: { scope: :user_id } validate :file_size_within_limit, if: -> { user.trial? } @@ -63,8 +64,14 @@ class Import < ApplicationRecord def file_size_within_limit return unless file.attached? - if file.blob.byte_size > 11.megabytes - errors.add(:file, 'is too large. Trial users can only upload files up to 10MB.') + return unless file.blob.byte_size > 11.megabytes + + errors.add(:file, 'is too large. Trial users can only upload files up to 10MB.') + end + + def recalculate_stats + years_and_months_tracked.each do |year, month| + Stats::CalculatingJob.perform_later(user.id, year, month) end end end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index 50034082..fec9ad1f 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Import, type: :model do describe 'file size validation' do context 'when user is a trial user' do - let(:user) do + let(:user) do user = create(:user) user.update!(status: :trial) user @@ -116,4 +116,28 @@ RSpec.describe Import, type: :model do end end end + + describe '#recalculate_stats' do + let(:import) { create(:import, user:) } + let!(:point1) { create(:point, import:, user:, timestamp: Time.zone.local(2024, 11, 15).to_i) } + let!(:point2) { create(:point, import:, user:, timestamp: Time.zone.local(2024, 12, 5).to_i) } + + it 'enqueues stats calculation jobs for each tracked month' do + expect do + import.send(:recalculate_stats) + end.to have_enqueued_job(Stats::CalculatingJob) + .with(user.id, 2024, 11) + .and have_enqueued_job(Stats::CalculatingJob).with(user.id, 2024, 12) + end + + context 'when import has no points' do + let(:empty_import) { create(:import, user:) } + + it 'does not enqueue any jobs' do + expect do + empty_import.send(:recalculate_stats) + end.not_to have_enqueued_job(Stats::CalculatingJob) + end + end + end end