mirror of https://github.com/jlelse/GoBlog
Refactorings, Lint fixes
This commit is contained in:
parent
6028c04a09
commit
56d3e22afa
|
@ -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
|
1
cache.go
1
cache.go
|
@ -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")
|
||||
|
|
2
http.go
2
http.go
|
@ -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
|
||||
|
|
218
micropub_test.go
218
micropub_test.go
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
12
utils.go
12
utils.go
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue