repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

2.3 KB · 81 lines · Go Raw History
 1package tools
 2
 3import (
 4	"context"
 5	"net/http"
 6	"net/http/httptest"
 7	"strings"
 8	"testing"
 9)
10
11const ddgXPage = `
12<a rel="nofollow" class="result__a" href="https://x.com/someone/status/1234">A post about Go</a>
13<a class="result__snippet" href="#">the snippet of the post</a>
14<a rel="nofollow" class="result__a" href="https://twitter.com/someone/status/5678">An older post</a>
15<a class="result__snippet" href="#">indexed under the old hostname</a>
16<a rel="nofollow" class="result__a" href="https://x.com/someone">The profile page</a>
17<a class="result__snippet" href="#">not a post</a>
18<a rel="nofollow" class="result__a" href="https://example.com/blog/x-thoughts">Someone's blog</a>
19<a class="result__snippet" href="#">not x at all</a>
20`
21
22// xcancel and Nitter are both closed, and the paid API needs a key, so a site
23// search is the way in. It has to keep the posts and drop everything else a
24// site search also returns.
25func TestXSearchKeepsPostsAndNormalisesTheHost(t *testing.T) {
26	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27		if !strings.Contains(r.URL.RawQuery, "site%3Ax.com") {
28			t.Errorf("the search was not scoped to x.com: %s", r.URL.RawQuery)
29		}
30		_, _ = w.Write([]byte(ddgXPage))
31	}))
32	defer srv.Close()
33
34	hits := parseDDG(ddgXPage, 0)
35	if len(hits) != 4 {
36		t.Fatalf("parsed %d results, want 4", len(hits))
37	}
38
39	var posts []SearchHit
40	for _, h := range hits {
41		if isXPost(h.URL) {
42			h.URL = asXCom(h.URL)
43			posts = append(posts, h)
44		}
45	}
46	if len(posts) != 2 {
47		t.Fatalf("kept %d posts, want the two status pages: %#v", len(posts), posts)
48	}
49	// One hostname in one answer, since twitter.com only redirects.
50	for _, p := range posts {
51		if !strings.HasPrefix(p.URL, "https://x.com/") {
52			t.Errorf("a link was left on the old hostname: %s", p.URL)
53		}
54	}
55	_ = context.Background()
56}
57
58func TestIsXPost(t *testing.T) {
59	yes := []string{
60		"https://x.com/a/status/1",
61		"https://twitter.com/a/status/1",
62		"https://www.x.com/a/status/1?s=20",
63	}
64	for _, u := range yes {
65		if !isXPost(u) {
66			t.Errorf("%s was not taken as a post", u)
67		}
68	}
69	no := []string{
70		"https://x.com/someone",
71		"https://x.com/hashtag/go",
72		"https://help.x.com/en/using-x",
73		"https://example.com/a/status/1",
74	}
75	for _, u := range no {
76		if isXPost(u) {
77			t.Errorf("%s was taken as a post", u)
78		}
79	}
80}