This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / repoverify / verify_test.go
3.1 kB 99 lines
1package repoverify 2 3import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "net/http" 8 "net/http/httptest" 9 "strings" 10 "testing" 11 12 "github.com/bluesky-social/indigo/atproto/identity" 13 "tangled.org/core/api/tangled" 14 "tangled.org/core/idresolver" 15 "tangled.org/core/repoident" 16) 17 18const ( 19 testRepoDid = repoident.RepoDid("did:plc:limpet") 20 testOwnerDid = "did:plc:akshay" 21) 22 23func describeRepoServer(t *testing.T, describedRepoDid repoident.RepoDid) *httptest.Server { 24 t.Helper() 25 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 26 if r.URL.Path != "/xrpc/"+tangled.RepoDescribeRepoNSID { 27 http.NotFound(w, r) 28 return 29 } 30 w.Header().Set("Content-Type", "application/json") 31 _ = json.NewEncoder(w).Encode(tangled.RepoDescribeRepo_Output{ 32 RepoDid: describedRepoDid.String(), 33 OwnerDid: testOwnerDid, 34 Rkey: "3kkkkkkkkkkkk", 35 }) 36 })) 37 t.Cleanup(srv.Close) 38 return srv 39} 40 41func verifyKnot(t *testing.T, knotURL string, dev bool) (Result, error) { 42 t.Helper() 43 resolver := idresolver.NewMockResolver(idresolver.MockDirectory{Ident: &identity.Identity{ 44 Services: map[string]identity.ServiceEndpoint{ 45 repoident.KnotServiceID: {Type: repoident.KnotServiceType, URL: knotURL}, 46 }, 47 }}) 48 return New(resolver, dev)(context.Background(), testRepoDid) 49} 50 51func TestNew_DevModeAcceptsHttpKnotEndpointAndStripsThePath(t *testing.T) { 52 srv := describeRepoServer(t, testRepoDid) 53 54 result, err := verifyKnot(t, srv.URL+"/repo/m5326fp3qemiriiqypxv6rrhai", true) 55 if err != nil { 56 t.Fatalf("dev mode should accept an http knot endpoint: %v", err) 57 } 58 if result.OwnerDid.String() != testOwnerDid { 59 t.Errorf("OwnerDid = %q, want %q", result.OwnerDid, testOwnerDid) 60 } 61 if result.KnotURL.String() != srv.URL { 62 t.Errorf("KnotURL = %q, want %q", result.KnotURL, srv.URL) 63 } 64} 65 66func TestNew_Rejections(t *testing.T) { 67 target := describeRepoServer(t, testRepoDid) 68 otherRepo := describeRepoServer(t, "did:plc:anemone") 69 redirector := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 70 http.Redirect(w, r, target.URL+r.URL.Path, http.StatusFound) 71 })) 72 t.Cleanup(redirector.Close) 73 74 cases := map[string]struct { 75 knotURL string 76 dev bool 77 want string 78 sentinel error 79 }{ 80 "http endpoint outside dev mode": {target.URL, false, "must use https", nil}, 81 "knot redirects elsewhere": {redirector.URL, true, "describeRepo on", nil}, 82 "identity declares no knot": {"", true, "", repoident.ErrNoKnotService}, 83 "describeRepo answers for another repo": {otherRepo.URL, true, `repoDid "did:plc:anemone"`, ErrKnotAnswer}, 84 } 85 for name, tc := range cases { 86 t.Run(name, func(t *testing.T) { 87 _, err := verifyKnot(t, tc.knotURL, tc.dev) 88 if err == nil { 89 t.Fatalf("verify accepted a knot it should reject") 90 } 91 if !strings.Contains(err.Error(), tc.want) { 92 t.Errorf("error = %v, want one mentioning %q", err, tc.want) 93 } 94 if tc.sentinel != nil && !errors.Is(err, tc.sentinel) { 95 t.Errorf("error = %v, want one matching %v", err, tc.sentinel) 96 } 97 }) 98 } 99}