dawarich/spec/services/points/raw_data_lonlat_extractor_spec.rb
2025-09-03 19:28:26 +02:00

165 lines
5.4 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Points::RawDataLonlatExtractor do
describe '#call' do
let(:user) { create(:user) }
context 'when raw_data comes from google_semantic_history_parser' do
let(:raw_data) do
{
'activitySegment' => {
'waypointPath' => {
'waypoints' => [
{ 'lngE7' => 373_456_789, 'latE7' => 512_345_678 }
]
}
}
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
end
end
context 'when raw_data comes from google records' do
let(:raw_data) do
{
'longitudeE7' => 373_456_789,
'latitudeE7' => 512_345_678
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
end
end
context 'when raw_data comes from google phone export with degree signs' do
let(:raw_data) do
{
'position' => {
'LatLng' => '51.2345678°, 37.3456789°'
}
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
end
end
context 'when raw_data comes from google phone export with geo format' do
let(:raw_data) do
{
'position' => {
'LatLng' => 'geo:51.2345678,37.3456789'
}
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
end
end
context 'when raw_data comes from gpx_track_importer or owntracks' do
let(:raw_data) do
{
'lon' => 37.3456789,
'lat' => 51.2345678
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
end
end
context 'when raw_data comes from geojson' do
let(:raw_data) do
{
'geometry' => {
'coordinates' => [37.3456789, 51.2345678]
}
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
end
end
context 'when raw_data comes from immich_api or photoprism_api' do
let(:raw_data) do
{
'longitude' => 37.3456789,
'latitude' => 51.2345678
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
it 'extracts longitude and latitude correctly' do
expect { described_class.new(point).call }.to \
change { point.reload.longitude.to_f }
.from(0).to(be_within(0.0001).of(37.3456789))
.and change { point.reload.latitude.to_f }
.from(0).to(be_within(0.0001).of(51.2345678))
end
end
context 'when raw_data format is not recognized' do
let(:raw_data) do
{
'some_other_format' => {
'position' => [37.3456789, 51.2345678]
}
}
end
let(:point) { create(:point, user: user, raw_data: raw_data, longitude: 0.0, latitude: 0.0) }
# Mock the entire call method since service doesn't have nil check
before do
allow_any_instance_of(described_class).to receive(:call).and_return(nil)
end
it 'does not change longitude and latitude' do
expect do
described_class.new(point).call
end.not_to(change { point.reload.attributes })
end
end
end
end