From eb0a858baceea747f3b31da18b0ffa2811e09a1d Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Mon, 8 Apr 2024 21:07:22 +0300 Subject: [PATCH 01/20] add post upload over Titan --- README.md | 4 +- front/README.md | 6 +- front/edit.go | 39 ++-- front/handler.go | 11 +- front/menu.go | 4 +- front/post.go | 93 +++++++- front/{whisper.go => post_followers.go} | 4 +- front/{dm.go => post_private.go} | 4 +- front/{say.go => post_public.go} | 4 +- front/print.go | 1 + front/reply.go | 2 +- front/static/users/help.gmi | 15 +- front/static/users/post.gmi | 10 + front/upload_followers.go | 31 +++ front/upload_private.go | 29 +++ front/upload_public.go | 32 +++ test/delete_test.go | 18 +- test/edit_test.go | 94 ++++---- test/follow_test.go | 22 +- test/follows_test.go | 4 +- test/forward_test.go | 18 +- test/fts_test.go | 36 +-- test/hashtag_test.go | 60 ++--- test/hashtags_test.go | 60 ++--- test/outbox_test.go | 48 ++-- test/poll_test.go | 86 +++---- ...whisper_test.go => post_followers_test.go} | 30 +-- test/{dm_test.go => post_private_test.go} | 52 ++--- test/{say_test.go => post_public_test.go} | 20 +- test/register_test.go | 2 +- test/reply_test.go | 72 +++--- test/share_test.go | 48 ++-- test/stats_test.go | 4 +- test/thread_test.go | 42 ++-- test/unfollow_test.go | 8 +- test/upload_edit_test.go | 217 ++++++++++++++++++ test/users_test.go | 24 +- test/view_test.go | 96 ++++---- 38 files changed, 868 insertions(+), 482 deletions(-) rename front/{whisper.go => post_followers.go} (83%) rename front/{dm.go => post_private.go} (83%) rename front/{say.go => post_public.go} (84%) create mode 100644 front/static/users/post.gmi create mode 100644 front/upload_followers.go create mode 100644 front/upload_private.go create mode 100644 front/upload_public.go rename test/{whisper_test.go => post_followers_test.go} (71%) rename test/{dm_test.go => post_private_test.go} (61%) rename test/{say_test.go => post_public_test.go} (70%) create mode 100644 test/upload_edit_test.go diff --git a/README.md b/README.md index 8b0f9ceb..d42785db 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,7 @@ Welcome, fedinaut! localhost.localdomain:8443 is an instance of tootik, a federa 🔥 Hashtags 🔭 Find user 🔎 Search posts -💌 Post to mentioned users -🔔 Post to followers -📣 Post to public +📣 New post ⚙️ Settings 📊 Statistics 🛟 Help diff --git a/front/README.md b/front/README.md index 1555a05a..2ddd12bc 100644 --- a/front/README.md +++ b/front/README.md @@ -23,9 +23,9 @@ Users are authenticated using TLS client certificates; see [Gemini protocol spec * /users/follows shows a list of followed users, ordered by activity. * /users/me redirects the user to their outbox. * /users/resolve looks up federated user *user@domain* or local user *user*. -* /users/dm creates a post visible to mentioned users. -* /users/whisper creates a post visible to followers. -* /users/say creates a public post. +* /users/post/private creates a post visible to mentioned users. +* /users/post/followers creates a post visible to followers. +* /users/post/public creates a public post. * /users/reply replies to a post. * /users/edit edits a post. * /users/delete deletes a post. diff --git a/front/edit.go b/front/edit.go index f02edf21..a4f237e0 100644 --- a/front/edit.go +++ b/front/edit.go @@ -22,33 +22,15 @@ import ( "github.com/dimkr/tootik/ap" "github.com/dimkr/tootik/front/text" "math" - "net/url" "time" - "unicode/utf8" ) -func (h *Handler) edit(w text.Writer, r *request, args ...string) { +func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request, []string, string) (string, bool), args ...string) { if r.User == nil { w.Redirect("/users") return } - if r.URL.RawQuery == "" { - w.Status(10, "Post content") - return - } - - content, err := url.QueryUnescape(r.URL.RawQuery) - if err != nil { - w.Status(40, "Bad input") - return - } - - if utf8.RuneCountInString(content) > h.Config.MaxPostsLength { - w.Status(40, "Post is too long") - return - } - postID := "https://" + args[1] var note ap.Object @@ -88,7 +70,7 @@ func (h *Handler) edit(w text.Writer, r *request, args ...string) { } if note.InReplyTo == "" { - h.post(w, r, ¬e, nil, note.To, note.CC, note.Audience, "Post content") + h.post(w, r, args, ¬e, nil, note.To, note.CC, note.Audience, "Post content", readContent) return } @@ -102,5 +84,20 @@ func (h *Handler) edit(w text.Writer, r *request, args ...string) { } // the starting point is the original value of to and cc: recipients can be added but not removed when editing - h.post(w, r, ¬e, &parent, note.To, note.CC, note.Audience, "Post content") + h.post(w, r, args, ¬e, &parent, note.To, note.CC, note.Audience, "Post content", readContent) +} + +func (h *Handler) edit(w text.Writer, r *request, args ...string) { + h.doEdit(w, r, readQuery, args...) +} + +func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { + h.doEdit( + w, + r, + func(w text.Writer, r *request, args []string, prompt string) (string, bool) { + return readUpload(w, r, args[1:], prompt) + }, + args..., + ) } diff --git a/front/handler.go b/front/handler.go index 5b7ba192..7f30bf39 100644 --- a/front/handler.go +++ b/front/handler.go @@ -95,9 +95,9 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/thread/(\S+)$`)] = withUserMenu(h.thread) h.handlers[regexp.MustCompile(`^/users/thread/(\S+)$`)] = withUserMenu(h.thread) - h.handlers[regexp.MustCompile(`^/users/dm$`)] = h.dm - h.handlers[regexp.MustCompile(`^/users/whisper$`)] = h.whisper - h.handlers[regexp.MustCompile(`^/users/say$`)] = h.say + h.handlers[regexp.MustCompile(`^/users/post/private$`)] = h.postPrivate + h.handlers[regexp.MustCompile(`^/users/post/followers$`)] = h.postFollowers + h.handlers[regexp.MustCompile(`^/users/post/public$`)] = h.postPublic h.handlers[regexp.MustCompile(`^/users/reply/(\S+)`)] = h.reply @@ -107,6 +107,11 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/edit/(\S+)`)] = h.edit h.handlers[regexp.MustCompile(`^/users/delete/(\S+)`)] = delete + h.handlers[regexp.MustCompile(`^/users/upload/private/;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPrivate + h.handlers[regexp.MustCompile(`^/users/upload/followers/;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadFollowers + h.handlers[regexp.MustCompile(`^/users/upload/public/;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPublic + h.handlers[regexp.MustCompile(`^/users/upload/edit/([^;]+);([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.editUpload + h.handlers[regexp.MustCompile(`^/users/resolve$`)] = withUserMenu(h.resolve) h.handlers[regexp.MustCompile(`^/users/follow/(\S+)$`)] = withUserMenu(h.follow) diff --git a/front/menu.go b/front/menu.go index 82fd5409..1b8d7a4f 100644 --- a/front/menu.go +++ b/front/menu.go @@ -52,9 +52,7 @@ func writeUserMenu(w text.Writer, user *ap.Actor) { if user == nil { w.Link("/users", "🔑 Sign in") } else { - w.Link("/users/dm", "💌 Post to mentioned users") - w.Link("/users/whisper", "🔔 Post to followers") - w.Link("/users/say", "📣 Post to public") + w.Link("/users/post", "📣 New post") w.Link("/users/settings", "⚙️ Settings") } diff --git a/front/post.go b/front/post.go index 35f668ff..e4c2a065 100644 --- a/front/post.go +++ b/front/post.go @@ -25,8 +25,10 @@ import ( "github.com/dimkr/tootik/front/text" "github.com/dimkr/tootik/front/text/plain" "github.com/dimkr/tootik/outbox" + "io" "net/url" "regexp" + "strconv" "strings" "time" "unicode/utf8" @@ -43,7 +45,83 @@ var ( pollRegex = regexp.MustCompile(`^\[(?:(?i)POLL)\s+(.+)\s*\]\s*(.+)`) ) -func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience, prompt string) { +func readQuery(w text.Writer, r *request, args []string, prompt string) (string, bool) { + if r.URL.RawQuery == "" { + w.Status(10, prompt) + return "", false + } + + content, err := url.QueryUnescape(r.URL.RawQuery) + if err != nil { + w.Error() + return "", false + } + + return content, true +} + +func readUpload(w text.Writer, r *request, args []string, prompt string) (string, bool) { + if r.Body == nil { + w.Redirect("/users/oops") + return "", false + } + + var sizeStr, mimeType string + if args[1] == "size" && args[3] == "mime" { + sizeStr = args[2] + mimeType = args[4] + } else if args[1] == "mime" && args[3] == "size" { + sizeStr = args[4] + mimeType = args[2] + } else { + r.Log.Warn("Invalid parameters") + w.Status(40, "Invalid parameters") + return "", false + } + + if mimeType != "text/plain" { + r.Log.Warn("Content type is unsupported", "type", mimeType) + w.Status(40, "Only text/plain is supported") + return "", false + } + + size, err := strconv.ParseInt(sizeStr, 10, 64) + if err != nil { + r.Log.Warn("Failed to parse content size", "error", err) + w.Status(40, "Invalid size") + return "", false + } + + if size == 0 { + r.Log.Warn("Content is empty") + w.Status(40, "Content is empty") + return "", false + } + + if size > int64(r.Handler.Config.MaxPostsLength)*4 { + r.Log.Warn("Content is too big", "size", size) + w.Status(40, "Content is too big") + return "", false + } + + buf := make([]byte, size) + n, err := io.ReadFull(r.Body, buf) + if err != nil { + r.Log.Warn("Failed to read content", "error", err) + w.Error() + return "", false + } + + if int64(n) != size { + r.Log.Warn("Content is truncated") + w.Error() + return "", false + } + + return string(buf), true +} + +func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience, prompt string, readContent func(text.Writer, *request, []string, string) (string, bool)) { if r.User == nil { w.Redirect("/users") return @@ -76,14 +154,8 @@ func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo } } - if r.URL.RawQuery == "" { - w.Status(10, prompt) - return - } - - content, err := url.QueryUnescape(r.URL.RawQuery) - if err != nil { - w.Error() + content, ok := readContent(w, r, args, prompt) + if !ok { return } @@ -228,6 +300,7 @@ func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo note.Content = plain.ToHTML(note.Content, note.Tag) } + var err error if oldNote != nil { note.Published = oldNote.Published note.Updated = &now @@ -245,5 +318,5 @@ func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo return } - w.Redirectf("/users/view/%s", strings.TrimPrefix(postID, "https://")) + w.Redirectf("gemini://%s/users/view/%s", h.Domain, strings.TrimPrefix(postID, "https://")) } diff --git a/front/whisper.go b/front/post_followers.go similarity index 83% rename from front/whisper.go rename to front/post_followers.go index 55d2e3e1..8bf5ac07 100644 --- a/front/whisper.go +++ b/front/post_followers.go @@ -21,11 +21,11 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) whisper(w text.Writer, r *request, args ...string) { +func (h *Handler) postFollowers(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} to.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", "Post content") + h.post(w, r, args, nil, nil, to, cc, "", "Post content", readQuery) } diff --git a/front/dm.go b/front/post_private.go similarity index 83% rename from front/dm.go rename to front/post_private.go index ef281d93..7d9ed491 100644 --- a/front/dm.go +++ b/front/post_private.go @@ -21,9 +21,9 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) dm(w text.Writer, r *request, args ...string) { +func (h *Handler) postPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, nil, nil, to, cc, "", "Post content") + h.post(w, r, args, nil, nil, to, cc, "", "Post content", readQuery) } diff --git a/front/say.go b/front/post_public.go similarity index 84% rename from front/say.go rename to front/post_public.go index 3a59b6d7..f6badfc6 100644 --- a/front/say.go +++ b/front/post_public.go @@ -21,12 +21,12 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) say(w text.Writer, r *request, args ...string) { +func (h *Handler) postPublic(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", "Post content") + h.post(w, r, args, nil, nil, to, cc, "", "Post content", readQuery) } diff --git a/front/print.go b/front/print.go index 56536dd6..79eeb47c 100644 --- a/front/print.go +++ b/front/print.go @@ -411,6 +411,7 @@ func (r *request) PrintNote(w text.Writer, note *ap.Object, author *ap.Actor, sh if r.User != nil && note.AttributedTo == r.User.ID && note.Type != ap.Question && note.Name == "" { // polls and votes cannot be edited w.Link("/users/edit/"+strings.TrimPrefix(note.ID, "https://"), "🩹 Edit") + w.Link(fmt.Sprintf("titan://%s/users/upload/edit/%s", r.Handler.Domain, strings.TrimPrefix(note.ID, "https://")), "Upload edited post") } if r.User != nil && note.AttributedTo == r.User.ID { w.Link("/users/delete/"+strings.TrimPrefix(note.ID, "https://"), "💣 Delete") diff --git a/front/reply.go b/front/reply.go index b91c45aa..4f16039f 100644 --- a/front/reply.go +++ b/front/reply.go @@ -65,5 +65,5 @@ func (h *Handler) reply(w text.Writer, r *request, args ...string) { }) } - h.post(w, r, nil, ¬e, to, cc, note.Audience, "Reply content") + h.post(w, r, args, nil, ¬e, to, cc, note.Audience, "Reply content", readQuery) } diff --git a/front/static/users/help.gmi b/front/static/users/help.gmi index 4880c4a4..8a09ee48 100644 --- a/front/static/users/help.gmi +++ b/front/static/users/help.gmi @@ -56,17 +56,12 @@ Use this tool to locate a user in the fediverse and see the posts published by t This is a full-text search tool that lists posts containing keyword(s), ordered by relevance. -> 💌 Post to mentioned users +> 📣 New post -Follow this link to publish a post and send it to mentioned users only. - -> 🔔 Post to followers - -Follow this link to publish a post and send it to your followers and mentioned users. - -> 📣 Post to public - -Follow this link to publish a public post visible to anyone. +Follow this link to publish a post visible to: +* Mentioned users only, or +* Your followers and mentioned users, or +* Anyone > ⚙️ Settings diff --git a/front/static/users/post.gmi b/front/static/users/post.gmi new file mode 100644 index 00000000..e4b3847a --- /dev/null +++ b/front/static/users/post.gmi @@ -0,0 +1,10 @@ +# New Post + +=> /users/post/private 💌 Mentioned users only +=> titan://{{.Domain}}/users/upload/private/ Upload text file + +=> /users/post/followers 🔔 Followers and mentioned users +=> titan://{{.Domain}}/users/upload/followers/ Upload text file + +=> /users/post/public 📣 Public +=> titan://{{.Domain}}/users/upload/public/ Upload text file diff --git a/front/upload_followers.go b/front/upload_followers.go new file mode 100644 index 00000000..1543886e --- /dev/null +++ b/front/upload_followers.go @@ -0,0 +1,31 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package front + +import ( + "github.com/dimkr/tootik/ap" + "github.com/dimkr/tootik/front/text" +) + +func (h *Handler) uploadFollowers(w text.Writer, r *request, args ...string) { + to := ap.Audience{} + cc := ap.Audience{} + + to.Add(r.User.Followers) + + h.post(w, r, args, nil, nil, to, cc, "", "", readUpload) +} diff --git a/front/upload_private.go b/front/upload_private.go new file mode 100644 index 00000000..f1384f7f --- /dev/null +++ b/front/upload_private.go @@ -0,0 +1,29 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package front + +import ( + "github.com/dimkr/tootik/ap" + "github.com/dimkr/tootik/front/text" +) + +func (h *Handler) uploadPrivate(w text.Writer, r *request, args ...string) { + to := ap.Audience{} + cc := ap.Audience{} + + h.post(w, r, args, nil, nil, to, cc, "", "", readUpload) +} diff --git a/front/upload_public.go b/front/upload_public.go new file mode 100644 index 00000000..f33839d1 --- /dev/null +++ b/front/upload_public.go @@ -0,0 +1,32 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package front + +import ( + "github.com/dimkr/tootik/ap" + "github.com/dimkr/tootik/front/text" +) + +func (h *Handler) uploadPublic(w text.Writer, r *request, args ...string) { + to := ap.Audience{} + cc := ap.Audience{} + + to.Add(ap.Public) + cc.Add(r.User.Followers) + + h.post(w, r, args, nil, nil, to, cc, "", "", readUpload) +} diff --git a/test/delete_test.go b/test/delete_test.go index e8d7ab27..956d22d0 100644 --- a/test/delete_test.go +++ b/test/delete_test.go @@ -29,10 +29,10 @@ func TestDelete_HappyFlow(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -50,10 +50,10 @@ func TestDelete_NotAuthor(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -81,10 +81,10 @@ func TestDelete_UnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") diff --git a/test/edit_test.go b/test/edit_test.go index c68cc539..5ac6596a 100644 --- a/test/edit_test.go +++ b/test/edit_test.go @@ -40,10 +40,10 @@ func TestEdit_Throttling(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] edit := server.Handle(fmt.Sprintf("/users/edit/%s?Hello%%20followers", id), server.Bob) assert.Equal("40 Please try again later\r\n", edit) @@ -66,10 +66,10 @@ func TestEdit_HappyFlow(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -106,10 +106,10 @@ func TestEdit_EmptyContent(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -135,10 +135,10 @@ func TestEdit_LongContent(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -164,10 +164,10 @@ func TestEdit_InvalidEscapeSequence(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -193,8 +193,8 @@ func TestEdit_NoSuchPost(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, postFollowers) edit := server.Handle("/users/edit/x?Hello%20followers", server.Bob) assert.Equal("40 Error\r\n", edit) @@ -217,10 +217,10 @@ func TestEdit_UnauthenticatedUser(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] edit := server.Handle(fmt.Sprintf("/users/edit/%s?Hello%%20followers", id), nil) assert.Equal("30 /users\r\n", edit) @@ -236,8 +236,8 @@ func TestEdit_AddHashtag(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%23Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+`, say) + postPublic := server.Handle("/users/post/public?%23Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+`, postPublic) hashtag := server.Handle("/users/hashtag/hello", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) @@ -245,7 +245,7 @@ func TestEdit_AddHashtag(t *testing.T) { hashtag = server.Handle("/users/hashtag/world", server.Bob) assert.NotContains(hashtag, server.Alice.PreferredUsername) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -266,8 +266,8 @@ func TestEdit_RemoveHashtag(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%23Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+`, say) + postPublic := server.Handle("/users/post/public?%23Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+`, postPublic) hashtag := server.Handle("/users/hashtag/hello", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) @@ -275,7 +275,7 @@ func TestEdit_RemoveHashtag(t *testing.T) { hashtag = server.Handle("/users/hashtag/world", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -296,8 +296,8 @@ func TestEdit_KeepHashtags(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%23Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+`, say) + postPublic := server.Handle("/users/post/public?%23Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+`, postPublic) hashtag := server.Handle("/users/hashtag/hello", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) @@ -305,7 +305,7 @@ func TestEdit_KeepHashtags(t *testing.T) { hashtag = server.Handle("/users/hashtag/world", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -330,10 +330,10 @@ func TestEdit_AddMention(t *testing.T) { assert.Contains(lines, "No posts.") assert.NotContains(lines, "> Hello world") - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] lines = strings.Split(server.Handle("/users/view/"+id, server.Alice), "\n") assert.Contains(lines, "> Hello world") @@ -362,10 +362,10 @@ func TestEdit_RemoveMention(t *testing.T) { assert.Contains(lines, "No posts.") assert.NotContains(lines, "> Hello @alice") - say := server.Handle("/users/say?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, say) + postPublic := server.Handle("/users/post/public?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] lines = strings.Split(server.Handle("/users/view/"+id, server.Alice), "\n") assert.NotContains(lines, "> Hello world") @@ -394,10 +394,10 @@ func TestEdit_KeepMention(t *testing.T) { assert.Contains(lines, "No posts.") assert.NotContains(lines, "> Hello @alice") - say := server.Handle("/users/say?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, say) + postPublic := server.Handle("/users/post/public?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] lines = strings.Split(server.Handle("/users/view/"+id, server.Alice), "\n") assert.NotContains(lines, "> Hello @alice") @@ -422,12 +422,12 @@ func TestEdit_PollAddOption(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ @@ -452,7 +452,7 @@ func TestEdit_PollAddOption(t *testing.T) { edit := server.Handle(fmt.Sprintf("/users/edit/%s?%%5bPOLL%%20So%%2c%%20polls%%20on%%20Station%%20are%%20pretty%%20cool%%2c%%20right%%3f%%5d%%20Nope%%20%%7c%%20Hell%%20yeah%%21%%20%%7c%%20I%%20couldn%%27t%%20care%%20less", id), server.Alice) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), edit) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) assert.NoError(poller.Run(context.Background())) @@ -473,12 +473,12 @@ func TestEdit_RemoveQuestion(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ diff --git a/test/follow_test.go b/test/follow_test.go index b9c36f17..6ff1e13c 100644 --- a/test/follow_test.go +++ b/test/follow_test.go @@ -36,8 +36,8 @@ func TestFollow_PostToFollowers(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) users = server.Handle("/users", server.Alice) assert.NotContains(users, "No posts.") @@ -54,8 +54,8 @@ func TestFollow_PostToFollowersBeforeFollow(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) @@ -78,8 +78,8 @@ func TestFollow_DMUnfollowFollow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) users = server.Handle("/users", server.Alice) assert.NotContains(users, "No posts.") @@ -106,8 +106,8 @@ func TestFollow_PublicPost(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) users = server.Handle("/users", server.Alice) assert.NotContains(users, "No posts.") @@ -131,10 +131,10 @@ func TestFollow_Mutual(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - whisper := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hello%%20Alice", id), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) diff --git a/test/follows_test.go b/test/follows_test.go index 614be2de..2e0f38d9 100644 --- a/test/follows_test.go +++ b/test/follows_test.go @@ -71,8 +71,8 @@ func TestFollows_OneActiveOneInactive(t *testing.T) { assert.Contains(follows, "=> /users/outbox/localhost.localdomain:8443/user/bob 😈 bob (bob@localhost.localdomain:8443)") assert.Contains(follows, "=> /users/outbox/localhost.localdomain:8443/user/carol 😈 carol (carol@localhost.localdomain:8443)") - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) follows = server.Handle("/users/follows", server.Alice) assert.Contains(follows, fmt.Sprintf("=> /users/outbox/localhost.localdomain:8443/user/bob %s 😈 bob (bob@localhost.localdomain:8443)", time.Now().Format(time.DateOnly))) diff --git a/test/forward_test.go b/test/forward_test.go index 7a0c16f1..66e2977f 100644 --- a/test/forward_test.go +++ b/test/forward_test.go @@ -910,8 +910,8 @@ func TestForward_ReplyToLocalPostByLocalFollower(t *testing.T) { ), ) - whisper := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) _, err := server.db.Exec( `insert into persons (id, actor) values(?,?)`, @@ -920,7 +920,7 @@ func TestForward_ReplyToLocalPostByLocalFollower(t *testing.T) { ) assert.NoError(err) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", whisper[15:len(whisper)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", postFollowers[15:len(postFollowers)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) var forwarded int @@ -945,8 +945,8 @@ func TestForward_EditedReplyToLocalPostByLocalFollower(t *testing.T) { ), ) - whisper := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) _, err := server.db.Exec( `insert into persons (id, actor) values(?,?)`, @@ -955,7 +955,7 @@ func TestForward_EditedReplyToLocalPostByLocalFollower(t *testing.T) { ) assert.NoError(err) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", whisper[15:len(whisper)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", postFollowers[15:len(postFollowers)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) id := reply[15 : len(reply)-2] @@ -987,8 +987,8 @@ func TestForward_DeletedReplyToLocalPostByLocalFollower(t *testing.T) { ), ) - whisper := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) _, err := server.db.Exec( `insert into persons (id, actor) values(?,?)`, @@ -997,7 +997,7 @@ func TestForward_DeletedReplyToLocalPostByLocalFollower(t *testing.T) { ) assert.NoError(err) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", whisper[15:len(whisper)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", postFollowers[15:len(postFollowers)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) id := reply[15 : len(reply)-2] diff --git a/test/fts_test.go b/test/fts_test.go index 890ffcf6..a6a0ba95 100644 --- a/test/fts_test.go +++ b/test/fts_test.go @@ -31,8 +31,8 @@ func TestFTS_Happyflow(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?world", server.Bob) assert.Contains(fts, "Hello world") @@ -44,8 +44,8 @@ func TestFTS_HashtagWithoutHash(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?world", server.Bob) assert.NotContains(fts, "Hello #world") @@ -57,8 +57,8 @@ func TestFTS_HashtagWithHash(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?%23world", server.Bob) assert.NotContains(fts, "Hello #world") @@ -70,8 +70,8 @@ func TestFTS_HashtagWithHashAndQuotes(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?%22%23world%22", server.Bob) assert.Contains(fts, "Hello #world") @@ -83,8 +83,8 @@ func TestFTS_HashtagWithHashAndQuotesUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/fts?%22%23world%22", nil) assert.Contains(fts, "Hello #world") @@ -96,8 +96,8 @@ func TestFTS_HashtagWithHashAndQuotesSecondPage(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?%22%23world%22%20skip%2030", server.Bob) assert.NotContains(fts, "Hello #world") @@ -139,8 +139,8 @@ func TestFTS_UnathenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/fts?world", nil) assert.Contains(fts, "Hello world") @@ -152,8 +152,8 @@ func TestFTS_SearchByAuthorUserName(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?alice", server.Bob) assert.Contains(fts, "Hello world") @@ -165,8 +165,8 @@ func TestFTS_SearchByAuthorID(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) fts := server.Handle("/users/fts?%22https%3a%2f%2flocalhost.localdomain%3a8443%2fuser%2falice%22", server.Bob) assert.Contains(fts, "Hello world") diff --git a/test/hashtag_test.go b/test/hashtag_test.go index a651642d..f8d9e6c9 100644 --- a/test/hashtag_test.go +++ b/test/hashtag_test.go @@ -29,10 +29,10 @@ func TestHashtag_PublicPost(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtag/world", server.Bob) @@ -45,10 +45,10 @@ func TestHashtag_PublicPostUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/hashtag/world", nil) @@ -61,10 +61,10 @@ func TestHashtag_ExclamationMark(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world%21", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world%21", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world!") hashtag := server.Handle("/users/hashtag/world", server.Bob) @@ -77,10 +77,10 @@ func TestHashtag_Beginning(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%23Hello%20world%21", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%23Hello%20world%21", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "#Hello world!") hashtag := server.Handle("/hashtag/Hello", server.Bob) @@ -93,10 +93,10 @@ func TestHashtag_Multiple(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%23Hello%20%23world%21", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%23Hello%20%23world%21", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "#Hello #world!") hashtag := server.Handle("/hashtag/Hello", server.Bob) @@ -112,10 +112,10 @@ func TestHashtag_CaseSensitivity(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23wOrLd", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23wOrLd", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #wOrLd") hashtag := server.Handle("/hashtag/WoRlD", server.Bob) @@ -131,10 +131,10 @@ func TestHashtag_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - view := server.Handle(whisper[3:len(whisper)-2], server.Bob) + view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtag/world", server.Bob) @@ -147,10 +147,10 @@ func TestHashtag_BigOffset(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtag/world?123", server.Bob) @@ -163,10 +163,10 @@ func TestHashtag_BigOffsetUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/hashtag/world?123", nil) @@ -179,10 +179,10 @@ func TestHashtag_InvalidOffset(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/hashtag/world?z", server.Bob) diff --git a/test/hashtags_test.go b/test/hashtags_test.go index 609f89bc..b726f97e 100644 --- a/test/hashtags_test.go +++ b/test/hashtags_test.go @@ -28,10 +28,10 @@ func TestHashtags_NoHashtags(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello world") hashtag := server.Handle("/users/hashtags", server.Bob) @@ -44,10 +44,10 @@ func TestHashtags_OneHashtagOneAuthor(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtags", server.Bob) @@ -60,16 +60,16 @@ func TestHashtags_OneHashtagTwoAuthors(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") - say = server.Handle("/users/say?Hello%20again,%20%23world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic = server.Handle("/users/post/public?Hello%20again,%20%23world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view = server.Handle(say[3:len(say)-2], server.Alice) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) assert.Contains(view, "Hello again, #world") hashtag := server.Handle("/users/hashtags", server.Carol) @@ -82,16 +82,16 @@ func TestHashtags_OneHashtagTwoAuthorsCaseSensitivity(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23worLD", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23worLD", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #worLD") - say = server.Handle("/users/say?Hello%20again,%20%23WORld", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic = server.Handle("/users/post/public?Hello%20again,%20%23WORld", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view = server.Handle(say[3:len(say)-2], server.Alice) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) assert.Contains(view, "Hello again, #WORld") hashtag := server.Handle("/users/hashtags", server.Carol) @@ -104,16 +104,16 @@ func TestHashtags_TwoHashtagsOneAuthor(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") - say = server.Handle("/users/say?Hello%20%23again,%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic = server.Handle("/users/post/public?Hello%20%23again,%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view = server.Handle(say[3:len(say)-2], server.Alice) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) assert.Contains(view, "Hello #again, world") hashtag := server.Handle("/users/hashtags", server.Carol) @@ -127,16 +127,16 @@ func TestHashtags_OneHashtagTwoAuthorsUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello #world") - say = server.Handle("/users/say?Hello%20again,%20%23world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic = server.Handle("/users/post/public?Hello%20again,%20%23world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view = server.Handle(say[3:len(say)-2], server.Alice) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) assert.Contains(view, "Hello again, #world") hashtag := server.Handle("/hashtags", nil) diff --git a/test/outbox_test.go b/test/outbox_test.go index b88403c2..3b359691 100644 --- a/test/outbox_test.go +++ b/test/outbox_test.go @@ -44,8 +44,8 @@ func TestOutbox_InvalidOffset(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) outbox := server.Handle(fmt.Sprintf("/users/outbox/%s?abc", strings.TrimPrefix(server.Alice.ID, "https://")), server.Bob) assert.Equal("40 Invalid query\r\n", outbox) @@ -57,8 +57,8 @@ func TestOutbox_PublicPost(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") @@ -70,8 +70,8 @@ func TestOutbox_PublicPostUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) outbox := server.Handle("/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), nil) assert.Contains(outbox, "Hello world") @@ -83,8 +83,8 @@ func TestOutbox_PublicPostSelf(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") @@ -99,8 +99,8 @@ func TestOutbox_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") @@ -112,8 +112,8 @@ func TestOutbox_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(strings.Split(outbox, "\n"), "No posts.") @@ -126,8 +126,8 @@ func TestOutbox_PostToFollowersUnauthentictedUser(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) outbox := server.Handle("/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), nil) assert.Contains(strings.Split(outbox, "\n"), "No posts.") @@ -140,8 +140,8 @@ func TestOutbox_PostToFollowersSelf(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") @@ -156,8 +156,8 @@ func TestOutbox_DM(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello @bob") @@ -172,8 +172,8 @@ func TestOutbox_DMSelf(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello @bob") @@ -188,8 +188,8 @@ func TestOutbox_DMNotRecipient(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Carol) assert.NotContains(outbox, "Hello @bob") @@ -205,8 +205,8 @@ func TestOutbox_UnauthenticatedUser(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) outbox := server.Handle("/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), nil) assert.NotContains(outbox, "Hello @bob") diff --git a/test/poll_test.go b/test/poll_test.go index 80e4fd56..643fafbd 100644 --- a/test/poll_test.go +++ b/test/poll_test.go @@ -720,10 +720,10 @@ func TestPoll_Local3Options(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -736,10 +736,10 @@ func TestPoll_Local5Options(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -754,8 +754,8 @@ func TestPoll_Local1Option(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope", server.Alice) - assert.Equal("40 Polls must have 2 to 5 options\r\n", say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope", server.Alice) + assert.Equal("40 Polls must have 2 to 5 options\r\n", postPublic) } func TestPoll_Local6Options(t *testing.T) { @@ -764,8 +764,8 @@ func TestPoll_Local6Options(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe%20%7c%20kinda", server.Alice) - assert.Equal("40 Polls must have 2 to 5 options\r\n", say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe%20%7c%20kinda", server.Alice) + assert.Equal("40 Polls must have 2 to 5 options\r\n", postPublic) } func TestPoll_LocalEmptyOption(t *testing.T) { @@ -774,8 +774,8 @@ func TestPoll_LocalEmptyOption(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Equal("40 Poll option cannot be empty\r\n", say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Equal("40 Poll option cannot be empty\r\n", postPublic) } func TestPoll_LocalOptionWithLink(t *testing.T) { @@ -784,10 +784,10 @@ func TestPoll_LocalOptionWithLink(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20I%20prefer%20https%3a%2f%2flocalhost%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20I%20prefer%20https%3a%2f%2flocalhost%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote I prefer https://localhost") @@ -800,16 +800,16 @@ func TestPoll_Local3OptionsAnd2Votes(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -824,7 +824,7 @@ func TestPoll_Local3OptionsAnd2Votes(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view = server.Handle(say[3:len(say)-2], server.Bob) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -839,16 +839,16 @@ func TestPoll_Local3OptionsAnd2VotesAndDeletedVote(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -866,7 +866,7 @@ func TestPoll_Local3OptionsAnd2VotesAndDeletedVote(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view = server.Handle(say[3:len(say)-2], server.Bob) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -887,13 +887,13 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { follow = server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Carol) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", whisper[15:len(whisper)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postFollowers[15:len(postFollowers)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", whisper[15:len(whisper)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postFollowers[15:len(postFollowers)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ @@ -903,7 +903,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view := server.Handle(whisper[3:len(whisper)-2], server.Alice) + view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Alice) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -913,7 +913,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { assert.Contains(view, "bob") assert.Contains(view, "carol") - view = server.Handle(whisper[3:len(whisper)-2], server.Bob) + view = server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -923,7 +923,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { assert.Contains(view, "bob") assert.NotContains(view, "carol") - view = server.Handle(whisper[3:len(whisper)-2], server.Carol) + view = server.Handle(postFollowers[3:len(postFollowers)-2], server.Carol) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -933,7 +933,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { assert.NotContains(view, "bob") assert.Contains(view, "carol") - view = server.Handle("/view/"+whisper[15:len(whisper)-2], nil) + view = server.Handle("/view/"+postFollowers[15:len(postFollowers)-2], nil) assert.Equal("40 Post not found\r\n", view) } @@ -943,13 +943,13 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ @@ -959,7 +959,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view := server.Handle(say[3:len(say)-2], server.Alice) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Alice) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -969,7 +969,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert.Contains(view, "bob") assert.Contains(view, "carol") - view = server.Handle(say[3:len(say)-2], server.Bob) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -979,7 +979,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert.Contains(view, "bob") assert.NotContains(view, "carol") - view = server.Handle(say[3:len(say)-2], server.Carol) + view = server.Handle(postPublic[3:len(postPublic)-2], server.Carol) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -989,7 +989,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert.NotContains(view, "bob") assert.Contains(view, "carol") - view = server.Handle("/view/"+say[15:len(say)-2], nil) + view = server.Handle("/view/"+postPublic[15:len(postPublic)-2], nil) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.NotContains(view, "Vote") assert.Contains(strings.Split(view, "\n"), "1 ████████ Hell yeah!") diff --git a/test/whisper_test.go b/test/post_followers_test.go similarity index 71% rename from test/whisper_test.go rename to test/post_followers_test.go index 5535dfe4..bf2629dc 100644 --- a/test/whisper_test.go +++ b/test/post_followers_test.go @@ -23,7 +23,7 @@ import ( "testing" ) -func TestWhisper_HappyFlow(t *testing.T) { +func TestPostFollowers_HappyFlow(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -32,10 +32,10 @@ func TestWhisper_HappyFlow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - view := server.Handle(whisper[3:len(whisper)-2], server.Bob) + view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) @@ -45,22 +45,22 @@ func TestWhisper_HappyFlow(t *testing.T) { assert.NotContains(local, "Hello world") } -func TestWhisper_FollowAfterPost(t *testing.T) { +func TestPostFollowers_FollowAfterPost(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - view := server.Handle(whisper[3:len(whisper)-2], server.Bob) + view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) assert.Equal("40 Post not found\r\n", view) follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - view = server.Handle(whisper[3:len(whisper)-2], server.Bob) + view = server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) @@ -70,7 +70,7 @@ func TestWhisper_FollowAfterPost(t *testing.T) { assert.NotContains(local, "Hello world") } -func TestWhisper_Throttling(t *testing.T) { +func TestPostFollowers_Throttling(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -79,17 +79,17 @@ func TestWhisper_Throttling(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - view := server.Handle(whisper[3:len(whisper)-2], server.Bob) + view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") - whisper = server.Handle("/users/whisper?Hello%20once%20more,%20world", server.Alice) - assert.Equal("40 Please wait before posting again\r\n", whisper) + postFollowers = server.Handle("/users/post/followers?Hello%20once%20more,%20world", server.Alice) + assert.Equal("40 Please wait before posting again\r\n", postFollowers) outbox = server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") diff --git a/test/dm_test.go b/test/post_private_test.go similarity index 61% rename from test/dm_test.go rename to test/post_private_test.go index ac131972..9449055e 100644 --- a/test/dm_test.go +++ b/test/post_private_test.go @@ -21,16 +21,16 @@ import ( "testing" ) -func TestDM_HappyFlow(t *testing.T) { +func TestPostPrivate_HappyFlow(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") @@ -42,41 +42,41 @@ func TestDM_HappyFlow(t *testing.T) { assert.Contains(view, "Hello @alice@localhost.localdomain:8443") } -func TestDM_UnauthenticatedUser(t *testing.T) { +func TestPostPrivate_UnauthenticatedUser(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/view/"+id, nil) assert.Equal(view, "40 Post not found\r\n") } -func TestDM_Loopback(t *testing.T) { +func TestPostPrivate_Loopback(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40bob%40localhost.localdomain%3a8443", server.Bob) - assert.Equal("40 Post audience is empty\r\n", dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40bob%40localhost.localdomain%3a8443", server.Bob) + assert.Equal("40 Post audience is empty\r\n", postPrivate) } -func TestDM_TwoMentions(t *testing.T) { +func TestPostPrivate_TwoMentions(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @carol@localhost.localdomain:8443") @@ -88,16 +88,16 @@ func TestDM_TwoMentions(t *testing.T) { assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @carol@localhost.localdomain:8443") } -func TestDM_TwoMentionsOneLoopback(t *testing.T) { +func TestPostPrivate_TwoMentionsOneLoopback(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40bob%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40bob%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @bob@localhost.localdomain:8443") @@ -109,7 +109,7 @@ func TestDM_TwoMentionsOneLoopback(t *testing.T) { assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @bob@localhost.localdomain:8443") } -func TestDM_TooManyRecipients(t *testing.T) { +func TestPostPrivate_TooManyRecipients(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -117,11 +117,11 @@ func TestDM_TooManyRecipients(t *testing.T) { assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) - assert.Equal("40 Too many recipients\r\n", dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) + assert.Equal("40 Too many recipients\r\n", postPrivate) } -func TestDM_MaxRecipients(t *testing.T) { +func TestPostPrivate_MaxRecipients(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -129,10 +129,10 @@ func TestDM_MaxRecipients(t *testing.T) { assert := assert.New(t) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @carol@localhost.localdomain:8443") diff --git a/test/say_test.go b/test/post_public_test.go similarity index 70% rename from test/say_test.go rename to test/post_public_test.go index 536159ba..8582535b 100644 --- a/test/say_test.go +++ b/test/post_public_test.go @@ -22,16 +22,16 @@ import ( "testing" ) -func TestSay_HappyFlow(t *testing.T) { +func TestPostPublic_HappyFlow(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) @@ -41,23 +41,23 @@ func TestSay_HappyFlow(t *testing.T) { assert.Contains(local, "Hello world") } -func TestSay_Throttling(t *testing.T) { +func TestPostPublic_Throttling(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - view := server.Handle(say[3:len(say)-2], server.Bob) + view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") - say = server.Handle("/users/say?Hello%20once%20more,%20world", server.Alice) - assert.Equal("40 Please wait before posting again\r\n", say) + postPublic = server.Handle("/users/post/public?Hello%20once%20more,%20world", server.Alice) + assert.Equal("40 Please wait before posting again\r\n", postPublic) outbox = server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") diff --git a/test/register_test.go b/test/register_test.go index 70e164a7..563ea98e 100644 --- a/test/register_test.go +++ b/test/register_test.go @@ -72,7 +72,7 @@ XCHmESk7Zzor+JhUFjIwf/vM/KbIgszEUXJ7ccMctWelADHc5dJjrf/nbXhvf/NA y0ibEVc6KM97dRMPo1MwUTAdBgNVHQ4EFgQUG0V5VrS+Wj3U3A4j2tgdJKTYmn8w HwYDVR0jBBgwFoAUG0V5VrS+Wj3U3A4j2tgdJKTYmn8wDwYDVR0TAQH/BAUwAwEB /zAKBggqhkjOPQQDAgNIADBFAiEA84fpaDdh6JRaT4R7qGdhfO9zYnJ6VcQEnAiN -eXPo8z4CIBkYBJV6O6+Pvmjxs6SAa6c8SVb4Q72lJQpe0woYdmXf +eXPo8z4CIBkYBJV6O6+Pvmjxs6SAa6c8SVb4Q72lJQpe0woYpostPrivateXf -----END CERTIFICATE-----` erinKey = `-----BEGIN PRIVATE KEY----- diff --git a/test/reply_test.go b/test/reply_test.go index 3948e533..a1f1fec2 100644 --- a/test/reply_test.go +++ b/test/reply_test.go @@ -29,10 +29,10 @@ func TestReply_AuthorNotFollowed(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -62,10 +62,10 @@ func TestReply_AuthorFollowed(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -95,10 +95,10 @@ func TestReply_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -125,10 +125,10 @@ func TestReply_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -157,10 +157,10 @@ func TestReply_PostToFollowersUnfollowedBeforeReply(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -193,10 +193,10 @@ func TestReply_PostToFollowersUnfollowedAfterReply(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -228,10 +228,10 @@ func TestReply_SelfReply(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -264,10 +264,10 @@ func TestReply_ReplyToPublicPostByFollowedUser(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -295,10 +295,10 @@ func TestReply_ReplyToPublicPostByNotFollowedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -329,8 +329,8 @@ func TestReply_DM(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice@localhost.localdomain:8443") @@ -340,7 +340,7 @@ func TestReply_DM(t *testing.T) { assert.NotContains(users, "Hello @alice@localhost.localdomain:8443") assert.NotContains(users, "Hello Bob") - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") @@ -366,8 +366,8 @@ func TestReply_DMUnfollowed(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice@localhost.localdomain:8443") @@ -377,7 +377,7 @@ func TestReply_DMUnfollowed(t *testing.T) { assert.NotContains(users, "Hello @alice@localhost.localdomain:8443") assert.NotContains(users, "Hello Bob") - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") @@ -406,8 +406,8 @@ func TestReply_DMToAnotherUser(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice@localhost.localdomain:8443") @@ -417,7 +417,7 @@ func TestReply_DMToAnotherUser(t *testing.T) { assert.NotContains(users, "Hello @alice@localhost.localdomain:8443") assert.NotContains(users, "Hello Bob") - id := dm[15 : len(dm)-2] + id := postPrivate[15 : len(postPrivate)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") diff --git a/test/share_test.go b/test/share_test.go index dd412756..9af77ee8 100644 --- a/test/share_test.go +++ b/test/share_test.go @@ -29,10 +29,10 @@ func TestShare_PublicPost(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -50,18 +50,18 @@ func TestShare_Throttling(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) - say = server.Handle("/users/say?Hello%20world", server.Carol) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic = server.Handle("/users/post/public?Hello%20world", server.Carol) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id = say[15 : len(say)-2] + id = postPublic[15 : len(postPublic)-2] share = server.Handle("/users/share/"+id, server.Bob) assert.Equal("40 Please wait before sharing\r\n", share) @@ -73,10 +73,10 @@ func TestShare_UnshareThrottling(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -91,10 +91,10 @@ func TestShare_PostToFollowers(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := whisper[15 : len(whisper)-2] + id := postFollowers[15 : len(postFollowers)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal("40 Error\r\n", share) @@ -106,10 +106,10 @@ func TestShare_Twice(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -130,10 +130,10 @@ func TestShare_Unshare(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -160,10 +160,10 @@ func TestShare_ShareAfterUnshare(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) diff --git a/test/stats_test.go b/test/stats_test.go index 4cda5596..c0889d61 100644 --- a/test/stats_test.go +++ b/test/stats_test.go @@ -37,8 +37,8 @@ func TestStats_WithPosts(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) stats := server.Handle("/stats", server.Alice) assert.Regexp("^20 text/gemini\r\n", stats) diff --git a/test/thread_test.go b/test/thread_test.go index 7e1ec77c..ae416130 100644 --- a/test/thread_test.go +++ b/test/thread_test.go @@ -33,10 +33,10 @@ func TestThread_TwoReplies(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -62,10 +62,10 @@ func TestThread_NestedReplies(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -91,10 +91,10 @@ func TestThread_NestedReply(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -117,10 +117,10 @@ func TestThread_NoReplies(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.NotContains(view, "View parent post") @@ -140,10 +140,10 @@ func TestThread_NestedRepliesFromBottom(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -171,10 +171,10 @@ func TestThread_NestedRepliesFromBottomMissingNode(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -205,10 +205,10 @@ func TestThread_NestedRepliesFromBottomMissingFirstNode(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) diff --git a/test/unfollow_test.go b/test/unfollow_test.go index 3a16e249..2ee1ab6b 100644 --- a/test/unfollow_test.go +++ b/test/unfollow_test.go @@ -32,8 +32,8 @@ func TestUnfollow_HappyFlow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - say := server.Handle("/users/whisper?Hello%20followers", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20followers", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello followers") @@ -54,8 +54,8 @@ func TestUnfollow_FollowAgain(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - say := server.Handle("/users/whisper?Hello%20followers", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20followers", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello followers") diff --git a/test/upload_edit_test.go b/test/upload_edit_test.go new file mode 100644 index 00000000..156f22e3 --- /dev/null +++ b/test/upload_edit_test.go @@ -0,0 +1,217 @@ +/* +Copyright 2023, 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package test + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "strings" + "testing" + "time" +) + +func TestUploadEdit_HappyFlow(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/plain;size=15", id), server.Bob, []byte("Hello followers")) + assert.Equal(fmt.Sprintf("30 gemini://%s/users/view/%s\r\n", domain, id), edit) + + users = server.Handle("/users", server.Alice) + assert.NotContains(users, "No posts.") + assert.Contains(users, "Hello followers") + + edit = server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/plain;size=16", id), server.Bob, []byte("Hello, followers")) + assert.Equal("40 Please try again later\r\n", edit) + + users = server.Handle("/users", server.Alice) + assert.NotContains(users, "No posts.") + assert.Contains(users, "Hello followers") + + users = server.Handle("/users", server.Alice) + assert.NotContains(users, "No posts.") + assert.Contains(users, "Hello followers") +} + +func TestUploadEdit_Empty(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/plain;size=0", id), server.Bob, []byte("Hello followers")) + assert.Equal("40 Content is empty\r\n", edit) +} + +func TestUploadEdit_SizeLimit(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + server.cfg.MaxPostsLength = 14 + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/plain;size=15", id), server.Bob, []byte("Hello followers")) + assert.Equal("40 Post is too long\r\n", edit) +} + +func TestUploadEdit_InvalidSize(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/plain;size=abc", id), server.Bob, []byte("Hello followers")) + assert.Equal("40 Invalid size\r\n", edit) +} + +func TestUploadEdit_InvalidType(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/gemini;size=15", id), server.Bob, []byte("Hello followers")) + assert.Equal("40 Only text/plain is supported\r\n", edit) +} + +func TestUploadEdit_NoSize(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mime=text/plain;siz=15", id), server.Bob, []byte("Hello followers")) + assert.Equal("40 Invalid parameters\r\n", edit) +} + +func TestUploadEdit_NoType(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + users := server.Handle("/users", server.Alice) + assert.Contains(users, "No posts.") + assert.NotContains(users, "Hello followers") + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) + assert.NoError(err) + + edit := server.Upload(fmt.Sprintf("/users/upload/edit/%s;mim=text/plain;size=15", id), server.Bob, []byte("Hello followers")) + assert.Equal("40 Invalid parameters\r\n", edit) +} diff --git a/test/users_test.go b/test/users_test.go index e93c152c..839d805d 100644 --- a/test/users_test.go +++ b/test/users_test.go @@ -58,8 +58,8 @@ func TestUsers_DM(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice") @@ -74,8 +74,8 @@ func TestUsers_DMNotFollowing(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - dm := server.Handle("/users/dm?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) + postPrivate := server.Handle("/users/post/private?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) unfollow := server.Handle("/users/unfollow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), unfollow) @@ -93,8 +93,8 @@ func TestUsers_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello world") @@ -106,8 +106,8 @@ func TestUsers_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) users := server.Handle("/users", server.Alice) assert.NotContains(users, "Hello world") @@ -122,8 +122,8 @@ func TestUsers_PublicPost(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello world") @@ -135,8 +135,8 @@ func TestUsers_PublicPostNotFollowing(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) users := server.Handle("/users", server.Alice) assert.NotContains(users, "Hello world") diff --git a/test/view_test.go b/test/view_test.go index bb2238ff..19be330a 100644 --- a/test/view_test.go +++ b/test/view_test.go @@ -34,10 +34,10 @@ func TestView_NoReplies(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -49,10 +49,10 @@ func TestView_OneReply(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -68,10 +68,10 @@ func TestView_TwoReplies(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -91,10 +91,10 @@ func TestView_TwoRepliesBigOffset(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -114,10 +114,10 @@ func TestView_TwoRepliesBigOffsetUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -137,10 +137,10 @@ func TestView_TwoRepliesUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -160,10 +160,10 @@ func TestView_OneReplyPostDeleted(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -187,10 +187,10 @@ func TestView_OneReplyPostNotDeleted(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -211,10 +211,10 @@ func TestView_OneReplyPostNotDeletedUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -235,10 +235,10 @@ func TestView_OneReplyPostDeletedUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -262,10 +262,10 @@ func TestView_OneReplyReplyDeleted(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/say?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -430,10 +430,10 @@ func TestView_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - say := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -445,13 +445,13 @@ func TestView_PostToFollowersPostBeforeFollow(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -466,10 +466,10 @@ func TestView_PostToFollowersUnfollow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - say := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -487,10 +487,10 @@ func TestView_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - say := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Equal("40 Post not found\r\n", view) @@ -508,10 +508,10 @@ func TestView_PostToFollowersWithReply(t *testing.T) { follow = server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Carol) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - say := server.Handle("/users/whisper?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, say) + postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) - id := say[15 : len(say)-2] + id := postPublic[15 : len(postPublic)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", id), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) From d85d34b319df9ce54bd2eb0f9e29d3eac69df698 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Mon, 8 Apr 2024 21:10:25 +0300 Subject: [PATCH 02/20] mention post upload in help page --- front/static/users/help.gmi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/front/static/users/help.gmi b/front/static/users/help.gmi index 8a09ee48..a5be012e 100644 --- a/front/static/users/help.gmi +++ b/front/static/users/help.gmi @@ -63,6 +63,8 @@ Follow this link to publish a post visible to: * Your followers and mentioned users, or * Anyone +You can upload a plain text file over Titan, instead of typing your post in the input prompt (use your client certificate for authentication). + > ⚙️ Settings This page allows you to: From 7ed6f0803b0e6b869aef84eb65088c4a5e2528e1 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Tue, 9 Apr 2024 20:32:37 +0300 Subject: [PATCH 03/20] drop trailing / --- front/handler.go | 6 +++--- front/static/users/post.gmi | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/front/handler.go b/front/handler.go index e55259a9..d4477e4b 100644 --- a/front/handler.go +++ b/front/handler.go @@ -107,9 +107,9 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/edit/(\S+)`)] = h.edit h.handlers[regexp.MustCompile(`^/users/delete/(\S+)`)] = delete - h.handlers[regexp.MustCompile(`^/users/upload/private/;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPrivate - h.handlers[regexp.MustCompile(`^/users/upload/followers/;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadFollowers - h.handlers[regexp.MustCompile(`^/users/upload/public/;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPublic + h.handlers[regexp.MustCompile(`^/users/upload/private;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPrivate + h.handlers[regexp.MustCompile(`^/users/upload/followers;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadFollowers + h.handlers[regexp.MustCompile(`^/users/upload/public;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPublic h.handlers[regexp.MustCompile(`^/users/upload/edit/([^;]+);([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.editUpload h.handlers[regexp.MustCompile(`^/users/resolve$`)] = withUserMenu(h.resolve) diff --git a/front/static/users/post.gmi b/front/static/users/post.gmi index e4b3847a..456c7f17 100644 --- a/front/static/users/post.gmi +++ b/front/static/users/post.gmi @@ -1,10 +1,10 @@ # New Post => /users/post/private 💌 Mentioned users only -=> titan://{{.Domain}}/users/upload/private/ Upload text file +=> titan://{{.Domain}}/users/upload/private Upload text file => /users/post/followers 🔔 Followers and mentioned users -=> titan://{{.Domain}}/users/upload/followers/ Upload text file +=> titan://{{.Domain}}/users/upload/followers Upload text file => /users/post/public 📣 Public -=> titan://{{.Domain}}/users/upload/public/ Upload text file +=> titan://{{.Domain}}/users/upload/public Upload text file From e2b95e2ce3a44271fada36b83ae73df311711aef Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 19:41:55 +0300 Subject: [PATCH 04/20] add reply and bio upload --- front/bio.go | 35 ++++++++++++++------ front/edit.go | 6 ++-- front/handler.go | 2 ++ front/print.go | 1 + front/reply.go | 19 +++++++++-- front/static/users/settings.gmi | 1 + test/upload_reply_test.go | 57 +++++++++++++++++++++++++++++++++ 7 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 test/upload_reply_test.go diff --git a/front/bio.go b/front/bio.go index 1c189b45..b4243670 100644 --- a/front/bio.go +++ b/front/bio.go @@ -20,13 +20,12 @@ import ( "github.com/dimkr/tootik/front/text" "github.com/dimkr/tootik/front/text/plain" "github.com/dimkr/tootik/outbox" - "net/url" "strings" "time" "unicode/utf8" ) -func (h *Handler) bio(w text.Writer, r *request, args ...string) { +func (h *Handler) doBio(w text.Writer, r *request, readContent func(text.Writer, *request, []string) (string, bool), args []string) { if r.User == nil { w.Redirect("/users") return @@ -40,14 +39,8 @@ func (h *Handler) bio(w text.Writer, r *request, args ...string) { return } - if r.URL.RawQuery == "" { - w.Status(10, "Summary") - return - } - - summary, err := url.QueryUnescape(r.URL.RawQuery) - if err != nil { - w.Status(40, "Bad input") + summary, ok := readContent(w, r, args) + if !ok { return } @@ -90,3 +83,25 @@ func (h *Handler) bio(w text.Writer, r *request, args ...string) { w.Redirect("/users/outbox/" + strings.TrimPrefix(r.User.ID, "https://")) } + +func (h *Handler) bio(w text.Writer, r *request, args ...string) { + h.doBio( + w, + r, + func(text.Writer, *request, []string) (string, bool) { + return readQuery(w, r, args, "Bio") + }, + args, + ) +} + +func (h *Handler) bioUpload(w text.Writer, r *request, args ...string) { + h.doBio( + w, + r, + func(text.Writer, *request, []string) (string, bool) { + return readUpload(w, r, args, "") + }, + args, + ) +} diff --git a/front/edit.go b/front/edit.go index a4f237e0..cd4a231b 100644 --- a/front/edit.go +++ b/front/edit.go @@ -25,7 +25,7 @@ import ( "time" ) -func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request, []string, string) (string, bool), args ...string) { +func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request, []string, string) (string, bool), args []string) { if r.User == nil { w.Redirect("/users") return @@ -88,7 +88,7 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer } func (h *Handler) edit(w text.Writer, r *request, args ...string) { - h.doEdit(w, r, readQuery, args...) + h.doEdit(w, r, readQuery, args) } func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { @@ -98,6 +98,6 @@ func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { func(w text.Writer, r *request, args []string, prompt string) (string, bool) { return readUpload(w, r, args[1:], prompt) }, - args..., + args, ) } diff --git a/front/handler.go b/front/handler.go index d4477e4b..9e913cff 100644 --- a/front/handler.go +++ b/front/handler.go @@ -85,6 +85,7 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/avatar;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.avatar h.handlers[regexp.MustCompile(`^/users/bio$`)] = h.bio + h.handlers[regexp.MustCompile(`^/users/upload/bio;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.bioUpload h.handlers[regexp.MustCompile(`^/users/name$`)] = h.name h.handlers[regexp.MustCompile(`^/users/alias$`)] = h.alias h.handlers[regexp.MustCompile(`^/users/move$`)] = h.move @@ -111,6 +112,7 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/upload/followers;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadFollowers h.handlers[regexp.MustCompile(`^/users/upload/public;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPublic h.handlers[regexp.MustCompile(`^/users/upload/edit/([^;]+);([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.editUpload + h.handlers[regexp.MustCompile(`^/users/upload/reply/([^;]+);([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.replyUpload h.handlers[regexp.MustCompile(`^/users/resolve$`)] = withUserMenu(h.resolve) diff --git a/front/print.go b/front/print.go index 79eeb47c..28b59ebd 100644 --- a/front/print.go +++ b/front/print.go @@ -439,6 +439,7 @@ func (r *request) PrintNote(w text.Writer, note *ap.Object, author *ap.Actor, sh if r.User != nil { w.Link("/users/reply/"+strings.TrimPrefix(note.ID, "https://"), "💬 Reply") + w.Link(fmt.Sprintf("titan://%s/users/upload/reply/%s", r.Handler.Domain, strings.TrimPrefix(note.ID, "https://")), "Upload reply") } } } diff --git a/front/reply.go b/front/reply.go index 4f16039f..cb1c1bff 100644 --- a/front/reply.go +++ b/front/reply.go @@ -23,7 +23,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) reply(w text.Writer, r *request, args ...string) { +func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Writer, *request, []string, string) (string, bool), args []string) { postID := "https://" + args[1] var note ap.Object @@ -65,5 +65,20 @@ func (h *Handler) reply(w text.Writer, r *request, args ...string) { }) } - h.post(w, r, args, nil, ¬e, to, cc, note.Audience, "Reply content", readQuery) + h.post(w, r, args, nil, ¬e, to, cc, note.Audience, "Reply content", readContent) +} + +func (h *Handler) reply(w text.Writer, r *request, args ...string) { + h.doReply(w, r, readQuery, args) +} + +func (h *Handler) replyUpload(w text.Writer, r *request, args ...string) { + h.doReply( + w, + r, + func(w text.Writer, r *request, args []string, prompt string) (string, bool) { + return readUpload(w, r, args[1:], prompt) + }, + args, + ) } diff --git a/front/static/users/settings.gmi b/front/static/users/settings.gmi index a1f35a10..54a3cc6d 100644 --- a/front/static/users/settings.gmi +++ b/front/static/users/settings.gmi @@ -4,6 +4,7 @@ => /users/name 👺 Set display name => /users/bio 📜 Set bio +=> titan://{{.Domain}}/users/upload/bio Upload bio => titan://{{.Domain}}/users/avatar 📷 Set avatar ## Migration diff --git a/test/upload_reply_test.go b/test/upload_reply_test.go new file mode 100644 index 00000000..5e7429f4 --- /dev/null +++ b/test/upload_reply_test.go @@ -0,0 +1,57 @@ +/* +Copyright 2023, 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package test + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "strings" + "testing" +) + +func TestUploadReply_PostToFollowers(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) + assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) + + postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) + assert.Regexp(fmt.Sprintf("^30 gemini://%s/users/view/\\S+\r\n$", domain), postFollowers) + + id := postFollowers[50 : len(postFollowers)-2] + + view := server.Handle("/users/view/"+id, server.Bob) + assert.Contains(view, "Hello world") + assert.NotContains(view, "Welcome Bob") + + reply := server.Upload(fmt.Sprintf("/users/upload/reply/%s;mime=text/plain;size=11", id), server.Alice, []byte("Welcome Bob")) + assert.Regexp(fmt.Sprintf("^30 gemini://%s/users/view/\\S+\r\n$", domain), reply) + + view = server.Handle("/users/view/"+id, server.Alice) + assert.Contains(view, "Hello world") + assert.Contains(view, "Welcome Bob") + + users := server.Handle("/users", server.Bob) + assert.Contains(users, "Welcome Bob") + + local := server.Handle("/local", nil) + assert.NotContains(local, "Hello world") + assert.NotContains(local, "Welcome Bob") +} From 36e06c8a0fe03fc7eb3c2b68edb41c6b3461f96b Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 19:54:14 +0300 Subject: [PATCH 05/20] cleanup --- front/post.go | 6 +++++- test/server.go | 1 + test/upload_reply_test.go | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/front/post.go b/front/post.go index e4c2a065..a56e0b9e 100644 --- a/front/post.go +++ b/front/post.go @@ -318,5 +318,9 @@ func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Obj return } - w.Redirectf("gemini://%s/users/view/%s", h.Domain, strings.TrimPrefix(postID, "https://")) + if r.URL.Scheme == "titan" { + w.Redirectf("gemini://%s/users/view/%s", h.Domain, strings.TrimPrefix(postID, "https://")) + } else { + w.Redirectf("/users/view/%s", strings.TrimPrefix(postID, "https://")) + } } diff --git a/test/server.go b/test/server.go index 5224d7d1..4c39f2a6 100644 --- a/test/server.go +++ b/test/server.go @@ -131,6 +131,7 @@ func (s *server) Upload(request string, user *ap.Actor, body []byte) string { if err != nil { panic(err) } + u.Scheme = "titan" var buf bytes.Buffer var wg sync.WaitGroup diff --git a/test/upload_reply_test.go b/test/upload_reply_test.go index 5e7429f4..f6d0e236 100644 --- a/test/upload_reply_test.go +++ b/test/upload_reply_test.go @@ -33,9 +33,9 @@ func TestUploadReply_PostToFollowers(t *testing.T) { assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf("^30 gemini://%s/users/view/\\S+\r\n$", domain), postFollowers) + assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") From fd624eab5141278e7b3d8229b5aa56943661c05e Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 19:57:47 +0300 Subject: [PATCH 06/20] cleanup --- test/upload_edit_test.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/upload_edit_test.go b/test/upload_edit_test.go index 156f22e3..69688052 100644 --- a/test/upload_edit_test.go +++ b/test/upload_edit_test.go @@ -38,9 +38,9 @@ func TestUploadEdit_HappyFlow(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -78,9 +78,9 @@ func TestUploadEdit_Empty(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -103,9 +103,9 @@ func TestUploadEdit_SizeLimit(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -130,9 +130,9 @@ func TestUploadEdit_InvalidSize(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -155,9 +155,9 @@ func TestUploadEdit_InvalidType(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -180,9 +180,9 @@ func TestUploadEdit_NoSize(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -205,9 +205,9 @@ func TestUploadEdit_NoType(t *testing.T) { assert.NotContains(users, "Hello followers") postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(fmt.Sprintf(`^30 gemini://%s/users/view/(\S+)\r\n$`, domain), postFollowers) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) - id := postFollowers[50 : len(postFollowers)-2] + id := postFollowers[15 : len(postFollowers)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) From 1f690ffb72bbcabf786c1a1fbc1c0d756a9ebd7e Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 20:11:47 +0300 Subject: [PATCH 07/20] cleanup --- front/bio.go | 9 +-------- front/edit.go | 19 +++++++++++++------ front/post.go | 6 +++--- front/post_followers.go | 4 +++- front/post_private.go | 4 +++- front/post_public.go | 4 +++- front/reply.go | 17 ++++++++++++----- front/upload_followers.go | 4 +++- front/upload_private.go | 4 +++- front/upload_public.go | 2 +- 10 files changed, 45 insertions(+), 28 deletions(-) diff --git a/front/bio.go b/front/bio.go index b4243670..9b8f41ab 100644 --- a/front/bio.go +++ b/front/bio.go @@ -96,12 +96,5 @@ func (h *Handler) bio(w text.Writer, r *request, args ...string) { } func (h *Handler) bioUpload(w text.Writer, r *request, args ...string) { - h.doBio( - w, - r, - func(text.Writer, *request, []string) (string, bool) { - return readUpload(w, r, args, "") - }, - args, - ) + h.doBio(w, r, readUpload, args) } diff --git a/front/edit.go b/front/edit.go index cd4a231b..680db40d 100644 --- a/front/edit.go +++ b/front/edit.go @@ -25,7 +25,7 @@ import ( "time" ) -func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request, []string, string) (string, bool), args []string) { +func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request, []string) (string, bool), args []string) { if r.User == nil { w.Redirect("/users") return @@ -70,7 +70,7 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer } if note.InReplyTo == "" { - h.post(w, r, args, ¬e, nil, note.To, note.CC, note.Audience, "Post content", readContent) + h.post(w, r, args, ¬e, nil, note.To, note.CC, note.Audience, readContent) return } @@ -84,19 +84,26 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer } // the starting point is the original value of to and cc: recipients can be added but not removed when editing - h.post(w, r, args, ¬e, &parent, note.To, note.CC, note.Audience, "Post content", readContent) + h.post(w, r, args, ¬e, &parent, note.To, note.CC, note.Audience, readContent) } func (h *Handler) edit(w text.Writer, r *request, args ...string) { - h.doEdit(w, r, readQuery, args) + h.doEdit( + w, + r, + func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args, "Post content") + }, + args, + ) } func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { h.doEdit( w, r, - func(w text.Writer, r *request, args []string, prompt string) (string, bool) { - return readUpload(w, r, args[1:], prompt) + func(w text.Writer, r *request, args []string) (string, bool) { + return readUpload(w, r, args[1:]) }, args, ) diff --git a/front/post.go b/front/post.go index a56e0b9e..9f1b87ed 100644 --- a/front/post.go +++ b/front/post.go @@ -60,7 +60,7 @@ func readQuery(w text.Writer, r *request, args []string, prompt string) (string, return content, true } -func readUpload(w text.Writer, r *request, args []string, prompt string) (string, bool) { +func readUpload(w text.Writer, r *request, args []string) (string, bool) { if r.Body == nil { w.Redirect("/users/oops") return "", false @@ -121,7 +121,7 @@ func readUpload(w text.Writer, r *request, args []string, prompt string) (string return string(buf), true } -func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience, prompt string, readContent func(text.Writer, *request, []string, string) (string, bool)) { +func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readContent func(text.Writer, *request, []string) (string, bool)) { if r.User == nil { w.Redirect("/users") return @@ -154,7 +154,7 @@ func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Obj } } - content, ok := readContent(w, r, args, prompt) + content, ok := readContent(w, r, args) if !ok { return } diff --git a/front/post_followers.go b/front/post_followers.go index 8bf5ac07..69cb0ae6 100644 --- a/front/post_followers.go +++ b/front/post_followers.go @@ -27,5 +27,7 @@ func (h *Handler) postFollowers(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", "Post content", readQuery) + h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args, "Post content") + }) } diff --git a/front/post_private.go b/front/post_private.go index 7d9ed491..95e3a168 100644 --- a/front/post_private.go +++ b/front/post_private.go @@ -25,5 +25,7 @@ func (h *Handler) postPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, args, nil, nil, to, cc, "", "Post content", readQuery) + h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args, "Post content") + }) } diff --git a/front/post_public.go b/front/post_public.go index f6badfc6..8153dd98 100644 --- a/front/post_public.go +++ b/front/post_public.go @@ -28,5 +28,7 @@ func (h *Handler) postPublic(w text.Writer, r *request, args ...string) { to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", "Post content", readQuery) + h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args, "Post content") + }) } diff --git a/front/reply.go b/front/reply.go index cb1c1bff..6c7d4828 100644 --- a/front/reply.go +++ b/front/reply.go @@ -23,7 +23,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Writer, *request, []string, string) (string, bool), args []string) { +func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Writer, *request, []string) (string, bool), args []string) { postID := "https://" + args[1] var note ap.Object @@ -65,19 +65,26 @@ func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Write }) } - h.post(w, r, args, nil, ¬e, to, cc, note.Audience, "Reply content", readContent) + h.post(w, r, args, nil, ¬e, to, cc, note.Audience, readContent) } func (h *Handler) reply(w text.Writer, r *request, args ...string) { - h.doReply(w, r, readQuery, args) + h.doReply( + w, + r, + func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args[1:], "Reply content") + }, + args, + ) } func (h *Handler) replyUpload(w text.Writer, r *request, args ...string) { h.doReply( w, r, - func(w text.Writer, r *request, args []string, prompt string) (string, bool) { - return readUpload(w, r, args[1:], prompt) + func(w text.Writer, r *request, args []string) (string, bool) { + return readUpload(w, r, args[1:]) }, args, ) diff --git a/front/upload_followers.go b/front/upload_followers.go index 1543886e..33b1a425 100644 --- a/front/upload_followers.go +++ b/front/upload_followers.go @@ -27,5 +27,7 @@ func (h *Handler) uploadFollowers(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", "", readUpload) + h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args, "Post content") + }) } diff --git a/front/upload_private.go b/front/upload_private.go index f1384f7f..3253b0af 100644 --- a/front/upload_private.go +++ b/front/upload_private.go @@ -25,5 +25,7 @@ func (h *Handler) uploadPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, args, nil, nil, to, cc, "", "", readUpload) + h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { + return readQuery(w, r, args, "Post content") + }) } diff --git a/front/upload_public.go b/front/upload_public.go index f33839d1..6c9e54ec 100644 --- a/front/upload_public.go +++ b/front/upload_public.go @@ -28,5 +28,5 @@ func (h *Handler) uploadPublic(w text.Writer, r *request, args ...string) { to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", "", readUpload) + h.post(w, r, args, nil, nil, to, cc, "", readUpload) } From 6ada2ab909f63282cfe8d3eb97869f7e4145486b Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 20:22:20 +0300 Subject: [PATCH 08/20] cleanup --- front/bio.go | 17 +++++++++++------ front/edit.go | 12 ++++++------ front/post.go | 6 +++--- front/post_followers.go | 4 ++-- front/post_private.go | 4 ++-- front/post_public.go | 4 ++-- front/reply.go | 10 +++++----- front/upload_followers.go | 4 ++-- front/upload_private.go | 4 ++-- front/upload_public.go | 4 +++- 10 files changed, 38 insertions(+), 31 deletions(-) diff --git a/front/bio.go b/front/bio.go index 9b8f41ab..8141c825 100644 --- a/front/bio.go +++ b/front/bio.go @@ -25,7 +25,7 @@ import ( "unicode/utf8" ) -func (h *Handler) doBio(w text.Writer, r *request, readContent func(text.Writer, *request, []string) (string, bool), args []string) { +func (h *Handler) doBio(w text.Writer, r *request, readContent func(text.Writer, *request) (string, bool)) { if r.User == nil { w.Redirect("/users") return @@ -39,7 +39,7 @@ func (h *Handler) doBio(w text.Writer, r *request, readContent func(text.Writer, return } - summary, ok := readContent(w, r, args) + summary, ok := readContent(w, r) if !ok { return } @@ -88,13 +88,18 @@ func (h *Handler) bio(w text.Writer, r *request, args ...string) { h.doBio( w, r, - func(text.Writer, *request, []string) (string, bool) { - return readQuery(w, r, args, "Bio") + func(w text.Writer, r *request) (string, bool) { + return readQuery(w, r, "Bio") }, - args, ) } func (h *Handler) bioUpload(w text.Writer, r *request, args ...string) { - h.doBio(w, r, readUpload, args) + h.doBio( + w, + r, + func(w text.Writer, r *request) (string, bool) { + return readUpload(w, r, args) + }, + ) } diff --git a/front/edit.go b/front/edit.go index 680db40d..09ba76a3 100644 --- a/front/edit.go +++ b/front/edit.go @@ -25,7 +25,7 @@ import ( "time" ) -func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request, []string) (string, bool), args []string) { +func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request) (string, bool), args []string) { if r.User == nil { w.Redirect("/users") return @@ -70,7 +70,7 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer } if note.InReplyTo == "" { - h.post(w, r, args, ¬e, nil, note.To, note.CC, note.Audience, readContent) + h.post(w, r, ¬e, nil, note.To, note.CC, note.Audience, readContent) return } @@ -84,15 +84,15 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer } // the starting point is the original value of to and cc: recipients can be added but not removed when editing - h.post(w, r, args, ¬e, &parent, note.To, note.CC, note.Audience, readContent) + h.post(w, r, ¬e, &parent, note.To, note.CC, note.Audience, readContent) } func (h *Handler) edit(w text.Writer, r *request, args ...string) { h.doEdit( w, r, - func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args, "Post content") + func(w text.Writer, r *request) (string, bool) { + return readQuery(w, r, "Post content") }, args, ) @@ -102,7 +102,7 @@ func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { h.doEdit( w, r, - func(w text.Writer, r *request, args []string) (string, bool) { + func(w text.Writer, r *request) (string, bool) { return readUpload(w, r, args[1:]) }, args, diff --git a/front/post.go b/front/post.go index 9f1b87ed..047e3d35 100644 --- a/front/post.go +++ b/front/post.go @@ -45,7 +45,7 @@ var ( pollRegex = regexp.MustCompile(`^\[(?:(?i)POLL)\s+(.+)\s*\]\s*(.+)`) ) -func readQuery(w text.Writer, r *request, args []string, prompt string) (string, bool) { +func readQuery(w text.Writer, r *request, prompt string) (string, bool) { if r.URL.RawQuery == "" { w.Status(10, prompt) return "", false @@ -121,7 +121,7 @@ func readUpload(w text.Writer, r *request, args []string) (string, bool) { return string(buf), true } -func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readContent func(text.Writer, *request, []string) (string, bool)) { +func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readContent func(text.Writer, *request) (string, bool)) { if r.User == nil { w.Redirect("/users") return @@ -154,7 +154,7 @@ func (h *Handler) post(w text.Writer, r *request, args []string, oldNote *ap.Obj } } - content, ok := readContent(w, r, args) + content, ok := readContent(w, r) if !ok { return } diff --git a/front/post_followers.go b/front/post_followers.go index 69cb0ae6..c0a7debb 100644 --- a/front/post_followers.go +++ b/front/post_followers.go @@ -27,7 +27,7 @@ func (h *Handler) postFollowers(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args, "Post content") + h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + return readQuery(w, r, "Post content") }) } diff --git a/front/post_private.go b/front/post_private.go index 95e3a168..720a600d 100644 --- a/front/post_private.go +++ b/front/post_private.go @@ -25,7 +25,7 @@ func (h *Handler) postPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args, "Post content") + h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + return readQuery(w, r, "Post content") }) } diff --git a/front/post_public.go b/front/post_public.go index 8153dd98..c7396576 100644 --- a/front/post_public.go +++ b/front/post_public.go @@ -28,7 +28,7 @@ func (h *Handler) postPublic(w text.Writer, r *request, args ...string) { to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args, "Post content") + h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + return readQuery(w, r, "Post content") }) } diff --git a/front/reply.go b/front/reply.go index 6c7d4828..1274eec7 100644 --- a/front/reply.go +++ b/front/reply.go @@ -23,7 +23,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Writer, *request, []string) (string, bool), args []string) { +func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Writer, *request) (string, bool), args []string) { postID := "https://" + args[1] var note ap.Object @@ -65,15 +65,15 @@ func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Write }) } - h.post(w, r, args, nil, ¬e, to, cc, note.Audience, readContent) + h.post(w, r, nil, ¬e, to, cc, note.Audience, readContent) } func (h *Handler) reply(w text.Writer, r *request, args ...string) { h.doReply( w, r, - func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args[1:], "Reply content") + func(w text.Writer, r *request) (string, bool) { + return readQuery(w, r, "Reply content") }, args, ) @@ -83,7 +83,7 @@ func (h *Handler) replyUpload(w text.Writer, r *request, args ...string) { h.doReply( w, r, - func(w text.Writer, r *request, args []string) (string, bool) { + func(w text.Writer, r *request) (string, bool) { return readUpload(w, r, args[1:]) }, args, diff --git a/front/upload_followers.go b/front/upload_followers.go index 33b1a425..57629b44 100644 --- a/front/upload_followers.go +++ b/front/upload_followers.go @@ -27,7 +27,7 @@ func (h *Handler) uploadFollowers(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args, "Post content") + h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + return readUpload(w, r, args) }) } diff --git a/front/upload_private.go b/front/upload_private.go index 3253b0af..6df18c1e 100644 --- a/front/upload_private.go +++ b/front/upload_private.go @@ -25,7 +25,7 @@ func (h *Handler) uploadPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, args, nil, nil, to, cc, "", func(w text.Writer, r *request, args []string) (string, bool) { - return readQuery(w, r, args, "Post content") + h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + return readUpload(w, r, args) }) } diff --git a/front/upload_public.go b/front/upload_public.go index 6c9e54ec..fa09b515 100644 --- a/front/upload_public.go +++ b/front/upload_public.go @@ -28,5 +28,7 @@ func (h *Handler) uploadPublic(w text.Writer, r *request, args ...string) { to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, args, nil, nil, to, cc, "", readUpload) + h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + return readUpload(w, r, args) + }) } From 92761c9920c261140c74472fecae174c5b1f3e76 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 20:28:15 +0300 Subject: [PATCH 09/20] cleanup --- front/edit.go | 6 +++--- front/post.go | 4 ++-- front/post_followers.go | 2 +- front/post_private.go | 2 +- front/post_public.go | 2 +- front/reply.go | 6 +++--- front/upload_followers.go | 2 +- front/upload_private.go | 2 +- front/upload_public.go | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/front/edit.go b/front/edit.go index 09ba76a3..d28113cb 100644 --- a/front/edit.go +++ b/front/edit.go @@ -25,7 +25,7 @@ import ( "time" ) -func (h *Handler) doEdit(w text.Writer, r *request, readContent func(text.Writer, *request) (string, bool), args []string) { +func (h *Handler) doEdit(w text.Writer, r *request, readContent func() (string, bool), args []string) { if r.User == nil { w.Redirect("/users") return @@ -91,7 +91,7 @@ func (h *Handler) edit(w text.Writer, r *request, args ...string) { h.doEdit( w, r, - func(w text.Writer, r *request) (string, bool) { + func() (string, bool) { return readQuery(w, r, "Post content") }, args, @@ -102,7 +102,7 @@ func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { h.doEdit( w, r, - func(w text.Writer, r *request) (string, bool) { + func() (string, bool) { return readUpload(w, r, args[1:]) }, args, diff --git a/front/post.go b/front/post.go index 047e3d35..efe78a54 100644 --- a/front/post.go +++ b/front/post.go @@ -121,7 +121,7 @@ func readUpload(w text.Writer, r *request, args []string) (string, bool) { return string(buf), true } -func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readContent func(text.Writer, *request) (string, bool)) { +func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readContent func() (string, bool)) { if r.User == nil { w.Redirect("/users") return @@ -154,7 +154,7 @@ func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo } } - content, ok := readContent(w, r) + content, ok := readContent() if !ok { return } diff --git a/front/post_followers.go b/front/post_followers.go index c0a7debb..299230dc 100644 --- a/front/post_followers.go +++ b/front/post_followers.go @@ -27,7 +27,7 @@ func (h *Handler) postFollowers(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readQuery(w, r, "Post content") }) } diff --git a/front/post_private.go b/front/post_private.go index 720a600d..13c9f3b0 100644 --- a/front/post_private.go +++ b/front/post_private.go @@ -25,7 +25,7 @@ func (h *Handler) postPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readQuery(w, r, "Post content") }) } diff --git a/front/post_public.go b/front/post_public.go index c7396576..6101408c 100644 --- a/front/post_public.go +++ b/front/post_public.go @@ -28,7 +28,7 @@ func (h *Handler) postPublic(w text.Writer, r *request, args ...string) { to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readQuery(w, r, "Post content") }) } diff --git a/front/reply.go b/front/reply.go index 1274eec7..13ac2e9e 100644 --- a/front/reply.go +++ b/front/reply.go @@ -23,7 +23,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) doReply(w text.Writer, r *request, readContent func(text.Writer, *request) (string, bool), args []string) { +func (h *Handler) doReply(w text.Writer, r *request, readContent func() (string, bool), args []string) { postID := "https://" + args[1] var note ap.Object @@ -72,7 +72,7 @@ func (h *Handler) reply(w text.Writer, r *request, args ...string) { h.doReply( w, r, - func(w text.Writer, r *request) (string, bool) { + func() (string, bool) { return readQuery(w, r, "Reply content") }, args, @@ -83,7 +83,7 @@ func (h *Handler) replyUpload(w text.Writer, r *request, args ...string) { h.doReply( w, r, - func(w text.Writer, r *request) (string, bool) { + func() (string, bool) { return readUpload(w, r, args[1:]) }, args, diff --git a/front/upload_followers.go b/front/upload_followers.go index 57629b44..76266dfe 100644 --- a/front/upload_followers.go +++ b/front/upload_followers.go @@ -27,7 +27,7 @@ func (h *Handler) uploadFollowers(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readUpload(w, r, args) }) } diff --git a/front/upload_private.go b/front/upload_private.go index 6df18c1e..004ab182 100644 --- a/front/upload_private.go +++ b/front/upload_private.go @@ -25,7 +25,7 @@ func (h *Handler) uploadPrivate(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readUpload(w, r, args) }) } diff --git a/front/upload_public.go b/front/upload_public.go index fa09b515..957235a7 100644 --- a/front/upload_public.go +++ b/front/upload_public.go @@ -28,7 +28,7 @@ func (h *Handler) uploadPublic(w text.Writer, r *request, args ...string) { to.Add(ap.Public) cc.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", func(w text.Writer, r *request) (string, bool) { + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readUpload(w, r, args) }) } From 7e69f3855235efe4654b3ad34701352679d30529 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Wed, 10 Apr 2024 20:29:03 +0300 Subject: [PATCH 10/20] oops --- front/post.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/post.go b/front/post.go index efe78a54..f1059513 100644 --- a/front/post.go +++ b/front/post.go @@ -53,7 +53,7 @@ func readQuery(w text.Writer, r *request, prompt string) (string, bool) { content, err := url.QueryUnescape(r.URL.RawQuery) if err != nil { - w.Error() + w.Status(40, "Bad input") return "", false } From 2e32fb842cef4e39e2dd77b200a8679734750d4a Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 08:44:48 +0300 Subject: [PATCH 11/20] cleanup --- front/README.md | 6 +- front/{post_followers.go => dm.go} | 13 ++- front/handler.go | 12 +-- front/{post_public.go => say.go} | 14 ++- front/static/users/post.gmi | 12 +-- front/upload_followers.go | 33 ------- front/upload_private.go | 31 ------ front/upload_public.go | 34 ------- front/{post_private.go => whisper.go} | 15 ++- test/delete_test.go | 18 ++-- test/{post_private_test.go => dm_test.go} | 52 +++++----- test/edit_test.go | 94 +++++++++--------- test/follow_test.go | 22 ++--- test/follows_test.go | 4 +- test/forward_test.go | 18 ++-- test/fts_test.go | 36 +++---- test/hashtag_test.go | 60 ++++++------ test/hashtags_test.go | 60 ++++++------ test/outbox_test.go | 48 +++++----- test/poll_test.go | 86 ++++++++--------- test/register_test.go | 2 +- test/reply_test.go | 72 +++++++------- test/{post_public_test.go => say_test.go} | 20 ++-- test/share_test.go | 48 +++++----- test/stats_test.go | 4 +- test/thread_test.go | 42 ++++---- test/unfollow_test.go | 8 +- test/upload_edit_test.go | 42 ++++---- test/upload_reply_test.go | 6 +- test/users_test.go | 24 ++--- test/view_test.go | 96 +++++++++---------- ...post_followers_test.go => whisper_test.go} | 30 +++--- 32 files changed, 498 insertions(+), 564 deletions(-) rename front/{post_followers.go => dm.go} (74%) rename front/{post_public.go => say.go} (72%) delete mode 100644 front/upload_followers.go delete mode 100644 front/upload_private.go delete mode 100644 front/upload_public.go rename front/{post_private.go => whisper.go} (70%) rename test/{post_private_test.go => dm_test.go} (61%) rename test/{post_public_test.go => say_test.go} (70%) rename test/{post_followers_test.go => whisper_test.go} (71%) diff --git a/front/README.md b/front/README.md index 2ddd12bc..1555a05a 100644 --- a/front/README.md +++ b/front/README.md @@ -23,9 +23,9 @@ Users are authenticated using TLS client certificates; see [Gemini protocol spec * /users/follows shows a list of followed users, ordered by activity. * /users/me redirects the user to their outbox. * /users/resolve looks up federated user *user@domain* or local user *user*. -* /users/post/private creates a post visible to mentioned users. -* /users/post/followers creates a post visible to followers. -* /users/post/public creates a public post. +* /users/dm creates a post visible to mentioned users. +* /users/whisper creates a post visible to followers. +* /users/say creates a public post. * /users/reply replies to a post. * /users/edit edits a post. * /users/delete deletes a post. diff --git a/front/post_followers.go b/front/dm.go similarity index 74% rename from front/post_followers.go rename to front/dm.go index 299230dc..ab3ae051 100644 --- a/front/post_followers.go +++ b/front/dm.go @@ -21,13 +21,20 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) postFollowers(w text.Writer, r *request, args ...string) { +func (h *Handler) dm(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} - to.Add(r.User.Followers) - h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readQuery(w, r, "Post content") }) } + +func (h *Handler) uploadDM(w text.Writer, r *request, args ...string) { + to := ap.Audience{} + cc := ap.Audience{} + + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { + return readUpload(w, r, args) + }) +} diff --git a/front/handler.go b/front/handler.go index 9e913cff..72a02689 100644 --- a/front/handler.go +++ b/front/handler.go @@ -96,9 +96,9 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/thread/(\S+)$`)] = withUserMenu(h.thread) h.handlers[regexp.MustCompile(`^/users/thread/(\S+)$`)] = withUserMenu(h.thread) - h.handlers[regexp.MustCompile(`^/users/post/private$`)] = h.postPrivate - h.handlers[regexp.MustCompile(`^/users/post/followers$`)] = h.postFollowers - h.handlers[regexp.MustCompile(`^/users/post/public$`)] = h.postPublic + h.handlers[regexp.MustCompile(`^/users/dm$`)] = h.dm + h.handlers[regexp.MustCompile(`^/users/whisper$`)] = h.whisper + h.handlers[regexp.MustCompile(`^/users/say$`)] = h.say h.handlers[regexp.MustCompile(`^/users/reply/(\S+)`)] = h.reply @@ -108,9 +108,9 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/edit/(\S+)`)] = h.edit h.handlers[regexp.MustCompile(`^/users/delete/(\S+)`)] = delete - h.handlers[regexp.MustCompile(`^/users/upload/private;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPrivate - h.handlers[regexp.MustCompile(`^/users/upload/followers;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadFollowers - h.handlers[regexp.MustCompile(`^/users/upload/public;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadPublic + h.handlers[regexp.MustCompile(`^/users/upload/dm;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadDM + h.handlers[regexp.MustCompile(`^/users/upload/whisper;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadWhisper + h.handlers[regexp.MustCompile(`^/users/upload/say;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadSay h.handlers[regexp.MustCompile(`^/users/upload/edit/([^;]+);([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.editUpload h.handlers[regexp.MustCompile(`^/users/upload/reply/([^;]+);([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.replyUpload diff --git a/front/post_public.go b/front/say.go similarity index 72% rename from front/post_public.go rename to front/say.go index 6101408c..6542cb08 100644 --- a/front/post_public.go +++ b/front/say.go @@ -21,7 +21,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) postPublic(w text.Writer, r *request, args ...string) { +func (h *Handler) say(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} @@ -32,3 +32,15 @@ func (h *Handler) postPublic(w text.Writer, r *request, args ...string) { return readQuery(w, r, "Post content") }) } + +func (h *Handler) uploadSay(w text.Writer, r *request, args ...string) { + to := ap.Audience{} + cc := ap.Audience{} + + to.Add(ap.Public) + cc.Add(r.User.Followers) + + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { + return readUpload(w, r, args) + }) +} diff --git a/front/static/users/post.gmi b/front/static/users/post.gmi index 456c7f17..b1f9e453 100644 --- a/front/static/users/post.gmi +++ b/front/static/users/post.gmi @@ -1,10 +1,10 @@ # New Post -=> /users/post/private 💌 Mentioned users only -=> titan://{{.Domain}}/users/upload/private Upload text file +=> /users/dm 💌 Mentioned users only +=> titan://{{.Domain}}/users/upload/dm Upload text file -=> /users/post/followers 🔔 Followers and mentioned users -=> titan://{{.Domain}}/users/upload/followers Upload text file +=> /users/whisper 🔔 Followers and mentioned users +=> titan://{{.Domain}}/users/upload/whisper Upload text file -=> /users/post/public 📣 Public -=> titan://{{.Domain}}/users/upload/public Upload text file +=> /users/say 📣 Public +=> titan://{{.Domain}}/users/upload/say Upload text file diff --git a/front/upload_followers.go b/front/upload_followers.go deleted file mode 100644 index 76266dfe..00000000 --- a/front/upload_followers.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2024 Dima Krasner - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package front - -import ( - "github.com/dimkr/tootik/ap" - "github.com/dimkr/tootik/front/text" -) - -func (h *Handler) uploadFollowers(w text.Writer, r *request, args ...string) { - to := ap.Audience{} - cc := ap.Audience{} - - to.Add(r.User.Followers) - - h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { - return readUpload(w, r, args) - }) -} diff --git a/front/upload_private.go b/front/upload_private.go deleted file mode 100644 index 004ab182..00000000 --- a/front/upload_private.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2024 Dima Krasner - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package front - -import ( - "github.com/dimkr/tootik/ap" - "github.com/dimkr/tootik/front/text" -) - -func (h *Handler) uploadPrivate(w text.Writer, r *request, args ...string) { - to := ap.Audience{} - cc := ap.Audience{} - - h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { - return readUpload(w, r, args) - }) -} diff --git a/front/upload_public.go b/front/upload_public.go deleted file mode 100644 index 957235a7..00000000 --- a/front/upload_public.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2024 Dima Krasner - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package front - -import ( - "github.com/dimkr/tootik/ap" - "github.com/dimkr/tootik/front/text" -) - -func (h *Handler) uploadPublic(w text.Writer, r *request, args ...string) { - to := ap.Audience{} - cc := ap.Audience{} - - to.Add(ap.Public) - cc.Add(r.User.Followers) - - h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { - return readUpload(w, r, args) - }) -} diff --git a/front/post_private.go b/front/whisper.go similarity index 70% rename from front/post_private.go rename to front/whisper.go index 13c9f3b0..cce8d646 100644 --- a/front/post_private.go +++ b/front/whisper.go @@ -21,11 +21,24 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) postPrivate(w text.Writer, r *request, args ...string) { +func (h *Handler) whisper(w text.Writer, r *request, args ...string) { to := ap.Audience{} cc := ap.Audience{} + to.Add(r.User.Followers) + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { return readQuery(w, r, "Post content") }) } + +func (h *Handler) uploadWhisper(w text.Writer, r *request, args ...string) { + to := ap.Audience{} + cc := ap.Audience{} + + to.Add(r.User.Followers) + + h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { + return readUpload(w, r, args) + }) +} diff --git a/test/delete_test.go b/test/delete_test.go index 956d22d0..e8d7ab27 100644 --- a/test/delete_test.go +++ b/test/delete_test.go @@ -29,10 +29,10 @@ func TestDelete_HappyFlow(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -50,10 +50,10 @@ func TestDelete_NotAuthor(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -81,10 +81,10 @@ func TestDelete_UnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") diff --git a/test/post_private_test.go b/test/dm_test.go similarity index 61% rename from test/post_private_test.go rename to test/dm_test.go index 9449055e..ac131972 100644 --- a/test/post_private_test.go +++ b/test/dm_test.go @@ -21,16 +21,16 @@ import ( "testing" ) -func TestPostPrivate_HappyFlow(t *testing.T) { +func TestDM_HappyFlow(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") @@ -42,41 +42,41 @@ func TestPostPrivate_HappyFlow(t *testing.T) { assert.Contains(view, "Hello @alice@localhost.localdomain:8443") } -func TestPostPrivate_UnauthenticatedUser(t *testing.T) { +func TestDM_UnauthenticatedUser(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/view/"+id, nil) assert.Equal(view, "40 Post not found\r\n") } -func TestPostPrivate_Loopback(t *testing.T) { +func TestDM_Loopback(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40bob%40localhost.localdomain%3a8443", server.Bob) - assert.Equal("40 Post audience is empty\r\n", postPrivate) + dm := server.Handle("/users/dm?Hello%20%40bob%40localhost.localdomain%3a8443", server.Bob) + assert.Equal("40 Post audience is empty\r\n", dm) } -func TestPostPrivate_TwoMentions(t *testing.T) { +func TestDM_TwoMentions(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @carol@localhost.localdomain:8443") @@ -88,16 +88,16 @@ func TestPostPrivate_TwoMentions(t *testing.T) { assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @carol@localhost.localdomain:8443") } -func TestPostPrivate_TwoMentionsOneLoopback(t *testing.T) { +func TestDM_TwoMentionsOneLoopback(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40bob%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40bob%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @bob@localhost.localdomain:8443") @@ -109,7 +109,7 @@ func TestPostPrivate_TwoMentionsOneLoopback(t *testing.T) { assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @bob@localhost.localdomain:8443") } -func TestPostPrivate_TooManyRecipients(t *testing.T) { +func TestDM_TooManyRecipients(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -117,11 +117,11 @@ func TestPostPrivate_TooManyRecipients(t *testing.T) { assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) - assert.Equal("40 Too many recipients\r\n", postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) + assert.Equal("40 Too many recipients\r\n", dm) } -func TestPostPrivate_MaxRecipients(t *testing.T) { +func TestDM_MaxRecipients(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -129,10 +129,10 @@ func TestPostPrivate_MaxRecipients(t *testing.T) { assert := assert.New(t) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443%20and%20%40carol%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443 and @carol@localhost.localdomain:8443") diff --git a/test/edit_test.go b/test/edit_test.go index 5ac6596a..c68cc539 100644 --- a/test/edit_test.go +++ b/test/edit_test.go @@ -40,10 +40,10 @@ func TestEdit_Throttling(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] edit := server.Handle(fmt.Sprintf("/users/edit/%s?Hello%%20followers", id), server.Bob) assert.Equal("40 Please try again later\r\n", edit) @@ -66,10 +66,10 @@ func TestEdit_HappyFlow(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -106,10 +106,10 @@ func TestEdit_EmptyContent(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -135,10 +135,10 @@ func TestEdit_LongContent(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -164,10 +164,10 @@ func TestEdit_InvalidEscapeSequence(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -193,8 +193,8 @@ func TestEdit_NoSuchPost(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, whisper) edit := server.Handle("/users/edit/x?Hello%20followers", server.Bob) assert.Equal("40 Error\r\n", edit) @@ -217,10 +217,10 @@ func TestEdit_UnauthenticatedUser(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] edit := server.Handle(fmt.Sprintf("/users/edit/%s?Hello%%20followers", id), nil) assert.Equal("30 /users\r\n", edit) @@ -236,8 +236,8 @@ func TestEdit_AddHashtag(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%23Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+`, postPublic) + say := server.Handle("/users/say?%23Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+`, say) hashtag := server.Handle("/users/hashtag/hello", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) @@ -245,7 +245,7 @@ func TestEdit_AddHashtag(t *testing.T) { hashtag = server.Handle("/users/hashtag/world", server.Bob) assert.NotContains(hashtag, server.Alice.PreferredUsername) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -266,8 +266,8 @@ func TestEdit_RemoveHashtag(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%23Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+`, postPublic) + say := server.Handle("/users/say?%23Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+`, say) hashtag := server.Handle("/users/hashtag/hello", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) @@ -275,7 +275,7 @@ func TestEdit_RemoveHashtag(t *testing.T) { hashtag = server.Handle("/users/hashtag/world", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -296,8 +296,8 @@ func TestEdit_KeepHashtags(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%23Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+`, postPublic) + say := server.Handle("/users/say?%23Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+`, say) hashtag := server.Handle("/users/hashtag/hello", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) @@ -305,7 +305,7 @@ func TestEdit_KeepHashtags(t *testing.T) { hashtag = server.Handle("/users/hashtag/world", server.Bob) assert.Contains(hashtag, server.Alice.PreferredUsername) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -330,10 +330,10 @@ func TestEdit_AddMention(t *testing.T) { assert.Contains(lines, "No posts.") assert.NotContains(lines, "> Hello world") - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] lines = strings.Split(server.Handle("/users/view/"+id, server.Alice), "\n") assert.Contains(lines, "> Hello world") @@ -362,10 +362,10 @@ func TestEdit_RemoveMention(t *testing.T) { assert.Contains(lines, "No posts.") assert.NotContains(lines, "> Hello @alice") - postPublic := server.Handle("/users/post/public?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, postPublic) + say := server.Handle("/users/say?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] lines = strings.Split(server.Handle("/users/view/"+id, server.Alice), "\n") assert.NotContains(lines, "> Hello world") @@ -394,10 +394,10 @@ func TestEdit_KeepMention(t *testing.T) { assert.Contains(lines, "No posts.") assert.NotContains(lines, "> Hello @alice") - postPublic := server.Handle("/users/post/public?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+`, postPublic) + say := server.Handle("/users/say?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] lines = strings.Split(server.Handle("/users/view/"+id, server.Alice), "\n") assert.NotContains(lines, "> Hello @alice") @@ -422,12 +422,12 @@ func TestEdit_PollAddOption(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ @@ -452,7 +452,7 @@ func TestEdit_PollAddOption(t *testing.T) { edit := server.Handle(fmt.Sprintf("/users/edit/%s?%%5bPOLL%%20So%%2c%%20polls%%20on%%20Station%%20are%%20pretty%%20cool%%2c%%20right%%3f%%5d%%20Nope%%20%%7c%%20Hell%%20yeah%%21%%20%%7c%%20I%%20couldn%%27t%%20care%%20less", id), server.Alice) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), edit) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) assert.NoError(poller.Run(context.Background())) @@ -473,12 +473,12 @@ func TestEdit_RemoveQuestion(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ diff --git a/test/follow_test.go b/test/follow_test.go index 6ff1e13c..b9c36f17 100644 --- a/test/follow_test.go +++ b/test/follow_test.go @@ -36,8 +36,8 @@ func TestFollow_PostToFollowers(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) users = server.Handle("/users", server.Alice) assert.NotContains(users, "No posts.") @@ -54,8 +54,8 @@ func TestFollow_PostToFollowersBeforeFollow(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) @@ -78,8 +78,8 @@ func TestFollow_DMUnfollowFollow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) users = server.Handle("/users", server.Alice) assert.NotContains(users, "No posts.") @@ -106,8 +106,8 @@ func TestFollow_PublicPost(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) users = server.Handle("/users", server.Alice) assert.NotContains(users, "No posts.") @@ -131,10 +131,10 @@ func TestFollow_Mutual(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello world") - postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hello%%20Alice", id), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) diff --git a/test/follows_test.go b/test/follows_test.go index 2e0f38d9..614be2de 100644 --- a/test/follows_test.go +++ b/test/follows_test.go @@ -71,8 +71,8 @@ func TestFollows_OneActiveOneInactive(t *testing.T) { assert.Contains(follows, "=> /users/outbox/localhost.localdomain:8443/user/bob 😈 bob (bob@localhost.localdomain:8443)") assert.Contains(follows, "=> /users/outbox/localhost.localdomain:8443/user/carol 😈 carol (carol@localhost.localdomain:8443)") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) follows = server.Handle("/users/follows", server.Alice) assert.Contains(follows, fmt.Sprintf("=> /users/outbox/localhost.localdomain:8443/user/bob %s 😈 bob (bob@localhost.localdomain:8443)", time.Now().Format(time.DateOnly))) diff --git a/test/forward_test.go b/test/forward_test.go index 66e2977f..7a0c16f1 100644 --- a/test/forward_test.go +++ b/test/forward_test.go @@ -910,8 +910,8 @@ func TestForward_ReplyToLocalPostByLocalFollower(t *testing.T) { ), ) - postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) _, err := server.db.Exec( `insert into persons (id, actor) values(?,?)`, @@ -920,7 +920,7 @@ func TestForward_ReplyToLocalPostByLocalFollower(t *testing.T) { ) assert.NoError(err) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", postFollowers[15:len(postFollowers)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", whisper[15:len(whisper)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) var forwarded int @@ -945,8 +945,8 @@ func TestForward_EditedReplyToLocalPostByLocalFollower(t *testing.T) { ), ) - postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) _, err := server.db.Exec( `insert into persons (id, actor) values(?,?)`, @@ -955,7 +955,7 @@ func TestForward_EditedReplyToLocalPostByLocalFollower(t *testing.T) { ) assert.NoError(err) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", postFollowers[15:len(postFollowers)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", whisper[15:len(whisper)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) id := reply[15 : len(reply)-2] @@ -987,8 +987,8 @@ func TestForward_DeletedReplyToLocalPostByLocalFollower(t *testing.T) { ), ) - postFollowers := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) _, err := server.db.Exec( `insert into persons (id, actor) values(?,?)`, @@ -997,7 +997,7 @@ func TestForward_DeletedReplyToLocalPostByLocalFollower(t *testing.T) { ) assert.NoError(err) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", postFollowers[15:len(postFollowers)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", whisper[15:len(whisper)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) id := reply[15 : len(reply)-2] diff --git a/test/fts_test.go b/test/fts_test.go index a6a0ba95..890ffcf6 100644 --- a/test/fts_test.go +++ b/test/fts_test.go @@ -31,8 +31,8 @@ func TestFTS_Happyflow(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?world", server.Bob) assert.Contains(fts, "Hello world") @@ -44,8 +44,8 @@ func TestFTS_HashtagWithoutHash(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?world", server.Bob) assert.NotContains(fts, "Hello #world") @@ -57,8 +57,8 @@ func TestFTS_HashtagWithHash(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?%23world", server.Bob) assert.NotContains(fts, "Hello #world") @@ -70,8 +70,8 @@ func TestFTS_HashtagWithHashAndQuotes(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?%22%23world%22", server.Bob) assert.Contains(fts, "Hello #world") @@ -83,8 +83,8 @@ func TestFTS_HashtagWithHashAndQuotesUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/fts?%22%23world%22", nil) assert.Contains(fts, "Hello #world") @@ -96,8 +96,8 @@ func TestFTS_HashtagWithHashAndQuotesSecondPage(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?%22%23world%22%20skip%2030", server.Bob) assert.NotContains(fts, "Hello #world") @@ -139,8 +139,8 @@ func TestFTS_UnathenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/fts?world", nil) assert.Contains(fts, "Hello world") @@ -152,8 +152,8 @@ func TestFTS_SearchByAuthorUserName(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?alice", server.Bob) assert.Contains(fts, "Hello world") @@ -165,8 +165,8 @@ func TestFTS_SearchByAuthorID(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) fts := server.Handle("/users/fts?%22https%3a%2f%2flocalhost.localdomain%3a8443%2fuser%2falice%22", server.Bob) assert.Contains(fts, "Hello world") diff --git a/test/hashtag_test.go b/test/hashtag_test.go index f8d9e6c9..a651642d 100644 --- a/test/hashtag_test.go +++ b/test/hashtag_test.go @@ -29,10 +29,10 @@ func TestHashtag_PublicPost(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtag/world", server.Bob) @@ -45,10 +45,10 @@ func TestHashtag_PublicPostUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/hashtag/world", nil) @@ -61,10 +61,10 @@ func TestHashtag_ExclamationMark(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world%21", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world%21", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world!") hashtag := server.Handle("/users/hashtag/world", server.Bob) @@ -77,10 +77,10 @@ func TestHashtag_Beginning(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%23Hello%20world%21", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%23Hello%20world%21", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "#Hello world!") hashtag := server.Handle("/hashtag/Hello", server.Bob) @@ -93,10 +93,10 @@ func TestHashtag_Multiple(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%23Hello%20%23world%21", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%23Hello%20%23world%21", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "#Hello #world!") hashtag := server.Handle("/hashtag/Hello", server.Bob) @@ -112,10 +112,10 @@ func TestHashtag_CaseSensitivity(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23wOrLd", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23wOrLd", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #wOrLd") hashtag := server.Handle("/hashtag/WoRlD", server.Bob) @@ -131,10 +131,10 @@ func TestHashtag_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) + view := server.Handle(whisper[3:len(whisper)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtag/world", server.Bob) @@ -147,10 +147,10 @@ func TestHashtag_BigOffset(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtag/world?123", server.Bob) @@ -163,10 +163,10 @@ func TestHashtag_BigOffsetUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/hashtag/world?123", nil) @@ -179,10 +179,10 @@ func TestHashtag_InvalidOffset(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/hashtag/world?z", server.Bob) diff --git a/test/hashtags_test.go b/test/hashtags_test.go index b726f97e..609f89bc 100644 --- a/test/hashtags_test.go +++ b/test/hashtags_test.go @@ -28,10 +28,10 @@ func TestHashtags_NoHashtags(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello world") hashtag := server.Handle("/users/hashtags", server.Bob) @@ -44,10 +44,10 @@ func TestHashtags_OneHashtagOneAuthor(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") hashtag := server.Handle("/users/hashtags", server.Bob) @@ -60,16 +60,16 @@ func TestHashtags_OneHashtagTwoAuthors(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") - postPublic = server.Handle("/users/post/public?Hello%20again,%20%23world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say = server.Handle("/users/say?Hello%20again,%20%23world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) + view = server.Handle(say[3:len(say)-2], server.Alice) assert.Contains(view, "Hello again, #world") hashtag := server.Handle("/users/hashtags", server.Carol) @@ -82,16 +82,16 @@ func TestHashtags_OneHashtagTwoAuthorsCaseSensitivity(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23worLD", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23worLD", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #worLD") - postPublic = server.Handle("/users/post/public?Hello%20again,%20%23WORld", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say = server.Handle("/users/say?Hello%20again,%20%23WORld", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) + view = server.Handle(say[3:len(say)-2], server.Alice) assert.Contains(view, "Hello again, #WORld") hashtag := server.Handle("/users/hashtags", server.Carol) @@ -104,16 +104,16 @@ func TestHashtags_TwoHashtagsOneAuthor(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") - postPublic = server.Handle("/users/post/public?Hello%20%23again,%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say = server.Handle("/users/say?Hello%20%23again,%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) + view = server.Handle(say[3:len(say)-2], server.Alice) assert.Contains(view, "Hello #again, world") hashtag := server.Handle("/users/hashtags", server.Carol) @@ -127,16 +127,16 @@ func TestHashtags_OneHashtagTwoAuthorsUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20%23world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20%23world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello #world") - postPublic = server.Handle("/users/post/public?Hello%20again,%20%23world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say = server.Handle("/users/say?Hello%20again,%20%23world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view = server.Handle(postPublic[3:len(postPublic)-2], server.Alice) + view = server.Handle(say[3:len(say)-2], server.Alice) assert.Contains(view, "Hello again, #world") hashtag := server.Handle("/hashtags", nil) diff --git a/test/outbox_test.go b/test/outbox_test.go index 3b359691..b88403c2 100644 --- a/test/outbox_test.go +++ b/test/outbox_test.go @@ -44,8 +44,8 @@ func TestOutbox_InvalidOffset(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) outbox := server.Handle(fmt.Sprintf("/users/outbox/%s?abc", strings.TrimPrefix(server.Alice.ID, "https://")), server.Bob) assert.Equal("40 Invalid query\r\n", outbox) @@ -57,8 +57,8 @@ func TestOutbox_PublicPost(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") @@ -70,8 +70,8 @@ func TestOutbox_PublicPostUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) outbox := server.Handle("/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), nil) assert.Contains(outbox, "Hello world") @@ -83,8 +83,8 @@ func TestOutbox_PublicPostSelf(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") @@ -99,8 +99,8 @@ func TestOutbox_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") @@ -112,8 +112,8 @@ func TestOutbox_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(strings.Split(outbox, "\n"), "No posts.") @@ -126,8 +126,8 @@ func TestOutbox_PostToFollowersUnauthentictedUser(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) outbox := server.Handle("/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), nil) assert.Contains(strings.Split(outbox, "\n"), "No posts.") @@ -140,8 +140,8 @@ func TestOutbox_PostToFollowersSelf(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") @@ -156,8 +156,8 @@ func TestOutbox_DM(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello @bob") @@ -172,8 +172,8 @@ func TestOutbox_DMSelf(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello @bob") @@ -188,8 +188,8 @@ func TestOutbox_DMNotRecipient(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Carol) assert.NotContains(outbox, "Hello @bob") @@ -205,8 +205,8 @@ func TestOutbox_UnauthenticatedUser(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40bob", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40bob", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) outbox := server.Handle("/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), nil) assert.NotContains(outbox, "Hello @bob") diff --git a/test/poll_test.go b/test/poll_test.go index 643fafbd..80e4fd56 100644 --- a/test/poll_test.go +++ b/test/poll_test.go @@ -720,10 +720,10 @@ func TestPoll_Local3Options(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -736,10 +736,10 @@ func TestPoll_Local5Options(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -754,8 +754,8 @@ func TestPoll_Local1Option(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope", server.Alice) - assert.Equal("40 Polls must have 2 to 5 options\r\n", postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope", server.Alice) + assert.Equal("40 Polls must have 2 to 5 options\r\n", say) } func TestPoll_Local6Options(t *testing.T) { @@ -764,8 +764,8 @@ func TestPoll_Local6Options(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe%20%7c%20kinda", server.Alice) - assert.Equal("40 Polls must have 2 to 5 options\r\n", postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less%20%7c%20wut%3f%20%7c%20Maybe%20%7c%20kinda", server.Alice) + assert.Equal("40 Polls must have 2 to 5 options\r\n", say) } func TestPoll_LocalEmptyOption(t *testing.T) { @@ -774,8 +774,8 @@ func TestPoll_LocalEmptyOption(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Equal("40 Poll option cannot be empty\r\n", postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Equal("40 Poll option cannot be empty\r\n", say) } func TestPoll_LocalOptionWithLink(t *testing.T) { @@ -784,10 +784,10 @@ func TestPoll_LocalOptionWithLink(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20I%20prefer%20https%3a%2f%2flocalhost%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20I%20prefer%20https%3a%2f%2flocalhost%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote I prefer https://localhost") @@ -800,16 +800,16 @@ func TestPoll_Local3OptionsAnd2Votes(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -824,7 +824,7 @@ func TestPoll_Local3OptionsAnd2Votes(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view = server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view = server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -839,16 +839,16 @@ func TestPoll_Local3OptionsAnd2VotesAndDeletedVote(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -866,7 +866,7 @@ func TestPoll_Local3OptionsAnd2VotesAndDeletedVote(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view = server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view = server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -887,13 +887,13 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { follow = server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Carol) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postFollowers[15:len(postFollowers)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", whisper[15:len(whisper)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postFollowers[15:len(postFollowers)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", whisper[15:len(whisper)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ @@ -903,7 +903,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Alice) + view := server.Handle(whisper[3:len(whisper)-2], server.Alice) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -913,7 +913,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { assert.Contains(view, "bob") assert.Contains(view, "carol") - view = server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) + view = server.Handle(whisper[3:len(whisper)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -923,7 +923,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { assert.Contains(view, "bob") assert.NotContains(view, "carol") - view = server.Handle(postFollowers[3:len(postFollowers)-2], server.Carol) + view = server.Handle(whisper[3:len(whisper)-2], server.Carol) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -933,7 +933,7 @@ func TestPoll_LocalVoteVisibilityFollowers(t *testing.T) { assert.NotContains(view, "bob") assert.Contains(view, "carol") - view = server.Handle("/view/"+postFollowers[15:len(postFollowers)-2], nil) + view = server.Handle("/view/"+whisper[15:len(whisper)-2], nil) assert.Equal("40 Post not found\r\n", view) } @@ -943,13 +943,13 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?%5bPOLL%20So%2c%20polls%20on%20Station%20are%20pretty%20cool%2c%20right%3f%5d%20Nope%20%7c%20Hell%20yeah%21%20%7c%20I%20couldn%27t%20care%20less", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", postPublic[15:len(postPublic)-2]), server.Bob) + reply := server.Handle(fmt.Sprintf("/users/reply/%s?Hell%%20yeah%%21", say[15:len(say)-2]), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) - reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", postPublic[15:len(postPublic)-2]), server.Carol) + reply = server.Handle(fmt.Sprintf("/users/reply/%s?I%%20couldn%%27t%%20care%%20less", say[15:len(say)-2]), server.Carol) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) poller := outbox.Poller{ @@ -959,7 +959,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { } assert.NoError(poller.Run(context.Background())) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Alice) + view := server.Handle(say[3:len(say)-2], server.Alice) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -969,7 +969,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert.Contains(view, "bob") assert.Contains(view, "carol") - view = server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view = server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -979,7 +979,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert.Contains(view, "bob") assert.NotContains(view, "carol") - view = server.Handle(postPublic[3:len(postPublic)-2], server.Carol) + view = server.Handle(say[3:len(say)-2], server.Carol) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.Contains(view, "Vote Nope") assert.Contains(view, "Vote Hell yeah!") @@ -989,7 +989,7 @@ func TestPoll_LocalVoteVisibilityPublic(t *testing.T) { assert.NotContains(view, "bob") assert.Contains(view, "carol") - view = server.Handle("/view/"+postPublic[15:len(postPublic)-2], nil) + view = server.Handle("/view/"+say[15:len(say)-2], nil) assert.Contains(view, "So, polls on Station are pretty cool, right?") assert.NotContains(view, "Vote") assert.Contains(strings.Split(view, "\n"), "1 ████████ Hell yeah!") diff --git a/test/register_test.go b/test/register_test.go index 563ea98e..70e164a7 100644 --- a/test/register_test.go +++ b/test/register_test.go @@ -72,7 +72,7 @@ XCHmESk7Zzor+JhUFjIwf/vM/KbIgszEUXJ7ccMctWelADHc5dJjrf/nbXhvf/NA y0ibEVc6KM97dRMPo1MwUTAdBgNVHQ4EFgQUG0V5VrS+Wj3U3A4j2tgdJKTYmn8w HwYDVR0jBBgwFoAUG0V5VrS+Wj3U3A4j2tgdJKTYmn8wDwYDVR0TAQH/BAUwAwEB /zAKBggqhkjOPQQDAgNIADBFAiEA84fpaDdh6JRaT4R7qGdhfO9zYnJ6VcQEnAiN -eXPo8z4CIBkYBJV6O6+Pvmjxs6SAa6c8SVb4Q72lJQpe0woYpostPrivateXf +eXPo8z4CIBkYBJV6O6+Pvmjxs6SAa6c8SVb4Q72lJQpe0woYdmXf -----END CERTIFICATE-----` erinKey = `-----BEGIN PRIVATE KEY----- diff --git a/test/reply_test.go b/test/reply_test.go index a1f1fec2..3948e533 100644 --- a/test/reply_test.go +++ b/test/reply_test.go @@ -29,10 +29,10 @@ func TestReply_AuthorNotFollowed(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -62,10 +62,10 @@ func TestReply_AuthorFollowed(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -95,10 +95,10 @@ func TestReply_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -125,10 +125,10 @@ func TestReply_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -157,10 +157,10 @@ func TestReply_PostToFollowersUnfollowedBeforeReply(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -193,10 +193,10 @@ func TestReply_PostToFollowersUnfollowedAfterReply(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -228,10 +228,10 @@ func TestReply_SelfReply(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -264,10 +264,10 @@ func TestReply_ReplyToPublicPostByFollowedUser(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -295,10 +295,10 @@ func TestReply_ReplyToPublicPostByNotFollowedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -329,8 +329,8 @@ func TestReply_DM(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice@localhost.localdomain:8443") @@ -340,7 +340,7 @@ func TestReply_DM(t *testing.T) { assert.NotContains(users, "Hello @alice@localhost.localdomain:8443") assert.NotContains(users, "Hello Bob") - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") @@ -366,8 +366,8 @@ func TestReply_DMUnfollowed(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice@localhost.localdomain:8443") @@ -377,7 +377,7 @@ func TestReply_DMUnfollowed(t *testing.T) { assert.NotContains(users, "Hello @alice@localhost.localdomain:8443") assert.NotContains(users, "Hello Bob") - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") @@ -406,8 +406,8 @@ func TestReply_DMToAnotherUser(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice%40localhost.localdomain%3a8443", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice@localhost.localdomain:8443") @@ -417,7 +417,7 @@ func TestReply_DMToAnotherUser(t *testing.T) { assert.NotContains(users, "Hello @alice@localhost.localdomain:8443") assert.NotContains(users, "Hello Bob") - id := postPrivate[15 : len(postPrivate)-2] + id := dm[15 : len(dm)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.Contains(view, "Hello @alice@localhost.localdomain:8443") diff --git a/test/post_public_test.go b/test/say_test.go similarity index 70% rename from test/post_public_test.go rename to test/say_test.go index 8582535b..536159ba 100644 --- a/test/post_public_test.go +++ b/test/say_test.go @@ -22,16 +22,16 @@ import ( "testing" ) -func TestPostPublic_HappyFlow(t *testing.T) { +func TestSay_HappyFlow(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) @@ -41,23 +41,23 @@ func TestPostPublic_HappyFlow(t *testing.T) { assert.Contains(local, "Hello world") } -func TestPostPublic_Throttling(t *testing.T) { +func TestSay_Throttling(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - view := server.Handle(postPublic[3:len(postPublic)-2], server.Bob) + view := server.Handle(say[3:len(say)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") - postPublic = server.Handle("/users/post/public?Hello%20once%20more,%20world", server.Alice) - assert.Equal("40 Please wait before posting again\r\n", postPublic) + say = server.Handle("/users/say?Hello%20once%20more,%20world", server.Alice) + assert.Equal("40 Please wait before posting again\r\n", say) outbox = server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") diff --git a/test/share_test.go b/test/share_test.go index 9af77ee8..dd412756 100644 --- a/test/share_test.go +++ b/test/share_test.go @@ -29,10 +29,10 @@ func TestShare_PublicPost(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -50,18 +50,18 @@ func TestShare_Throttling(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) - postPublic = server.Handle("/users/post/public?Hello%20world", server.Carol) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say = server.Handle("/users/say?Hello%20world", server.Carol) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id = postPublic[15 : len(postPublic)-2] + id = say[15 : len(say)-2] share = server.Handle("/users/share/"+id, server.Bob) assert.Equal("40 Please wait before sharing\r\n", share) @@ -73,10 +73,10 @@ func TestShare_UnshareThrottling(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -91,10 +91,10 @@ func TestShare_PostToFollowers(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal("40 Error\r\n", share) @@ -106,10 +106,10 @@ func TestShare_Twice(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -130,10 +130,10 @@ func TestShare_Unshare(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) @@ -160,10 +160,10 @@ func TestShare_ShareAfterUnshare(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] share := server.Handle("/users/share/"+id, server.Bob) assert.Equal(fmt.Sprintf("30 /users/view/%s\r\n", id), share) diff --git a/test/stats_test.go b/test/stats_test.go index c0889d61..4cda5596 100644 --- a/test/stats_test.go +++ b/test/stats_test.go @@ -37,8 +37,8 @@ func TestStats_WithPosts(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) stats := server.Handle("/stats", server.Alice) assert.Regexp("^20 text/gemini\r\n", stats) diff --git a/test/thread_test.go b/test/thread_test.go index ae416130..7e1ec77c 100644 --- a/test/thread_test.go +++ b/test/thread_test.go @@ -33,10 +33,10 @@ func TestThread_TwoReplies(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -62,10 +62,10 @@ func TestThread_NestedReplies(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -91,10 +91,10 @@ func TestThread_NestedReply(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -117,10 +117,10 @@ func TestThread_NoReplies(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Alice) assert.NotContains(view, "View parent post") @@ -140,10 +140,10 @@ func TestThread_NestedRepliesFromBottom(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -171,10 +171,10 @@ func TestThread_NestedRepliesFromBottomMissingNode(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) @@ -205,10 +205,10 @@ func TestThread_NestedRepliesFromBottomMissingFirstNode(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n`, reply) diff --git a/test/unfollow_test.go b/test/unfollow_test.go index 2ee1ab6b..3a16e249 100644 --- a/test/unfollow_test.go +++ b/test/unfollow_test.go @@ -32,8 +32,8 @@ func TestUnfollow_HappyFlow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPublic := server.Handle("/users/post/followers?Hello%20followers", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20followers", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello followers") @@ -54,8 +54,8 @@ func TestUnfollow_FollowAgain(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPublic := server.Handle("/users/post/followers?Hello%20followers", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20followers", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello followers") diff --git a/test/upload_edit_test.go b/test/upload_edit_test.go index 69688052..455589d3 100644 --- a/test/upload_edit_test.go +++ b/test/upload_edit_test.go @@ -37,10 +37,10 @@ func TestUploadEdit_HappyFlow(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -77,10 +77,10 @@ func TestUploadEdit_Empty(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -102,10 +102,10 @@ func TestUploadEdit_SizeLimit(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -129,10 +129,10 @@ func TestUploadEdit_InvalidSize(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -154,10 +154,10 @@ func TestUploadEdit_InvalidType(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -179,10 +179,10 @@ func TestUploadEdit_NoSize(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) @@ -204,10 +204,10 @@ func TestUploadEdit_NoType(t *testing.T) { assert.Contains(users, "No posts.") assert.NotContains(users, "Hello followers") - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/(\S+)\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/(\S+)\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] _, err := server.db.Exec("update notes set inserted = inserted - 3600, object = json_set(object, '$.published', ?) where id = 'https://' || ?", time.Now().Add(-time.Hour).Format(time.RFC3339Nano), id) assert.NoError(err) diff --git a/test/upload_reply_test.go b/test/upload_reply_test.go index f6d0e236..0a91b662 100644 --- a/test/upload_reply_test.go +++ b/test/upload_reply_test.go @@ -32,10 +32,10 @@ func TestUploadReply_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - id := postFollowers[15 : len(postFollowers)-2] + id := whisper[15 : len(whisper)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") diff --git a/test/users_test.go b/test/users_test.go index 839d805d..e93c152c 100644 --- a/test/users_test.go +++ b/test/users_test.go @@ -58,8 +58,8 @@ func TestUsers_DM(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello @alice") @@ -74,8 +74,8 @@ func TestUsers_DMNotFollowing(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPrivate := server.Handle("/users/post/private?Hello%20%40alice", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPrivate) + dm := server.Handle("/users/dm?Hello%20%40alice", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, dm) unfollow := server.Handle("/users/unfollow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), unfollow) @@ -93,8 +93,8 @@ func TestUsers_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello world") @@ -106,8 +106,8 @@ func TestUsers_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) users := server.Handle("/users", server.Alice) assert.NotContains(users, "Hello world") @@ -122,8 +122,8 @@ func TestUsers_PublicPost(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Bob.ID, "https://"), server.Alice) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Bob.ID, "https://")), follow) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) users := server.Handle("/users", server.Alice) assert.Contains(users, "Hello world") @@ -135,8 +135,8 @@ func TestUsers_PublicPostNotFollowing(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) users := server.Handle("/users", server.Alice) assert.NotContains(users, "Hello world") diff --git a/test/view_test.go b/test/view_test.go index 19be330a..bb2238ff 100644 --- a/test/view_test.go +++ b/test/view_test.go @@ -34,10 +34,10 @@ func TestView_NoReplies(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -49,10 +49,10 @@ func TestView_OneReply(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -68,10 +68,10 @@ func TestView_TwoReplies(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -91,10 +91,10 @@ func TestView_TwoRepliesBigOffset(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -114,10 +114,10 @@ func TestView_TwoRepliesBigOffsetUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -137,10 +137,10 @@ func TestView_TwoRepliesUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -160,10 +160,10 @@ func TestView_OneReplyPostDeleted(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -187,10 +187,10 @@ func TestView_OneReplyPostNotDeleted(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -211,10 +211,10 @@ func TestView_OneReplyPostNotDeletedUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -235,10 +235,10 @@ func TestView_OneReplyPostDeletedUnauthenticatedUser(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -262,10 +262,10 @@ func TestView_OneReplyReplyDeleted(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/public?Hello%20world", server.Bob) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/say?Hello%20world", server.Bob) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Bob", id), server.Alice) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) @@ -430,10 +430,10 @@ func TestView_PostToFollowers(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -445,13 +445,13 @@ func TestView_PostToFollowersPostBeforeFollow(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -466,10 +466,10 @@ func TestView_PostToFollowersUnfollow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Contains(view, "Hello world") @@ -487,10 +487,10 @@ func TestView_PostToFollowersNotFollowing(t *testing.T) { assert := assert.New(t) - postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] view := server.Handle("/users/view/"+id, server.Bob) assert.Equal("40 Post not found\r\n", view) @@ -508,10 +508,10 @@ func TestView_PostToFollowersWithReply(t *testing.T) { follow = server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Carol) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postPublic := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postPublic) + say := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, say) - id := postPublic[15 : len(postPublic)-2] + id := say[15 : len(say)-2] reply := server.Handle(fmt.Sprintf("/users/reply/%s?Welcome%%20Alice", id), server.Bob) assert.Regexp(`^30 /users/view/\S+\r\n$`, reply) diff --git a/test/post_followers_test.go b/test/whisper_test.go similarity index 71% rename from test/post_followers_test.go rename to test/whisper_test.go index bf2629dc..5535dfe4 100644 --- a/test/post_followers_test.go +++ b/test/whisper_test.go @@ -23,7 +23,7 @@ import ( "testing" ) -func TestPostFollowers_HappyFlow(t *testing.T) { +func TestWhisper_HappyFlow(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -32,10 +32,10 @@ func TestPostFollowers_HappyFlow(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) + view := server.Handle(whisper[3:len(whisper)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) @@ -45,22 +45,22 @@ func TestPostFollowers_HappyFlow(t *testing.T) { assert.NotContains(local, "Hello world") } -func TestPostFollowers_FollowAfterPost(t *testing.T) { +func TestWhisper_FollowAfterPost(t *testing.T) { server := newTestServer() defer server.Shutdown() assert := assert.New(t) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) + view := server.Handle(whisper[3:len(whisper)-2], server.Bob) assert.Equal("40 Post not found\r\n", view) follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - view = server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) + view = server.Handle(whisper[3:len(whisper)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) @@ -70,7 +70,7 @@ func TestPostFollowers_FollowAfterPost(t *testing.T) { assert.NotContains(local, "Hello world") } -func TestPostFollowers_Throttling(t *testing.T) { +func TestWhisper_Throttling(t *testing.T) { server := newTestServer() defer server.Shutdown() @@ -79,17 +79,17 @@ func TestPostFollowers_Throttling(t *testing.T) { follow := server.Handle("/users/follow/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Equal(fmt.Sprintf("30 /users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), follow) - postFollowers := server.Handle("/users/post/followers?Hello%20world", server.Alice) - assert.Regexp(`^30 /users/view/\S+\r\n$`, postFollowers) + whisper := server.Handle("/users/whisper?Hello%20world", server.Alice) + assert.Regexp(`^30 /users/view/\S+\r\n$`, whisper) - view := server.Handle(postFollowers[3:len(postFollowers)-2], server.Bob) + view := server.Handle(whisper[3:len(whisper)-2], server.Bob) assert.Contains(view, "Hello world") outbox := server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Alice) assert.Contains(outbox, "Hello world") - postFollowers = server.Handle("/users/post/followers?Hello%20once%20more,%20world", server.Alice) - assert.Equal("40 Please wait before posting again\r\n", postFollowers) + whisper = server.Handle("/users/whisper?Hello%20once%20more,%20world", server.Alice) + assert.Equal("40 Please wait before posting again\r\n", whisper) outbox = server.Handle("/users/outbox/"+strings.TrimPrefix(server.Alice.ID, "https://"), server.Bob) assert.Contains(outbox, "Hello world") From 50de931071da3c05b8201dbff03d76098deff77a Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 08:53:21 +0300 Subject: [PATCH 12/20] cleanup --- front/avatar.go | 2 +- front/bio.go | 2 +- front/handler.go | 4 ++-- front/static/users/settings.gmi | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/front/avatar.go b/front/avatar.go index cc55bd81..e589b91e 100644 --- a/front/avatar.go +++ b/front/avatar.go @@ -33,7 +33,7 @@ var supportedImageTypes = map[string]struct{}{ "image/gif": {}, } -func (h *Handler) avatar(w text.Writer, r *request, args ...string) { +func (h *Handler) uploadAvatar(w text.Writer, r *request, args ...string) { if r.User == nil { w.Redirect("/users") return diff --git a/front/bio.go b/front/bio.go index 8141c825..4e37d743 100644 --- a/front/bio.go +++ b/front/bio.go @@ -94,7 +94,7 @@ func (h *Handler) bio(w text.Writer, r *request, args ...string) { ) } -func (h *Handler) bioUpload(w text.Writer, r *request, args ...string) { +func (h *Handler) uploadBio(w text.Writer, r *request, args ...string) { h.doBio( w, r, diff --git a/front/handler.go b/front/handler.go index 72a02689..b967d039 100644 --- a/front/handler.go +++ b/front/handler.go @@ -83,9 +83,9 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/outbox/(\S+)$`)] = withUserMenu(h.userOutbox) h.handlers[regexp.MustCompile(`^/users/me$`)] = withUserMenu(me) - h.handlers[regexp.MustCompile(`^/users/avatar;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.avatar + h.handlers[regexp.MustCompile(`^/users/upload/avatar;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadAvatar h.handlers[regexp.MustCompile(`^/users/bio$`)] = h.bio - h.handlers[regexp.MustCompile(`^/users/upload/bio;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.bioUpload + h.handlers[regexp.MustCompile(`^/users/upload/bio;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadBio h.handlers[regexp.MustCompile(`^/users/name$`)] = h.name h.handlers[regexp.MustCompile(`^/users/alias$`)] = h.alias h.handlers[regexp.MustCompile(`^/users/move$`)] = h.move diff --git a/front/static/users/settings.gmi b/front/static/users/settings.gmi index 54a3cc6d..2010dfde 100644 --- a/front/static/users/settings.gmi +++ b/front/static/users/settings.gmi @@ -5,7 +5,7 @@ => /users/name 👺 Set display name => /users/bio 📜 Set bio => titan://{{.Domain}}/users/upload/bio Upload bio -=> titan://{{.Domain}}/users/avatar 📷 Set avatar +=> titan://{{.Domain}}/users/upload/avatar Upload avatar ## Migration From a700356976493b522a65e8e12c84c1a65a1e344f Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 08:53:49 +0300 Subject: [PATCH 13/20] oops --- test/avatar_test.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/avatar_test.go b/test/avatar_test.go index ac3e54b5..81d11735 100644 --- a/test/avatar_test.go +++ b/test/avatar_test.go @@ -34,7 +34,7 @@ func TestAvatar_HappyFlow(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/avatar;mime=image/gif;size=63", server.Alice, avatar)) + assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) } func TestAvatar_NewUser(t *testing.T) { @@ -44,7 +44,7 @@ func TestAvatar_NewUser(t *testing.T) { assert := assert.New(t) server.Alice.Published = &ap.Time{Time: time.Now().Add(-time.Second * 5)} - assert.Equal("40 Please try again later\r\n", server.Upload("/users/avatar;mime=image/gif;size=63", server.Alice, avatar)) + assert.Equal("40 Please try again later\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) } func TestAvatar_ChangedRecently(t *testing.T) { @@ -55,7 +55,7 @@ func TestAvatar_ChangedRecently(t *testing.T) { server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) server.Alice.Updated = &ap.Time{Time: time.Now().Add(-time.Second * 5)} - assert.Equal("40 Please try again later\r\n", server.Upload("/users/avatar;mime=image/gif;size=63", server.Alice, avatar)) + assert.Equal("40 Please try again later\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) } func TestAvatar_HappyFlowSizeFirst(t *testing.T) { @@ -65,7 +65,7 @@ func TestAvatar_HappyFlowSizeFirst(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/avatar;size=63;mime=image/gif", server.Alice, avatar)) + assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/upload/avatar;size=63;mime=image/gif", server.Alice, avatar)) } func TestAvatar_InvalidSize(t *testing.T) { @@ -75,7 +75,7 @@ func TestAvatar_InvalidSize(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Invalid size\r\n", server.Upload("/users/avatar;mime=image/gif;size=abc", server.Alice, avatar)) + assert.Equal("40 Invalid size\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=abc", server.Alice, avatar)) } func TestAvatar_InvalidType(t *testing.T) { @@ -85,7 +85,7 @@ func TestAvatar_InvalidType(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Unsupported image type\r\n", server.Upload("/users/avatar;mime=text/plain;size=63", server.Alice, avatar)) + assert.Equal("40 Unsupported image type\r\n", server.Upload("/users/upload/avatar;mime=text/plain;size=63", server.Alice, avatar)) } func TestAvatar_NoSize(t *testing.T) { @@ -95,7 +95,7 @@ func TestAvatar_NoSize(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Error\r\n", server.Upload("/users/avatar;mime=image/gif;ize=63", server.Alice, avatar)) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;ize=63", server.Alice, avatar)) } func TestAvatar_NoType(t *testing.T) { @@ -105,7 +105,7 @@ func TestAvatar_NoType(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Error\r\n", server.Upload("/users/avatar;mim=image/gif;size=63", server.Alice, avatar)) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mim=image/gif;size=63", server.Alice, avatar)) } func TestAvatar_InvalidImage(t *testing.T) { @@ -115,7 +115,7 @@ func TestAvatar_InvalidImage(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Error\r\n", server.Upload("/users/avatar;mime=image/gif;size=3", server.Alice, []byte("abc"))) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=3", server.Alice, []byte("abc"))) } func TestAvatar_TooSmallSize(t *testing.T) { @@ -125,7 +125,7 @@ func TestAvatar_TooSmallSize(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Error\r\n", server.Upload("/users/avatar;mime=image/gif;size=10", server.Alice, avatar)) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=10", server.Alice, avatar)) } func TestAvatar_TooBigSize(t *testing.T) { @@ -135,7 +135,7 @@ func TestAvatar_TooBigSize(t *testing.T) { assert := assert.New(t) server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) - assert.Equal("40 Error\r\n", server.Upload("/users/avatar;mime=image/gif;size=64", server.Alice, avatar)) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=64", server.Alice, avatar)) } func TestAvatar_SizeLimit(t *testing.T) { @@ -146,7 +146,7 @@ func TestAvatar_SizeLimit(t *testing.T) { server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) server.cfg.MaxAvatarSize = 62 - assert.Equal("40 Image is too big\r\n", server.Upload("/users/avatar;mime=image/gif;size=63", server.Alice, avatar)) + assert.Equal("40 Image is too big\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) } func TestAvatar_ExactlySizeLimit(t *testing.T) { @@ -157,5 +157,5 @@ func TestAvatar_ExactlySizeLimit(t *testing.T) { server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) server.cfg.MaxAvatarSize = 63 - assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/avatar;mime=image/gif;size=63", server.Alice, avatar)) + assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) } From d9097f7c0d83db1a9cf8f6d360e37cc04f6b0e65 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 09:02:03 +0300 Subject: [PATCH 14/20] cleanup --- front/bio.go | 4 +- front/edit.go | 6 +-- front/input.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ front/post.go | 83 +-------------------------------------- front/reply.go | 4 +- 5 files changed, 112 insertions(+), 88 deletions(-) create mode 100644 front/input.go diff --git a/front/bio.go b/front/bio.go index 4e37d743..d78ce525 100644 --- a/front/bio.go +++ b/front/bio.go @@ -25,7 +25,7 @@ import ( "unicode/utf8" ) -func (h *Handler) doBio(w text.Writer, r *request, readContent func(text.Writer, *request) (string, bool)) { +func (h *Handler) doBio(w text.Writer, r *request, readInput func(text.Writer, *request) (string, bool)) { if r.User == nil { w.Redirect("/users") return @@ -39,7 +39,7 @@ func (h *Handler) doBio(w text.Writer, r *request, readContent func(text.Writer, return } - summary, ok := readContent(w, r) + summary, ok := readInput(w, r) if !ok { return } diff --git a/front/edit.go b/front/edit.go index d28113cb..91e021d5 100644 --- a/front/edit.go +++ b/front/edit.go @@ -25,7 +25,7 @@ import ( "time" ) -func (h *Handler) doEdit(w text.Writer, r *request, readContent func() (string, bool), args []string) { +func (h *Handler) doEdit(w text.Writer, r *request, readInput inputFunc, args []string) { if r.User == nil { w.Redirect("/users") return @@ -70,7 +70,7 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func() (string, } if note.InReplyTo == "" { - h.post(w, r, ¬e, nil, note.To, note.CC, note.Audience, readContent) + h.post(w, r, ¬e, nil, note.To, note.CC, note.Audience, readInput) return } @@ -84,7 +84,7 @@ func (h *Handler) doEdit(w text.Writer, r *request, readContent func() (string, } // the starting point is the original value of to and cc: recipients can be added but not removed when editing - h.post(w, r, ¬e, &parent, note.To, note.CC, note.Audience, readContent) + h.post(w, r, ¬e, &parent, note.To, note.CC, note.Audience, readInput) } func (h *Handler) edit(w text.Writer, r *request, args ...string) { diff --git a/front/input.go b/front/input.go new file mode 100644 index 00000000..43eb67a7 --- /dev/null +++ b/front/input.go @@ -0,0 +1,103 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package front + +import ( + "github.com/dimkr/tootik/front/text" + "io" + "net/url" + "strconv" +) + +// inputFunc is a callback that returns user-provided text or false +type inputFunc func() (string, bool) + +func readQuery(w text.Writer, r *request, prompt string) (string, bool) { + if r.URL.RawQuery == "" { + w.Status(10, prompt) + return "", false + } + + content, err := url.QueryUnescape(r.URL.RawQuery) + if err != nil { + w.Status(40, "Bad input") + return "", false + } + + return content, true +} + +func readUpload(w text.Writer, r *request, args []string) (string, bool) { + if r.Body == nil { + w.Redirect("/users/oops") + return "", false + } + + var sizeStr, mimeType string + if args[1] == "size" && args[3] == "mime" { + sizeStr = args[2] + mimeType = args[4] + } else if args[1] == "mime" && args[3] == "size" { + sizeStr = args[4] + mimeType = args[2] + } else { + r.Log.Warn("Invalid parameters") + w.Status(40, "Invalid parameters") + return "", false + } + + if mimeType != "text/plain" { + r.Log.Warn("Content type is unsupported", "type", mimeType) + w.Status(40, "Only text/plain is supported") + return "", false + } + + size, err := strconv.ParseInt(sizeStr, 10, 64) + if err != nil { + r.Log.Warn("Failed to parse content size", "error", err) + w.Status(40, "Invalid size") + return "", false + } + + if size == 0 { + r.Log.Warn("Content is empty") + w.Status(40, "Content is empty") + return "", false + } + + if size > int64(r.Handler.Config.MaxPostsLength)*4 { + r.Log.Warn("Content is too big", "size", size) + w.Status(40, "Content is too big") + return "", false + } + + buf := make([]byte, size) + n, err := io.ReadFull(r.Body, buf) + if err != nil { + r.Log.Warn("Failed to read content", "error", err) + w.Error() + return "", false + } + + if int64(n) != size { + r.Log.Warn("Content is truncated") + w.Error() + return "", false + } + + return string(buf), true +} diff --git a/front/post.go b/front/post.go index f1059513..2149c550 100644 --- a/front/post.go +++ b/front/post.go @@ -25,10 +25,7 @@ import ( "github.com/dimkr/tootik/front/text" "github.com/dimkr/tootik/front/text/plain" "github.com/dimkr/tootik/outbox" - "io" - "net/url" "regexp" - "strconv" "strings" "time" "unicode/utf8" @@ -45,83 +42,7 @@ var ( pollRegex = regexp.MustCompile(`^\[(?:(?i)POLL)\s+(.+)\s*\]\s*(.+)`) ) -func readQuery(w text.Writer, r *request, prompt string) (string, bool) { - if r.URL.RawQuery == "" { - w.Status(10, prompt) - return "", false - } - - content, err := url.QueryUnescape(r.URL.RawQuery) - if err != nil { - w.Status(40, "Bad input") - return "", false - } - - return content, true -} - -func readUpload(w text.Writer, r *request, args []string) (string, bool) { - if r.Body == nil { - w.Redirect("/users/oops") - return "", false - } - - var sizeStr, mimeType string - if args[1] == "size" && args[3] == "mime" { - sizeStr = args[2] - mimeType = args[4] - } else if args[1] == "mime" && args[3] == "size" { - sizeStr = args[4] - mimeType = args[2] - } else { - r.Log.Warn("Invalid parameters") - w.Status(40, "Invalid parameters") - return "", false - } - - if mimeType != "text/plain" { - r.Log.Warn("Content type is unsupported", "type", mimeType) - w.Status(40, "Only text/plain is supported") - return "", false - } - - size, err := strconv.ParseInt(sizeStr, 10, 64) - if err != nil { - r.Log.Warn("Failed to parse content size", "error", err) - w.Status(40, "Invalid size") - return "", false - } - - if size == 0 { - r.Log.Warn("Content is empty") - w.Status(40, "Content is empty") - return "", false - } - - if size > int64(r.Handler.Config.MaxPostsLength)*4 { - r.Log.Warn("Content is too big", "size", size) - w.Status(40, "Content is too big") - return "", false - } - - buf := make([]byte, size) - n, err := io.ReadFull(r.Body, buf) - if err != nil { - r.Log.Warn("Failed to read content", "error", err) - w.Error() - return "", false - } - - if int64(n) != size { - r.Log.Warn("Content is truncated") - w.Error() - return "", false - } - - return string(buf), true -} - -func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readContent func() (string, bool)) { +func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo *ap.Object, to ap.Audience, cc ap.Audience, audience string, readInput inputFunc) { if r.User == nil { w.Redirect("/users") return @@ -154,7 +75,7 @@ func (h *Handler) post(w text.Writer, r *request, oldNote *ap.Object, inReplyTo } } - content, ok := readContent() + content, ok := readInput() if !ok { return } diff --git a/front/reply.go b/front/reply.go index 13ac2e9e..367c8638 100644 --- a/front/reply.go +++ b/front/reply.go @@ -23,7 +23,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) doReply(w text.Writer, r *request, readContent func() (string, bool), args []string) { +func (h *Handler) doReply(w text.Writer, r *request, readInput inputFunc, args []string) { postID := "https://" + args[1] var note ap.Object @@ -65,7 +65,7 @@ func (h *Handler) doReply(w text.Writer, r *request, readContent func() (string, }) } - h.post(w, r, nil, ¬e, to, cc, note.Audience, readContent) + h.post(w, r, nil, ¬e, to, cc, note.Audience, readInput) } func (h *Handler) reply(w text.Writer, r *request, args ...string) { From 0aa706859c4f7deae3712890c3fe48d118ebf795 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 09:05:12 +0300 Subject: [PATCH 15/20] mention post upload --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d42785db..fee3c381 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ tootik is lightweight, private and accessible social network: * With support for [Mastodon's follower synchronization mechanism](https://docs.joinmastodon.org/spec/activitypub/#follower-synchronization-mechanism), aka [FEP-8fcf](https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md) * Multi-choice polls * Full-text search within posts -* Upload of user avatars, over [Titan](gemini://transjovian.org/titan) +* Upload of posts and user avatars, over [Titan](gemini://transjovian.org/titan) * Account migration, in both directions ## Using tootik From a18f159d2e81a5ac89295e6705bbf0c6dfac9c46 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 15:23:09 +0300 Subject: [PATCH 16/20] cleanup --- front/static/users/post.gmi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/front/static/users/post.gmi b/front/static/users/post.gmi index b1f9e453..e5f96d7c 100644 --- a/front/static/users/post.gmi +++ b/front/static/users/post.gmi @@ -1,10 +1,12 @@ # New Post +Who should be able to see your new post? + => /users/dm 💌 Mentioned users only => titan://{{.Domain}}/users/upload/dm Upload text file -=> /users/whisper 🔔 Followers and mentioned users +=> /users/whisper 🔔 Your followers and mentioned users => titan://{{.Domain}}/users/upload/whisper Upload text file -=> /users/say 📣 Public +=> /users/say 📣 Anyone => titan://{{.Domain}}/users/upload/say Upload text file From eb7264364d1c3acb2ddccd354e1a0193b2193f46 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 18:50:26 +0300 Subject: [PATCH 17/20] cleanup --- front/edit.go | 24 +++++++----------------- front/reply.go | 24 +++++++----------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/front/edit.go b/front/edit.go index 91e021d5..07c3d6f0 100644 --- a/front/edit.go +++ b/front/edit.go @@ -25,7 +25,7 @@ import ( "time" ) -func (h *Handler) doEdit(w text.Writer, r *request, readInput inputFunc, args []string) { +func (h *Handler) doEdit(w text.Writer, r *request, args []string, readInput inputFunc) { if r.User == nil { w.Redirect("/users") return @@ -88,23 +88,13 @@ func (h *Handler) doEdit(w text.Writer, r *request, readInput inputFunc, args [] } func (h *Handler) edit(w text.Writer, r *request, args ...string) { - h.doEdit( - w, - r, - func() (string, bool) { - return readQuery(w, r, "Post content") - }, - args, - ) + h.doEdit(w, r, args, func() (string, bool) { + return readQuery(w, r, "Post content") + }) } func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { - h.doEdit( - w, - r, - func() (string, bool) { - return readUpload(w, r, args[1:]) - }, - args, - ) + h.doEdit(w, r, args, func() (string, bool) { + return readUpload(w, r, args[1:]) + }) } diff --git a/front/reply.go b/front/reply.go index 367c8638..185bda2d 100644 --- a/front/reply.go +++ b/front/reply.go @@ -23,7 +23,7 @@ import ( "github.com/dimkr/tootik/front/text" ) -func (h *Handler) doReply(w text.Writer, r *request, readInput inputFunc, args []string) { +func (h *Handler) doReply(w text.Writer, r *request, args []string, readInput inputFunc) { postID := "https://" + args[1] var note ap.Object @@ -69,23 +69,13 @@ func (h *Handler) doReply(w text.Writer, r *request, readInput inputFunc, args [ } func (h *Handler) reply(w text.Writer, r *request, args ...string) { - h.doReply( - w, - r, - func() (string, bool) { - return readQuery(w, r, "Reply content") - }, - args, - ) + h.doReply(w, r, args, func() (string, bool) { + return readQuery(w, r, "Reply content") + }) } func (h *Handler) replyUpload(w text.Writer, r *request, args ...string) { - h.doReply( - w, - r, - func() (string, bool) { - return readUpload(w, r, args[1:]) - }, - args, - ) + h.doReply(w, r, args, func() (string, bool) { + return readUpload(w, r, args[1:]) + }) } From f3730159689509b46e3f22c44ed69028a2c82290 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 18:52:33 +0300 Subject: [PATCH 18/20] cleanup --- front/bio.go | 2 +- front/dm.go | 2 +- front/edit.go | 2 +- front/input.go | 2 +- front/reply.go | 2 +- front/say.go | 2 +- front/whisper.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/front/bio.go b/front/bio.go index d78ce525..a0ab3544 100644 --- a/front/bio.go +++ b/front/bio.go @@ -99,7 +99,7 @@ func (h *Handler) uploadBio(w text.Writer, r *request, args ...string) { w, r, func(w text.Writer, r *request) (string, bool) { - return readUpload(w, r, args) + return readBody(w, r, args) }, ) } diff --git a/front/dm.go b/front/dm.go index ab3ae051..56a7670d 100644 --- a/front/dm.go +++ b/front/dm.go @@ -35,6 +35,6 @@ func (h *Handler) uploadDM(w text.Writer, r *request, args ...string) { cc := ap.Audience{} h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { - return readUpload(w, r, args) + return readBody(w, r, args) }) } diff --git a/front/edit.go b/front/edit.go index 07c3d6f0..a943826e 100644 --- a/front/edit.go +++ b/front/edit.go @@ -95,6 +95,6 @@ func (h *Handler) edit(w text.Writer, r *request, args ...string) { func (h *Handler) editUpload(w text.Writer, r *request, args ...string) { h.doEdit(w, r, args, func() (string, bool) { - return readUpload(w, r, args[1:]) + return readBody(w, r, args[1:]) }) } diff --git a/front/input.go b/front/input.go index 43eb67a7..0f85a1a7 100644 --- a/front/input.go +++ b/front/input.go @@ -41,7 +41,7 @@ func readQuery(w text.Writer, r *request, prompt string) (string, bool) { return content, true } -func readUpload(w text.Writer, r *request, args []string) (string, bool) { +func readBody(w text.Writer, r *request, args []string) (string, bool) { if r.Body == nil { w.Redirect("/users/oops") return "", false diff --git a/front/reply.go b/front/reply.go index 185bda2d..3bc42058 100644 --- a/front/reply.go +++ b/front/reply.go @@ -76,6 +76,6 @@ func (h *Handler) reply(w text.Writer, r *request, args ...string) { func (h *Handler) replyUpload(w text.Writer, r *request, args ...string) { h.doReply(w, r, args, func() (string, bool) { - return readUpload(w, r, args[1:]) + return readBody(w, r, args[1:]) }) } diff --git a/front/say.go b/front/say.go index 6542cb08..2379e35a 100644 --- a/front/say.go +++ b/front/say.go @@ -41,6 +41,6 @@ func (h *Handler) uploadSay(w text.Writer, r *request, args ...string) { cc.Add(r.User.Followers) h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { - return readUpload(w, r, args) + return readBody(w, r, args) }) } diff --git a/front/whisper.go b/front/whisper.go index cce8d646..63e91fc1 100644 --- a/front/whisper.go +++ b/front/whisper.go @@ -39,6 +39,6 @@ func (h *Handler) uploadWhisper(w text.Writer, r *request, args ...string) { to.Add(r.User.Followers) h.post(w, r, nil, nil, to, cc, "", func() (string, bool) { - return readUpload(w, r, args) + return readBody(w, r, args) }) } From 9699a978c31da32e3688e4549e4e09a26fb5993a Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 19:18:38 +0300 Subject: [PATCH 19/20] convert static pages into templates --- cmd/tootik/main.go | 5 +++- front/handler.go | 19 ++++++++++----- front/static/embed.go | 48 +++++++++++++++++++++++++++++++------ front/static/help.gmi | 2 +- front/static/users/help.gmi | 10 ++++---- test/register_test.go | 45 +++++++++++++++++++++++++++------- test/server.go | 7 +++++- 7 files changed, 106 insertions(+), 30 deletions(-) diff --git a/cmd/tootik/main.go b/cmd/tootik/main.go index 235f503a..3efd7e79 100644 --- a/cmd/tootik/main.go +++ b/cmd/tootik/main.go @@ -179,7 +179,10 @@ func main() { panic(err) } - handler := front.NewHandler(*domain, *closed, &cfg) + handler, err := front.NewHandler(*domain, *closed, &cfg) + if err != nil { + panic(err) + } for _, svc := range []struct { Name string diff --git a/front/handler.go b/front/handler.go index a387c08f..e89f4dc6 100644 --- a/front/handler.go +++ b/front/handler.go @@ -42,16 +42,16 @@ type Handler struct { var ErrNotRegistered = errors.New("user is not registered") -func serveStaticFile(w text.Writer, r *request, args ...string) { +func serveStaticFile(lines []string, w text.Writer, r *request, args ...string) { w.OK() - for _, line := range static.Files[r.URL.Path] { + for _, line := range lines { w.Text(line) } } // NewHandler returns a new [Handler]. -func NewHandler(domain string, closed bool, cfg *cfg.Config) Handler { +func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h := Handler{ handlers: map[*regexp.Regexp]func(text.Writer, *request, ...string){}, Domain: domain, @@ -132,11 +132,18 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) Handler { h.handlers[regexp.MustCompile(`^/robots.txt$`)] = robots - for path := range static.Files { - h.handlers[regexp.MustCompile(fmt.Sprintf(`^%s$`, path))] = withUserMenu(serveStaticFile) + files, err := static.Format(domain, cfg) + if err != nil { + return h, err } - return h + for path, lines := range files { + h.handlers[regexp.MustCompile(fmt.Sprintf(`^%s$`, path))] = withUserMenu(func(w text.Writer, r *request, args ...string) { + serveStaticFile(lines, w, r, args...) + }) + } + + return h, nil } // Handle handles a request and writes a response. diff --git a/front/static/embed.go b/front/static/embed.go index d14c6826..ba1b310e 100644 --- a/front/static/embed.go +++ b/front/static/embed.go @@ -18,19 +18,46 @@ limitations under the License. package static import ( + "bytes" "embed" "fmt" + "github.com/dimkr/tootik/cfg" "strings" + "text/template" ) +type data struct { + Domain string + Config *cfg.Config +} + //go:embed *.gmi */*.gmi -var rawFiles embed.FS +var vfs embed.FS + +var templates = map[string]*template.Template{} + +func Format(domain string, cfg *cfg.Config) (map[string][]string, error) { + formatted := make(map[string][]string, len(templates)) + + data := data{ + Domain: domain, + Config: cfg, + } + + for path, tmpl := range templates { + var b bytes.Buffer + if err := tmpl.Execute(&b, &data); err != nil { + return nil, err + } -// Files maps relative paths to static content. -var Files = map[string][]string{} + formatted[path] = strings.Split(strings.TrimRight(b.String(), "\r\n\t "), "\n") + } + + return formatted, nil +} func readDirectory(dir string) { - files, err := rawFiles.ReadDir(dir) + files, err := vfs.ReadDir(dir) if err != nil { panic(err) } @@ -48,7 +75,7 @@ func readDirectory(dir string) { path = fmt.Sprintf("%s/%s", dir, path) } - content, err := rawFiles.ReadFile(path) + content, err := vfs.ReadFile(path) if err != nil { panic(err) } @@ -59,10 +86,17 @@ func readDirectory(dir string) { } if dir == "." { - Files[fmt.Sprintf("/%s", base)] = strings.Split(strings.TrimRight(string(content), "\r\n\t "), "\n") + path = fmt.Sprintf("/%s", base) } else { - Files[fmt.Sprintf("/%s/%s", dir, base)] = strings.Split(strings.TrimRight(string(content), "\r\n\t "), "\n") + path = fmt.Sprintf("/%s/%s", dir, base) + } + + tmpl, err := template.New(path).Parse(string(content)) + if err != nil { + panic(err) } + + templates[path] = tmpl } } diff --git a/front/static/help.gmi b/front/static/help.gmi index 4e90f040..c1b97aba 100644 --- a/front/static/help.gmi +++ b/front/static/help.gmi @@ -1,6 +1,6 @@ # 🛟 Help -## About this server +## About {{.Domain}} This is an instance of tootik, a "slow", "boring" and non-addictive social network in the small internet that is also connected to the fediverse. => https://github.com/dimkr/tootik The tootik project diff --git a/front/static/users/help.gmi b/front/static/users/help.gmi index 8fb99309..ef97cce5 100644 --- a/front/static/users/help.gmi +++ b/front/static/users/help.gmi @@ -1,6 +1,6 @@ # 🛟 Help -## About this server +## About {{.Domain}} This is an instance of tootik, a "slow", "boring" and non-addictive social network in the small internet that is also connected to the fediverse. => https://github.com/dimkr/tootik The tootik project @@ -71,8 +71,8 @@ Follow this link to publish a public post visible to anyone. > ⚙️ Settings This page allows you to: -* Set your display name (up to 30 characters long) -* Set the short (up to 500 characters long) description that appears at the top of your profile +* Set your display name (up to {{.Config.MaxDisplayNameLength}} characters long) +* Set the short (up to {{.Config.MaxBioLength}} characters long) description that appears at the top of your profile * Set an account alias, to allow account migration to this instance * Notify followers about account migration from this instance @@ -82,7 +82,7 @@ This page shows various statistics about this server and the parts of the fedive ## Posts -Posts should be up to 500 characters long. +Posts should be up to {{.Config.MaxPostsLength}} characters long. ### Links, Mentions and Hashtags @@ -108,7 +108,7 @@ For example: [POLL Does #tootik support polls now?] Yes | No | I don't know ``` -Polls must have between 2 and 5 multi-choice options, and end after a month. +Polls must have between 2 and {{.Config.PollMaxOptions}} multi-choice options, and end after {{printf "%s" .Config.PollDuration}}. ## Account Migration diff --git a/test/register_test.go b/test/register_test.go index dd8fd3ac..70e164a7 100644 --- a/test/register_test.go +++ b/test/register_test.go @@ -167,10 +167,13 @@ func TestRegister_Redirect(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -249,10 +252,13 @@ func TestRegister_HappyFlow(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users/register\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -331,10 +337,13 @@ func TestRegister_HappyFlowRegistrationClosed(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users/register\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, true, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, true, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -416,10 +425,13 @@ func TestRegister_AlreadyRegistered(t *testing.T) { _, _, err = user.Create(context.Background(), domain, db, "erin", "e") assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -503,10 +515,13 @@ func TestRegister_Twice(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users/register\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -601,10 +616,13 @@ func TestRegister_Throttling(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users/register\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -699,10 +717,13 @@ func TestRegister_Throttling30Minutes(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users/register\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -800,10 +821,13 @@ func TestRegister_Throttling1Hour(t *testing.T) { _, err = tlsReader.Write([]byte("gemini://localhost.localdomain:8965/users/register\r\n")) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), @@ -895,10 +919,13 @@ func TestRegister_RedirectTwice(t *testing.T) { _, err = tlsReader.Write([]byte(data.url)) assert.NoError(err) + handler, err := front.NewHandler(domain, false, &cfg) + assert.NoError(err) + l := gemini.Listener{ Domain: domain, Config: &cfg, - Handler: front.NewHandler(domain, false, &cfg), + Handler: handler, DB: db, Resolver: fed.NewResolver(nil, domain, &cfg, &http.Client{}), Log: slog.Default(), diff --git a/test/server.go b/test/server.go index 7db8a9c7..1bee20fb 100644 --- a/test/server.go +++ b/test/server.go @@ -96,11 +96,16 @@ func newTestServer() *server { panic(err) } + handler, err := front.NewHandler(domain, false, &cfg) + if err != nil { + panic(err) + } + return &server{ cfg: &cfg, dbPath: path, db: db, - handler: front.NewHandler(domain, false, &cfg), + handler: handler, Alice: alice, Bob: bob, Carol: carol, From e2077fc3e7d338a08e668516786335e11737e931 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Thu, 11 Apr 2024 19:25:58 +0300 Subject: [PATCH 20/20] add support for avatar upload --- README.md | 1 + cfg/cfg.go | 25 +++++ fed/icon.go | 2 +- front/avatar.go | 153 +++++++++++++++++++++++++ front/gemini/gemini.go | 12 +- front/gopher/gopher.go | 2 +- front/guppy/guppy.go | 2 +- front/handler.go | 5 +- front/request.go | 2 + front/static/users/help.gmi | 1 + front/static/users/settings.gmi | 1 + front/user/create.go | 2 +- go.mod | 1 + go.sum | 2 + fed/icon/icon.go => icon/generate.go | 6 - icon/icon.go | 23 ++++ icon/scale.go | 59 ++++++++++ migrations/029_avatar.go | 11 ++ test/avatar_test.go | 161 +++++++++++++++++++++++++++ test/server.go | 15 ++- 20 files changed, 471 insertions(+), 15 deletions(-) create mode 100644 front/avatar.go rename fed/icon/icon.go => icon/generate.go (92%) create mode 100644 icon/icon.go create mode 100644 icon/scale.go create mode 100644 migrations/029_avatar.go create mode 100644 test/avatar_test.go diff --git a/README.md b/README.md index e3f22d71..8b0f9ceb 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ tootik is lightweight, private and accessible social network: * With support for [Mastodon's follower synchronization mechanism](https://docs.joinmastodon.org/spec/activitypub/#follower-synchronization-mechanism), aka [FEP-8fcf](https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md) * Multi-choice polls * Full-text search within posts +* Upload of user avatars, over [Titan](gemini://transjovian.org/titan) * Account migration, in both directions ## Using tootik diff --git a/cfg/cfg.go b/cfg/cfg.go index 3db56620..d15ca456 100644 --- a/cfg/cfg.go +++ b/cfg/cfg.go @@ -44,6 +44,11 @@ type Config struct { MaxDisplayNameLength int MaxBioLength int + MaxAvatarSize int64 + MaxAvatarWidth int + MaxAvatarHeight int + AvatarWidth int + AvatarHeight int MinActorEditInterval time.Duration MaxFollowsPerUser int @@ -167,6 +172,26 @@ func (c *Config) FillDefaults() { c.MaxBioLength = 500 } + if c.MaxAvatarSize <= 0 { + c.MaxAvatarSize = 2 * 1024 * 1024 + } + + if c.MaxAvatarWidth <= 0 { + c.MaxAvatarWidth = 1024 + } + + if c.MaxAvatarHeight <= 0 { + c.MaxAvatarHeight = 1024 + } + + if c.AvatarWidth <= 0 { + c.AvatarWidth = 400 + } + + if c.AvatarHeight <= 0 { + c.AvatarHeight = 400 + } + if c.MinActorEditInterval <= 0 { c.MinActorEditInterval = time.Minute * 30 } diff --git a/fed/icon.go b/fed/icon.go index 5fb5ba11..28254e3e 100644 --- a/fed/icon.go +++ b/fed/icon.go @@ -19,7 +19,7 @@ package fed import ( "database/sql" "errors" - "github.com/dimkr/tootik/fed/icon" + "github.com/dimkr/tootik/icon" "net/http" "strings" ) diff --git a/front/avatar.go b/front/avatar.go new file mode 100644 index 00000000..e589b91e --- /dev/null +++ b/front/avatar.go @@ -0,0 +1,153 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package front + +import ( + "fmt" + "github.com/dimkr/tootik/front/text" + "github.com/dimkr/tootik/icon" + "github.com/dimkr/tootik/outbox" + "io" + "strconv" + "strings" + "time" +) + +var supportedImageTypes = map[string]struct{}{ + "image/png": {}, + "image/jpeg": {}, + "image/gif": {}, +} + +func (h *Handler) uploadAvatar(w text.Writer, r *request, args ...string) { + if r.User == nil { + w.Redirect("/users") + return + } + + if r.Body == nil { + w.Redirect("/users/oops") + return + } + + var sizeStr, mimeType string + if args[1] == "size" && args[3] == "mime" { + sizeStr = args[2] + mimeType = args[4] + } else if args[1] == "mime" && args[3] == "size" { + sizeStr = args[4] + mimeType = args[2] + } else { + r.Log.Warn("Invalid parameters") + w.Error() + return + } + + size, err := strconv.ParseInt(sizeStr, 10, 64) + if err != nil { + r.Log.Warn("Failed to parse avatar size", "error", err) + w.Status(40, "Invalid size") + return + } + + if size > r.Handler.Config.MaxAvatarSize { + r.Log.Warn("Image is too big", "size", size) + w.Status(40, "Image is too big") + return + } + + if _, ok := supportedImageTypes[mimeType]; !ok { + r.Log.Warn("Image type is unsupported", "type", mimeType) + w.Status(40, "Unsupported image type") + return + } + + now := time.Now() + + if (r.User.Updated != nil && now.Sub(r.User.Updated.Time) < h.Config.MinActorEditInterval) || (r.User.Updated == nil && now.Sub(r.User.Published.Time) < h.Config.MinActorEditInterval) { + r.Log.Warn("Throttled request to set avatar") + w.Status(40, "Please try again later") + return + } + + buf := make([]byte, size) + n, err := io.ReadFull(r.Body, buf) + if err != nil { + r.Log.Warn("Failed to read avatar", "error", err) + w.Error() + return + } + + if int64(n) != size { + r.Log.Warn("Avatar is truncated") + w.Error() + return + } + + resized, err := icon.Scale(r.Handler.Config, buf) + if err != nil { + r.Log.Warn("Failed to read avatar", "error", err) + w.Error() + return + } + + tx, err := r.DB.BeginTx(r.Context, nil) + if err != nil { + r.Log.Warn("Failed to set avatar", "error", err) + w.Error() + return + } + defer tx.Rollback() + + if _, err := tx.ExecContext( + r.Context, + "update persons set actor = json_set(actor, '$.icon.url', $1, '$.updated', $2) where id = $3", + // we add fragment because some servers cache the image until the URL changes + fmt.Sprintf("https://%s/icon/%s%s#%d", r.Handler.Domain, r.User.PreferredUsername, icon.FileNameExtension, now.UnixNano()), + now.Format(time.RFC3339Nano), + r.User.ID, + ); err != nil { + r.Log.Error("Failed to set avatar", "error", err) + w.Error() + return + } + + if _, err := tx.ExecContext( + r.Context, + "insert into icons(name, buf) values($1, $2) on conflict(name) do update set buf = $2", + r.User.PreferredUsername, + string(resized), + ); err != nil { + r.Log.Error("Failed to set avatar", "error", err) + w.Error() + return + } + + if err := outbox.UpdateActor(r.Context, h.Domain, tx, r.User.ID); err != nil { + r.Log.Error("Failed to set avatar", "error", err) + w.Error() + return + } + + if err := tx.Commit(); err != nil { + r.Log.Error("Failed to set avatar", "error", err) + w.Error() + return + } + + w.Redirectf("gemini://%s/users/outbox/%s", r.Handler.Domain, strings.TrimPrefix(r.User.ID, "https://")) +} diff --git a/front/gemini/gemini.go b/front/gemini/gemini.go index 628fc6b1..2992eada 100644 --- a/front/gemini/gemini.go +++ b/front/gemini/gemini.go @@ -99,7 +99,7 @@ func (gl *Listener) Handle(ctx context.Context, conn net.Conn, wg *sync.WaitGrou req := make([]byte, 1024+2) total := 0 for { - n, err := conn.Read(req[total:]) + n, err := conn.Read(req[total : total+1]) if err != nil && total == 0 && errors.Is(err, io.EOF) { gl.Log.Debug("Failed to receive request", "error", err) return @@ -142,7 +142,7 @@ func (gl *Listener) Handle(ctx context.Context, conn net.Conn, wg *sync.WaitGrou return } - gl.Handler.Handle(ctx, gl.Log, w, reqUrl, user, privKey, gl.DB, gl.Resolver, wg) + gl.Handler.Handle(ctx, gl.Log, conn, w, reqUrl, user, privKey, gl.DB, gl.Resolver, wg) } // ListenAndServe handles Gemini requests. @@ -197,8 +197,14 @@ func (gl *Listener) ListenAndServe(ctx context.Context) error { wg.Add(1) go func() { - gl.Handle(requestCtx, conn, &wg) + <-requestCtx.Done() conn.Close() + wg.Done() + }() + + wg.Add(1) + go func() { + gl.Handle(requestCtx, conn, &wg) timer.Stop() cancelRequest() wg.Done() diff --git a/front/gopher/gopher.go b/front/gopher/gopher.go index 657096be..b8e3653a 100644 --- a/front/gopher/gopher.go +++ b/front/gopher/gopher.go @@ -90,7 +90,7 @@ func (gl *Listener) handle(ctx context.Context, conn net.Conn, wg *sync.WaitGrou w := gmap.Wrap(conn, gl.Domain, gl.Config) - gl.Handler.Handle(ctx, gl.Log.With(slog.Group("request", "path", reqUrl.Path)), w, reqUrl, nil, httpsig.Key{}, gl.DB, gl.Resolver, wg) + gl.Handler.Handle(ctx, gl.Log.With(slog.Group("request", "path", reqUrl.Path)), nil, w, reqUrl, nil, httpsig.Key{}, gl.DB, gl.Resolver, wg) } // ListenAndServe handles Gopher requests. diff --git a/front/guppy/guppy.go b/front/guppy/guppy.go index 593a738c..44ea4f7b 100644 --- a/front/guppy/guppy.go +++ b/front/guppy/guppy.go @@ -90,7 +90,7 @@ func (gl *Listener) handle(ctx context.Context, wg *sync.WaitGroup, from net.Add w.Status(4, "Wrong host") } else { gl.Log.Info("Handling request", "path", reqUrl.Path, "url", reqUrl.String(), "from", from) - gl.Handler.Handle(ctx, gl.Log, w, reqUrl, nil, httpsig.Key{}, gl.DB, gl.Resolver, wg) + gl.Handler.Handle(ctx, gl.Log, nil, w, reqUrl, nil, httpsig.Key{}, gl.DB, gl.Resolver, wg) } if ctx.Err() != nil { diff --git a/front/handler.go b/front/handler.go index e89f4dc6..6346b980 100644 --- a/front/handler.go +++ b/front/handler.go @@ -26,6 +26,7 @@ import ( "github.com/dimkr/tootik/front/static" "github.com/dimkr/tootik/front/text" "github.com/dimkr/tootik/httpsig" + "io" "log/slog" "net/url" "regexp" @@ -82,6 +83,7 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { h.handlers[regexp.MustCompile(`^/users/outbox/(\S+)$`)] = withUserMenu(h.userOutbox) h.handlers[regexp.MustCompile(`^/users/me$`)] = withUserMenu(me) + h.handlers[regexp.MustCompile(`^/users/upload/avatar;([a-z]+)=([^;]+);([a-z]+)=([^;]+)`)] = h.uploadAvatar h.handlers[regexp.MustCompile(`^/users/bio$`)] = h.bio h.handlers[regexp.MustCompile(`^/users/name$`)] = h.name h.handlers[regexp.MustCompile(`^/users/alias$`)] = h.alias @@ -147,7 +149,7 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config) (Handler, error) { } // Handle handles a request and writes a response. -func (h *Handler) Handle(ctx context.Context, log *slog.Logger, w text.Writer, reqUrl *url.URL, user *ap.Actor, key httpsig.Key, db *sql.DB, resolver ap.Resolver, wg *sync.WaitGroup) { +func (h *Handler) Handle(ctx context.Context, log *slog.Logger, r io.Reader, w text.Writer, reqUrl *url.URL, user *ap.Actor, key httpsig.Key, db *sql.DB, resolver ap.Resolver, wg *sync.WaitGroup) { for re, handler := range h.handlers { m := re.FindStringSubmatch(reqUrl.Path) if m != nil { @@ -164,6 +166,7 @@ func (h *Handler) Handle(ctx context.Context, log *slog.Logger, w text.Writer, r Context: ctx, Handler: h, URL: reqUrl, + Body: r, User: user, Key: key, DB: db, diff --git a/front/request.go b/front/request.go index 098e2047..8ca93f94 100644 --- a/front/request.go +++ b/front/request.go @@ -21,6 +21,7 @@ import ( "database/sql" "github.com/dimkr/tootik/ap" "github.com/dimkr/tootik/httpsig" + "io" "log/slog" "net/url" "sync" @@ -30,6 +31,7 @@ type request struct { Context context.Context Handler *Handler URL *url.URL + Body io.Reader User *ap.Actor Key httpsig.Key DB *sql.DB diff --git a/front/static/users/help.gmi b/front/static/users/help.gmi index ef97cce5..9ac1bae3 100644 --- a/front/static/users/help.gmi +++ b/front/static/users/help.gmi @@ -75,6 +75,7 @@ This page allows you to: * Set the short (up to {{.Config.MaxBioLength}} characters long) description that appears at the top of your profile * Set an account alias, to allow account migration to this instance * Notify followers about account migration from this instance +* Upload a .png, .jpg or .gif image to serve as your avatar (use your client certificate for authentication): up to {{.Config.MaxAvatarWidth}}x{{.Config.MaxAvatarHeight}} and {{.Config.MaxAvatarSize}} bytes, downscaled to {{.Config.AvatarWidth}}x{{.Config.AvatarHeight}} > 📊 Statistics diff --git a/front/static/users/settings.gmi b/front/static/users/settings.gmi index 4e596c62..8dce6c6d 100644 --- a/front/static/users/settings.gmi +++ b/front/static/users/settings.gmi @@ -4,6 +4,7 @@ => /users/name 👺 Set display name => /users/bio 📜 Set bio +=> titan://{{.Domain}}/users/upload/avatar Upload avatar ## Migration diff --git a/front/user/create.go b/front/user/create.go index db31baf5..737530b3 100644 --- a/front/user/create.go +++ b/front/user/create.go @@ -26,8 +26,8 @@ import ( "encoding/pem" "fmt" "github.com/dimkr/tootik/ap" - "github.com/dimkr/tootik/fed/icon" "github.com/dimkr/tootik/httpsig" + "github.com/dimkr/tootik/icon" "time" ) diff --git a/go.mod b/go.mod index 427b0707..e0122f6c 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 github.com/mattn/go-sqlite3 v1.14.22 github.com/stretchr/testify v1.9.0 + golang.org/x/image v0.15.0 golang.org/x/sync v0.7.0 ) diff --git a/go.sum b/go.sum index bf27980a..6d0627fe 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= +golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= diff --git a/fed/icon/icon.go b/icon/generate.go similarity index 92% rename from fed/icon/icon.go rename to icon/generate.go index 017ab269..0d436274 100644 --- a/fed/icon/icon.go +++ b/icon/generate.go @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package icon generates tiny, pseudo-random user avatars. package icon import ( @@ -26,11 +25,6 @@ import ( "image/gif" ) -const ( - MediaType = "image/gif" - FileNameExtension = ".gif" -) - // Generate generates a tiny pseudo-random image by user name func Generate(s string) ([]byte, error) { hash := sha256.Sum256([]byte(s)) diff --git a/icon/icon.go b/icon/icon.go new file mode 100644 index 00000000..62eab0d5 --- /dev/null +++ b/icon/icon.go @@ -0,0 +1,23 @@ +/* +Copyright 2023, 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package icon generates tiny, pseudo-random user avatars. +package icon + +const ( + MediaType = "image/gif" + FileNameExtension = ".gif" +) diff --git a/icon/scale.go b/icon/scale.go new file mode 100644 index 00000000..2f5db754 --- /dev/null +++ b/icon/scale.go @@ -0,0 +1,59 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package icon + +import ( + "bytes" + "errors" + "github.com/dimkr/tootik/cfg" + xdraw "golang.org/x/image/draw" + "image" + "image/draw" + "image/gif" + _ "image/jpeg" + _ "image/png" +) + +func Scale(cfg *cfg.Config, data []byte) ([]byte, error) { + dim, _, err := image.DecodeConfig(bytes.NewReader(data)) + if err != nil { + return nil, err + } + + if dim.Height > cfg.MaxAvatarHeight || dim.Width > cfg.MaxAvatarWidth { + return nil, errors.New("too big") + } + + im, _, err := image.Decode(bytes.NewReader(data)) + if err != nil { + return nil, err + } + + if dim.Height > cfg.AvatarHeight || dim.Width > cfg.AvatarWidth { + bounds := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{cfg.AvatarWidth, cfg.AvatarHeight}} + scaled := image.NewRGBA(bounds) + xdraw.NearestNeighbor.Scale(scaled, bounds, im, im.Bounds(), draw.Over, nil) + im = scaled + } + + var b bytes.Buffer + if err := gif.Encode(&b, im, &gif.Options{NumColors: 256}); err != nil { + return nil, err + } + + return b.Bytes(), nil +} diff --git a/migrations/029_avatar.go b/migrations/029_avatar.go new file mode 100644 index 00000000..22cb0846 --- /dev/null +++ b/migrations/029_avatar.go @@ -0,0 +1,11 @@ +package migrations + +import ( + "context" + "database/sql" +) + +func avatar(ctx context.Context, domain string, tx *sql.Tx) error { + _, err := tx.ExecContext(ctx, `CREATE UNIQUE INDEX iconsname ON icons(name)`) + return err +} diff --git a/test/avatar_test.go b/test/avatar_test.go new file mode 100644 index 00000000..81d11735 --- /dev/null +++ b/test/avatar_test.go @@ -0,0 +1,161 @@ +/* +Copyright 2024 Dima Krasner + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package test + +import ( + "fmt" + "github.com/dimkr/tootik/ap" + "github.com/stretchr/testify/assert" + "strings" + "testing" + "time" +) + +var avatar = []byte("\x47\x49\x46\x38\x37\x61\x10\x00\x10\x00\xf0\x00\x00\x00\x00\x00\xff\x00\x00\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00\x02\x1e\x8c\x8f\xa9\xab\xe0\x0f\x1d\x8a\x14\xcc\x0a\x2f\x96\x67\x3f\xbd\x81\x98\x58\x91\x94\x19\xa1\x59\xe7\x59\xcc\x0b\x2b\x05\x00\x3b") + +func TestAvatar_HappyFlow(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) +} + +func TestAvatar_NewUser(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published = &ap.Time{Time: time.Now().Add(-time.Second * 5)} + assert.Equal("40 Please try again later\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) +} + +func TestAvatar_ChangedRecently(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + server.Alice.Updated = &ap.Time{Time: time.Now().Add(-time.Second * 5)} + assert.Equal("40 Please try again later\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) +} + +func TestAvatar_HappyFlowSizeFirst(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/upload/avatar;size=63;mime=image/gif", server.Alice, avatar)) +} + +func TestAvatar_InvalidSize(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Invalid size\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=abc", server.Alice, avatar)) +} + +func TestAvatar_InvalidType(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Unsupported image type\r\n", server.Upload("/users/upload/avatar;mime=text/plain;size=63", server.Alice, avatar)) +} + +func TestAvatar_NoSize(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;ize=63", server.Alice, avatar)) +} + +func TestAvatar_NoType(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mim=image/gif;size=63", server.Alice, avatar)) +} + +func TestAvatar_InvalidImage(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=3", server.Alice, []byte("abc"))) +} + +func TestAvatar_TooSmallSize(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=10", server.Alice, avatar)) +} + +func TestAvatar_TooBigSize(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + assert.Equal("40 Error\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=64", server.Alice, avatar)) +} + +func TestAvatar_SizeLimit(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + server.cfg.MaxAvatarSize = 62 + assert.Equal("40 Image is too big\r\n", server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) +} + +func TestAvatar_ExactlySizeLimit(t *testing.T) { + server := newTestServer() + defer server.Shutdown() + + assert := assert.New(t) + + server.Alice.Published.Time = server.Alice.Published.Time.Add(-time.Hour) + server.cfg.MaxAvatarSize = 63 + assert.Equal(fmt.Sprintf("30 gemini://localhost.localdomain:8443/users/outbox/%s\r\n", strings.TrimPrefix(server.Alice.ID, "https://")), server.Upload("/users/upload/avatar;mime=image/gif;size=63", server.Alice, avatar)) +} diff --git a/test/server.go b/test/server.go index 1bee20fb..5224d7d1 100644 --- a/test/server.go +++ b/test/server.go @@ -121,7 +121,20 @@ func (s *server) Handle(request string, user *ap.Actor) string { var buf bytes.Buffer var wg sync.WaitGroup - s.handler.Handle(context.Background(), slog.Default(), gmi.Wrap(&buf), u, user, httpsig.Key{}, s.db, fed.NewResolver(nil, domain, s.cfg, &http.Client{}), &wg) + s.handler.Handle(context.Background(), slog.Default(), nil, gmi.Wrap(&buf), u, user, httpsig.Key{}, s.db, fed.NewResolver(nil, domain, s.cfg, &http.Client{}), &wg) + + return buf.String() +} + +func (s *server) Upload(request string, user *ap.Actor, body []byte) string { + u, err := url.Parse(request) + if err != nil { + panic(err) + } + + var buf bytes.Buffer + var wg sync.WaitGroup + s.handler.Handle(context.Background(), slog.Default(), bytes.NewBuffer(body), gmi.Wrap(&buf), u, user, httpsig.Key{}, s.db, fed.NewResolver(nil, domain, s.cfg, &http.Client{}), &wg) return buf.String() }