mirror of
https://github.com/mattermost/mattermost.git
synced 2026-04-13 04:57:45 -04:00
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Mattermost Build <build@mattermost.com>
247 lines
5.3 KiB
Go
247 lines
5.3 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package model
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestMessageAttachment_IsValid(t *testing.T) {
|
|
tests := map[string]struct {
|
|
attachment *MessageAttachment
|
|
wantErr string
|
|
}{
|
|
"valid attachment": {
|
|
attachment: &MessageAttachment{
|
|
Text: "This is a test",
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"invalid color": {
|
|
attachment: &MessageAttachment{
|
|
Color: "invalid",
|
|
},
|
|
wantErr: "invalid style 'invalid' - must be one of [good, warning, danger] or a hex color",
|
|
},
|
|
"valid predefined color": {
|
|
attachment: &MessageAttachment{
|
|
Color: "good",
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"valid warning color": {
|
|
attachment: &MessageAttachment{
|
|
Color: "warning",
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"valid danger color": {
|
|
attachment: &MessageAttachment{
|
|
Color: "danger",
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"valid hex color": {
|
|
attachment: &MessageAttachment{
|
|
Color: "#FF0000",
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"author link without name": {
|
|
attachment: &MessageAttachment{
|
|
AuthorLink: "http://example.com",
|
|
},
|
|
wantErr: "author link cannot be set without author name",
|
|
},
|
|
"invalid author link": {
|
|
attachment: &MessageAttachment{
|
|
AuthorName: "Author",
|
|
AuthorLink: "invalid-url",
|
|
},
|
|
wantErr: "invalid author link URL",
|
|
},
|
|
"invalid author icon": {
|
|
attachment: &MessageAttachment{
|
|
AuthorIcon: "invalid-url",
|
|
},
|
|
wantErr: "invalid author icon URL",
|
|
},
|
|
"title link without title": {
|
|
attachment: &MessageAttachment{
|
|
TitleLink: "http://example.com",
|
|
},
|
|
wantErr: "title link cannot be set without title",
|
|
},
|
|
"invalid title link": {
|
|
attachment: &MessageAttachment{
|
|
Title: "Title",
|
|
TitleLink: "invalid-url",
|
|
},
|
|
wantErr: "invalid title link URL",
|
|
},
|
|
"invalid image URL": {
|
|
attachment: &MessageAttachment{
|
|
ImageURL: "invalid-url",
|
|
},
|
|
wantErr: "invalid image URL",
|
|
},
|
|
"invalid thumb URL": {
|
|
attachment: &MessageAttachment{
|
|
ThumbURL: "invalid-url",
|
|
},
|
|
wantErr: "invalid thumb URL",
|
|
},
|
|
"invalid footer icon": {
|
|
attachment: &MessageAttachment{
|
|
FooterIcon: "invalid-url",
|
|
},
|
|
wantErr: "invalid footer icon URL",
|
|
},
|
|
"invalid timestamp type": {
|
|
attachment: &MessageAttachment{
|
|
Timestamp: []string{"invalid"},
|
|
},
|
|
wantErr: "timestamp must be either a string or int64",
|
|
},
|
|
"valid timestamp string": {
|
|
attachment: &MessageAttachment{
|
|
Timestamp: "1234567890",
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"valid timestamp int64": {
|
|
attachment: &MessageAttachment{
|
|
Timestamp: int64(1234567890),
|
|
},
|
|
wantErr: "",
|
|
},
|
|
"invalid action": {
|
|
attachment: &MessageAttachment{
|
|
Actions: []*PostAction{
|
|
{
|
|
Name: "", // Invalid - missing name
|
|
},
|
|
},
|
|
},
|
|
wantErr: "action must have a name",
|
|
},
|
|
"invalid field value type": {
|
|
attachment: &MessageAttachment{
|
|
Fields: []*MessageAttachmentField{
|
|
{
|
|
Title: "Title",
|
|
Value: []string{"invalid"},
|
|
},
|
|
},
|
|
},
|
|
wantErr: "value must be either a string or int",
|
|
},
|
|
"valid fields": {
|
|
attachment: &MessageAttachment{
|
|
Fields: []*MessageAttachmentField{
|
|
{
|
|
Title: "Title",
|
|
Value: "string value",
|
|
},
|
|
{
|
|
Title: "Number",
|
|
Value: 42,
|
|
},
|
|
},
|
|
},
|
|
wantErr: "",
|
|
},
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
err := tc.attachment.IsValid()
|
|
if tc.wantErr == "" {
|
|
assert.NoError(t, err, name)
|
|
} else {
|
|
assert.ErrorContains(t, err, tc.wantErr, name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseMessageAttachment(t *testing.T) {
|
|
t.Run("empty list", func(t *testing.T) {
|
|
post := &Post{}
|
|
attachments := []*MessageAttachment{}
|
|
|
|
ParseMessageAttachment(post, attachments)
|
|
|
|
expectedPost := &Post{
|
|
Type: PostTypeMessageAttachment,
|
|
Props: map[string]any{
|
|
PostPropsAttachments: []*MessageAttachment{},
|
|
},
|
|
}
|
|
assert.Equal(t, expectedPost, post)
|
|
})
|
|
|
|
t.Run("list with nil", func(t *testing.T) {
|
|
post := &Post{}
|
|
attachments := []*MessageAttachment{
|
|
nil,
|
|
}
|
|
|
|
ParseMessageAttachment(post, attachments)
|
|
|
|
expectedPost := &Post{
|
|
Type: PostTypeMessageAttachment,
|
|
Props: map[string]any{
|
|
PostPropsAttachments: []*MessageAttachment{},
|
|
},
|
|
}
|
|
assert.Equal(t, expectedPost, post)
|
|
})
|
|
}
|
|
|
|
func TestMessageAttachment_Equals_PrimitiveAndNonPrimitiveField(t *testing.T) {
|
|
// Field with primitive type (string)
|
|
attachment1 := &MessageAttachment{
|
|
Fields: []*MessageAttachmentField{
|
|
{
|
|
Title: "Field1",
|
|
Value: "value",
|
|
Short: true,
|
|
},
|
|
},
|
|
}
|
|
attachment2 := &MessageAttachment{
|
|
Fields: []*MessageAttachmentField{
|
|
{
|
|
Title: "Field1",
|
|
Value: "value",
|
|
Short: true,
|
|
},
|
|
},
|
|
}
|
|
assert.True(t, attachment1.Equals(attachment2), "Attachments with identical primitive field values should be equal")
|
|
|
|
// Field with non-primitive type ([]interface{})
|
|
attachment3 := &MessageAttachment{
|
|
Fields: []*MessageAttachmentField{
|
|
{
|
|
Title: "Field1",
|
|
Value: []any{"value", 2},
|
|
Short: true,
|
|
},
|
|
},
|
|
}
|
|
attachment4 := &MessageAttachment{
|
|
Fields: []*MessageAttachmentField{
|
|
{
|
|
Title: "Field1",
|
|
Value: []any{"value", 2},
|
|
Short: true,
|
|
},
|
|
},
|
|
}
|
|
assert.True(t, attachment3.Equals(attachment4), "Attachments with identical non-primitive ([]interface{}) field values should be equal")
|
|
}
|