diff --git a/server/channels/app/post_metadata_test.go b/server/channels/app/post_metadata_test.go index 39e1e322d7d..ce6a0ffc8a9 100644 --- a/server/channels/app/post_metadata_test.go +++ b/server/channels/app/post_metadata_test.go @@ -1806,7 +1806,8 @@ func TestGetEmojiNamesForPost(t *testing.T) { }, }, }, - Expected: []string{"smile", "coffee", "thumbsup", "rocket", "tada"}, + // Button labels are not included in Post.AllStrings (see model.TestPost_AllStrings_interactiveProps). + Expected: []string{"smile", "coffee", "rocket", "tada"}, }, } diff --git a/server/public/model/feature_flags_test.go b/server/public/model/feature_flags_test.go index 2ca3ca5808f..dcbbdc319de 100644 --- a/server/public/model/feature_flags_test.go +++ b/server/public/model/feature_flags_test.go @@ -54,7 +54,7 @@ func TestFeatureFlagsToMap(t *testing.T) { func TestFeatureFlagsMmBlocksEnabledDefault(t *testing.T) { var f FeatureFlags f.SetDefaults() - require.False(t, f.MmBlocksEnabled) + require.True(t, f.MmBlocksEnabled) require.Equal(t, "true", f.ToMap()["MmBlocksEnabled"]) } diff --git a/server/public/model/mm_blocks_actions_test.go b/server/public/model/mm_blocks_actions_test.go index a9308e5df66..af91edf7c9f 100644 --- a/server/public/model/mm_blocks_actions_test.go +++ b/server/public/model/mm_blocks_actions_test.go @@ -89,7 +89,7 @@ func TestPostGetMmBlocksActionSpec(t *testing.T) { "act1": map[string]any{ "type": MmBlocksActionTypeExternal, "url": "https://hooks.example.com/x?keep=yes", - "context": `{"k":"v"}`, + "context": map[string]any{"k": "v"}, "query": map[string]any{"a": "1", "keep": "no"}, }, "open1": map[string]any{ @@ -123,22 +123,6 @@ func TestPostGetMmBlocksActionSpec_encryptedProp(t *testing.T) { assert.Nil(t, p.GetMmBlocksActionSpec("any")) } -func TestPostGetMmBlocksActionSpec_mapContext(t *testing.T) { - p := &Post{} - p.SetProps(StringInterface{ - PostPropsMmBlocksActions: map[string]any{ - "act1": map[string]any{ - "type": MmBlocksActionTypeExternal, - "url": "https://hooks.example.com/x", - "context": map[string]any{"k": "v"}, - }, - }, - }) - spec := p.GetMmBlocksActionSpec("act1") - require.NotNil(t, spec) - assert.Equal(t, "v", spec.Context["k"]) -} - func TestMmBlocksActionCookie_ActionSpec(t *testing.T) { var nilCookie *MmBlocksActionCookie assert.Nil(t, nilCookie.ActionSpec("a")) @@ -195,7 +179,7 @@ func TestAddMmBlocksActionCookies_ReplacesWithEncryptedString(t *testing.T) { "a1": map[string]any{ "type": MmBlocksActionTypeExternal, "url": "https://example.com/hook?keep=1", - "context": `{"k":"v"}`, + "context": map[string]any{"k": "v"}, "query": map[string]any{"keep": "2", "a": "b"}, }, }, diff --git a/server/public/model/post.go b/server/public/model/post.go index c819ff1449f..c231d6194c3 100644 --- a/server/public/model/post.go +++ b/server/public/model/post.go @@ -732,27 +732,27 @@ func (o *Post) HasUnsafeLinks() bool { // It is intended for mention checks, search indexing, and similar uses alongside integration metadata. func (o *Post) AllStrings() []string { var out []string - appendTrimmedNonEmptyString(&out, o.Message) + appendNonWhitespaceOnlyMessage(&out, o.Message) for _, attachment := range o.Attachments() { if attachment == nil { continue } - appendTrimmedNonEmptyString(&out, attachment.AuthorName) - appendTrimmedNonEmptyString(&out, attachment.Title) - appendTrimmedNonEmptyString(&out, attachment.Text) - appendTrimmedNonEmptyString(&out, attachment.Pretext) - appendTrimmedNonEmptyString(&out, attachment.Footer) + appendNonWhitespaceOnlyMessage(&out, attachment.AuthorName) + appendNonWhitespaceOnlyMessage(&out, attachment.Title) + appendNonWhitespaceOnlyMessage(&out, attachment.Text) + appendNonWhitespaceOnlyMessage(&out, attachment.Pretext) + appendNonWhitespaceOnlyMessage(&out, attachment.Footer) for _, field := range attachment.Fields { if field == nil { continue } - appendTrimmedNonEmptyString(&out, field.Title) + appendNonWhitespaceOnlyMessage(&out, field.Title) if field.Value == nil { continue } switch v := field.Value.(type) { case string: - appendTrimmedNonEmptyString(&out, v) + appendNonWhitespaceOnlyMessage(&out, v) default: if s := strings.TrimSpace(fmt.Sprint(v)); s != "" { out = append(out, s) @@ -787,10 +787,11 @@ func (o *Post) InteractiveBlocksImageURLs() []string { return out } -func appendTrimmedNonEmptyString(out *[]string, s string) { - if t := strings.TrimSpace(s); t != "" { - *out = append(*out, t) +func appendNonWhitespaceOnlyMessage(out *[]string, s string) { + if strings.TrimSpace(s) == "" { + return } + *out = append(*out, s) } // nonEmptyInteractivePayloadPropKeys lists non-empty interactive payload props (mm_blocks, diff --git a/server/public/model/post_interactive_blocks.go b/server/public/model/post_interactive_blocks.go index 75a3883cec6..17d162d6338 100644 --- a/server/public/model/post_interactive_blocks.go +++ b/server/public/model/post_interactive_blocks.go @@ -52,7 +52,7 @@ func appendHumanStringsFromMmBlockMap(m map[string]any, out *[]string) { switch typ { case "text": if s, ok := m["text"].(string); ok { - appendTrimmedNonEmptyString(out, s) + appendNonWhitespaceOnlyMessage(out, s) } case "container": appendHumanStringsFromMmBlocksArray(m["content"], out) @@ -102,11 +102,13 @@ func appendHumanStringsFromBlockKitTree(v any, out *[]string) { switch typ { case "markdown": if s, ok := blockMap["text"].(string); ok { - appendTrimmedNonEmptyString(out, s) + appendNonWhitespaceOnlyMessage(out, s) } case "section": - if s, ok := blockMap["text"].(string); ok { - appendTrimmedNonEmptyString(out, s) + if textBlock, ok := blockMap["text"].(map[string]any); ok { + if s, ok := textBlock["text"].(string); ok { + appendNonWhitespaceOnlyMessage(out, s) + } } if fields, ok := blockMap["fields"].([]any); ok { for _, field := range fields { @@ -116,13 +118,13 @@ func appendHumanStringsFromBlockKitTree(v any, out *[]string) { } fieldText, ok := fieldMap["text"].(string) if ok { - appendTrimmedNonEmptyString(out, fieldText) + appendNonWhitespaceOnlyMessage(out, fieldText) } } } case "header": if s, ok := blockMap["text"].(string); ok { - appendTrimmedNonEmptyString(out, s) + appendNonWhitespaceOnlyMessage(out, s) } } } @@ -157,7 +159,7 @@ func appendHumanStringsFromAdaptiveCardsItem(item any, out *[]string) { switch typ { case "TextBlock": if s, ok := itemMap["text"].(string); ok { - appendTrimmedNonEmptyString(out, s) + appendNonWhitespaceOnlyMessage(out, s) } case "Container": if items, ok := itemMap["items"].([]any); ok { diff --git a/server/public/model/post_test.go b/server/public/model/post_test.go index f3111ff8689..944586777e8 100644 --- a/server/public/model/post_test.go +++ b/server/public/model/post_test.go @@ -1048,21 +1048,20 @@ func TestPost_AllStrings_interactiveProps(t *testing.T) { PostPropsBlockKitBlocks: []any{ map[string]any{"type": "image", "image_url": "https://example.com/i.png", "alt_text": "logo"}, }, - PostPropsAdaptiveCards: map[string]any{ - "type": "AdaptiveCard", - "body": []any{ + PostPropsAdaptiveCards: []any{ + map[string]any{"type": "AdaptiveCard", "version": "1.0", "body": []any{ map[string]any{"type": "TextBlock", "text": "card-line"}, - }, + }}, }, }, } got := p.AllStrings() require.Contains(t, got, "root") require.Contains(t, got, "mm-line") - require.Contains(t, got, "OK") + require.NotContains(t, got, "OK") require.NotContains(t, got, "act") require.NotContains(t, got, "https://example.com/i.png") - require.Contains(t, got, "logo") + require.NotContains(t, got, "logo") require.Contains(t, got, "card-line") } @@ -1106,7 +1105,7 @@ func TestPost_AllStrings_interactivePropsWithoutMessage(t *testing.T) { }, } got := p.AllStrings() - require.Equal(t, []string{"Go"}, got) + require.Len(t, got, 0) } func TestPost_AllStrings_nilProps(t *testing.T) {