dawarich/spec/services/visits/find_within_bounding_box_spec.rb
2025-03-09 14:58:30 +01:00

161 lines
3.8 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Visits::FindWithinBoundingBox do
let(:user) { create(:user) }
let(:other_user) { create(:user) }
# Define a bounding box for testing
# This creates a box around central Paris
let(:sw_lat) { 48.8534 } # Southwest latitude
let(:sw_lng) { 2.3380 } # Southwest longitude
let(:ne_lat) { 48.8667 } # Northeast latitude
let(:ne_lng) { 2.3580 } # Northeast longitude
# Create places inside the bounding box
let!(:place_inside_1) do
create(:place, latitude: 48.8600, longitude: 2.3500) # Inside the bounding box
end
let!(:place_inside_2) do
create(:place, latitude: 48.8580, longitude: 2.3450) # Inside the bounding box
end
# Create places outside the bounding box
let!(:place_outside_1) do
create(:place, latitude: 48.8700, longitude: 2.3600) # North of the bounding box
end
let!(:place_outside_2) do
create(:place, latitude: 48.8500, longitude: 2.3300) # Southwest of the bounding box
end
# Create visits for the test user
let!(:visit_inside_1) do
create(
:visit,
user: user,
place: place_inside_1,
started_at: 2.hours.ago,
ended_at: 1.hour.ago
)
end
let!(:visit_inside_2) do
create(
:visit,
user: user,
place: place_inside_2,
started_at: 4.hours.ago,
ended_at: 3.hours.ago
)
end
let!(:visit_outside_1) do
create(
:visit,
user: user,
place: place_outside_1,
started_at: 6.hours.ago,
ended_at: 5.hours.ago
)
end
let!(:visit_outside_2) do
create(
:visit,
user: user,
place: place_outside_2,
started_at: 8.hours.ago,
ended_at: 7.hours.ago
)
end
# Create a visit for another user inside the bounding box
let!(:other_user_visit_inside) do
create(
:visit,
user: other_user,
place: place_inside_1,
started_at: 3.hours.ago,
ended_at: 2.hours.ago
)
end
describe '#call' do
let(:params) do
{
sw_lat: sw_lat.to_s,
sw_lng: sw_lng.to_s,
ne_lat: ne_lat.to_s,
ne_lng: ne_lng.to_s
}
end
subject(:result) { described_class.new(user, params).call }
it 'returns visits within the specified bounding box' do
expect(result).to include(visit_inside_1, visit_inside_2)
expect(result).not_to include(visit_outside_1, visit_outside_2)
end
it 'returns visits in descending order by started_at' do
expect(result.to_a).to eq([visit_inside_1, visit_inside_2])
end
it 'does not include visits from other users' do
expect(result).not_to include(other_user_visit_inside)
end
it 'preloads the place association' do
expect(result.first.association(:place)).to be_loaded
end
context 'with an empty bounding box' do
let(:params) do
{
sw_lat: '0',
sw_lng: '0',
ne_lat: '0',
ne_lng: '0'
}
end
it 'returns an empty collection' do
expect(result).to be_empty
end
end
context 'with a very large bounding box' do
let(:params) do
{
sw_lat: '-90',
sw_lng: '-180',
ne_lat: '90',
ne_lng: '180'
}
end
it 'returns all visits for the user' do
expect(result).to include(visit_inside_1, visit_inside_2, visit_outside_1, visit_outside_2)
expect(result).not_to include(other_user_visit_inside)
end
end
context 'with string coordinates' do
let(:params) do
{
sw_lat: sw_lat.to_s,
sw_lng: sw_lng.to_s,
ne_lat: ne_lat.to_s,
ne_lng: ne_lng.to_s
}
end
it 'converts strings to floats' do
expect(result).to include(visit_inside_1, visit_inside_2)
end
end
end
end