commit 72320321465c1bf8564dd05524ff12742f4fe71b
parent b1193b66930246396763b35cd823002f3ce972a0
Author: MichaĆ M. Sapka <michal@sapka.me>
Date: Thu, 13 Jul 2023 23:26:41 +0200
test: add first batch of tests
Diffstat:
M | main.go | | | 108 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
A | main_test.go | | | 78 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 127 insertions(+), 59 deletions(-)
diff --git a/main.go b/main.go
@@ -19,78 +19,33 @@ package main
import (
"fmt"
+ "io"
"log"
"net/http"
- "io"
- "strings"
-
+
"gopkg.in/sevlyar/go-daemon.v0"
)
-// Proxies requests to Plausible.io and returns the response to the client
-func proxy(w http.ResponseWriter, r *http.Request) {
-
- client := &http.Client{}
-
- proxiedr := r.clone
-
-
- /*
- req, err := http.NewRequest(r.Method, "https://plausible.io" + r.URL.Path, r.Body)
-
- fmt.Println(r.Body)
-
-
-
- if err != nil {
- log.Fatal(err)
- }
-
- /*
- for k,v := range r.Header {
- value := strings.Join(v[:], " ")
- req.Header.Set(string(k), value)
- }
- */
-
- /*
- resp, err := client.Do(req)
- if err != nil {
- log.Fatal(err)
- }
-
- defer resp.Body.Close()
-
- bodyBytes, err := io.ReadAll(resp.Body)
- if err != nil {
- log.Fatal(err)
- }
-
- bodyString := string(bodyBytes)
- for k, v := range resp.Header {
- fmt.Println(string(k))
- value := strings.Join(v[:], " ")
- w.Header().Set(string(k), value)
- }
- */
-
- fmt.Fprintf(w, bodyString)
+// HTTPClient interface
+type HTTPClient interface {
+ Do(req *http.Request) (*http.Response, error)
}
+var (
+ Client HTTPClient
+)
-func serveProxy() {
- http.HandleFunc("/js/script.js", proxy)
- http.HandleFunc("/api/event", proxy)
-
- if err := http.ListenAndServe(":9090", nil); err != nil {
- log.Fatal(err)
- }
+func init() {
+ Client = &http.Client{}
}
+const PlausibleHost = "plausible.io"
+
func main() {
+
serveProxy()
return
-
+
cntxt := &daemon.Context{
PidFileName: "plaprox.pid",
PidFilePerm: 0644,
@@ -112,3 +67,38 @@ func main() {
serveProxy()
}
+
+// Proxies requests to Plausible.io and returns the response to the client
+func Proxy(w http.ResponseWriter, r *http.Request) {
+ req, _ := http.NewRequest(r.Method, "https://"+PlausibleHost+r.URL.Path, r.Body)
+
+ for key, values := range r.Header {
+ for _, value := range values {
+ req.Header.Add(key, value)
+ }
+ }
+
+ resp, _ := Client.Do(req)
+ defer resp.Body.Close()
+
+ bodyBytes, _ := io.ReadAll(resp.Body)
+
+ bodyString := string(bodyBytes)
+ for key, values := range resp.Header {
+ w.Header().Del(key)
+ for _, value := range values {
+ w.Header().Add(key, value)
+ }
+ }
+
+ fmt.Fprintf(w, bodyString)
+}
+
+func serveProxy() {
+ http.HandleFunc("/js/script.js", Proxy)
+ http.HandleFunc("/api/event", Proxy)
+
+ if err := http.ListenAndServe(":9090", nil); err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/main_test.go b/main_test.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+ "bytes"
+
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+)
+
+// Custom type that allows setting the func that our Mock Do func will run instead
+type MockDoType func(req *http.Request) (*http.Response, error) // MockClient is the mock client
+type MockClient struct {
+ MockDo MockDoType
+} // Overriding what the Do function should "do" in our MockClient
+func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
+ return m.MockDo(req)
+}
+
+func mockProxiedCall(url string, responseBody string, headers map[string][]string, t *testing.T) {
+
+ r := ioutil.NopCloser(bytes.NewReader([]byte(responseBody)))
+ Client = &MockClient{
+ MockDo: func(req *http.Request) (*http.Response, error) {
+ if req.Host != "plausible.io" {
+ t.Errorf("Invalid host. Got: %q, want: %q", req.Host, "plausible.io")
+
+ }
+ if req.URL.Path != url {
+ t.Errorf("Invalid url. Got: %q, want: %q", req.URL.Path, url)
+ }
+ if fmt.Sprint(req.Header) != fmt.Sprint(headers) {
+ t.Errorf("Invalid proxied headers. Got: %q, want: %q", req.Header, headers)
+
+ }
+
+ return &http.Response{
+ StatusCode: 200,
+ Body: r,
+ Header: headers,
+ }, nil
+
+ },
+ }
+
+}
+
+func TestProxy(t *testing.T) {
+ proxiedBody := `[{"full_name": "mock-repo" }]`
+ wantedHeaders := map[string][]string{
+ "Key": []string{"value"},
+ "Key2": []string{"value1", "value2"},
+ "Content-Type": []string{"application/javascript"},
+ }
+
+ mockProxiedCall("/js/script.js", proxiedBody, wantedHeaders, t)
+
+ request, _ := http.NewRequest(http.MethodGet, "/js/script.js", nil)
+
+ request.Header.Add("key", "value")
+ request.Header.Add("key2", "value1")
+ request.Header.Add("key2", "value2")
+ request.Header.Set("Content-Type", "application/javascript")
+
+ response := httptest.NewRecorder()
+
+ Proxy(response, request)
+
+ if response.Body.String() != proxiedBody {
+ t.Errorf("got %q, want %q", response.Body.String(), proxiedBody)
+ }
+
+ if fmt.Sprint(response.Header()) != fmt.Sprint(wantedHeaders) {
+ t.Errorf("Invalid returned headers. Got: %q, want: %q", response.Header(), wantedHeaders)
+ }
+}