Skip to content

Commit

Permalink
chore: handler tests (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
notnmeyer authored Oct 22, 2023
1 parent 156675c commit b09eb7f
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 24 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/notnmeyer/mockpi

go 1.20

require github.com/spf13/pflag v1.0.5
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
58 changes: 35 additions & 23 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,53 @@ import (
"net/http"
"os"
"strconv"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var (
contentType = "application/json; charset=utf-8"
responseBody = r.Header["X-Response-Json"][0]
responseCode int
)
flag "github.com/spf13/pflag"
)

responseCode, err := validateResponseCode(r.Header)
if err != nil {
responseBody = err.Error()
contentType = "text/plain; charset=utf-8"
}
type config struct {
port int
}

if !isJSON(responseBody) {
responseBody = fmt.Errorf("x-response-json must be valid JSON").Error()
responseCode = http.StatusBadRequest
contentType = "text/plain; charset=utf-8"
}
var c config

w.Header().Set("Content-Type", contentType)
w.WriteHeader(responseCode)
w.Write([]byte(responseBody))
})
func init() {
flag.IntVarP(&c.port, "port", "p", 8080, "the listen port")
flag.Parse()
}

listenAddr := ":8080"
func main() {
http.HandleFunc("/", handler)
listenAddr := fmt.Sprintf(":%d", c.port)
fmt.Printf("Listening on %s...\n", listenAddr)
if err := http.ListenAndServe(listenAddr, nil); err != nil {
fmt.Println("server error: ", err)
os.Exit(1)
}
}

func handler(w http.ResponseWriter, r *http.Request) {
var (
contentType = "application/json; charset=utf-8"
responseBody = r.Header["X-Response-Json"][0]
responseCode int
)

responseCode, err := validateResponseCode(r.Header)
if err != nil {
responseBody = err.Error()
contentType = "text/plain; charset=utf-8"
} else if !isJSON(responseBody) {
responseBody = fmt.Errorf("x-response-json must be valid JSON").Error()
responseCode = http.StatusBadRequest
contentType = "text/plain; charset=utf-8"
}

w.Header().Set("Content-Type", contentType)
w.WriteHeader(responseCode)
w.Write([]byte(responseBody))
}

func validateResponseCode(header map[string][]string) (int, error) {
if val, exists := header["X-Response-Code"]; exists {
// verify its a number
Expand Down
118 changes: 117 additions & 1 deletion main_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,115 @@
package main

import "testing"
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)

func TestHandlerValidRequest(t *testing.T) {
expectedContentType := "application/json; charset=utf-8"
expectedResponseBody := `{"foo":"bar"}`
expectedResponseCode := http.StatusTeapot

// set up the request
req, err := http.NewRequest("POST", "/test", nil)
if err != nil {
t.Fatal(err)
}
req.Header.Add("X-Response-Json", expectedResponseBody)
req.Header.Add("X-Response-Code", fmt.Sprint(expectedResponseCode))

// make the request
rr := httptest.NewRecorder()
h := http.HandlerFunc(handler)
h.ServeHTTP(rr, req)

// status code
if status := rr.Code; status != expectedResponseCode {
t.Errorf("handler returned wrong status code: got '%d' want '%d'", status, expectedResponseCode)
}

// response body
if rr.Body.String() != expectedResponseBody {
t.Errorf("handler returned unexpected body: got '%s' want '%s'", rr.Body.String(), expectedResponseBody)
}

// content-type
if rr.Header()["Content-Type"][0] != expectedContentType {
t.Errorf("handler returned wrong content-type: got '%s' wanted '%s'", rr.Header()["Content-Type"][0], expectedContentType)
}
}

func TestHandlerWithInvalidXResponseJson(t *testing.T) {
expectedContentType := "text/plain; charset=utf-8"
invalidResponseBody := `{"foo":bar}`
expectedResponseBody := "x-response-json must be valid JSON"
expectedResponseCode := http.StatusBadRequest

// set up the request
req, err := http.NewRequest("POST", "/test", nil)
if err != nil {
t.Fatal(err)
}
req.Header.Add("X-Response-Json", invalidResponseBody)
req.Header.Add("X-Response-Code", fmt.Sprint(expectedResponseCode))

// make the request
rr := httptest.NewRecorder()
h := http.HandlerFunc(handler)
h.ServeHTTP(rr, req)

// status code
if status := rr.Code; status != expectedResponseCode {
t.Errorf("handler returned wrong status code: got '%d' want '%d'", status, expectedResponseCode)
}

// response body
if rr.Body.String() != expectedResponseBody {
t.Errorf("handler returned unexpected body: got '%s' want '%s'", rr.Body.String(), expectedResponseBody)
}

// content-type
if rr.Header()["Content-Type"][0] != expectedContentType {
t.Errorf("handler returned wrong content-type: got '%s' wanted '%s'", rr.Header()["Content-Type"][0], expectedContentType)
}
}

func TestHandlerWithInvalidXResponseCode(t *testing.T) {
expectedContentType := "text/plain; charset=utf-8"
expectedResponseBody := "x-response-code must be a number\n"
invalidResponseCode := "blah"
expectedResponseCode := http.StatusBadRequest

// set up the request
req, err := http.NewRequest("POST", "/test", nil)
if err != nil {
t.Fatal(err)
}
req.Header.Add("X-Response-Json", "{}")
req.Header.Add("X-Response-Code", invalidResponseCode)

// make the request
rr := httptest.NewRecorder()
h := http.HandlerFunc(handler)
h.ServeHTTP(rr, req)

// status code
if status := rr.Code; status != expectedResponseCode {
t.Errorf("handler returned wrong status code: got '%d' want '%d'", status, expectedResponseCode)
}

// response body
if rr.Body.String() != expectedResponseBody {
t.Errorf("handler returned unexpected body: got '%s' want '%s'", rr.Body.String(), expectedResponseBody)
}

// content-type
if rr.Header()["Content-Type"][0] != expectedContentType {
t.Errorf("handler returned wrong content-type: got '%s' wanted '%s'", rr.Header()["Content-Type"][0], expectedContentType)
}
}

func TestValidateResponseCode(t *testing.T) {
valid := map[string][]string{
Expand All @@ -16,6 +125,13 @@ func TestValidateResponseCode(t *testing.T) {
if _, err := validateResponseCode(invalid); err == nil {
t.Errorf("expected %v to be an invalid response code\n", invalid)
}

invalidStr := map[string][]string{
"X-Response-Code": {"hello"},
}
if _, err := validateResponseCode(invalidStr); err == nil {
t.Errorf("expected %v to be an invalid response code\n", invalid)
}
}

func TestIsJSON(t *testing.T) {
Expand Down

0 comments on commit b09eb7f

Please sign in to comment.