[fiddle] Switch over to using the scrap api client.

Bug: skia:11108
Change-Id: Id038c56c01ed534ece857133405acac99a4546c9
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/352980
Commit-Queue: Joe Gregorio <jcgregorio@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/fiddlek/go/fiddle/main.go b/fiddlek/go/fiddle/main.go
index f186a42..8e38830 100644
--- a/fiddlek/go/fiddle/main.go
+++ b/fiddlek/go/fiddle/main.go
@@ -2,6 +2,7 @@
 package main
 
 import (
+	"bytes"
 	"context"
 	"encoding/base64"
 	"encoding/json"
@@ -9,7 +10,6 @@
 	"fmt"
 	"html/template"
 	ttemplate "html/template"
-	"io/ioutil"
 	"net/http"
 	"path/filepath"
 	"regexp"
@@ -32,6 +32,7 @@
 	"go.skia.org/infra/go/sklog"
 	"go.skia.org/infra/go/timer"
 	"go.skia.org/infra/go/util"
+	"go.skia.org/infra/scrap/go/client"
 	"go.skia.org/infra/scrap/go/scrap"
 )
 
@@ -118,7 +119,7 @@
 	failingNamed = []store.Named{}
 	failingMutex = sync.Mutex{}
 	run          *runner.Runner
-	httpClient   *http.Client
+	scrapClient  scrap.ScrapExchange
 )
 
 func loadTemplates() {
@@ -268,22 +269,16 @@
 // scrapHandler handles links to scrap exchange expanded templates and turns them into fiddles.
 func scrapHandler(w http.ResponseWriter, r *http.Request) {
 	// Load the scrap.
-	typ := mux.Vars(r)["type"]
+	typ := scrap.ToType(mux.Vars(r)["type"])
 	hashOrName := mux.Vars(r)["hashOrName"]
-	resp, err := httpClient.Get(fmt.Sprintf("http://%s/_/tmpl/%s/%s/%s", *scrapExchange, typ, hashOrName, scrap.CPP))
-	if err != nil || resp.StatusCode != http.StatusOK {
+	var b bytes.Buffer
+	if err := scrapClient.Expand(r.Context(), typ, hashOrName, scrap.CPP, &b); err != nil {
 		httputils.ReportError(w, err, "Failed to load templated scrap.", http.StatusInternalServerError)
 		return
 	}
-	defer util.Close(resp.Body)
-	b, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		httputils.ReportError(w, err, "Failed to read templated scrap.", http.StatusInternalServerError)
-		return
-	}
 
 	// Create the fiddle.
-	fiddleHash, err := fiddleStore.Put(string(b), defaultFiddle.Options, nil)
+	fiddleHash, err := fiddleStore.Put(b.String(), defaultFiddle.Options, nil)
 	if err != nil {
 		httputils.ReportError(w, err, "Failed to write fiddle.", http.StatusInternalServerError)
 		return
@@ -542,6 +537,21 @@
 	http.Redirect(w, r, "/c/cbb8dee39e9f1576cd97c2d504db8eee?mode=basic", http.StatusFound)
 }
 
+func addHandlers(r *mux.Router) {
+	r.PathPrefix("/dist/").HandlerFunc(makeDistHandler())
+	r.HandleFunc("/i/{id:[@0-9a-zA-Z._]+}", imageHandler).Methods("GET")
+	r.HandleFunc("/c/{id:[@0-9a-zA-Z_]+}", individualHandle).Methods("GET")
+	r.HandleFunc("/e/{id:[@0-9a-zA-Z_]+}", embedHandle).Methods("GET")
+	r.HandleFunc("/s/{id:[0-9]+}", sourceHandler).Methods("GET")
+	r.HandleFunc("/scrap/{type:[a-z]+}/{hashOrName:[@0-9a-zA-Z-_]+}", scrapHandler).Methods("GET")
+	r.HandleFunc("/f/", failedHandler).Methods("GET")
+	r.HandleFunc("/named/", namedHandler).Methods("GET")
+	r.HandleFunc("/new", basicModeHandler).Methods("GET")
+	r.HandleFunc("/", mainHandler).Methods("GET")
+	r.HandleFunc("/_/run", runHandler).Methods("POST")
+	r.HandleFunc("/healthz", healthzHandler).Methods("GET")
+}
+
 func main() {
 	common.InitWithMust(
 		"fiddle",
@@ -565,7 +575,10 @@
 	if err != nil {
 		sklog.Fatalf("Failed to connect to store: %s", err)
 	}
-	httpClient = httputils.DefaultClientConfig().With2xxOnly().Client()
+	scrapClient, err = client.New(*scrapExchange)
+	if err != nil {
+		sklog.Fatalf("Failed to create scrap exchange client: %s", err)
+	}
 	run, err = runner.New(*local, *sourceImageDir)
 	if err != nil {
 		sklog.Fatalf("Failed to initialize runner: %s", err)
@@ -578,18 +591,7 @@
 	names = named.New(fiddleStore)
 
 	r := mux.NewRouter()
-	r.PathPrefix("/dist/").HandlerFunc(makeDistHandler())
-	r.HandleFunc("/i/{id:[@0-9a-zA-Z._]+}", imageHandler)
-	r.HandleFunc("/c/{id:[@0-9a-zA-Z_]+}", individualHandle)
-	r.HandleFunc("/e/{id:[@0-9a-zA-Z_]+}", embedHandle)
-	r.HandleFunc("/s/{id:[0-9]+}", sourceHandler)
-	r.HandleFunc("/scrap/{type:[a-z]+}/{hashOrName:[@0-9a-zA-Z-_]+}", scrapHandler).Methods("GET")
-	r.HandleFunc("/f/", failedHandler)
-	r.HandleFunc("/named/", namedHandler)
-	r.HandleFunc("/new", basicModeHandler)
-	r.HandleFunc("/", mainHandler)
-	r.HandleFunc("/_/run", runHandler)
-	r.HandleFunc("/healthz", healthzHandler)
+	addHandlers(r)
 
 	h := httputils.LoggingGzipRequestResponse(r)
 	h = httputils.CrossOriginResourcePolicy(h)
diff --git a/fiddlek/go/fiddle/main_test.go b/fiddlek/go/fiddle/main_test.go
index cf9bd8b..3418716 100644
--- a/fiddlek/go/fiddle/main_test.go
+++ b/fiddlek/go/fiddle/main_test.go
@@ -3,15 +3,19 @@
 
 import (
 	"fmt"
-	"net/http"
+	"io"
 	"net/http/httptest"
-	"net/url"
 	"testing"
 
+	"github.com/gorilla/mux"
+	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
 	"go.skia.org/infra/fiddlek/go/store/mocks"
 	"go.skia.org/infra/fiddlek/go/types"
+	"go.skia.org/infra/go/testutils"
 	"go.skia.org/infra/go/testutils/unittest"
+	"go.skia.org/infra/scrap/go/scrap"
+	scrapMocks "go.skia.org/infra/scrap/go/scrap/mocks"
 )
 
 const (
@@ -29,18 +33,14 @@
 	r := httptest.NewRequest("GET", "/scrap/svg/@smiley", nil)
 	w := httptest.NewRecorder()
 
-	// Create a test server that mocks out the scrap exchange.
-	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		_, err := fmt.Fprint(w, code)
+	// Mock the scrapClient.
+	scrapClientMock := &scrapMocks.ScrapExchange{}
+	scrapClientMock.On("Expand", testutils.AnyContext, scrap.SVG, "@smiley", scrap.CPP, mock.Anything).Run(func(args mock.Arguments) {
+		_, err := args.Get(4).(io.Writer).Write([]byte(code))
 		require.NoError(t, err)
-	}))
-	defer func() { testServer.Close() }()
-	u, err := url.Parse(testServer.URL)
-	require.NoError(t, err)
-
-	// Configure main to point at the test server.
-	*scrapExchange = u.Host
-	httpClient = testServer.Client()
+	}).Return(nil)
+	defer scrapClientMock.AssertExpectations(t)
+	scrapClient = scrapClientMock
 
 	// Mock the fiddle store.
 	store := &mocks.Store{}
@@ -48,7 +48,12 @@
 	defer store.AssertExpectations(t)
 	fiddleStore = store
 
-	scrapHandler(w, r)
+	// Make the request through a mux.Router so the URL paths get parsed and
+	// routed correctly.
+	router := mux.NewRouter()
+	addHandlers(router)
+
+	router.ServeHTTP(w, r)
 
 	// Should redirect to the newly created fiddle.
 	require.Equal(t, 307, w.Code)
@@ -61,22 +66,20 @@
 	r := httptest.NewRequest("GET", "/scrap/svg/@smiley", nil)
 	w := httptest.NewRecorder()
 
-	// Create a test server that mocks out the scrap exchange.
-	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		http.Error(w, "Failure", http.StatusInternalServerError)
-	}))
-	defer func() { testServer.Close() }()
-	u, err := url.Parse(testServer.URL)
-	require.NoError(t, err)
+	// Mock the scrapClient.
+	scrapClientMock := &scrapMocks.ScrapExchange{}
+	scrapClientMock.On("Expand", testutils.AnyContext, scrap.SVG, "@smiley", scrap.CPP, mock.Anything).Return(errMyMockError)
+	defer scrapClientMock.AssertExpectations(t)
+	scrapClient = scrapClientMock
 
-	// Configure main to point at the test server.
-	*scrapExchange = u.Host
-	httpClient = testServer.Client()
+	// Make the request through a mux.Router so the URL paths get parsed and
+	// routed correctly.
+	router := mux.NewRouter()
+	addHandlers(router)
 
-	scrapHandler(w, r)
+	router.ServeHTTP(w, r)
 
 	require.Equal(t, 500, w.Code)
-	require.Contains(t, w.Body.String(), "Failed to load")
 }
 
 func TestScrapHandler_FiddleStorePutFails_ReturnsInternalServerError(t *testing.T) {
@@ -85,27 +88,27 @@
 	r := httptest.NewRequest("GET", "/scrap/svg/@smiley", nil)
 	w := httptest.NewRecorder()
 
-	// Create a test server that mocks out the scrap exchange.
-	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		_, err := fmt.Fprint(w, code)
+	// Mock the scrapClient.
+	scrapClientMock := &scrapMocks.ScrapExchange{}
+	scrapClientMock.On("Expand", testutils.AnyContext, scrap.SVG, "@smiley", scrap.CPP, mock.Anything).Run(func(args mock.Arguments) {
+		_, err := args[4].(io.Writer).Write([]byte(code))
 		require.NoError(t, err)
-	}))
-	defer func() { testServer.Close() }()
-	u, err := url.Parse(testServer.URL)
-	require.NoError(t, err)
-
-	// Configure main to point at the test server.
-	*scrapExchange = u.Host
-	httpClient = testServer.Client()
+	}).Return(nil)
+	defer scrapClientMock.AssertExpectations(t)
+	scrapClient = scrapClientMock
 
 	// Mock the fiddle store.
 	store := &mocks.Store{}
-	store.On("Put", code, defaultFiddle.Options, (*types.Result)(nil)).Return(hash, errMyMockError)
+	store.On("Put", code, defaultFiddle.Options, (*types.Result)(nil)).Return("", errMyMockError)
 	defer store.AssertExpectations(t)
 	fiddleStore = store
 
-	scrapHandler(w, r)
+	// Make the request through a mux.Router so the URL paths get parsed and
+	// routed correctly.
+	router := mux.NewRouter()
+	addHandlers(router)
+
+	router.ServeHTTP(w, r)
 
 	require.Equal(t, 500, w.Code)
-	require.Contains(t, w.Body.String(), "Failed to write")
 }