Discover Web App Manifest in HTML

... and return a hash of the JSON data.
This commit is contained in:
Basti 2018-06-28 21:11:52 -07:00
parent ee49c0bfaf
commit 193319945a
6 changed files with 132 additions and 15 deletions

View File

@ -13,8 +13,25 @@ module Manifique
end end
def fetch_web_manifest def fetch_web_manifest
do_get_request @url res = do_get_request @url
# binding.pry links = parse_http_link_header(res)
doc = Nokogiri::HTML(res.body)
manifest_url = discover_web_manifest_url(links, doc)
unless manifest_url.match(/^https?\:\/\//)
# Link is just the manifest path, not an absolute URL
manifest_url = @url + manifest_url
end
res = do_get_request manifest_url
begin
manifest_data = JSON.parse(res.body)
rescue
manifest_data = false
end
manifest_data
end end
private private
@ -31,5 +48,20 @@ module Manifique
res res
end end
end end
def parse_http_link_header(response)
link_parser = Nitlink::Parser.new
link_parser.parse(response)
end
def discover_web_manifest_url(links, doc)
# TODO implement/test link header discovery
# if url = links.by_rel('manifest').target.to_s or
if url = doc.at_css("link[rel=manifest]").attributes["href"].value
return url
else
raise "No Web App Manifest found on #{@url}"
end
end
end end
end end

1
manifest.json Normal file
View File

@ -0,0 +1 @@
{"name":"kosmos.social","short_name":"kosmos.social","description":"A friendly place for tooting. Run by the Kosmos peeps.","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"}],"theme_color":"#282c37","background_color":"#191b22","display":"standalone","start_url":"/web/timelines/home","scope":"https://kosmos.social/","share_target":{"url_template":"share?title={title}\u0026text={text}\u0026url={url}"}}

View File

@ -0,0 +1,20 @@
{
"name": "kosmos.social",
"short_name": "kosmos.social",
"description": "A friendly place for tooting. Run by the Kosmos peeps.",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"theme_color": "#282c37",
"background_color": "#191b22",
"display": "standalone",
"start_url": "/web/timelines/home",
"scope": "https://kosmos.social/",
"share_target": {
"url_template": "share?title={title}&text={text}&url={url}"
}
}

38
spec/fixtures/mastodon.html vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -5,8 +5,8 @@ RSpec.describe Manifique::Agent do
describe "URL validation" do describe "URL validation" do
context "with invalid URL" do context "with invalid URL" do
it "raises an exception" do it "raises an exception" do
expect { Manifique::Agent.new }.to raise_error expect { Manifique::Agent.new }.to raise_error(RuntimeError)
expect { Manifique::Agent.new(url: "htp://example.com") }.to raise_error expect { Manifique::Agent.new(url: "htp://example.com") }.to raise_error(RuntimeError)
end end
end end

View File

@ -2,18 +2,18 @@ require "spec_helper"
require "manifique/web_client" require "manifique/web_client"
RSpec.describe Manifique::WebClient do RSpec.describe Manifique::WebClient do
before do
stub_request(:get, "http://example.com/200_empty").
to_return(body: "", status: 200, headers: {})
stub_request(:get, "http://example.com/404").
to_return(body: "", status: 404, headers: {})
stub_request(:get, "http://example.com/500").
to_return(body: "", status: 500, headers: {})
end
describe "#do_get_request" do describe "#do_get_request" do
before do
stub_request(:get, "http://example.com/404").
to_return(body: "", status: 404, headers: {})
stub_request(:get, "http://example.com/500").
to_return(body: "", status: 500, headers: {})
stub_request(:get, "http://example.com/200_empty").
to_return(body: "", status: 200, headers: {})
end
context "unsuccessful requests" do context "unsuccessful requests" do
describe "404" do describe "404" do
let(:client) { Manifique::WebClient.new } let(:client) { Manifique::WebClient.new }
@ -48,4 +48,30 @@ RSpec.describe Manifique::WebClient do
end end
end end
end end
describe "#fetch_web_manifest" do
context "link[rel=manifest] present" do
before do
index_html = File.read(File.join(__dir__, "..", "fixtures", "mastodon.html"));
stub_request(:get, "https://kosmos.social/").
to_return(body: index_html, status: 200, headers: {
"Content-Type": "text/html; charset=utf-8"
})
manifest = File.read(File.join(__dir__, "..", "fixtures", "mastodon-web-app-manifest.json"));
stub_request(:get, "https://kosmos.social/mastodon-web-app-manifest.json").
to_return(body: manifest, status: 200, headers: {
"Content-Type": "application/json; charset=utf-8"
})
end
let(:agent) { Manifique::WebClient.new(url: "https://kosmos.social") }
subject { agent.fetch_web_manifest }
it "fetches and returns the manifest" do
expect(subject).to be_kind_of(Hash)
expect(subject["name"]).to eq("kosmos.social")
end
end
end
end end