package imgbundler import ( "context" "crypto/rand" _ "embed" "fmt" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "oss.terrastruct.com/util-go/cmdlog" "oss.terrastruct.com/util-go/xos" "oss.terrastruct.com/util-go/xmain" ) //go:embed test_png.png var testPNGFile []byte type roundTripFunc func(req *http.Request) *http.Response func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { return f(req), nil } func TestRegex(t *testing.T) { urls := []string{ "https://icons.terrastruct.com/essentials/004-picture.svg", "http://icons.terrastruct.com/essentials/004-picture.svg", } notURLs := []string{ "hi.png", "./cat.png", "/cat.png", } for _, href := range append(urls, notURLs...) { str := fmt.Sprintf(``, href) matches := imageRegex.FindAllStringSubmatch(str, -1) if len(matches) != 1 { t.Fatalf("uri regex didn't match %s", str) } } } func TestInlineRemote(t *testing.T) { ctx := context.Background() svgURL := "https://icons.terrastruct.com/essentials/004-picture.svg" pngURL := "https://cdn4.iconfinder.com/data/icons/smart-phones-technologies/512/android-phone.png" sampleSVG := fmt.Sprintf(` ab `, svgURL, pngURL) ms := &xmain.State{ Name: "test", Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, Env: xos.NewEnv(os.Environ()), } ms.Log = cmdlog.NewTB(ms.Env, t) httpClient.Transport = roundTripFunc(func(req *http.Request) *http.Response { respRecorder := httptest.NewRecorder() switch req.URL.String() { case svgURL: respRecorder.WriteString(`\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n`) case pngURL: respRecorder.Write(testPNGFile) default: t.Fatal(req.URL) } respRecorder.WriteHeader(200) return respRecorder.Result() }) out, err := BundleRemote(ctx, ms, []byte(sampleSVG)) if err != nil { t.Fatal(err) } if strings.Contains(string(out), "https://") { t.Fatal("links still exist") } if !strings.Contains(string(out), "image/svg+xml") { t.Fatal("no svg image inserted") } if !strings.Contains(string(out), "image/png") { t.Fatal("no png image inserted") } // Test almost too large response httpClient.Transport = roundTripFunc(func(req *http.Request) *http.Response { respRecorder := httptest.NewRecorder() bytes := make([]byte, maxImageSize) rand.Read(bytes) respRecorder.Write(bytes) respRecorder.WriteHeader(200) return respRecorder.Result() }) _, err = BundleRemote(ctx, ms, []byte(sampleSVG)) if err != nil { t.Fatal(err) } // Test too large response httpClient.Transport = roundTripFunc(func(req *http.Request) *http.Response { respRecorder := httptest.NewRecorder() bytes := make([]byte, maxImageSize+1) rand.Read(bytes) respRecorder.Write(bytes) respRecorder.WriteHeader(200) return respRecorder.Result() }) _, err = BundleRemote(ctx, ms, []byte(sampleSVG)) if err == nil { t.Fatal("expected error") } // Test error response httpClient.Transport = roundTripFunc(func(req *http.Request) *http.Response { respRecorder := httptest.NewRecorder() respRecorder.WriteHeader(500) return respRecorder.Result() }) _, err = BundleRemote(ctx, ms, []byte(sampleSVG)) if err == nil { t.Fatal("expected error") } } func TestInlineLocal(t *testing.T) { ctx := context.Background() svgURL, err := filepath.Abs("./test_svg.svg") if err != nil { t.Fatal(err) } pngURL, err := filepath.Abs("./test_png.png") if err != nil { t.Fatal(err) } sampleSVG := fmt.Sprintf(` ab `, svgURL, pngURL) ms := &xmain.State{ Name: "test", Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, Env: xos.NewEnv(os.Environ()), } ms.Log = cmdlog.NewTB(ms.Env, t) out, err := BundleLocal(ctx, ms, []byte(sampleSVG)) if err != nil { t.Fatal(err) } if strings.Contains(string(out), svgURL) { t.Fatal("links still exist") } if !strings.Contains(string(out), "image/svg+xml") { t.Fatal("no svg image inserted") } if !strings.Contains(string(out), "image/png") { t.Fatal("no png image inserted") } }