diff --git a/bingo_web.rb b/bingo_web.rb index 5e2a340..fea9a14 100644 --- a/bingo_web.rb +++ b/bingo_web.rb @@ -39,17 +39,31 @@ class BingoWeb < Sinatra::Base 'publisher' => { '@type' => 'Person', 'name' => 'asxpi', 'url' => 'https://asxp.io' } }, { '@type' => 'ItemList', 'url' => url, 'name' => t(:seo_title), 'description' => desc, 'inLanguage' => @locale, 'numberOfItems' => board.cells.size, + 'dateModified' => board.updated_on&.utc&.iso8601, 'itemListElement' => board.cells.each_with_index.map do |dc, i| - place = { '@type' => 'Place', 'name' => dc.l(:name, @locale), - 'address' => { '@type' => 'PostalAddress', 'addressLocality' => dc.l(:city, @locale), 'addressCountry' => 'RU' } } - place['image'] = "#{base_url}#{photo_path(dc, 1200)}" if dc.photo_key - place['sameAs'] = dc.info_url if dc.info_url - { '@type' => 'ListItem', 'position' => i + 1, 'item' => place } - end } + { '@type' => 'ListItem', 'position' => i + 1, 'item' => ld_place(dc) } + end }.compact ] ).gsub(' 'PostalAddress', 'addressLocality' => dc.l(:city, @locale), 'addressCountry' => 'RU' } + place = { '@type' => 'Place', 'name' => dc.l(:name, @locale), 'address' => address } + place['image'] = "#{base_url}#{photo_path(dc, 1200)}" if dc.photo_key + place['subjectOf'] = { '@type' => 'CreativeWork', 'url' => dc.info_url } if dc.info_url + events = dc.incidents.map do |i| + { '@type' => 'Event', 'name' => "#{kind_label(i.kind)}: #{i.l(:title, @locale)}", + 'startDate' => i.occurred_on.iso8601, 'url' => i.url, + 'location' => { '@type' => 'Place', 'name' => place['name'], 'address' => address } }.compact + end + place['event'] = events if events.any? + place + end + # Preview image: the most recent hit with a photo, else the first photo. def og_dc(board) board.incidents.map(&:datacenter).find(&:photo_key) || board.cells.find(&:photo_key) diff --git a/test/bingo_test.rb b/test/bingo_test.rb index 54f9a41..9d6ab31 100644 --- a/test/bingo_test.rb +++ b/test/bingo_test.rb @@ -209,6 +209,7 @@ class BingoTest < Minitest::Test def test_seo_head hit!(3) @dcs[3].update(photo_key: 'bingo/dc-4-0123abcd.jpg', photo_variants: true) + @dcs[0].update(info_url: 'https://example.com/dc-1') get '/en' body = last_response.body assert_includes body, 'Datacenter Bingo — strikes' @@ -228,6 +229,13 @@ class BingoTest < Minitest::Test list = ld['@graph'].find { |n| n['@type'] == 'ItemList' } assert_equal 25, list['itemListElement'].size assert_equal 'DC 1', list['itemListElement'][0]['item']['name'] + hit = list['itemListElement'][3]['item'] + assert_equal Date.today.iso8601, hit['event'][0]['startDate'] + assert_equal 'Outage: Авария 3', hit['event'][0]['name'] + refute list['itemListElement'][0]['item'].key?('event') + assert_equal({ '@type' => 'CreativeWork', 'url' => 'https://example.com/dc-1' }, list['itemListElement'][0]['item']['subjectOf']) + refute_includes body, 'sameAs' + assert list['dateModified'] end def test_photo_falls_back_to_original_without_variants