mirror of https://github.com/jlelse/GoBlog
326 lines
10 KiB
Go
326 lines
10 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/carlmjohnson/requests"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.goblog.app/app/pkgs/contenttype"
|
|
"go.hacdias.com/indielib/micropub"
|
|
)
|
|
|
|
func Test_micropubQuery(t *testing.T) {
|
|
|
|
app := &goBlog{
|
|
cfg: createDefaultTestConfig(t),
|
|
}
|
|
_ = app.initConfig(false)
|
|
|
|
// Create a test post with tags
|
|
err := app.createPost(&post{
|
|
Path: "/test/post",
|
|
Content: "Test post",
|
|
Parameters: map[string][]string{
|
|
"tags": {"test", "test2"},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
type testCase struct {
|
|
query string
|
|
want string
|
|
wantStatus int
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
query: "config",
|
|
want: "{\"categories\":[\"test\",\"test2\"],\"channels\":[{\"uid\":\"default\",\"name\":\"default: My Blog\"},{\"uid\":\"default/posts\",\"name\":\"default/posts: posts\"}],\"media-endpoint\":\"http://localhost:8080/micropub/media\",\"visibility\":[\"private\",\"unlisted\",\"public\"]}\n",
|
|
wantStatus: http.StatusOK,
|
|
},
|
|
{
|
|
query: "source&url=http://localhost:8080/test/post",
|
|
want: "{\"properties\":{\"category\":[\"test\",\"test2\"],\"content\":[\"---\\nblog: default\\npath: /test/post\\npriority: 0\\npublished: \\\"\\\"\\nsection: \\\"\\\"\\nstatus: published\\ntags:\\n - test\\n - test2\\nupdated: \\\"\\\"\\nvisibility: public\\n---\\nTest post\"],\"mp-channel\":[\"default\"],\"mp-slug\":[\"\"],\"post-status\":[\"published\"],\"published\":[\"\"],\"updated\":[\"\"],\"url\":[\"http://localhost:8080/test/post\"],\"visibility\":[\"public\"]},\"type\":[\"h-entry\"]}\n",
|
|
wantStatus: http.StatusOK,
|
|
},
|
|
{
|
|
query: "source",
|
|
want: "{\"items\":[{\"properties\":{\"category\":[\"test\",\"test2\"],\"content\":[\"---\\nblog: default\\npath: /test/post\\npriority: 0\\npublished: \\\"\\\"\\nsection: \\\"\\\"\\nstatus: published\\ntags:\\n - test\\n - test2\\nupdated: \\\"\\\"\\nvisibility: public\\n---\\nTest post\"],\"mp-channel\":[\"default\"],\"mp-slug\":[\"\"],\"post-status\":[\"published\"],\"published\":[\"\"],\"updated\":[\"\"],\"url\":[\"http://localhost:8080/test/post\"],\"visibility\":[\"public\"]},\"type\":[\"h-entry\"]}]}\n",
|
|
wantStatus: http.StatusOK,
|
|
},
|
|
{
|
|
query: "category",
|
|
want: "{\"categories\":[\"test\",\"test2\"]}\n",
|
|
wantStatus: http.StatusOK,
|
|
},
|
|
{
|
|
query: "channel",
|
|
want: "{\"channels\":[{\"uid\":\"default\",\"name\":\"default: My Blog\"},{\"uid\":\"default/posts\",\"name\":\"default/posts: posts\"}]}\n",
|
|
wantStatus: http.StatusOK,
|
|
},
|
|
{
|
|
query: "somethingelse",
|
|
wantStatus: http.StatusNotFound,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/micropub?q="+tc.query, nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
app.getMicropubImplementation().getHandler().ServeHTTP(rec, req)
|
|
rec.Flush()
|
|
|
|
assert.Equal(t, tc.wantStatus, rec.Code)
|
|
if tc.want != "" {
|
|
assert.Equal(t, tc.want, rec.Body.String())
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func Test_micropubCreate(t *testing.T) {
|
|
app := &goBlog{
|
|
cfg: createDefaultTestConfig(t),
|
|
}
|
|
_ = app.initConfig(false)
|
|
|
|
// Modify settings for easier testing
|
|
bc := app.cfg.Blogs[app.cfg.DefaultBlog]
|
|
sc := bc.Sections[bc.DefaultSection]
|
|
sc.PathTemplate = `{{printf "/%v" .Slug}}`
|
|
|
|
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"]}}`
|
|
|
|
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, "Test post", p.Content)
|
|
assert.Equal(t, []string{"Cool"}, p.Parameters["tags"])
|
|
})
|
|
|
|
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"]}}`
|
|
|
|
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![](https://photos.example.com/123.jpg)", p.Content)
|
|
assert.Equal(t, []string{"https://photos.example.com/123.jpg"}, p.Parameters["images"])
|
|
})
|
|
|
|
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)
|
|
|
|
t.Run("Delete", func(t *testing.T) {
|
|
postPath := "/delete1"
|
|
|
|
err := app.createPost(&post{
|
|
Path: postPath,
|
|
Content: "Test post",
|
|
Parameters: map[string][]string{
|
|
"tags": {"test", "test2"},
|
|
"random": {"abc", "def"},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = app.getMicropubImplementation().Update(µpub.Request{
|
|
URL: app.cfg.Server.PublicAddress + postPath,
|
|
Updates: micropub.RequestUpdate{
|
|
Delete: map[string]any{
|
|
// Should filter the parameters
|
|
"category": []any{"test"},
|
|
// Should do nothing, because it's a custom parameter and thus ignored
|
|
"random": []any{"def"},
|
|
// Should do nothing
|
|
"content": []any{},
|
|
},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
p, err := app.getPost(postPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, []string{"test2"}, p.Parameters["tags"])
|
|
assert.Equal(t, []string{"abc", "def"}, p.Parameters["random"])
|
|
assert.Equal(t, "Test post", p.Content)
|
|
})
|
|
|
|
t.Run("Replace", func(t *testing.T) {
|
|
postPath := "/replace1"
|
|
|
|
err := app.createPost(&post{
|
|
Path: postPath,
|
|
Content: "Test post",
|
|
Status: statusPublished,
|
|
Visibility: visibilityPublic,
|
|
Parameters: map[string][]string{
|
|
"tags": {"test", "test2"},
|
|
"random": {"abc", "def"},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = app.getMicropubImplementation().Update(µpub.Request{
|
|
URL: app.cfg.Server.PublicAddress + postPath,
|
|
Updates: micropub.RequestUpdate{
|
|
Replace: map[string][]any{
|
|
"category": {"test"},
|
|
"random": {"def"},
|
|
"content": {"New test"},
|
|
"post-status": {"published-deleted"},
|
|
"visibility": {"unlisted"},
|
|
},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
p, err := app.getPost(postPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, []string{"test"}, p.Parameters["tags"])
|
|
assert.Equal(t, []string{"def"}, p.Parameters["random"])
|
|
assert.Equal(t, "New test", p.Content)
|
|
assert.Equal(t, statusPublished, p.Status)
|
|
assert.Nil(t, p.Parameters["post-status"])
|
|
assert.Equal(t, visibilityUnlisted, p.Visibility)
|
|
})
|
|
|
|
t.Run("Add", func(t *testing.T) {
|
|
postPath := "/add1"
|
|
|
|
err := app.createPost(&post{
|
|
Path: postPath,
|
|
Content: "Test post",
|
|
Parameters: map[string][]string{
|
|
"tags": {"test"},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = app.getMicropubImplementation().Update(µpub.Request{
|
|
URL: app.cfg.Server.PublicAddress + postPath,
|
|
Updates: micropub.RequestUpdate{
|
|
Add: map[string][]any{
|
|
"category": {"test2"},
|
|
"random": {"abc"},
|
|
"content": {"Add", "Bbb"},
|
|
"post-status": {"published"},
|
|
},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
p, err := app.getPost(postPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, []string{"test", "test2"}, p.Parameters["tags"])
|
|
assert.Equal(t, []string{"abc"}, p.Parameters["random"])
|
|
assert.Equal(t, "Test post", p.Content)
|
|
assert.Nil(t, p.Parameters["post-status"])
|
|
})
|
|
}
|