You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
memos/server/router/api/v1/test/memo_service_test.go

253 lines
8.3 KiB
Go

package v1
import (
"context"
"fmt"
"slices"
"testing"
"github.com/stretchr/testify/require"
apiv1 "github.com/usememos/memos/proto/gen/api/v1"
)
func TestListMemos(t *testing.T) {
ctx := context.Background()
ts := NewTestService(t)
defer ts.Cleanup()
// Create userOne
userOne, err := ts.CreateRegularUser(ctx, "test-user-1")
require.NoError(t, err)
require.NotNil(t, userOne)
// Create userOne context
userOneCtx := ts.CreateUserContext(ctx, userOne.ID)
// Create userTwo
userTwo, err := ts.CreateRegularUser(ctx, "test-user-2")
require.NoError(t, err)
require.NotNil(t, userTwo)
// Create userTwo context
userTwoCtx := ts.CreateUserContext(ctx, userTwo.ID)
// Create attachmentOne by userOne
attachmentOne, err := ts.Service.CreateAttachment(userOneCtx, &apiv1.CreateAttachmentRequest{
Attachment: &apiv1.Attachment{
Name: "",
Filename: "hello.txt",
Size: 5,
Type: "text/plain",
Content: []byte{
104, 101, 108, 108, 111,
},
},
})
require.NoError(t, err)
require.NotNil(t, attachmentOne)
// Create attachmentTwo by userOne
attachmentTwo, err := ts.Service.CreateAttachment(userOneCtx, &apiv1.CreateAttachmentRequest{
Attachment: &apiv1.Attachment{
Name: "",
Filename: "world.txt",
Size: 5,
Type: "text/plain",
Content: []byte{
119, 111, 114, 108, 100,
},
},
})
require.NoError(t, err)
require.NotNil(t, attachmentTwo)
// Create memoOne with two attachments by userOne
memoOne, err := ts.Service.CreateMemo(userOneCtx, &apiv1.CreateMemoRequest{
Memo: &apiv1.Memo{
Content: "Hellooo, any words after this sentence won't be in the snippet. This is the next sentence. And I also have two attachments.",
Visibility: apiv1.Visibility_PROTECTED,
Attachments: []*apiv1.Attachment{
&apiv1.Attachment{
Name: attachmentOne.Name,
},
&apiv1.Attachment{
Name: attachmentTwo.Name,
},
},
},
})
require.NoError(t, err)
require.NotNil(t, memoOne)
// Create memoTwo by userTwo referencing memoOne
memoTwo, err := ts.Service.CreateMemo(userTwoCtx, &apiv1.CreateMemoRequest{
Memo: &apiv1.Memo{
Content: "This is a memo reminding you to check the attachment attached to memoOne. I have referenced the memo below.⬇️",
Visibility: apiv1.Visibility_PROTECTED,
Relations: []*apiv1.MemoRelation{
&apiv1.MemoRelation{
RelatedMemo: &apiv1.MemoRelation_Memo{
Name: memoOne.Name,
},
},
},
},
})
require.NoError(t, err)
require.NotNil(t, memoTwo)
// Create memoThree by userOne
memoThree, err := ts.Service.CreateMemo(userOneCtx, &apiv1.CreateMemoRequest{
Memo: &apiv1.Memo{
Content: "This is a very popular memo. I have 2 reactions!",
Visibility: apiv1.Visibility_PROTECTED,
},
})
require.NoError(t, err)
require.NotNil(t, memoThree)
// Create reaction from userOne on memoThree
reactionOne, err := ts.Service.UpsertMemoReaction(userOneCtx, &apiv1.UpsertMemoReactionRequest{
Name: memoThree.Name,
Reaction: &apiv1.Reaction{
ContentId: memoThree.Name,
ReactionType: "❤️",
},
})
require.NoError(t, err)
require.NotNil(t, reactionOne)
// Create reaction from userTwo on memoThree
reactionTwo, err := ts.Service.UpsertMemoReaction(userTwoCtx, &apiv1.UpsertMemoReactionRequest{
Name: memoThree.Name,
Reaction: &apiv1.Reaction{
ContentId: memoThree.Name,
ReactionType: "👍",
},
})
require.NoError(t, err)
require.NotNil(t, reactionTwo)
memos, err := ts.Service.ListMemos(userOneCtx, &apiv1.ListMemosRequest{PageSize: 10})
require.NoError(t, err)
require.NotNil(t, memos)
require.Equal(t, 3, len(memos.Memos))
// ///////////////
// VERIFY MEMO ONE
// ///////////////
memoOneResIdx := slices.IndexFunc(memos.Memos, func(m *apiv1.Memo) bool { return m.GetName() == memoOne.GetName() })
require.NotEqual(t, memoOneResIdx, -1)
memoOneRes := memos.Memos[memoOneResIdx]
require.NotNil(t, memoOneRes)
require.Equal(t, fmt.Sprintf("users/%d", userOne.ID), memoOneRes.GetCreator())
require.Equal(t, apiv1.Visibility_PROTECTED, memoOneRes.GetVisibility())
require.Equal(t, memoOne.Content, memoOneRes.GetContent())
require.Equal(t, memoOne.Content[:64]+"...", memoOneRes.GetSnippet(), "memoOne's content is snipped past the 64 char limit")
require.Len(t, memoOneRes.Attachments, 2)
require.Len(t, memoOneRes.Relations, 1)
require.Empty(t, memoOneRes.Reactions)
// verify memoOne's attachments
// attachment one
attachmentOneResIdx := slices.IndexFunc(memoOneRes.Attachments, func(a *apiv1.Attachment) bool { return a.GetName() == attachmentOne.GetName() })
require.NotEqual(t, attachmentOneResIdx, -1)
attachmentOneRes := memoOneRes.Attachments[attachmentOneResIdx]
require.NotNil(t, attachmentOneRes)
require.Equal(t, attachmentOne.GetName(), attachmentOneRes.GetName())
require.Equal(t, attachmentOne.GetContent(), attachmentOneRes.GetContent())
// attachment two
attachmentTwoResIdx := slices.IndexFunc(memoOneRes.Attachments, func(a *apiv1.Attachment) bool { return a.GetName() == attachmentTwo.GetName() })
require.NotEqual(t, attachmentTwoResIdx, -1)
attachmentTwoRes := memoOneRes.Attachments[attachmentTwoResIdx]
require.NotNil(t, attachmentTwoRes)
require.Equal(t, attachmentTwo.GetName(), attachmentTwoRes.GetName())
require.Equal(t, attachmentTwo.GetName(), attachmentTwoRes.GetName())
require.Equal(t, attachmentTwo.GetContent(), attachmentTwoRes.GetContent())
// verify memoOne's relations
require.Len(t, memoOneRes.Relations, 1)
memoOneExpectedRelation := &apiv1.MemoRelation{
Memo: &apiv1.MemoRelation_Memo{Name: memoTwo.GetName()},
RelatedMemo: &apiv1.MemoRelation_Memo{Name: memoOne.GetName()},
}
require.Equal(t, memoOneExpectedRelation.Memo.GetName(), memoOneRes.Relations[0].Memo.GetName())
require.Equal(t, memoOneExpectedRelation.RelatedMemo.GetName(), memoOneRes.Relations[0].RelatedMemo.GetName())
// ///////////////
// VERIFY MEMO TWO
// ///////////////
memoTwoResIdx := slices.IndexFunc(memos.Memos, func(m *apiv1.Memo) bool { return m.GetName() == memoTwo.GetName() })
require.NotEqual(t, memoTwoResIdx, -1)
memoTwoRes := memos.Memos[memoTwoResIdx]
require.NotNil(t, memoTwoRes)
require.Equal(t, fmt.Sprintf("users/%d", userTwo.ID), memoTwoRes.GetCreator())
require.Equal(t, apiv1.Visibility_PROTECTED, memoTwoRes.GetVisibility())
require.Equal(t, memoTwo.Content, memoTwoRes.GetContent())
require.Empty(t, memoTwoRes.Attachments)
require.Len(t, memoTwoRes.Relations, 1)
require.Empty(t, memoTwoRes.Reactions)
// verify memoTwo's relations
require.Len(t, memoTwoRes.Relations, 1)
memoTwoExpectedRelation := &apiv1.MemoRelation{
Memo: &apiv1.MemoRelation_Memo{Name: memoTwo.GetName()},
RelatedMemo: &apiv1.MemoRelation_Memo{Name: memoOne.GetName()},
}
require.Equal(t, memoTwoExpectedRelation.Memo.GetName(), memoTwoRes.Relations[0].Memo.GetName())
require.Equal(t, memoTwoExpectedRelation.RelatedMemo.GetName(), memoTwoRes.Relations[0].RelatedMemo.GetName())
// ///////////////
// VERIFY MEMO THREE
// ///////////////
memoThreeResIdx := slices.IndexFunc(memos.Memos, func(m *apiv1.Memo) bool { return m.GetName() == memoThree.GetName() })
require.NotEqual(t, memoThreeResIdx, -1)
memoThreeRes := memos.Memos[memoThreeResIdx]
require.NotNil(t, memoThreeRes)
require.Equal(t, fmt.Sprintf("users/%d", userOne.ID), memoThreeRes.GetCreator())
require.Equal(t, apiv1.Visibility_PROTECTED, memoThreeRes.GetVisibility())
require.Equal(t, memoThree.Content, memoThreeRes.GetContent())
require.Empty(t, memoThreeRes.Attachments)
require.Empty(t, memoThreeRes.Relations)
require.Len(t, memoThreeRes.Reactions, 2)
// verify memoThree's reactions
require.Len(t, memoThreeRes.Reactions, 2)
// userOne's reaction
userOneReactionIdx := slices.IndexFunc(memoThreeRes.Reactions, func(r *apiv1.Reaction) bool { return r.GetCreator() == fmt.Sprintf("users/%d", userOne.ID) })
require.NotEqual(t, userOneReactionIdx, -1)
userOneReaction := memoThreeRes.Reactions[userOneReactionIdx]
require.NotNil(t, userOneReaction)
require.Equal(t, "❤️", userOneReaction.ReactionType)
// userTwo's reaction
userTwoReactionIdx := slices.IndexFunc(memoThreeRes.Reactions, func(r *apiv1.Reaction) bool { return r.GetCreator() == fmt.Sprintf("users/%d", userTwo.ID) })
require.NotEqual(t, userTwoReactionIdx, -1)
userTwoReaction := memoThreeRes.Reactions[userTwoReactionIdx]
require.NotNil(t, userTwoReaction)
require.Equal(t, "👍", userTwoReaction.ReactionType)
}