Commit 5869415c authored by Jamie Tanna's avatar Jamie Tanna
Browse files

Verify that Webmention endpoint is well formed

To ensure that I don't accidentally break my Webmention discovery in the
future, I want to use my newfound power with HTMLProofer's custom
`Check`s to catch future regressions in the metadata.

Note that we only check this on the home page as that's the important
place that a client would be looking it up - other pages may be valid,
but this is the key one.

Closes #386.
parent f971b2c0
Pipeline #52433925 passed with stages
in 6 minutes and 57 seconds
require_relative 'checks/home_page_has_valid_hcard'
require_relative 'checks/home_page_has_valid_webmention_endpoint'
require 'html-proofer'
require_relative '../../lib/predicates/valid_webmention_endpoint'
class HomePageHasValidWebmentionEndpoint < ::HTMLProofer::Check
def run
return unless './public/index.html' == @path
validator = ValidWebmentionEndpoint.new
element = @html.at('link[rel="webmention"]')
href = if element
element['href']
else
nil
end
begin
validator.validate(href)
rescue InvalidWebmentionEndpointError => e
add_issue(e.message)
end
end
end
class InvalidWebmentionEndpointError < RuntimeError
end
require_relative '../invalid_webmention_endpoint_error'
class ValidWebmentionEndpoint
VALID_URL = 'https://webmention.io/www.jvt.me/webmention'.freeze
def validate(url)
raise InvalidWebmentionEndpointError, "Webmention endpoint is not #{VALID_URL}" unless VALID_URL == url
end
end
<html>
<head>
<link rel="webmention" href="https://webmention.io/www.jvt.me/webmention" />
</head>
</html>
require 'spec_helper'
require 'nokogiri'
describe 'HomePageHasValidWebmentionEndpoint' do
context 'with no endpoint' do
let(:html) { Nokogiri::HTML(File.read('spec/fixtures/invalid_webmention_data.html')) }
let(:sut) { HomePageHasValidWebmentionEndpoint.new('', './public/index.html', html, {}) }
it 'adds an issue' do
wm = double('ValidWebmentionEndpoint')
allow(::ValidWebmentionEndpoint).to receive(:new)
.and_return wm
allow(wm).to receive(:validate)
.and_raise InvalidWebmentionEndpointError, 'Invalid Webmention endpoint'
expect(sut).to receive(:add_issue)
.with('Invalid Webmention endpoint')
.and_call_original
sut.run
expect(sut.issues.length).to eq 1
end
end
context 'with a valid endpoint' do
let(:html) { Nokogiri::HTML(File.read('spec/fixtures/valid_webmention_data.html')) }
let(:sut) { HomePageHasValidWebmentionEndpoint.new('', './public/index.html', html, {}) }
it 'does not add an issue' do
wm = double('ValidWebmentionEndpoint')
allow(::ValidWebmentionEndpoint).to receive(:new)
.and_return wm
allow(wm).to receive(:validate)
.and_return nil
sut.run
# no errors
expect(sut.issues.length).to be_zero
end
end
context 'when not on the home page' do
let(:html) { Nokogiri::HTML(File.read('spec/fixtures/invalid_webmention_data.html')) }
let(:sut) { HomePageHasValidWebmentionEndpoint.new('', './public/directory.html', html, {}) }
it 'does nothing' do
expect(sut).to_not receive(:add_issue)
expect(::ValidWebmentionEndpoint).to_not receive(:new)
# when
sut.run
end
end
end
require_relative '../../../lib/predicates/valid_webmention_endpoint'
describe 'ValidWebmentionEndpoint' do
let(:sut) { ValidWebmentionEndpoint.new }
context 'when nil' do
it 'throws' do
expect { sut.validate(nil)}.to raise_error(InvalidWebmentionEndpointError, 'Webmention endpoint is not https://webmention.io/www.jvt.me/webmention')
end
end
context 'when empty' do
it 'throws' do
expect { sut.validate('')}.to raise_error(InvalidWebmentionEndpointError, 'Webmention endpoint is not https://webmention.io/www.jvt.me/webmention')
end
end
context 'when different end of string ' do
it 'throws' do
expect { sut.validate('https://webmention.io/www.jvt.me/webmentions')}.to raise_error(InvalidWebmentionEndpointError, 'Webmention endpoint is not https://webmention.io/www.jvt.me/webmention')
end
end
context 'when valid' do
it 'does not throw' do
sut.validate('https://webmention.io/www.jvt.me/webmention')
# no error
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment