memos/server/router/api/v1/memo_create_helpers_test.go

147 lines
5.9 KiB
Go

package v1
import (
"context"
"fmt"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
v1pb "github.com/usememos/memos/proto/gen/api/v1"
"github.com/usememos/memos/store"
)
func TestMemoCreateSharedPreparationPreservesFields(t *testing.T) {
ctx := context.Background()
service := newIntegrationService(t)
user := createSpaceTestUser(ctx, t, service, "memo-create-fields", store.RoleUser)
userCtx := userCtx(ctx, user.ID)
referenceTarget, err := service.CreateMemo(userCtx, &v1pb.CreateMemoRequest{
MemoId: "create-fields-reference",
Memo: &v1pb.Memo{Content: "reference target", Visibility: v1pb.Visibility_PRIVATE},
})
require.NoError(t, err)
createAttachment := func(id string) *v1pb.Attachment {
t.Helper()
attachment, err := service.CreateAttachment(userCtx, &v1pb.CreateAttachmentRequest{
AttachmentId: id,
Attachment: &v1pb.Attachment{
Filename: id + ".png",
Type: "image/png",
Content: []byte("test image"),
},
})
require.NoError(t, err)
return attachment
}
createReference := func() *v1pb.MemoRelation {
return &v1pb.MemoRelation{
RelatedMemo: &v1pb.MemoRelation_Memo{Name: referenceTarget.Name},
Type: v1pb.MemoRelation_REFERENCE,
}
}
topAttachment := createAttachment("create-fields-top-image")
topAttachmentUID := strings.TrimPrefix(topAttachment.Name, "attachments/")
topCreateTime := time.Date(2022, time.March, 4, 5, 6, 7, 0, time.UTC)
topUpdateTime := topCreateTime.Add(2 * time.Hour)
topLocation := &v1pb.Location{Placeholder: "top location", Latitude: 1.25, Longitude: 2.5}
topMemo, err := service.CreateMemo(userCtx, &v1pb.CreateMemoRequest{
MemoId: "create-fields-top",
Memo: &v1pb.Memo{
Content: fmt.Sprintf("![top](/file/attachments/%s)", topAttachmentUID),
Visibility: v1pb.Visibility_PRIVATE,
CreateTime: timestamppb.New(topCreateTime),
UpdateTime: timestamppb.New(topUpdateTime),
Attachments: []*v1pb.Attachment{{Name: topAttachment.Name}},
Relations: []*v1pb.MemoRelation{createReference()},
Location: topLocation,
},
})
require.NoError(t, err)
require.Equal(t, topCreateTime.Unix(), topMemo.CreateTime.AsTime().Unix())
require.Equal(t, topUpdateTime.Unix(), topMemo.UpdateTime.AsTime().Unix())
require.Equal(t, topLocation.Placeholder, topMemo.Location.Placeholder)
require.Equal(t, topLocation.Latitude, topMemo.Location.Latitude)
require.Equal(t, topLocation.Longitude, topMemo.Location.Longitude)
require.Len(t, topMemo.Attachments, 1)
require.Equal(t, topAttachment.Name, topMemo.Attachments[0].Name)
requireMemoCreateRelation(t, topMemo, v1pb.MemoRelation_REFERENCE, referenceTarget.Name)
commentAttachment := createAttachment("create-fields-comment-image")
commentAttachmentUID := strings.TrimPrefix(commentAttachment.Name, "attachments/")
commentCreateTime := time.Date(2023, time.April, 5, 6, 7, 8, 0, time.UTC)
commentUpdateTime := commentCreateTime.Add(3 * time.Hour)
commentLocation := &v1pb.Location{Placeholder: "comment location", Latitude: 3.75, Longitude: 4.5}
comment, err := service.CreateMemoComment(userCtx, &v1pb.CreateMemoCommentRequest{
Name: topMemo.Name,
CommentId: "create-fields-comment",
Comment: &v1pb.Memo{
Content: fmt.Sprintf("![comment](/file/attachments/%s)", commentAttachmentUID),
Visibility: v1pb.Visibility_PROTECTED,
CreateTime: timestamppb.New(commentCreateTime),
UpdateTime: timestamppb.New(commentUpdateTime),
Attachments: []*v1pb.Attachment{{Name: commentAttachment.Name}},
Relations: []*v1pb.MemoRelation{createReference()},
Location: commentLocation,
},
})
require.NoError(t, err)
require.Equal(t, commentCreateTime.Unix(), comment.CreateTime.AsTime().Unix())
require.Equal(t, commentUpdateTime.Unix(), comment.UpdateTime.AsTime().Unix())
require.Equal(t, commentLocation.Placeholder, comment.Location.Placeholder)
require.Equal(t, commentLocation.Latitude, comment.Location.Latitude)
require.Equal(t, commentLocation.Longitude, comment.Location.Longitude)
require.Equal(t, v1pb.Visibility_PROTECTED, comment.Visibility)
require.Len(t, comment.Attachments, 1)
require.Equal(t, commentAttachment.Name, comment.Attachments[0].Name)
requireMemoCreateRelation(t, comment, v1pb.MemoRelation_COMMENT, topMemo.Name)
requireMemoCreateRelation(t, comment, v1pb.MemoRelation_REFERENCE, referenceTarget.Name)
}
func TestMemoCreateDuplicateIDsUseAlreadyExists(t *testing.T) {
ctx := context.Background()
service := newIntegrationService(t)
user := createSpaceTestUser(ctx, t, service, "memo-create-duplicates", store.RoleUser)
userCtx := userCtx(ctx, user.ID)
parent, err := service.CreateMemo(userCtx, &v1pb.CreateMemoRequest{
MemoId: "duplicate-parent",
Memo: &v1pb.Memo{Content: "parent", Visibility: v1pb.Visibility_PRIVATE},
})
require.NoError(t, err)
_, err = service.CreateMemo(userCtx, &v1pb.CreateMemoRequest{
MemoId: "duplicate-parent",
Memo: &v1pb.Memo{Content: "duplicate", Visibility: v1pb.Visibility_PRIVATE},
})
require.Equal(t, codes.AlreadyExists, status.Code(err))
createComment := func() error {
_, err := service.CreateMemoComment(userCtx, &v1pb.CreateMemoCommentRequest{
Name: parent.Name,
CommentId: "duplicate-comment",
Comment: &v1pb.Memo{Content: "comment", Visibility: v1pb.Visibility_PRIVATE},
})
return err
}
require.NoError(t, createComment())
require.Equal(t, codes.AlreadyExists, status.Code(createComment()))
}
func requireMemoCreateRelation(t *testing.T, memo *v1pb.Memo, relationType v1pb.MemoRelation_Type, relatedMemoName string) {
t.Helper()
for _, relation := range memo.Relations {
if relation.Type == relationType && relation.GetRelatedMemo().GetName() == relatedMemoName {
require.Equal(t, memo.Name, relation.GetMemo().GetName())
return
}
}
require.Failf(t, "memo relation not found", "missing %s relation from %s to %s", relationType, memo.Name, relatedMemoName)
}