Browse Source

Merge branch 'feature/opening-details' into develop

* feature/opening-details:
  Include sundays in open_this_week attribute.
  Ensure we handle empty addresses correctly
  Remove unused method from place_id aggregate
  Ensure at_time helper also stubs out Date.today
  Allow make initiator to define the pattern of tests to be ran.
  Add Sunday to opening hours of fixture.
  Render an opening hours table in the detail page.
tags/0.3.0^2
Bèr Kessels 5 months ago
parent
commit
f18a1d975b

+ 2
- 1
Makefile View File

@@ -1,5 +1,6 @@
CMD_PREFIX=bundle exec
CONTAINER_NAME=hours_development
TEST_FILES_PATTERN ?= **/*_test.rb

# You want latexmk to *always* run, because make does not have all the info.
# Also, include non-file targets in .PHONY so they are run regardless of any
@@ -17,7 +18,7 @@ db:
# CUSTOM BUILD RULES
test: export APP_ENV=test
test:
$(CMD_PREFIX) ruby -I lib:test:. -e "Dir.glob('**/*_test.rb') { |f| require(f) }"
$(CMD_PREFIX) ruby -I lib:test:. -e "Dir.glob('$(TEST_FILES_PATTERN)') { |f| require(f) }"
lint:
$(CMD_PREFIX) rubocop


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

@@ -57,10 +57,6 @@ module Hours
{ lat: geometry.y, lon: geometry.x }
end

def address
properties.select { |key, _| key.to_s.match?(/addr:.*/) }
end

def categories
opr_catalog.map do |cat, predicament|
value_at_key = properties[predicament['key']]

+ 22
- 10
app/models/place.rb View File

@@ -43,11 +43,13 @@ module Hours
end

def address
return unless raw_address

OpenStruct.new(Sequel::Postgres::HStore.parse(raw_address).to_hash)
end

def region
address.city
address&.city
end

def raw_address
@@ -63,28 +65,38 @@ module Hours
def get_intervals_as_week(date_ranges, date_in_week)
from = beginning_of_week(date_in_week)
to = end_of_week(date_in_week)
# Ensure we always get an array to append to.
as_week = Hash.new { |hash, key| hash[key] = [] }

this_week = ITERATOR.get_time_iterator(date_ranges).select do |interval|
interval[:start] >= from && interval[:end] <= to
end

this_week.each do |interval|
as_week = european_week.dup
intervals_for(date_ranges, from, to).each do |interval|
as_week[interval[:start].wday] << interval
end

as_week
end

def intervals_for(date_ranges, from, to)
ITERATOR.get_time_iterator(date_ranges).select do |interval|
interval[:start] >= from && interval[:end] <= to
end
end

# Sets up an empty 7-day week template
def european_week
week = {}
[1, 2, 3, 4, 5, 6, 0].each do |wday|
week[wday] = []
end
week
end

def beginning_of_week(date)
days_to_monday = date.wday != 0 ? date.wday - 1 : 6
(date - days_to_monday).to_time
end

def end_of_week(date)
days_to_sunday = date.wday != 0 ? 7 - date.wday : 0
(date + days_to_sunday).to_time
days_to_next_monday = date.wday != 0 ? 8 - date.wday : 1
(date + days_to_next_monday).to_time - 1
end
end
end

+ 1
- 1
app/projections/query.rb View File

@@ -86,7 +86,7 @@ module Hours
first_place = dataset.select(:address).first(region_slug: @region_slug)
return unless first_place

@region_name = Hours::Models::Place.new(first_place).address[:city]
@region_name = Hours::Models::Place.new(first_place).region
end
end
end

+ 23
- 0
app/views/place.erb View File

@@ -30,5 +30,28 @@
<%= @place.address.city %>
</span>
</address>

<% @wday_idx = %w[Zo Ma Di Wo Do Vr Za] %>
<table id="opening_hours" class="table-responsive table-sm table-hover">
<tbody>
<% @place.open_this_week.each do |wday, openings| %>
<tr>
<% if wday == Date.today.wday %>
<th scope="row"><strong><%= @wday_idx[wday] %></strong></th>
<% openings.each do |slot| %>
<td><strong><%= slot[:start].strftime('%H:%M') %></strong></td>
<td><strong><%= slot[:end].strftime('%H:%M') %><strong></td>
<% end %>
<% else %>
<th scope="row"><%= @wday_idx[wday] %></th>
<% openings.each do |slot| %>
<td><%= slot[:start].strftime('%H:%M') %></td>
<td><%= slot[:end].strftime('%H:%M') %></td>
<% end %>
<% end %>
</tr>
<% end %>
</tbody>
</table>
</div>
</section>

+ 9
- 9
test/fixtures/input/addressless.json View File

@@ -1,11 +1,11 @@
{
"id": 42,
"name": "Sint-Nicolaaskapel",
"addr_housenumber": null,
"addr_postcode": null,
"addr_street": null,
"addr_city": null,
"addr_country_code": null,
"opening_hours": "24/7; PH closed",
"geometry": { "type": "Point", "coordinates": [51.8473397, 5.8653234] }
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [5.8653234, 51.8473397]
},
"properties": {
"name": "Sint-Nicolaaskapel",
"opening_hours": "24/7; PH closed"
}
}

+ 1
- 1
test/fixtures/input/hm_burchtstraat.json View File

@@ -14,7 +14,7 @@
"addr:postcode": "6511RA",
"addr:street": "Burchtstraat",
"name": "H&M",
"opening_hours": "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30",
"opening_hours": "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30; Su 12:00-17:30",
"shop": "clothes",
"shop:number": "NL0050",
"source": "BAG;http://www.hm.com/nl/",

+ 7
- 1
test/fixtures/output/hm_burchtstraat.json View File

@@ -44,9 +44,15 @@
"start": "1989-11-11 09:30:00 +0100",
"end": "1989-11-11 17:30:00 +0100"
}
],
"0": [
{
"start": "1989-11-12 12:00:00 +0100",
"end": "1989-11-12 17:30:00 +0100"
}
]
},
"raw_opening_hours": "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30",
"raw_opening_hours": "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30; Su 12:00-17:30",
"address": {
"postcode": "6511RA",
"city": "Nijmegen",

+ 5
- 1
test/fixtures/output/places.json View File

@@ -17,7 +17,7 @@
"type" : "place",
"attributes" : {
"place_id": "9F37RV00+;shop:clothes;hm",
"raw_opening_hours" : "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30",
"raw_opening_hours" : "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30; Su 12:00-17:30",
"open_this_week" : {
"1": [{
"start" : "1989-11-06 10:00:00 +0100",
@@ -42,6 +42,10 @@
"6": [{
"start" : "1989-11-11 09:30:00 +0100",
"end" : "1989-11-11 17:30:00 +0100"
}],
"0": [{
"start": "1989-11-12 12:00:00 +0100",
"end": "1989-11-12 17:30:00 +0100"
}]
},
"name" : "H&M",

+ 11
- 0
test/integration/web/view_places_test.rb View File

@@ -33,6 +33,17 @@ describe 'web view places' do

# A badge with class success means open.
page.assert_selector('span.badge-success', text: 'Open')

within('table#opening_hours') do
page.assert_selector('tr', text: 'Ma 10:00 18:00')
page.assert_selector('tr', text: 'Zo 12:00 17:30')

# Current day is Thursday. Current Day is bold
assert_equal 4, die_wende.wday
page.assert_selector('tr>th>strong', text: 'Do')
page.assert_selector('tr>td>strong', text: '10:00')
page.assert_selector('tr>td>strong', text: '21:00')
end
end
end


+ 73
- 5
test/models/place_test.rb View File

@@ -28,18 +28,26 @@ describe Hours::Models::Place do
it 'has a city' do
assert_equal 'Nijmegen', subject.address.city
end

it 'handles nil addresses' do
subject.address = nil
assert_nil subject.address&.city
end
end

describe 'region' do
describe 'with city' do
before do
subject.address = hstore_address
end
before { subject.address = hstore_address }

it 'uses the city' do
assert_equal 'Nijmegen', subject.region
end
end

it 'handles nil addresses' do
subject.address = nil
assert_nil subject.region
end
end

describe 'location' do
@@ -57,13 +65,73 @@ describe Hours::Models::Place do
end

describe 'opening_hours' do
let(:opening_hours) { '1989 Mo-Fr 10:00-19:00' }
let(:opening_hours) { '1989 Mo-Fr 10:00-12:30,13:00-19:00' }

let(:first_start) { Time.parse('1989-11-06 10:00:00 +0100') }

before do
subject.opening_hours = opening_hours
end

describe 'status' do
describe '#open_this_week' do
it 'has all 7 days' do
at_time do
assert_equal 7, subject.open_this_week.length
assert_equal [1, 2, 3, 4, 5, 6, 0], subject.open_this_week.keys
end
end

it 'has a start and end entry for each timerange' do
at_time do
# Sanity check: it should be wednesday
assert_equal 4, Date.today.wday
assert_equal 2, subject.open_this_week[4].length
assert_equal(
[{
start: Time.parse('1989-11-09 10:00:00 +0100'),
end: Time.parse('1989-11-09 12:30:00 +0100')
}, {
start: Time.parse('1989-11-09 13:00:00 +0100'),
end: Time.parse('1989-11-09 19:00:00 +0100')
}],
subject.open_this_week[4]
)
end
end

it 'correctly identifies the beginning of this week' do
at_time do
assert_equal 4, Date.today.wday
assert_equal first_start, subject.open_this_week[1][0][:start]
end
# When it is monday, we must still correctly identify this week
# Checking for fencepost errors
at_time(Time.parse('1989-11-06 00:00:00')) do
assert_equal 1, Date.today.wday
assert_equal first_start, subject.open_this_week[1][0][:start]
end
end

it 'correctly identifies the end of this week' do
at_time do
assert_equal 4, Date.today.wday
# Sunday has no entries
assert_nil subject.open_this_week[0][0]
end
# When it is the last second of sunday, we must still correctly
# identify this week.
# Checking for fencepost errors
at_time(Time.parse('1989-11-12 23:59:59')) do
assert_equal 0, Date.today.wday
# Still no entries for sunday
assert_nil subject.open_this_week[0][0]
# But let's check that we are in the correct week by checking monday
assert_equal first_start, subject.open_this_week[1][0][:start]
end
end
end

describe '#status' do
it 'is :open between 10:00 and 19:00' do
at_time do
assert_time_after(Time.parse('10:00'))

+ 4
- 3
test/projections/query_test.rb View File

@@ -102,13 +102,14 @@ describe Hours::Projections::RegionQuery do
id: SecureRandom.uuid,
place_id: SecureRandom.hex,
region_slug: 'nijmegen',
location: location
location: location,
address: Sequel.hstore(city: 'Nijmegen')
)
end
result = subject.handle('nijmegen')
assert_equal result.centerpoint, center
places = result.to_a
assert_equal center, result.centerpoint

places = result.to_a
distance0 = center.euclidian_distance(places[0].location)
distance1 = center.euclidian_distance(places[1].location)
assert distance1 > distance0

+ 12
- 1
test/support/time_helpers.rb View File

@@ -6,12 +6,23 @@ module TimeHelpers
# stub goes away once the block is done
def at_time(time = die_wende, &block)
Time.stub :now, time do
yield block
Date.stub :today, time.to_date do
yield block
end
end
end

##
# Time Helper, returns a Time
# Time is the moment the Berlin Wall fell: 9-11-1989 18:57:00
#
# November 1989
# zo ma di wo do vr za
# 1 2 3 4
# > 5 6 7 8 9 10 11
# 12 13 14 15 16 17 18
# 19 20 21 22 23 24 25
# 26 27 28 29 30
def die_wende
Time.local(1989, 11, 9, 18, 57, 0, 0)
end

Loading…
Cancel
Save