@linktr.ee/messaging-react 3.6.2-rc-1783304704 → 3.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Card-6FOd4_j_.cjs → Card-BThi6-oD.cjs} +2 -2
- package/dist/{Card-6FOd4_j_.cjs.map → Card-BThi6-oD.cjs.map} +1 -1
- package/dist/{Card-DN8P8IeT.js → Card-Cz8tanga.js} +2 -2
- package/dist/{Card-DN8P8IeT.js.map → Card-Cz8tanga.js.map} +1 -1
- package/dist/{Card-CA63InbA.cjs → Card-DEk34Twe.cjs} +2 -2
- package/dist/{Card-CA63InbA.cjs.map → Card-DEk34Twe.cjs.map} +1 -1
- package/dist/{Card-C_TfROjB.js → Card-DSQclaiH.js} +3 -3
- package/dist/{Card-C_TfROjB.js.map → Card-DSQclaiH.js.map} +1 -1
- package/dist/{Card-BhIG7T7c.cjs → Card-Jc1n2Iqu.cjs} +2 -2
- package/dist/{Card-BhIG7T7c.cjs.map → Card-Jc1n2Iqu.cjs.map} +1 -1
- package/dist/{Card-DgWCIgWw.js → Card-NDZLmjxS.js} +2 -2
- package/dist/{Card-DgWCIgWw.js.map → Card-NDZLmjxS.js.map} +1 -1
- package/dist/{LockedThumbnail-DPlNLdpK.cjs → LockedThumbnail-CqcnnPXB.cjs} +2 -2
- package/dist/{LockedThumbnail-DPlNLdpK.cjs.map → LockedThumbnail-CqcnnPXB.cjs.map} +1 -1
- package/dist/{LockedThumbnail-DNy4CoCm.js → LockedThumbnail-t9fLaFmy.js} +2 -2
- package/dist/{LockedThumbnail-DNy4CoCm.js.map → LockedThumbnail-t9fLaFmy.js.map} +1 -1
- package/dist/index-CPCX_7gP.cjs +2 -0
- package/dist/index-CPCX_7gP.cjs.map +1 -0
- package/dist/{index-CxGOKFnx.js → index-bPlX3Oo5.js} +3566 -3284
- package/dist/index-bPlX3Oo5.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/components/CustomMessage/StreamAttachmentMessage.stories.tsx +178 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +186 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.tsx +417 -0
- package/src/components/CustomMessage/index.tsx +67 -0
- package/dist/index-ClREqfMm.cjs +0 -2
- package/dist/index-ClREqfMm.cjs.map +0 -1
- package/dist/index-CxGOKFnx.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-CPCX_7gP.cjs");exports.ActionButton=e.ActionButton;exports.Avatar=e.Avatar;exports.ChannelEmptyState=e.ChannelEmptyState;exports.ChannelList=e.ChannelList;exports.ChannelView=e.ChannelView;exports.CustomMessageProvider=e.CustomMessageProvider;exports.FaqList=e.FaqList;exports.FaqListItem=e.FaqListItem;exports.LinkAttachment=e.LinkAttachment;exports.LockedAttachment=e.LockedAttachment;exports.MediaMessage=e.MediaMessage;exports.MessageAttachment=e.MessageAttachment;exports.MessageVoteButtons=e.MessageVoteButtons;exports.MessagingProvider=e.MessagingProvider;exports.MessagingShell=e.MessagingShell;exports.buildCompactMetaLabel=e.buildCompactMetaLabel;exports.formatFileSize=e.formatFileSize;exports.formatRelativeTime=e.formatRelativeTime;exports.getFileExtensionLabel=e.getFileExtensionLabel;exports.getMessageDisplayText=e.getMessageDisplayText;exports.isLinkAttachment=e.isLinkAttachment;exports.isUuidLike=e.isUuidLike;exports.messageAttachmentGroupPositionFromStream=e.bubbleGroupPositionFromStream;exports.normalizeLanguageCode=e.normalizeLanguageCode;exports.resolveConversationParticipant=e.resolveConversationParticipant;exports.resolveLinkAttachment=e.resolveLinkAttachment;exports.resolveMediaFromMessage=e.resolveMediaFromMessage;exports.resolveParticipantDisplayName=e.resolveParticipantDisplayName;exports.useComposerLocked=e.useComposerLocked;exports.useCustomMessage=e.useCustomMessage;exports.useMessageVote=e.useMessageVote;exports.useMessaging=e.useMessaging;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, b as t, C as i, c as o, d as n, e as m, F as r, f as g, L as l, h as M, M as c, i as u, j as L, k as h, l as d, m as p, n as v, o as C, p as A, q as k, s as F, t as P, u as b, v as f, w as x, x as y, y as S, z as q, B as z, D as B, E as D, G as E } from "./index-
|
|
1
|
+
import { a as e, b as t, C as i, c as o, d as n, e as m, F as r, f as g, L as l, h as M, M as c, i as u, j as L, k as h, l as d, m as p, n as v, o as C, p as A, q as k, s as F, t as P, u as b, v as f, w as x, x as y, y as S, z as q, B as z, D as B, E as D, G as E } from "./index-bPlX3Oo5.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ActionButton,
|
|
4
4
|
t as Avatar,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linktr.ee/messaging-react",
|
|
3
|
-
"version": "3.6.2
|
|
3
|
+
"version": "3.6.2",
|
|
4
4
|
"description": "React messaging components built on messaging-core for web applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@linktr.ee/component-library": "11.8.6",
|
|
41
|
-
"@linktr.ee/messaging-core": "2.
|
|
41
|
+
"@linktr.ee/messaging-core": "^2.2.0",
|
|
42
42
|
"@phosphor-icons/react": "^2.1.10"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from '@storybook/react'
|
|
2
|
+
import classNames from 'classnames'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import type { Attachment } from 'stream-chat'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
currentUserArgType,
|
|
8
|
+
storyUsers,
|
|
9
|
+
type StoryUser,
|
|
10
|
+
} from '../../stories/decorators/storyUser'
|
|
11
|
+
|
|
12
|
+
import StreamAttachmentMessage from './StreamAttachmentMessage'
|
|
13
|
+
|
|
14
|
+
/* ──────────────────────────────────────────────────────────────────
|
|
15
|
+
* Stories for `StreamAttachmentMessage` — the toolkit-owned renderer
|
|
16
|
+
* that `CustomMessage` uses for every generic Stream-attachment message
|
|
17
|
+
* (link OG previews + image / video / audio / pdf / file media).
|
|
18
|
+
*
|
|
19
|
+
* Unlike `MessageAttachmentConversations.stories.tsx` — which hand-builds
|
|
20
|
+
* `MessageAttachment.*` JSX directly — these stories feed raw Stream
|
|
21
|
+
* `Attachment[]` shapes through `StreamAttachmentMessage` so they exercise
|
|
22
|
+
* the mapping the component actually owns: ordered segment building,
|
|
23
|
+
* Stream-attachment → `LinkAttachment` prop mapping, caption
|
|
24
|
+
* de-duplication (including emoji preservation), and media clustering.
|
|
25
|
+
*
|
|
26
|
+
* The component renders bare rows; this wrapper just anchors the run to
|
|
27
|
+
* the correct chat edge so sent/received read the way they do in-app.
|
|
28
|
+
* ────────────────────────────────────────────────────────────────── */
|
|
29
|
+
|
|
30
|
+
const Bubbles: React.FC<{ isMyMessage: boolean; children: React.ReactNode }> = ({
|
|
31
|
+
isMyMessage,
|
|
32
|
+
children,
|
|
33
|
+
}) => (
|
|
34
|
+
<div className="mx-auto max-w-2xl p-12">
|
|
35
|
+
<div
|
|
36
|
+
className={classNames(
|
|
37
|
+
'flex flex-col gap-[2px]',
|
|
38
|
+
isMyMessage ? 'items-end' : 'items-start'
|
|
39
|
+
)}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
const Render = (attachments: Attachment[], text?: string): StoryFn<StoryArgs> =>
|
|
47
|
+
function StreamAttachmentStory({ currentUser }) {
|
|
48
|
+
const isMyMessage = currentUser.id === storyUsers.creator.id
|
|
49
|
+
return (
|
|
50
|
+
<Bubbles isMyMessage={isMyMessage}>
|
|
51
|
+
<StreamAttachmentMessage
|
|
52
|
+
groupPosition="single"
|
|
53
|
+
isMyMessage={isMyMessage}
|
|
54
|
+
message={{ attachments, text }}
|
|
55
|
+
/>
|
|
56
|
+
</Bubbles>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const HERO = 'https://picsum.photos/seed/og-hero/1200/630'
|
|
61
|
+
const PHOTO = (seed: string) => `https://picsum.photos/seed/${seed}/720/720`
|
|
62
|
+
const VIDEO_SRC = '/video-source.mp4'
|
|
63
|
+
const VIDEO_POSTER = '/video-thumbnail.jpg'
|
|
64
|
+
const PDF_SRC = 'https://www.w3.org/WAI/WCAG21/wcag21.pdf'
|
|
65
|
+
|
|
66
|
+
const linkAttachment = (overrides: Partial<Attachment> = {}): Attachment => ({
|
|
67
|
+
type: 'link',
|
|
68
|
+
og_scrape_url: 'https://linktr.ee/marketplace',
|
|
69
|
+
title: 'Linktree Marketplace',
|
|
70
|
+
text: 'Browse the best apps to customize your link in bio.',
|
|
71
|
+
image_url: HERO,
|
|
72
|
+
...overrides,
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const imageAttachment = (seed: string): Attachment => ({
|
|
76
|
+
type: 'image',
|
|
77
|
+
image_url: PHOTO(seed),
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
interface StoryArgs {
|
|
81
|
+
currentUser: StoryUser
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const meta: Meta<StoryArgs> = {
|
|
85
|
+
title: 'CustomMessage/StreamAttachmentMessage',
|
|
86
|
+
argTypes: currentUserArgType,
|
|
87
|
+
args: { currentUser: storyUsers.creator },
|
|
88
|
+
parameters: {
|
|
89
|
+
layout: 'fullscreen',
|
|
90
|
+
// Story render output embeds live React elements; pin source generation
|
|
91
|
+
// to the static story code (matches MessageAttachmentConversations).
|
|
92
|
+
docs: { source: { type: 'code' } },
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
export default meta
|
|
96
|
+
|
|
97
|
+
/** Link share with an OG image → the featured card layout. */
|
|
98
|
+
export const LinkFeatured = Render([linkAttachment()])
|
|
99
|
+
|
|
100
|
+
/** Link share with no thumbnail → the classic (compact) card layout. */
|
|
101
|
+
export const LinkClassic = Render([
|
|
102
|
+
linkAttachment({ image_url: undefined, thumb_url: undefined }),
|
|
103
|
+
])
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Link share with an emoji-only caption alongside the URL. The emoji is
|
|
107
|
+
* real content, so the caption is preserved as a separate bubble beneath
|
|
108
|
+
* the card (regression guard for the caption-dedup predicate).
|
|
109
|
+
*/
|
|
110
|
+
export const LinkWithEmojiCaption = Render(
|
|
111
|
+
[linkAttachment({ og_scrape_url: 'https://mrdrnose.itch.io/votv' })],
|
|
112
|
+
'https://mrdrnose.itch.io/votv 👽'
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Caption that is just the link URL → suppressed (the card already shows
|
|
117
|
+
* the URL, so no duplicate text bubble).
|
|
118
|
+
*/
|
|
119
|
+
export const LinkWithUrlOnlyCaption = Render(
|
|
120
|
+
[linkAttachment()],
|
|
121
|
+
'https://linktr.ee/marketplace'
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
/** Single image attachment. */
|
|
125
|
+
export const SingleImage = Render([imageAttachment('single')])
|
|
126
|
+
|
|
127
|
+
/** Several images in one message → a clustered image bubble. */
|
|
128
|
+
export const ImageCluster = Render([
|
|
129
|
+
imageAttachment('cluster-1'),
|
|
130
|
+
imageAttachment('cluster-2'),
|
|
131
|
+
imageAttachment('cluster-3'),
|
|
132
|
+
])
|
|
133
|
+
|
|
134
|
+
/** Video attachment (poster + play affordance). */
|
|
135
|
+
export const Video = Render([
|
|
136
|
+
{
|
|
137
|
+
type: 'video',
|
|
138
|
+
asset_url: VIDEO_SRC,
|
|
139
|
+
thumb_url: VIDEO_POSTER,
|
|
140
|
+
mime_type: 'video/mp4',
|
|
141
|
+
title: 'trailer.mp4',
|
|
142
|
+
},
|
|
143
|
+
])
|
|
144
|
+
|
|
145
|
+
/** PDF document attachment with a caption. */
|
|
146
|
+
export const Pdf = Render(
|
|
147
|
+
[
|
|
148
|
+
{
|
|
149
|
+
type: 'file',
|
|
150
|
+
asset_url: PDF_SRC,
|
|
151
|
+
mime_type: 'application/pdf',
|
|
152
|
+
title: 'launch-checklist.pdf',
|
|
153
|
+
file_size: 142_336,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
'Section 4 has the details.'
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
/** Generic (non-PDF) file attachment with a download affordance. */
|
|
160
|
+
export const GenericFile = Render([
|
|
161
|
+
{
|
|
162
|
+
type: 'file',
|
|
163
|
+
asset_url: 'https://cdn.example.com/brand-kit.zip',
|
|
164
|
+
mime_type: 'application/zip',
|
|
165
|
+
title: 'brand-kit.zip',
|
|
166
|
+
file_size: 11_500_000,
|
|
167
|
+
},
|
|
168
|
+
])
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Mixed message — media followed by a link share with a caption. Exercises
|
|
172
|
+
* ordered-segment building across kinds: the image cluster renders first,
|
|
173
|
+
* the link card second, and the caption attaches to the last bubble.
|
|
174
|
+
*/
|
|
175
|
+
export const MixedMediaAndLink = Render(
|
|
176
|
+
[imageAttachment('mixed-1'), imageAttachment('mixed-2'), linkAttachment()],
|
|
177
|
+
'Check these out 🔥'
|
|
178
|
+
)
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { renderWithProviders, screen } from '../../test/utils'
|
|
5
|
+
|
|
6
|
+
import StreamAttachmentMessage, {
|
|
7
|
+
linkCaptionDuplicatesAttachmentUrl,
|
|
8
|
+
linkCardPropsFromStreamAttachment,
|
|
9
|
+
} from './StreamAttachmentMessage'
|
|
10
|
+
|
|
11
|
+
describe('linkCardPropsFromStreamAttachment', () => {
|
|
12
|
+
it('uses the featured layout when a thumbnail is present', () => {
|
|
13
|
+
expect(
|
|
14
|
+
linkCardPropsFromStreamAttachment({
|
|
15
|
+
type: 'link',
|
|
16
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
17
|
+
image_url: 'https://cdn.example.com/thumb.jpg',
|
|
18
|
+
}).layout
|
|
19
|
+
).toBe('featured')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('uses the classic layout for a plain link with no thumbnail', () => {
|
|
23
|
+
expect(
|
|
24
|
+
linkCardPropsFromStreamAttachment({
|
|
25
|
+
type: 'link',
|
|
26
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
27
|
+
}).layout
|
|
28
|
+
).toBe('classic')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('keeps the featured layout for a playable clip with no thumbnail so the player renders', () => {
|
|
32
|
+
expect(
|
|
33
|
+
linkCardPropsFromStreamAttachment({
|
|
34
|
+
type: 'link',
|
|
35
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
36
|
+
asset_url: 'https://cdn.example.com/clip.mp3',
|
|
37
|
+
mime_type: 'audio/mpeg',
|
|
38
|
+
}).layout
|
|
39
|
+
).toBe('featured')
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
describe('linkCaptionDuplicatesAttachmentUrl', () => {
|
|
44
|
+
it('suppresses captions that are just the link plus punctuation', () => {
|
|
45
|
+
expect(
|
|
46
|
+
linkCaptionDuplicatesAttachmentUrl(
|
|
47
|
+
'https://tr.ee/abc !',
|
|
48
|
+
'https://tr.ee/abc'
|
|
49
|
+
)
|
|
50
|
+
).toBe(true)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('keeps captions that add emoji after the link', () => {
|
|
54
|
+
expect(
|
|
55
|
+
linkCaptionDuplicatesAttachmentUrl(
|
|
56
|
+
'https://tr.ee/abc 😎',
|
|
57
|
+
'https://tr.ee/abc'
|
|
58
|
+
)
|
|
59
|
+
).toBe(false)
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('StreamAttachmentMessage', () => {
|
|
64
|
+
it('renders a sent link card and suppresses a URL-only caption', () => {
|
|
65
|
+
renderWithProviders(
|
|
66
|
+
<StreamAttachmentMessage
|
|
67
|
+
groupPosition="single"
|
|
68
|
+
isMyMessage={true}
|
|
69
|
+
message={{
|
|
70
|
+
attachments: [
|
|
71
|
+
{
|
|
72
|
+
type: 'link',
|
|
73
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
74
|
+
title: 'My Linktree',
|
|
75
|
+
text: 'Check out my links',
|
|
76
|
+
image_url: 'https://cdn.example.com/thumb.jpg',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
text: 'https://linktr.ee/someone !',
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
expect(
|
|
85
|
+
screen.getByRole('link', { name: /my linktree/i })
|
|
86
|
+
).toHaveAttribute('href', 'https://linktr.ee/someone')
|
|
87
|
+
expect(screen.queryByText('https://linktr.ee/someone !')).toBeNull()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('keeps an emoji-only caption instead of dropping it', () => {
|
|
91
|
+
renderWithProviders(
|
|
92
|
+
<StreamAttachmentMessage
|
|
93
|
+
groupPosition="single"
|
|
94
|
+
isMyMessage={false}
|
|
95
|
+
message={{
|
|
96
|
+
attachments: [
|
|
97
|
+
{
|
|
98
|
+
type: 'link',
|
|
99
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
100
|
+
title: 'My Linktree',
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
text: 'https://linktr.ee/someone 😎',
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
expect(screen.getByText('https://linktr.ee/someone 😎')).toBeInTheDocument()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('renders mixed link and media attachments in order', () => {
|
|
112
|
+
const { container } = renderWithProviders(
|
|
113
|
+
<StreamAttachmentMessage
|
|
114
|
+
groupPosition="single"
|
|
115
|
+
isMyMessage={true}
|
|
116
|
+
message={{
|
|
117
|
+
attachments: [
|
|
118
|
+
{
|
|
119
|
+
type: 'link',
|
|
120
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
121
|
+
title: 'My Linktree',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: 'image',
|
|
125
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
126
|
+
title: 'Vacation',
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
text: 'caption',
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
const link = screen.getByRole('link', { name: /my linktree/i })
|
|
135
|
+
const imageBubble = screen.getByTestId('image-attachment')
|
|
136
|
+
|
|
137
|
+
expect(link.compareDocumentPosition(imageBubble)).toBe(
|
|
138
|
+
Node.DOCUMENT_POSITION_FOLLOWING
|
|
139
|
+
)
|
|
140
|
+
expect(container).toHaveTextContent('caption')
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// The message text must never be dropped when a message carries an
|
|
144
|
+
// attachment — only genuine URL-only captions are suppressed.
|
|
145
|
+
it('renders the accompanying message text next to a link attachment', () => {
|
|
146
|
+
renderWithProviders(
|
|
147
|
+
<StreamAttachmentMessage
|
|
148
|
+
groupPosition="single"
|
|
149
|
+
isMyMessage={true}
|
|
150
|
+
message={{
|
|
151
|
+
attachments: [
|
|
152
|
+
{
|
|
153
|
+
type: 'link',
|
|
154
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
155
|
+
title: 'My Linktree',
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
text: 'you have to see this',
|
|
159
|
+
}}
|
|
160
|
+
/>
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
expect(screen.getByText('you have to see this')).toBeInTheDocument()
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('renders the accompanying message text next to a media attachment', () => {
|
|
167
|
+
const { container } = renderWithProviders(
|
|
168
|
+
<StreamAttachmentMessage
|
|
169
|
+
groupPosition="single"
|
|
170
|
+
isMyMessage={false}
|
|
171
|
+
message={{
|
|
172
|
+
attachments: [
|
|
173
|
+
{
|
|
174
|
+
type: 'image',
|
|
175
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
176
|
+
title: 'Vacation',
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
text: 'from the trip',
|
|
180
|
+
}}
|
|
181
|
+
/>
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
expect(container).toHaveTextContent('from the trip')
|
|
185
|
+
})
|
|
186
|
+
})
|