go-jamming/app/webmention/validate_test.go

160 lines
3.4 KiB
Go

package webmention
import (
"errors"
"net/http"
"testing"
"brainbaking.com/go-jamming/common"
"brainbaking.com/go-jamming/mocks"
)
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.Config{
BaseURL: "https://somecool.base.url/",
Port: 1337,
Token: "miauwkes",
AllowedWebmentionSources: []string{"brainbaking.com", "jefklakscodex.com"},
Blacklist: []string{"youtube.com"},
Whitelist: []string{"brainbaking.com"},
}
)
func TestValidate(t *testing.T) {
cases := []struct {
label string
source string
target string
contentType string
expected bool
}{
{
"is valid if encoded as form including the charset",
"https://brainbaking.com/bla1",
"https://jefklakscodex.com/bla",
"application/x-www-form-urlencoded; charset=utf-8",
true,
},
{
"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)
}
})
}
}
func TestIsValidTargetUrlFalseIfGetFails(t *testing.T) {
client := &mocks.RestClientMock{
GetFunc: func(url string) (*http.Response, error) {
return nil, errors.New("whoops")
},
}
result := isValidTargetUrl("failing", client)
if result != false {
t.Fatalf("expected to fail")
}
}
func TestIsValidTargetUrlTrueIfGetSucceeds(t *testing.T) {
client := &mocks.RestClientMock{
GetFunc: func(url string) (*http.Response, error) {
return nil, nil
},
}
result := isValidTargetUrl("valid stuff!", client)
if result != true {
t.Fatalf("expected to succeed")
}
}