first tests 🍻 albeit with ugly self-made mocks

This commit is contained in:
Wouter Groeneveld 2021-04-07 15:22:24 +02:00
parent 4c01023fcd
commit 5f5c7c6f21
5 changed files with 159 additions and 2 deletions

View File

@ -8,4 +8,4 @@ jobs:
- uses: actions/setup-go@v2
with:
go-version: '^1.16.0'
- run: go version
- run: go test ./...

View File

@ -22,6 +22,11 @@ func HandlePut(conf *common.Config) http.HandlerFunc {
func HandlePost(conf *common.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
if !validate(r, r.Header, conf) {
http.Error(w, "400 bad request", http.StatusBadRequest)
}
fmt.Printf("%+v\n", r.Header)
}
}

View File

@ -0,0 +1,37 @@
package webmention
import (
"strings"
"github.com/wgroeneveld/go-jamming/common"
)
func isValidUrl(url string) bool {
return url != "" &&
(strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://"))
}
func isValidDomain(url string, conf *common.Config) bool {
for _, domain := range conf.AllowedWebmentionSources {
if strings.Index(url, domain) != -1 {
return true
}
}
return false
}
type httpReq interface {
FormValue(key string) string
}
type httpHeader interface {
Get(key string) string
}
func validate(r httpReq, h httpHeader, conf *common.Config) bool {
return h.Get("Content-Type") == "application/x-www-form-urlencoded" &&
isValidUrl(r.FormValue("source")) &&
isValidUrl(r.FormValue("target")) &&
r.FormValue("source") != r.FormValue("target") &&
isValidDomain(r.FormValue("target"), conf)
}

View File

@ -0,0 +1,115 @@
package webmention
import (
"testing"
"github.com/wgroeneveld/go-jamming/common"
)
type httpReqMock struct {
source string
target string
}
type httpHeaderMock struct {
contentType string
}
func (mock *httpHeaderMock) Get(key string) string {
return mock.contentType
}
func (mock *httpReqMock) FormValue(key string) string {
switch key {
case "source": return mock.source
case "target": return mock.target
default: return ""
}
}
func buildHttpReq(source string, target string) *httpReqMock {
return &httpReqMock{
source: source,
target: target,
}
}
var config = common.Configure()
func TestValidate(t *testing.T) {
cases := []struct {
label string
source string
target string
contentType string
expected bool
} {
{
"is valid if source and target https urls",
"http://brainbaking.com/bla1",
"http://jefklakscodex.com/bla",
"application/x-www-form-urlencoded",
true,
},
{
"is NOT valid if target is a valid url but not form valid domain",
"http://brainbaking.com/bla1",
"http://brainthe.bake/jup",
"application/x-www-form-urlencoded",
false,
},
{
"is NOT valid if source and target are the same urls",
"http://brainbaking.com/bla1",
"http://brainbaking.com/bla1",
"application/x-www-form-urlencoded",
false,
},
{
"is NOT valid if source is not a valid url",
"lolz",
"http://brainbaking.com/bla1",
"application/x-www-form-urlencoded",
false,
},
{
"is NOT valid if source is missing",
"",
"http://brainbaking.com/bla1",
"application/x-www-form-urlencoded",
false,
},
{
"is NOT valid if target is missing",
"http://brainbaking.com/bla1",
"",
"application/x-www-form-urlencoded",
false,
},
{
"is NOT valid if no valid encoded form",
"http://brainbaking.com/bla1",
"http://jefklakscodex.com/bla",
"application/lolz",
false,
},
{
"is NOT valid if body is missing",
"",
"",
"application/x-www-form-urlencoded",
false,
},
}
for _, tc := range cases {
t.Run(tc.label, func(t *testing.T) {
httpReq := buildHttpReq(tc.source, tc.target)
httpHeader := &httpHeaderMock{ contentType: tc.contentType }
actual := validate(httpReq, httpHeader, config)
if actual != tc.expected {
t.Fatalf("got %v, want %v", actual, tc.expected)
}
})
}
}

2
go.mod
View File

@ -2,4 +2,4 @@ module github.com/wgroeneveld/go-jamming
go 1.16
require github.com/gorilla/mux v1.8.0 // indirect
require github.com/gorilla/mux v1.8.0