mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
220 lines
5.7 KiB
Ruby
220 lines
5.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
RSpec.describe Places::NameFetcher do
|
|
describe '#call' do
|
|
subject(:service) { described_class.new(place) }
|
|
|
|
let(:place) do
|
|
create(
|
|
:place,
|
|
name: Place::DEFAULT_NAME,
|
|
city: nil,
|
|
country: nil,
|
|
geodata: {},
|
|
lonlat: 'POINT(10.0 10.0)'
|
|
)
|
|
end
|
|
|
|
let(:geocoder_result) do
|
|
double(
|
|
'geocoder_result',
|
|
data: {
|
|
'properties' => {
|
|
'name' => 'Central Park',
|
|
'city' => 'New York',
|
|
'country' => 'United States'
|
|
}
|
|
}
|
|
)
|
|
end
|
|
|
|
before do
|
|
allow(Geocoder).to receive(:search).and_return([geocoder_result])
|
|
end
|
|
|
|
context 'when geocoding is successful' do
|
|
it 'calls Geocoder with correct parameters' do
|
|
expect(Geocoder).to receive(:search)
|
|
.with([place.lat, place.lon], units: :km, limit: 1, distance_sort: true)
|
|
.and_return([geocoder_result])
|
|
|
|
service.call
|
|
end
|
|
|
|
it 'updates place name from geocoder data' do
|
|
expect { service.call }.to change(place, :name)
|
|
.from(Place::DEFAULT_NAME)
|
|
.to('Central Park')
|
|
end
|
|
|
|
it 'updates place city from geocoder data' do
|
|
expect { service.call }.to change(place, :city)
|
|
.from(nil)
|
|
.to('New York')
|
|
end
|
|
|
|
it 'updates place country from geocoder data' do
|
|
expect { service.call }.to change(place, :country)
|
|
.from(nil)
|
|
.to('United States')
|
|
end
|
|
|
|
it 'saves the place' do
|
|
expect(place).to receive(:save!)
|
|
|
|
service.call
|
|
end
|
|
|
|
context 'when DawarichSettings.store_geodata? is enabled' do
|
|
before do
|
|
allow(DawarichSettings).to receive(:store_geodata?).and_return(true)
|
|
end
|
|
|
|
it 'stores geodata in the place' do
|
|
expect { service.call }.to change(place, :geodata)
|
|
.from({})
|
|
.to(geocoder_result.data)
|
|
end
|
|
end
|
|
|
|
context 'when DawarichSettings.store_geodata? is disabled' do
|
|
before do
|
|
allow(DawarichSettings).to receive(:store_geodata?).and_return(false)
|
|
end
|
|
|
|
it 'does not store geodata in the place' do
|
|
expect { service.call }.not_to change(place, :geodata)
|
|
end
|
|
end
|
|
|
|
context 'when place has visits with default name' do
|
|
let!(:visit_with_default_name) do
|
|
create(:visit, name: Place::DEFAULT_NAME)
|
|
end
|
|
let!(:visit_with_custom_name) do
|
|
create(:visit, name: 'Custom Visit Name')
|
|
end
|
|
|
|
before do
|
|
place.visits << visit_with_default_name
|
|
place.visits << visit_with_custom_name
|
|
end
|
|
|
|
it 'updates visits with default name to the new place name' do
|
|
expect { service.call }.to \
|
|
change { visit_with_default_name.reload.name }
|
|
.from(Place::DEFAULT_NAME)
|
|
.to('Central Park')
|
|
end
|
|
|
|
it 'does not update visits with custom names' do
|
|
expect { service.call }.not_to \
|
|
change { visit_with_custom_name.reload.name }
|
|
end
|
|
end
|
|
|
|
context 'when using transactions' do
|
|
it 'wraps updates in a transaction' do
|
|
expect(ActiveRecord::Base).to \
|
|
receive(:transaction).and_call_original
|
|
|
|
service.call
|
|
end
|
|
|
|
it 'rolls back changes if save fails' do
|
|
allow(place).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
|
|
|
|
expect { service.call }.to raise_error(ActiveRecord::RecordInvalid)
|
|
expect(place.reload.name).to eq(Place::DEFAULT_NAME)
|
|
end
|
|
end
|
|
|
|
it 'returns the updated place' do
|
|
result = service.call
|
|
expect(result).to eq(place)
|
|
expect(result.name).to eq('Central Park')
|
|
end
|
|
end
|
|
|
|
context 'when geocoding returns no results' do
|
|
before do
|
|
allow(Geocoder).to receive(:search).and_return([])
|
|
end
|
|
|
|
it 'returns nil' do
|
|
expect(service.call).to be_nil
|
|
end
|
|
|
|
it 'does not update the place' do
|
|
expect { service.call }.not_to change(place, :name)
|
|
end
|
|
|
|
it 'does not call save on the place' do
|
|
expect(place).not_to receive(:save!)
|
|
|
|
service.call
|
|
end
|
|
end
|
|
|
|
context 'when geocoding returns nil result' do
|
|
before do
|
|
allow(Geocoder).to receive(:search).and_return([nil])
|
|
end
|
|
|
|
it 'returns nil' do
|
|
expect(service.call).to be_nil
|
|
end
|
|
|
|
it 'does not update the place' do
|
|
expect { service.call }.not_to change(place, :name)
|
|
end
|
|
end
|
|
|
|
context 'when geocoder result has missing properties' do
|
|
let(:incomplete_geocoder_result) do
|
|
double(
|
|
'geocoder_result',
|
|
data: {
|
|
'properties' => {
|
|
'name' => 'Partial Place',
|
|
'city' => nil,
|
|
'country' => 'United States'
|
|
}
|
|
}
|
|
)
|
|
end
|
|
|
|
before do
|
|
allow(Geocoder).to receive(:search).and_return([incomplete_geocoder_result])
|
|
end
|
|
|
|
it 'updates place with available data' do
|
|
service.call
|
|
|
|
expect(place.name).to eq('Partial Place')
|
|
expect(place.city).to be_nil
|
|
expect(place.country).to eq('United States')
|
|
end
|
|
end
|
|
|
|
context 'when geocoder result has no properties' do
|
|
let(:no_properties_result) do
|
|
double('geocoder_result', data: {})
|
|
end
|
|
|
|
before do
|
|
allow(Geocoder).to receive(:search).and_return([no_properties_result])
|
|
end
|
|
|
|
it 'handles missing properties gracefully' do
|
|
expect { service.call }.not_to raise_error
|
|
|
|
expect(place.name).to eq(Place::DEFAULT_NAME)
|
|
expect(place.city).to be_nil
|
|
expect(place.country).to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|