hmn/src/hmnurl/hmnurl_test.go

147 lines
5.7 KiB
Go

package hmnurl
import (
"net/url"
"regexp"
"testing"
"git.handmade.network/hmn/hmn/src/config"
"github.com/stretchr/testify/assert"
)
func TestUrl(t *testing.T) {
defer func() {
SetGlobalBaseUrl(config.Config.BaseUrl)
}()
SetGlobalBaseUrl("http://handmade.test")
t.Run("no query", func(t *testing.T) {
result := Url("/test/foo", nil)
assert.Equal(t, "http://handmade.test/test/foo", result)
})
t.Run("yes query", func(t *testing.T) {
result := Url("/test/foo", []Q{{"bar", "baz"}, {"zig??", "zig & zag!!"}})
assert.Equal(t, "http://handmade.test/test/foo?bar=baz&zig%3F%3F=zig+%26+zag%21%21", result)
})
}
func TestHomepage(t *testing.T) {
AssertRegexMatch(t, BuildHomepage(), RegexHomepage, nil)
}
func TestLogin(t *testing.T) {
AssertRegexMatch(t, BuildLogin(), RegexLogin, nil)
}
func TestLogout(t *testing.T) {
AssertRegexMatch(t, BuildLogout(), RegexLogout, nil)
}
func TestStaticPages(t *testing.T) {
AssertRegexMatch(t, BuildManifesto(), RegexManifesto, nil)
AssertRegexMatch(t, BuildAbout(), RegexAbout, nil)
AssertRegexMatch(t, BuildCodeOfConduct(), RegexCodeOfConduct, nil)
AssertRegexMatch(t, BuildCommunicationGuidelines(), RegexCommunicationGuidelines, nil)
AssertRegexMatch(t, BuildContactPage(), RegexContactPage, nil)
AssertRegexMatch(t, BuildMonthlyUpdatePolicy(), RegexMonthlyUpdatePolicy, nil)
AssertRegexMatch(t, BuildProjectSubmissionGuidelines(), RegexProjectSubmissionGuidelines, nil)
}
func TestFeed(t *testing.T) {
AssertRegexMatch(t, BuildFeed(), RegexFeed, nil)
assert.Equal(t, BuildFeed(), BuildFeedWithPage(1))
AssertRegexMatch(t, BuildFeedWithPage(1), RegexFeed, nil)
AssertRegexMatch(t, "/feed/1", RegexFeed, nil) // NOTE(asaf): We should never build this URL, but we should still accept it.
AssertRegexMatch(t, BuildFeedWithPage(5), RegexFeed, map[string]string{"page": "5"})
assert.Panics(t, func() { BuildFeedWithPage(-1) })
assert.Panics(t, func() { BuildFeedWithPage(0) })
}
func TestForumThread(t *testing.T) {
AssertRegexMatch(t, BuildForumThread("", nil, 1, 1), RegexForumThread, map[string]string{"threadid": "1"})
AssertRegexMatch(t, BuildForumThread("", []string{"wip"}, 1, 2), RegexForumThread, map[string]string{"cats": "forums/wip", "page": "2", "threadid": "1"})
AssertRegexMatch(t, BuildForumThread("", []string{"sub", "wip"}, 1, 2), RegexForumThread, map[string]string{"cats": "forums/sub/wip", "page": "2", "threadid": "1"})
AssertSubdomain(t, BuildForumThread("hmn", nil, 1, 1), "")
AssertSubdomain(t, BuildForumThread("", nil, 1, 1), "")
AssertSubdomain(t, BuildForumThread("hero", nil, 1, 1), "hero")
assert.Panics(t, func() { BuildForumThread("", []string{"", "wip"}, 1, 1) })
assert.Panics(t, func() { BuildForumThread("", []string{" ", "wip"}, 1, 1) })
assert.Panics(t, func() { BuildForumThread("", []string{"wip/jobs"}, 1, 1) })
}
func TestForumCategory(t *testing.T) {
AssertRegexMatch(t, BuildForumCategory("", nil, 1), RegexForumCategory, nil)
AssertRegexMatch(t, BuildForumCategory("", []string{"wip"}, 2), RegexForumCategory, map[string]string{"cats": "forums/wip", "page": "2"})
AssertRegexMatch(t, BuildForumCategory("", []string{"sub", "wip"}, 2), RegexForumCategory, map[string]string{"cats": "forums/sub/wip", "page": "2"})
AssertSubdomain(t, BuildForumCategory("hmn", nil, 1), "")
AssertSubdomain(t, BuildForumCategory("", nil, 1), "")
AssertSubdomain(t, BuildForumCategory("hero", nil, 1), "hero")
assert.Panics(t, func() { BuildForumCategory("", []string{"", "wip"}, 1) })
assert.Panics(t, func() { BuildForumCategory("", []string{" ", "wip"}, 1) })
assert.Panics(t, func() { BuildForumCategory("", []string{"wip/jobs"}, 1) })
}
func TestProjectCSS(t *testing.T) {
AssertRegexMatch(t, BuildProjectCSS("000000"), RegexProjectCSS, nil)
}
func TestPublic(t *testing.T) {
AssertRegexMatch(t, BuildPublic("test"), RegexPublic, nil)
AssertRegexMatch(t, BuildPublic("/test"), RegexPublic, nil)
AssertRegexMatch(t, BuildPublic("/test/"), RegexPublic, nil)
AssertRegexMatch(t, BuildPublic("/test/thing/image.png"), RegexPublic, nil)
assert.Panics(t, func() { BuildPublic("") })
assert.Panics(t, func() { BuildPublic("/") })
assert.Panics(t, func() { BuildPublic("/thing//image.png") })
assert.Panics(t, func() { BuildPublic("/thing/ /image.png") })
}
func AssertSubdomain(t *testing.T, fullUrl string, expectedSubdomain string) {
parsed, err := url.Parse(fullUrl)
ok := assert.Nilf(t, err, "Full url could not be parsed: %s", fullUrl)
if !ok {
return
}
fullHost := parsed.Host
if len(expectedSubdomain) == 0 {
assert.Equal(t, baseUrlParsed.Host, fullHost, "Did not expect a subdomain")
} else {
assert.Equalf(t, expectedSubdomain+"."+baseUrlParsed.Host, fullHost, "Subdomain mismatch")
}
}
func AssertRegexMatch(t *testing.T, fullUrl string, regex *regexp.Regexp, paramsToVerify map[string]string) {
parsed, err := url.Parse(fullUrl)
ok := assert.Nilf(t, err, "Full url could not be parsed: %s", fullUrl)
if !ok {
return
}
requestPath := parsed.Path
if len(requestPath) == 0 {
requestPath = "/"
}
match := regex.FindStringSubmatch(requestPath)
assert.NotNilf(t, match, "Url did not match regex: [%s] vs [%s]", requestPath, regex.String())
if paramsToVerify != nil {
subexpNames := regex.SubexpNames()
for i, matchedValue := range match {
paramName := subexpNames[i]
expectedValue, ok := paramsToVerify[paramName]
if ok {
assert.Equalf(t, expectedValue, matchedValue, "Param mismatch for [%s]", paramName)
delete(paramsToVerify, paramName)
}
}
if len(paramsToVerify) > 0 {
unmatchedParams := make([]string, 0, len(paramsToVerify))
for paramName := range paramsToVerify {
unmatchedParams = append(unmatchedParams, paramName)
}
assert.Fail(t, "Expected match groups not found", unmatchedParams)
}
}
}