bingo: ping IndexNow when the card changes
A newly recorded incident only showed up in search once a crawler happened to come back. IndexNow lets Bing, Yandex and the other participating engines know about changed URLs right away. Bingo::IndexNow posts the card URLs plus the affected datacenter pages to api.indexnow.org, in a background thread so admin saves don't wait. Incidents ping their datacenter. Edits ping the datacenter, or every page when positions move (create, delete, reorder, sort). A deleted datacenter's pages are included so the engines see the 404. BingoWeb serves the key at /<key>.txt. The key comes from the INDEXNOW Forgejo secret, written to .env as INDEXNOW_KEY. With no key set this does nothing. Assisted-by: Claude:opus-5
This commit is contained in:
parent
ca48f4292b
commit
26e862ff04
6 changed files with 106 additions and 2 deletions
|
|
@ -1,4 +1,5 @@
|
|||
require_relative 'test_helper'
|
||||
require 'minitest/mock'
|
||||
|
||||
class BingoTest < Minitest::Test
|
||||
include Rack::Test::Methods
|
||||
|
|
@ -288,6 +289,52 @@ class BingoTest < Minitest::Test
|
|||
assert_includes body, '<div class="dc"><a href="/en/dc/dc-1">DC 1</a>'
|
||||
end
|
||||
|
||||
def with_env(vars)
|
||||
old = vars.to_h { |k, _| [k, ENV[k]] }
|
||||
vars.each { |k, v| ENV[k] = v }
|
||||
yield
|
||||
ensure
|
||||
old.each { |k, v| ENV[k] = v }
|
||||
end
|
||||
|
||||
def test_indexnow_key_file
|
||||
get '/0123456789abcdef.txt'
|
||||
assert_equal 404, last_response.status
|
||||
with_env('INDEXNOW_KEY' => '0123456789abcdef') do
|
||||
get '/0123456789abcdef.txt'
|
||||
assert last_response.ok?
|
||||
assert_equal '0123456789abcdef', last_response.body
|
||||
get '/fedcba9876543210.txt'
|
||||
assert_equal 404, last_response.status
|
||||
end
|
||||
end
|
||||
|
||||
def test_indexnow_ping
|
||||
assert_nil Bingo::IndexNow.ping([@dcs[0]]) # no key: nothing sent
|
||||
sent = []
|
||||
with_env('INDEXNOW_KEY' => '0123456789abcdef', 'BINGO_HOST' => 'bingo.example') do
|
||||
Bingo::IndexNow.stub(:deliver, ->(body) { sent << JSON.parse(body) }) do
|
||||
Bingo::IndexNow.ping([@dcs[0]]).join
|
||||
end
|
||||
end
|
||||
body = sent.fetch(0)
|
||||
assert_equal 'bingo.example', body['host']
|
||||
assert_equal 'https://bingo.example/0123456789abcdef.txt', body['keyLocation']
|
||||
assert_equal %w[/ru /en /uk /ru/dc/dc-1 /en/dc/dc-1 /uk/dc/dc-1].map { |p| "https://bingo.example#{p}" }, body['urlList']
|
||||
end
|
||||
|
||||
def test_admin_incident_pings_indexnow
|
||||
@app = AsxpioWeb
|
||||
token = admin_token
|
||||
pinged = []
|
||||
Bingo::IndexNow.stub(:ping, ->(dcs) { pinged << dcs.map(&:slug) }) do
|
||||
post '/admin/bingo/incidents', { authenticity_token: token, datacenter_id: @dcs[2].id, occurred_on: '2026-10-01',
|
||||
kind: 'fire', title_ru: 'Пожар' }, admin_env
|
||||
post "/admin/bingo/incidents/#{Bingo::Incident.first.id}/delete", { authenticity_token: token }, admin_env
|
||||
end
|
||||
assert_equal [['dc-3'], ['dc-3']], pinged
|
||||
end
|
||||
|
||||
def test_root_varies_on_language
|
||||
get '/'
|
||||
assert_equal 'Accept-Language', last_response.headers['Vary']
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue