Refactorings, Lint fixes

This commit is contained in:
Jan-Lukas Else 2023-12-25 13:44:35 +01:00
parent 6028c04a09
commit 56d3e22afa
7 changed files with 130 additions and 122 deletions

View File

@ -1,7 +1,7 @@
run:
timeout: 5m
issue-exit-code: 0
skip-tests: true
issues-exit-code: 0
tests: false
build-tags:
- linux
- libsqlite3
@ -21,7 +21,7 @@ linters:
- bidichk
- bodyclose
- containedctx
- contextcheck
# - contextcheck
- dupl
- durationcheck
- gofmt
@ -32,10 +32,10 @@ linters:
- unparam
linters-settings:
gosimple:
go: "1.19"
go: "1.21"
checks: ["all"]
gostatichcheck:
go: "1.19"
staticcheck:
go: "1.21"
checks: ["all"]
dupl:
threshold: 125

View File

@ -171,6 +171,7 @@ func (c *cache) getCache(key string, next http.Handler, r *http.Request) *cacheI
}
// No cache available
// Make and use copy of r
//nolint:contextcheck
cr := r.Clone(valueOnlyContext{r.Context()})
// Remove problematic headers
cr.Header.Del("If-Modified-Since")

View File

@ -263,7 +263,7 @@ func (a *goBlog) servePostsAliasesRedirects() http.HandlerFunc {
}
// Check if post or alias
path := r.URL.Path
row, err := a.db.QueryRow(`
row, err := a.db.QueryRowContext(r.Context(), `
-- normal posts
select 'post', status, visibility, 200 from posts where path = @path
union all

View File

@ -15,12 +15,16 @@ import (
"go.hacdias.com/indielib/micropub"
)
func Test_micropubQuery(t *testing.T) {
func createMicropubTestEnv(t *testing.T) *goBlog {
app := &goBlog{
cfg: createDefaultTestConfig(t),
}
_ = app.initConfig(false)
return app
}
func Test_micropubQuery(t *testing.T) {
app := createMicropubTestEnv(t)
// Create a test post with tags
err := app.createPost(&post{
@ -86,10 +90,7 @@ func Test_micropubQuery(t *testing.T) {
}
func Test_micropubCreate(t *testing.T) {
app := &goBlog{
cfg: createDefaultTestConfig(t),
}
_ = app.initConfig(false)
app := createMicropubTestEnv(t)
// Modify settings for easier testing
bc := app.cfg.Blogs[app.cfg.DefaultBlog]
@ -98,120 +99,127 @@ func Test_micropubCreate(t *testing.T) {
handler := addAllScopes(app.getMicropubImplementation().getHandler())
t.Run("Normal (JSON)", func(t *testing.T) {
postPath := "/create1"
reqBody := `{"type":["h-entry"],"properties":{"content":["Test post"],"mp-slug":["create1"],"category":["Cool"]}}`
t.Run("JSON", func(t *testing.T) {
testCases := []struct {
name, postPath, reqBody string
assertions func(t *testing.T, p *post)
}{
{
"Normal",
"/create1",
`{"type":["h-entry"],"properties":{"content":["Test post"],"mp-slug":["create1"],"category":["Cool"]}}`,
func(t *testing.T, p *post) {
assert.Equal(t, "Test post", p.Content)
assert.Equal(t, []string{"Cool"}, p.Parameters["tags"])
},
},
{
"Photo",
"/create2",
`{"type":["h-entry"],"properties":{"mp-slug":["create2"],"photo":["https://photos.example.com/123.jpg"]}}`,
func(t *testing.T, p *post) {
assert.Equal(t, "\n![](https://photos.example.com/123.jpg)", p.Content)
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
},
},
{
"Photo with alternative text",
"/create3",
`{"type":["h-entry"],"properties":{"mp-slug":["create3"],"photo":[{
"value": "https://photos.example.com/123.jpg",
"alt": "This is a photo"
}]}}`,
func(t *testing.T, p *post) {
assert.Equal(t, "\n![This is a photo](https://photos.example.com/123.jpg \"This is a photo\")", p.Content)
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
assert.Equal(t, []string{"This is a photo"}, p.Parameters["imagealts"])
},
},
}
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyReader(strings.NewReader(reqBody)).ContentType(contenttype.JSONUTF8).Request(context.Background())
handler.ServeHTTP(recorder, req)
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+postPath, result.Header.Get("Location"))
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyReader(strings.NewReader(tc.reqBody)).ContentType(contenttype.JSONUTF8).Request(context.Background())
handler.ServeHTTP(recorder, req)
p, err := app.getPost(postPath)
require.NoError(t, err)
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+tc.postPath, result.Header.Get("Location"))
_ = result.Body.Close()
assert.Equal(t, "Test post", p.Content)
assert.Equal(t, []string{"Cool"}, p.Parameters["tags"])
p, err := app.getPost(tc.postPath)
require.NoError(t, err)
tc.assertions(t, p)
})
}
})
t.Run("Photo (JSON)", func(t *testing.T) {
postPath := "/create2"
reqBody := `{"type":["h-entry"],"properties":{"mp-slug":["create2"],"photo":["https://photos.example.com/123.jpg"]}}`
t.Run("Form", func(t *testing.T) {
testCases := []struct {
name, postPath string
bodyForm url.Values
assertions func(t *testing.T, p *post)
}{
{
"Photo with alternative text",
"/create4",
url.Values{
"h": []string{"entry"},
"mp-slug": []string{"create4"},
"photo": []string{"https://photos.example.com/123.jpg"},
"mp-photo-alt": []string{"This is a photo"},
},
func(t *testing.T, p *post) {
assert.Equal(t, "\n![This is a photo](https://photos.example.com/123.jpg \"This is a photo\")", p.Content)
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
assert.Equal(t, []string{"This is a photo"}, p.Parameters["imagealts"])
},
},
{
"Custom parameter",
"/create5",
url.Values{
"h": []string{"entry"},
"mp-slug": []string{"create5"},
"random": []string{"Abc", "Def"},
},
func(t *testing.T, p *post) {
assert.Equal(t, []string{"Abc", "Def"}, p.Parameters["random"])
},
},
}
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyReader(strings.NewReader(reqBody)).ContentType(contenttype.JSONUTF8).Request(context.Background())
handler.ServeHTTP(recorder, req)
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+postPath, result.Header.Get("Location"))
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyForm(tc.bodyForm).Request(context.Background())
handler.ServeHTTP(recorder, req)
p, err := app.getPost(postPath)
require.NoError(t, err)
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+tc.postPath, result.Header.Get("Location"))
_ = result.Body.Close()
assert.Equal(t, "\n![](https://photos.example.com/123.jpg)", p.Content)
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
p, err := app.getPost(tc.postPath)
require.NoError(t, err)
tc.assertions(t, p)
})
}
})
t.Run("Photo with alternative text (JSON)", func(t *testing.T) {
postPath := "/create3"
reqBody := `{"type":["h-entry"],"properties":{"mp-slug":["create3"],"photo":[{
"value": "https://photos.example.com/123.jpg",
"alt": "This is a photo"
}]}}`
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyReader(strings.NewReader(reqBody)).ContentType(contenttype.JSONUTF8).Request(context.Background())
handler.ServeHTTP(recorder, req)
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+postPath, result.Header.Get("Location"))
p, err := app.getPost(postPath)
require.NoError(t, err)
assert.Equal(t, "\n![This is a photo](https://photos.example.com/123.jpg \"This is a photo\")", p.Content)
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
assert.Equal(t, []string{"This is a photo"}, p.Parameters["imagealts"])
})
t.Run("Photo with alternative text (Form)", func(t *testing.T) {
postPath := "/create4"
bodyForm := url.Values{}
bodyForm["h"] = []string{"entry"}
bodyForm["mp-slug"] = []string{"create4"}
bodyForm["photo"] = []string{"https://photos.example.com/123.jpg"}
bodyForm["mp-photo-alt"] = []string{"This is a photo"}
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyForm(bodyForm).Request(context.Background())
handler.ServeHTTP(recorder, req)
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+postPath, result.Header.Get("Location"))
p, err := app.getPost(postPath)
require.NoError(t, err)
assert.Equal(t, "\n![This is a photo](https://photos.example.com/123.jpg \"This is a photo\")", p.Content)
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
assert.Equal(t, []string{"This is a photo"}, p.Parameters["imagealts"])
})
t.Run("Custom parameter (Form)", func(t *testing.T) {
postPath := "/create5"
bodyForm := url.Values{}
bodyForm["h"] = []string{"entry"}
bodyForm["mp-slug"] = []string{"create5"}
bodyForm["random"] = []string{"Abc", "Def"}
recorder := httptest.NewRecorder()
req, _ := requests.New().Post().BodyForm(bodyForm).Request(context.Background())
handler.ServeHTTP(recorder, req)
result := recorder.Result()
require.Equal(t, http.StatusAccepted, result.StatusCode)
require.Equal(t, "http://localhost:8080"+postPath, result.Header.Get("Location"))
p, err := app.getPost(postPath)
require.NoError(t, err)
assert.Equal(t, []string{"Abc", "Def"}, p.Parameters["random"])
})
}
func Test_micropubUpdate(t *testing.T) {
app := &goBlog{
cfg: createDefaultTestConfig(t),
}
_ = app.initConfig(false)
app := createMicropubTestEnv(t)
t.Run("Delete", func(t *testing.T) {
postPath := "/delete1"

View File

@ -49,7 +49,7 @@ func (a *goBlog) serveProfileImage(format profileImageFormat) http.HandlerFunc {
switch format {
case profileImageFormatPNG:
mediaType = "image/png"
encode = func(output io.Writer, img *image.NRGBA, quality int) error {
encode = func(output io.Writer, img *image.NRGBA, _ int) error {
return imaging.Encode(output, img, imaging.PNG, imaging.PNGCompressionLevel(png.BestCompression))
}
default:

View File

@ -233,11 +233,6 @@ func mBytesString(size int64) string {
return fmt.Sprintf("%.2f MB", datasize.ByteSize(size).MBytes())
}
func htmlText(s string) string {
text, _ := htmlTextFromReader(strings.NewReader(s))
return text
}
// Build policy to only allow a subset of HTML tags
var textPolicy = bluemonday.StrictPolicy().
AllowElements("h1", "h2", "h3", "h4", "h5", "h6"). // Headers
@ -411,10 +406,9 @@ func matchTimeDiffLocale(lang string) tdl.Locale {
timeDiffLocaleMutex.Lock()
defer timeDiffLocaleMutex.Unlock()
supportedLangs := []string{"en", "de", "es", "hi", "pt", "ru", "zh-CN"}
var supportedTags []language.Tag
for _, lang := range supportedLangs {
supportedTags = append(supportedTags, language.Make(lang))
}
supportedTags := lo.Map(supportedLangs, func(lang string, _ int) language.Tag {
return language.Make(lang)
})
matcher := language.NewMatcher(supportedTags)
_, idx, _ := matcher.Match(language.Make(lang))
locale := tdl.Locale(supportedLangs[idx])

View File

@ -88,6 +88,11 @@ func Test_urlHasExt(t *testing.T) {
}
func Test_htmlText(t *testing.T) {
htmlText := func(s string) string {
text, _ := htmlTextFromReader(strings.NewReader(s))
return text
}
// Text without HTML
assert.Equal(t, "This is a test", htmlText("This is a test"))
// Text without HTML and Emojis