orchard
mirrorEvery 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
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}