forked from wgroeneveld/go-jamming
first tests 🍻 albeit with ugly self-made mocks
This commit is contained in:
parent
4c01023fcd
commit
5f5c7c6f21
|
@ -8,4 +8,4 @@ jobs:
|
|||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.0'
|
||||
- run: go version
|
||||
- run: go test ./...
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue