Browse Source

Ensure we always have a "city". Set it from geocoder if not provided

tags/0.3.0^2
Bèr Kessels 1 year ago
parent
commit
bc4278ddbf

+ 21
- 9
app/aggregates/place.rb View File

@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative './place/place_id.rb'
require_relative './place/region.rb'

module Hours
module Aggregates
@@ -20,7 +21,7 @@ module Hours
PlaceId.new(payload).id)
end

attr_writer :place_id_builder, :region_slug_builder
attr_writer :place_id_builder, :region_builder
attr_reader :place_id, :region_slug

# These apply methods are the hook that this aggregate uses to update
@@ -32,9 +33,9 @@ module Hours
def add(payload)
raise DuplicateError, "Place #{id.inspect} already exists" if added?

@payload = payload
@payload = Hashie.symbolize_keys(payload)
@place_id = place_id_builder.id
@region_slug = region_slug_builder.region
@region_slug = region_builder.region_slug

apply_event(PlaceAdded, aggregate_id: id, body: event_body)
self
@@ -47,18 +48,29 @@ module Hours
end

def event_body
properties = @payload.fetch(:properties, {})
.merge(place_id: place_id,
region_slug: region_slug)
@payload.merge(properties: properties)
@payload.merge(
properties: properties.merge(
place_id: place_id,
region_slug: region_slug,
'addr:city': city
)
)
end

def properties
@payload.fetch(:properties, {})
end

def place_id_builder
@place_id_builder || PlaceId.new(@payload)
end

def region_slug_builder
@region_slug_builder || RegionSlug.new(@payload)
def region_builder
@region_builder || Region.new(@payload)
end

def city
properties[:'addr:city'] || region_builder.city
end
end
end

+ 0
- 1
app/aggregates/place/place_id.rb View File

@@ -1,6 +1,5 @@
# frozen_string_literal: true

require 'hashie'
require 'plus_codes/open_location_code'
require 'rgeo/geo_json'


app/aggregates/place/region_slug.rb → app/aggregates/place/region.rb View File

@@ -5,16 +5,20 @@ require 'offline_geocoder'
module Hours
module Aggregates
# Generates a normalized, distinguishable region string.
class RegionSlug
class Region
attr_writer :offline_geocoder

def initialize(geojson)
@geojson = Hashie.symbolize_keys(geojson)
end

def region
def region_slug
city.downcase
end

def city
@geojson.fetch(:properties, {})
.fetch(:'addr:city', region_from_geom).downcase
.fetch(:'addr:city', region_from_geom)
end

private

+ 1
- 1
app/models/place.rb View File

@@ -16,7 +16,7 @@ module Hours
PARSER = OpeningHoursConverter::OpeningHoursParser.new

attr_accessor :id, :location, :place_id, :name,
:region_slug
:region_slug, :distance
attr_writer :address, :opening_hours

def lat

+ 1
- 0
lib/hours.rb View File

@@ -2,6 +2,7 @@

require 'event_sourcery'
require 'event_sourcery/postgres'
require 'hashie'
require 'pathname'
require 'sequel-postgis-georuby'
require 'securerandom'

test/aggregates/place/region_slug_test.rb → test/aggregates/place/region_test.rb View File

@@ -1,19 +1,24 @@
# frozen_string_literal: true

require 'test_helper'
require_relative Hours.base_path.join 'app/aggregates/place/region_slug.rb'
require_relative Hours.base_path.join 'app/aggregates/place/region.rb'

describe Hours::Aggregates::RegionSlug do
describe Hours::Aggregates::Region do
let(:offline_geocoder) { Minitest::Mock.new }

subject do
Hours::Aggregates::RegionSlug.new(geojson)
Hours::Aggregates::Region.new(geojson)
end

describe 'with addr:city' do
let(:geojson) { json_fixtures('input/hm_burchtstraat.json') }
it 'generates from addr:city attribute' do
assert_equal 'nijmegen', subject.region

it 'generates region_slug from addr:city attribute' do
assert_equal 'nijmegen', subject.region_slug
end

it 'has city from addr:city attribute' do
assert_equal 'Nijmegen', subject.city
end
end

@@ -35,12 +40,21 @@ describe Hours::Aggregates::RegionSlug do
}
end

it 'generates from offline_geocoder using city' do
it 'generates from offline_geocoder' do
assert_nil geojson[:properties][:'addr:city']
subject.offline_geocoder = offline_geocoder
offline_geocoder.expect(:search, bayswater, [lat, lon])

assert_equal 'bayswater', subject.region_slug
assert_mock offline_geocoder
end

it 'sets the city from offline_geocoder' do
assert_nil geojson[:properties][:'addr:city']
subject.offline_geocoder = offline_geocoder
offline_geocoder.expect(:search, bayswater, [lat, lon])

assert_equal 'bayswater', subject.region
assert_equal 'Bayswater', subject.city
assert_mock offline_geocoder
end
end

+ 23
- 4
test/aggregates/place_test.rb View File

@@ -9,15 +9,17 @@ describe Hours::Aggregates::Place do
let(:place_id) { 'PLACEID' }
let(:place_id_builder) { Minitest::Mock.new }
let(:region_slug) { 'region' }
let(:region_slug_builder) { Minitest::Mock.new }
let(:city) { 'Region' }
let(:region_builder) { Minitest::Mock.new }
subject { Hours::Aggregates::Place.new(aggregate_id, events) }

before do
place_id_builder.expect(:id, place_id)
subject.place_id_builder = place_id_builder

region_slug_builder.expect(:region, region_slug)
subject.region_slug_builder = region_slug_builder
region_builder.expect(:region_slug, region_slug)
region_builder.expect(:city, city)
subject.region_builder = region_builder
end

# This is implemented in EventSourcery::AggregateRoot, but it allows
@@ -38,6 +40,23 @@ describe Hours::Aggregates::Place do
it 'builds a region_slug' do
place = subject.add(payload)
assert_equal region_slug, place.region_slug
assert_mock region_slug_builder
assert_mock region_builder
end

describe 'when city is empty' do
it 'sets the addr:city from region' do
place = subject.add(payload)
assert_equal 'Region', place.changes.first.body['properties']['addr:city']
assert_mock region_builder
end
end

describe 'when city is not empty' do
let(:payload) { { properties: { 'addr:city' => 'City' } } }

it 'leaves the add:city alone' do
place = subject.add(payload)
assert_equal 'City', place.changes.first.body['properties']['addr:city']
end
end
end

Loading…
Cancel
Save