Improve webmention verification and add automatic test

This commit is contained in:
Jan-Lukas Else 2021-11-10 22:24:36 +01:00
parent dd54d20a1c
commit d6ff2f7bd8
3 changed files with 100 additions and 6 deletions

33
testdata/wmtest.html vendored Normal file
View File

@ -0,0 +1,33 @@
<!-- Modified from https://jan.boddez.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms -->
<!doctype html>
<html lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Tests Blog &mdash; Micropub, Crossposting to Twitter, and Enabling &#8220;Tweetstorms&#8221;</title>
<meta property="og:title" content="Micropub, Crossposting to Twitter, and Enabling &#8220;Tweetstorms&#8221;">
<meta property="og:url" content="https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms">
<meta property="og:type" content="website">
</head>
<body class="single">
<main id="content" class="site-content">
<article class="h-entry post">
<header class="entry-header">
<h1 class="entry-title p-name">Micropub, Crossposting to Twitter, and Enabling &#8220;Tweetstorms&#8221;</h1>
<div class="p-author h-card vcard sr-only">
By <a class="u-uid u-url url" href="https://example.net/" rel="me"><img class="u-photo" src="/images/photo.jpg" alt="Tests photo" width="75" height="75"> <span class="p-name fn">Test Blogger</span></a>
</div>
<div class="entry-meta">On <a class="u-url" href="https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms" rel="bookmark"><time datetime="2021-02-22T19:17:05+01:00" class="dt-published">Feb 22, 2021</time></a></div>
</header>
<div class="e-content">
<p>I&#8217;ve previously talked about how I <a href="https://example.org/articles/micropub-syndication-targets-and-crossposting-to-mastodon">crosspost from this blog to my Mastodon account</a> without the need for a third-party service, and how I leverage WordPress&#8217;s hook system to even enable toot threading.</p>
<p>In this post, I&#8217;m going to really quickly explain my (extremely similar) Twitter setup. (Note: I don&#8217;t actually syndicate <em>this</em> blog&#8217;s posts to Twitter, but I <em>do</em> use this very setup on another site of mine.)</p>
<p>I liked the idea of a dead-simple Twitter plugin, so I forked my Mastodon plugin and tweaked a few things here and there. Once I&#8217;ve installed it, and created a developer account, generated the necessary keys, and let WordPress know about them, things look, well, <em>very</em> familiar. In fact, crossposting should now <em>just work</em>.</p>
<p>Now, to enable this when posting through Micropub rather than WordPress&#8217;s admin interface! Again, since posting through Micropub means no WordPress interface, and thus no &#8220;meta box&#8221; and no checkbox, and no way for WordPress to know if I wanted to crosspost a certain article or not, I&#8217;m going to have to use &#8230; <em>syndication targets</em> (which were invented precisely for this reason).</p>
</div>
<footer class="entry-footer">
<p class="entry-meta tags">Tagged: <a href="https://example.net/articles/tag/wordpress" rel="tag" class="p-category">wordpress</a>, <a href="https://example.net/articles/tag/indieweb" rel="tag" class="p-category">indieweb</a></p>
</footer>
</article>
</main>
</body>
</html>

View File

@ -85,9 +85,10 @@ func (a *goBlog) verifyMention(m *mention) error {
}
}
// Check if source has a redirect
ru := resp.Request.URL
if m.Source != ru.String() {
m.NewSource = ru.String()
if respReq := resp.Request; respReq != nil {
if ru := respReq.URL; m.Source != ru.String() {
m.NewSource = ru.String()
}
}
// Parse response body
err = m.verifyReader(resp.Body)
@ -105,6 +106,7 @@ func (a *goBlog) verifyMention(m *mention) error {
if cr := []rune(m.Content); len(cr) > 500 {
m.Content = string(cr[0:497]) + "…"
}
m.Content = strings.ReplaceAll(m.Content, "\n", " ")
if tr := []rune(m.Title); len(tr) > 60 {
m.Title = string(tr[0:57]) + "…"
}
@ -132,11 +134,17 @@ func (a *goBlog) verifyMention(m *mention) error {
sql.Named("source", m.Source),
sql.Named("target", m.Target),
)
if err != nil {
return err
}
} else {
if m.NewSource != "" {
m.Source = m.NewSource
}
_ = a.db.insertWebmention(m, newStatus)
err = a.db.insertWebmention(m, newStatus)
if err != nil {
return err
}
a.sendNotification(fmt.Sprintf("New webmention from %s to %s", m.Source, m.Target))
}
return err
@ -223,8 +231,8 @@ func (m *mention) fillTitle(mf *microformats.Microformat) {
func (m *mention) fillContent(mf *microformats.Microformat) {
if contents, ok := mf.Properties["content"]; ok && len(contents) > 0 {
if content, ok := contents[0].(map[string]string); ok {
if contentValue, ok := content["value"]; ok {
m.Content = strings.TrimSpace(contentValue)
if contentHTML, ok := content["html"]; ok {
m.Content = cleanHTMLText(contentHTML)
}
}
}

View File

@ -0,0 +1,53 @@
package main
import (
"net/http"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
func Test_verifyMention(t *testing.T) {
testHtmlBytes, err := os.ReadFile("testdata/wmtest.html")
require.NoError(t, err)
testHtml := string(testHtmlBytes)
mockClient := &fakeHttpClient{}
mockClient.setFakeResponse(http.StatusOK, testHtml)
app := &goBlog{
httpClient: mockClient,
cfg: &config{
Db: &configDb{
File: filepath.Join(t.TempDir(), "test.db"),
},
Server: &configServer{
PublicAddress: "https://example.org",
},
},
}
_ = app.initDatabase(false)
app.initComponents(false)
m := &mention{
Source: "https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms",
Target: "https://example.org/articles/micropub-syndication-targets-and-crossposting-to-mastodon",
}
err = app.verifyMention(m)
require.NoError(t, err)
require.Equal(t, "https://example.org/articles/micropub-syndication-targets-and-crossposting-to-mastodon", m.Target)
require.Equal(t, "https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms", m.Source)
require.Equal(t, "Micropub, Crossposting to Twitter, and Enabling “Tweetsto…", m.Title)
require.Equal(t, "Ive previously talked about how I crosspost from this blog to my Mastodon account without the need for a third-party service, and how I leverage WordPresss hook system to even enable toot threading. In this post, Im going to really quickly explain my (extremely similar) Twitter setup. (Note: I dont actually syndicate this blogs posts to Twitter, but I do use this very setup on another site of mine.) I liked the idea of a dead-simple Twitter plugin, so I forked my Mastodon plugin and twea…", m.Content)
require.Equal(t, "Test Blogger", m.Author)
err = app.verifyMention(m)
require.NoError(t, err)
}