post_test.gno
9.70 Kb · 385 lines
1package boards2
2
3import (
4 "std"
5 "strings"
6 "testing"
7
8 "gno.land/p/nt/testutils"
9 "gno.land/p/nt/uassert"
10 "gno.land/p/nt/ufmt"
11)
12
13func TestPostFlag(t *testing.T) {
14 addr := testutils.TestAddress("creator")
15 post := createTestThread(t)
16
17 uassert.True(t, post.Flag(addr, "foo"))
18 uassert.False(t, post.Flag(addr, "foo"), "should reject flag from duplicate user")
19 uassert.Equal(t, post.FlagsCount(), 1)
20}
21
22func TestPostRepost(t *testing.T) {
23 // TODO: Improve this unit test
24 addr := testutils.TestAddress("creatorDstBoard")
25 perms := createBasicBoardPermissions(addr)
26 cases := []struct {
27 name, title, body string
28 dstBoard *Board
29 thread *Post
30 setup func() *Post
31 err string
32 }{
33 {
34 name: "repost thread",
35 title: "Repost Title",
36 body: "Repost body",
37 dstBoard: newBoard(42, "dst123", addr, perms),
38 setup: func() *Post { return createTestThread(t) },
39 },
40 {
41 name: "invalid repost from reply",
42 setup: func() *Post { return createTestReply(t) },
43 err: "post must be a thread to be reposted to another board",
44 },
45 }
46
47 for _, tc := range cases {
48 t.Run(tc.name, func(t *testing.T) {
49 var (
50 repost *Post
51 creator = testutils.TestAddress("repostCreator")
52 thread = tc.setup()
53 )
54
55 createRepost := func() {
56 repost = thread.Repost(creator, tc.dstBoard, tc.title, tc.body)
57 }
58
59 if tc.err != "" {
60 uassert.PanicsWithMessage(t, tc.err, createRepost)
61 return
62 } else {
63 uassert.NotPanics(t, createRepost)
64 }
65
66 r, found := tc.dstBoard.GetThread(repost.ID)
67 uassert.True(t, found)
68 uassert.True(t, repost == r)
69 uassert.Equal(t, tc.title, repost.Title)
70 uassert.Equal(t, tc.body, repost.Body)
71 uassert.Equal(t, uint(thread.Board.ID), uint(repost.RepostBoardID))
72 })
73 }
74}
75
76func TestNewThread(t *testing.T) {
77 testing.SetRealm(std.NewCodeRealm("gno.land/r/gnoland/boards2/v1"))
78
79 creator := testutils.TestAddress("creator")
80 title := "Test Title"
81 body := strings.Repeat("A", 82)
82 boardID := BoardID(1)
83 threadID := PostID(42)
84 boardName := "test123"
85 perms := createBasicBoardPermissions(creator)
86 board := newBoard(boardID, boardName, creator, perms)
87 url := ufmt.Sprintf(
88 "/r/gnoland/boards2/v1:%s/%d",
89 boardName,
90 uint(threadID),
91 )
92 replyURL := ufmt.Sprintf(
93 "/r/gnoland/boards2/v1$help&func=CreateReply&boardID=%d&body=&replyID=0&threadID=%d",
94 uint(boardID),
95 uint(threadID),
96 )
97 editURL := ufmt.Sprintf(
98 "/r/gnoland/boards2/v1$help&func=EditThread&boardID=%d&body=%s&threadID=%d&title=%s",
99 uint(boardID),
100 body,
101 uint(threadID),
102 strings.ReplaceAll(title, " ", "+"),
103 )
104 repostURL := ufmt.Sprintf(
105 "/r/gnoland/boards2/v1$help&func=CreateRepost&boardID=%d&body=&destinationBoardID=&threadID=%d&title=",
106 uint(boardID),
107 uint(threadID),
108 )
109 deleteURL := ufmt.Sprintf(
110 "/r/gnoland/boards2/v1$help&func=DeleteThread&boardID=%d&threadID=%d",
111 uint(boardID),
112 uint(threadID),
113 )
114 flagURL := ufmt.Sprintf(
115 "/r/gnoland/boards2/v1$help&func=FlagThread&boardID=%d&reason=&threadID=%d",
116 uint(boardID),
117 uint(threadID),
118 )
119
120 thread := newPost(board, threadID, threadID, creator, title, body)
121
122 uassert.True(t, thread.IsThread())
123 uassert.Equal(t, uint(threadID), uint(thread.ID))
124 uassert.False(t, thread.CreatedAt().IsZero())
125 uassert.True(t, thread.UpdatedAt.IsZero())
126 uassert.Equal(t, title, thread.Title)
127 uassert.Equal(t, body[:77]+"...", thread.Summary())
128 uassert.False(t, thread.HasReplies())
129 uassert.Equal(t, url, makeThreadURI(thread))
130 uassert.Equal(t, replyURL, makeCreateReplyURI(thread))
131 uassert.Equal(t, editURL, makeEditPostURI(thread))
132 uassert.Equal(t, repostURL, makeCreateRepostURI(thread))
133 uassert.Equal(t, deleteURL, makeDeletePostURI(thread))
134 uassert.Equal(t, flagURL, makeFlagURI(thread))
135}
136
137func TestThreadAddReply(t *testing.T) {
138 replier := testutils.TestAddress("replier")
139 thread := createTestThread(t)
140 threadID := uint(thread.ID)
141 body := "A reply"
142
143 reply := thread.AddReply(replier, body)
144
145 r, found := thread.GetReply(reply.ID)
146 uassert.True(t, found)
147 uassert.True(t, reply == r)
148 uassert.Equal(t, threadID+1, uint(reply.ID))
149 uassert.Equal(t, reply.Creator, replier)
150 uassert.Equal(t, reply.Body, body)
151 uassert.True(t, thread.HasReplies())
152}
153
154func TestThreadGetReply(t *testing.T) {
155 cases := []struct {
156 name string
157 thread *Post
158 setup func(thread *Post) (replyID PostID)
159 found bool
160 }{
161 {
162 name: "found",
163 thread: createTestThread(t),
164 setup: func(thread *Post) PostID {
165 reply := thread.AddReply(testutils.TestAddress("replier"), "")
166 return reply.ID
167 },
168 found: true,
169 },
170 {
171 name: "not found",
172 thread: createTestThread(t),
173 setup: func(*Post) PostID { return 42 },
174 },
175 }
176
177 for _, tc := range cases {
178 t.Run(tc.name, func(t *testing.T) {
179 replyID := tc.setup(tc.thread)
180
181 reply, found := tc.thread.GetReply(replyID)
182
183 uassert.Equal(t, tc.found, found)
184 if reply != nil {
185 uassert.Equal(t, uint(replyID), uint(reply.ID))
186 }
187 })
188 }
189}
190
191func TestThreadDeleteReply(t *testing.T) {
192 thread := createTestThread(t)
193 cases := []struct {
194 name string
195 setup func() PostID
196 err string
197 }{
198 {
199 name: "ok",
200 setup: func() PostID {
201 reply := thread.AddReply(testutils.TestAddress("replier"), "")
202 return reply.ID
203 },
204 },
205 {
206 name: "ok nested",
207 setup: func() PostID {
208 reply := thread.AddReply(testutils.TestAddress("replier"), "")
209 return reply.AddReply(testutils.TestAddress("replier2"), "").ID
210 },
211 },
212 {
213 name: "invalid",
214 setup: func() PostID { return thread.ID },
215 err: "expected an ID of an inner reply",
216 },
217 {
218 name: "not found",
219 setup: func() PostID { return 42 },
220 err: "reply not found in thread",
221 },
222 }
223
224 for _, tc := range cases {
225 t.Run(tc.name, func(t *testing.T) {
226 replyID := tc.setup()
227
228 err := thread.DeleteReply(replyID)
229
230 if tc.err != "" {
231 uassert.ErrorContains(t, err, tc.err)
232 return
233 }
234
235 uassert.NoError(t, err)
236 _, found := thread.GetReply(replyID)
237 uassert.False(t, found)
238 })
239 }
240}
241
242func TestThreadRenderSummary(t *testing.T) {
243 t.Skip("TODO: implement")
244}
245
246func TestThreadRender(t *testing.T) {
247 t.Skip("TODO: implement")
248}
249
250func TestThreadRenderInner(t *testing.T) {
251 t.Skip("TODO: implement")
252}
253
254func TestNewReply(t *testing.T) {
255 testing.SetRealm(std.NewCodeRealm("gno.land/r/gnoland/boards2/v1"))
256
257 creator := testutils.TestAddress("creator")
258 body := strings.Repeat("A", 82)
259 boardID := BoardID(1)
260 threadID := PostID(42)
261 parentID := PostID(1)
262 replyID := PostID(2)
263 boardName := "test123"
264 perms := createBasicBoardPermissions(creator)
265 board := newBoard(boardID, boardName, creator, perms)
266 url := ufmt.Sprintf(
267 "/r/gnoland/boards2/v1:%s/%d/%d",
268 boardName,
269 uint(threadID),
270 uint(replyID),
271 )
272 replyURL := ufmt.Sprintf(
273 "/r/gnoland/boards2/v1$help&func=CreateReply&boardID=%d&body=&replyID=%d&threadID=%d",
274 uint(boardID),
275 uint(replyID),
276 uint(threadID),
277 )
278 deleteURL := ufmt.Sprintf(
279 "/r/gnoland/boards2/v1$help&func=DeleteReply&boardID=%d&replyID=%d&threadID=%d",
280 uint(boardID),
281 uint(replyID),
282 uint(threadID),
283 )
284
285 reply := newPost(board, threadID, replyID, creator, "", body)
286 reply.ParentID = parentID
287
288 uassert.False(t, reply.IsThread())
289 uassert.Equal(t, uint(replyID), uint(reply.ID))
290 uassert.False(t, reply.CreatedAt().IsZero())
291 uassert.True(t, reply.UpdatedAt.IsZero())
292 uassert.False(t, reply.HasReplies())
293 uassert.Equal(t, body[:77]+"...", reply.Summary())
294 uassert.Equal(t, url, makeReplyURI(reply))
295 uassert.Equal(t, replyURL, makeCreateReplyURI(reply))
296 uassert.Equal(t, deleteURL, makeDeletePostURI(reply))
297}
298
299func TestReplyAddReply(t *testing.T) {
300 replier := testutils.TestAddress("replier")
301 thread := createTestThread(t)
302 parentReply := thread.AddReply(testutils.TestAddress("parentReplier"), "")
303 parentReplyID := uint(parentReply.ID)
304 body := "A child reply"
305
306 reply := parentReply.AddReply(replier, body)
307
308 r, found := thread.GetReply(reply.ID)
309 uassert.True(t, found)
310 uassert.True(t, reply == r)
311 uassert.Equal(t, parentReplyID, uint(reply.ParentID))
312 uassert.Equal(t, parentReplyID+1, uint(reply.ID))
313 uassert.Equal(t, reply.Creator, replier)
314 uassert.Equal(t, reply.Body, body)
315 uassert.False(t, reply.HasReplies())
316 uassert.True(t, parentReply.HasReplies())
317}
318
319func TestReplyGetReply(t *testing.T) {
320 thread := createTestThread(t)
321 parentReply := thread.AddReply(testutils.TestAddress("parentReplier"), "")
322 cases := []struct {
323 name string
324 setup func() PostID
325 found bool
326 }{
327 {
328 name: "found",
329 setup: func() PostID {
330 reply := parentReply.AddReply(testutils.TestAddress("replier"), "")
331 return reply.ID
332 },
333 found: true,
334 },
335 {
336 name: "not found",
337 setup: func() PostID { return 42 },
338 },
339 }
340
341 for _, tc := range cases {
342 t.Run(tc.name, func(t *testing.T) {
343 replyID := tc.setup()
344
345 reply, found := thread.GetReply(replyID)
346
347 uassert.Equal(t, tc.found, found)
348 if reply != nil {
349 uassert.Equal(t, uint(replyID), uint(reply.ID))
350 }
351 })
352 }
353}
354
355func TestReplyDeleteReply(t *testing.T) {
356 thread := createTestThread(t)
357 parentReply := thread.AddReply(testutils.TestAddress("replier"), "")
358 reply := parentReply.AddReply(testutils.TestAddress("replier2"), "")
359
360 // NOTE: Deleting a reply from a parent reply should eventually be suported
361 uassert.PanicsWithMessage(t, "cannot delete reply from a non-thread post", func() {
362 parentReply.DeleteReply(reply.ID)
363 })
364}
365
366func TestReplyRender(t *testing.T) {
367 t.Skip("TODO: implement")
368}
369
370func createTestThread(t *testing.T) *Post {
371 t.Helper()
372
373 creator := testutils.TestAddress("creator")
374 perms := createBasicBoardPermissions(creator)
375 board := newBoard(1, "test_board_123", creator, perms)
376 return board.AddThread(creator, "Title", "Body")
377}
378
379func createTestReply(t *testing.T) *Post {
380 t.Helper()
381
382 creator := testutils.TestAddress("replier")
383 thread := createTestThread(t)
384 return thread.AddReply(creator, "Test message")
385}