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

View File

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

View File

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

View File

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

View File

@ -49,7 +49,7 @@ func (a *goBlog) serveProfileImage(format profileImageFormat) http.HandlerFunc {
switch format { switch format {
case profileImageFormatPNG: case profileImageFormatPNG:
mediaType = "image/png" 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)) return imaging.Encode(output, img, imaging.PNG, imaging.PNGCompressionLevel(png.BestCompression))
} }
default: default:

View File

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

View File

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