internal/deps/registry_test.go
90 lines · 2834 bytes
1package deps
2
3import (
4 "context"
5 "net/http"
6 "net/http/httptest"
7 "testing"
8)
9
10// fakeRegistry serves one canned body per path and records what was asked
11// for, so the test can check the URL each ecosystem builds.
12func fakeRegistry(t *testing.T, bodies map[string]string) (*httptest.Server, *[]string) {
13 t.Helper()
14 var asked []string
15 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
16 asked = append(asked, r.URL.Path)
17 body, ok := bodies[r.URL.Path]
18 if !ok {
19 http.NotFound(w, r)
20 return
21 }
22 w.Write([]byte(body))
23 }))
24 t.Cleanup(srv.Close)
25 return srv, &asked
26}
27
28func TestLatestPerEcosystem(t *testing.T) {
29 srv, asked := fakeRegistry(t, map[string]string{
30 "/github.com/!burnt!sushi/toml/@latest": `{"Version":"v1.6.0"}`,
31 "/@types/node": `{"dist-tags":{"latest":"20.11.5"}}`,
32 "/serde": `{"crate":{"max_stable_version":"1.0.197"}}`,
33 "/requests/json": `{"info":{"version":"2.31.0"}}`,
34 })
35 c := NewClient("test")
36 c.Hosts = map[string]string{EcoGo: srv.URL, EcoNPM: srv.URL, EcoCargo: srv.URL, EcoPyPI: srv.URL}
37
38 cases := []struct{ eco, name, want string }{
39 {EcoGo, "github.com/BurntSushi/toml", "v1.6.0"},
40 {EcoNPM, "@types/node", "20.11.5"},
41 {EcoCargo, "serde", "1.0.197"},
42 {EcoPyPI, "requests", "2.31.0"},
43 }
44 for _, c2 := range cases {
45 got, err := c.Latest(context.Background(), c2.eco, c2.name)
46 if err != nil {
47 t.Errorf("Latest(%s, %s): %v", c2.eco, c2.name, err)
48 continue
49 }
50 if got != c2.want {
51 t.Errorf("Latest(%s, %s) = %q, want %q", c2.eco, c2.name, got, c2.want)
52 }
53 }
54 if len(*asked) != 4 {
55 t.Errorf("asked for %v", *asked)
56 }
57}
58
59func TestLatestSkipsPrerelease(t *testing.T) {
60 srv, _ := fakeRegistry(t, map[string]string{"/x/json": `{"info":{"version":"2.0.0rc1"}}`})
61 c := NewClient("test")
62 c.Hosts = map[string]string{EcoPyPI: srv.URL}
63 got, err := c.Latest(context.Background(), EcoPyPI, "x")
64 if err != nil || got != "" {
65 t.Errorf("Latest = %q, %v; want no answer for a prerelease", got, err)
66 }
67}
68
69func TestLatestRejectsUnusableNames(t *testing.T) {
70 srv, asked := fakeRegistry(t, nil)
71 c := NewClient("test")
72 c.Hosts = map[string]string{EcoGo: srv.URL}
73 for _, name := range []string{"../../etc/passwd", "a/../b", "foo?bar", "foo bar", "", "-x"} {
74 if _, err := c.Latest(context.Background(), EcoGo, name); err == nil {
75 t.Errorf("Latest accepted %q", name)
76 }
77 }
78 if len(*asked) != 0 {
79 t.Errorf("unusable names reached the network: %v", *asked)
80 }
81}
82
83func TestLatestReportsHTTPError(t *testing.T) {
84 srv, _ := fakeRegistry(t, nil)
85 c := NewClient("test")
86 c.Hosts = map[string]string{EcoCargo: srv.URL}
87 if _, err := c.Latest(context.Background(), EcoCargo, "missing"); err == nil {
88 t.Error("Latest on a 404 returned no error")
89 }
90}