a love letter to tangled (android, iOS, and a search API)
at main 123 lines 3.2 kB view raw
1package backfill 2 3import ( 4 "context" 5 "encoding/json" 6 "net/http" 7 "net/http/httptest" 8 "net/url" 9 "reflect" 10 "testing" 11) 12 13func TestHTTPLightrailClientListReposByCollectionSinglePage(t *testing.T) { 14 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 if r.URL.Path != "/xrpc/"+listReposByCollectionNSID { 16 http.NotFound(w, r) 17 return 18 } 19 _ = json.NewEncoder(w).Encode(map[string]any{ 20 "repos": []map[string]string{ 21 {"did": "did:plc:a"}, 22 {"did": "did:plc:b"}, 23 }, 24 }) 25 })) 26 defer srv.Close() 27 28 client := NewHTTPLightrailClient() 29 dids, err := client.ListReposByCollection( 30 context.Background(), srv.URL, []string{"sh.tangled.repo"}, 100, 31 ) 32 if err != nil { 33 t.Fatalf("list repos: %v", err) 34 } 35 36 want := []string{"did:plc:a", "did:plc:b"} 37 if !reflect.DeepEqual(dids, want) { 38 t.Fatalf("dids: got %#v want %#v", dids, want) 39 } 40} 41 42func TestHTTPLightrailClientListReposByCollectionPaginatesAndDedupes(t *testing.T) { 43 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 44 query := r.URL.Query() 45 cursor := query.Get("cursor") 46 switch cursor { 47 case "": 48 _ = json.NewEncoder(w).Encode(map[string]any{ 49 "cursor": "page-2", 50 "repos": []map[string]string{ 51 {"did": "did:plc:a"}, 52 {"did": "did:plc:b"}, 53 }, 54 }) 55 case "page-2": 56 _ = json.NewEncoder(w).Encode(map[string]any{ 57 "repos": []map[string]string{ 58 {"did": "did:plc:b"}, 59 {"did": "did:plc:c"}, 60 }, 61 }) 62 default: 63 t.Fatalf("unexpected cursor %q", cursor) 64 } 65 })) 66 defer srv.Close() 67 68 client := NewHTTPLightrailClient() 69 dids, err := client.ListReposByCollection( 70 context.Background(), srv.URL, []string{"sh.tangled.repo"}, 2, 71 ) 72 if err != nil { 73 t.Fatalf("list repos: %v", err) 74 } 75 76 want := []string{"did:plc:a", "did:plc:b", "did:plc:c"} 77 if !reflect.DeepEqual(dids, want) { 78 t.Fatalf("dids: got %#v want %#v", dids, want) 79 } 80} 81 82func TestHTTPLightrailClientListReposByCollectionAddsRepeatedCollections(t *testing.T) { 83 var got url.Values 84 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 85 got = r.URL.Query() 86 _ = json.NewEncoder(w).Encode(map[string]any{"repos": []map[string]string{}}) 87 })) 88 defer srv.Close() 89 90 client := NewHTTPLightrailClient() 91 if _, err := client.ListReposByCollection( 92 context.Background(), 93 srv.URL, 94 []string{"sh.tangled.actor.profile", "sh.tangled.repo"}, 95 50, 96 ); err != nil { 97 t.Fatalf("list repos: %v", err) 98 } 99 100 if got.Get("limit") != "50" { 101 t.Fatalf("limit: got %q", got.Get("limit")) 102 } 103 if values := got["collection"]; !reflect.DeepEqual(values, []string{ 104 "sh.tangled.actor.profile", 105 "sh.tangled.repo", 106 }) { 107 t.Fatalf("collections: got %#v", values) 108 } 109} 110 111func TestHTTPLightrailClientListReposByCollectionErrorsOnNonSuccess(t *testing.T) { 112 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { 113 http.Error(w, `{"message":"boom"}`, http.StatusBadGateway) 114 })) 115 defer srv.Close() 116 117 client := NewHTTPLightrailClient() 118 if _, err := client.ListReposByCollection( 119 context.Background(), srv.URL, []string{"sh.tangled.repo"}, 100, 120 ); err == nil { 121 t.Fatal("expected error") 122 } 123}