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