@linktr.ee/messaging-react 1.37.0 → 1.38.0-rc-1777583423
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-BlXnKGaR.js +127 -0
- package/dist/Card-BlXnKGaR.js.map +1 -0
- package/dist/Card-DoNJA-jg.js +138 -0
- package/dist/Card-DoNJA-jg.js.map +1 -0
- package/dist/{index-DOsC03ZN.js → index-jnKl3mQ0.js} +1404 -1352
- package/dist/index-jnKl3mQ0.js.map +1 -0
- package/dist/index.d.ts +21 -1
- package/dist/index.js +15 -13
- package/package.json +1 -1
- package/src/components/{LockedAttachment/components → AttachmentCard}/MediaPlayer.tsx +4 -3
- package/src/components/AttachmentCard/Thumbnail.tsx +150 -0
- package/src/components/AttachmentCard/index.tsx +112 -0
- package/src/components/LockedAttachment/components/Creator/Card.tsx +123 -113
- package/src/components/LockedAttachment/components/Visitor/Card.tsx +43 -42
- package/src/components/LockedAttachment/components/Visitor/LockBadge.tsx +12 -0
- package/src/components/MediaMessage/MediaMessage.stories.tsx +45 -4
- package/src/components/MediaMessage/MediaMessage.test.tsx +125 -160
- package/src/components/MediaMessage/index.tsx +226 -349
- package/src/index.ts +7 -3
- package/dist/Card-BHrnmHeu.js +0 -167
- package/dist/Card-BHrnmHeu.js.map +0 -1
- package/dist/Card-D4vEgqWt.js +0 -195
- package/dist/Card-D4vEgqWt.js.map +0 -1
- package/dist/index-DOsC03ZN.js.map +0 -1
- package/src/components/LockedAttachment/components/Creator/CardThumbnail.tsx +0 -114
- package/src/components/LockedAttachment/components/Visitor/CardThumbnail.tsx +0 -81
- /package/src/components/{LockedAttachment → AttachmentCard}/utils/icons.ts +0 -0
- /package/src/components/{LockedAttachment → AttachmentCard}/utils/mimeType.test.ts +0 -0
- /package/src/components/{LockedAttachment → AttachmentCard}/utils/mimeType.ts +0 -0
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import type { LocalMessage } from 'stream-chat'
|
|
3
|
-
import {
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
4
4
|
|
|
5
5
|
import { renderWithProviders, screen, fireEvent } from '../../test/utils'
|
|
6
6
|
|
|
7
7
|
import { MediaMessage } from '.'
|
|
8
8
|
|
|
9
|
-
beforeAll(() => {
|
|
10
|
-
HTMLDialogElement.prototype.showModal = vi.fn(function (this: HTMLDialogElement) {
|
|
11
|
-
this.setAttribute('open', '')
|
|
12
|
-
})
|
|
13
|
-
HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
|
|
14
|
-
this.removeAttribute('open')
|
|
15
|
-
})
|
|
16
|
-
})
|
|
17
|
-
|
|
18
9
|
vi.mock('../Avatar', () => ({
|
|
19
10
|
Avatar: ({ id }: { id: string }) => (
|
|
20
11
|
<div data-testid="avatar" data-user-id={id} />
|
|
21
12
|
),
|
|
22
13
|
}))
|
|
23
14
|
|
|
24
|
-
vi.mock('../
|
|
15
|
+
vi.mock('../AttachmentCard/MediaPlayer', () => ({
|
|
25
16
|
default: ({
|
|
26
17
|
source,
|
|
27
18
|
mimeType,
|
|
28
|
-
onContainerClick,
|
|
29
19
|
}: {
|
|
30
20
|
source: string
|
|
31
21
|
mimeType: string
|
|
32
|
-
onContainerClick?: (e: React.MouseEvent) => void
|
|
33
22
|
}) => (
|
|
34
23
|
<div
|
|
35
24
|
role="button"
|
|
@@ -37,17 +26,15 @@ vi.mock('../LockedAttachment/components/MediaPlayer', () => ({
|
|
|
37
26
|
data-testid="media-player"
|
|
38
27
|
data-source={source}
|
|
39
28
|
data-mime-type={mimeType}
|
|
40
|
-
onClick={onContainerClick}
|
|
41
|
-
onKeyDown={undefined}
|
|
42
29
|
/>
|
|
43
30
|
),
|
|
44
31
|
}))
|
|
45
32
|
|
|
46
|
-
vi.mock('../
|
|
33
|
+
vi.mock('../AttachmentCard/utils/icons', () => ({
|
|
47
34
|
renderTypeIcon: () => <span data-testid="type-icon" />,
|
|
48
35
|
}))
|
|
49
36
|
|
|
50
|
-
vi.mock('../
|
|
37
|
+
vi.mock('../AttachmentCard/utils/mimeType', () => ({
|
|
51
38
|
getSourceType: (mimeType: string) => {
|
|
52
39
|
if (mimeType.startsWith('video/')) return 'video'
|
|
53
40
|
if (mimeType.startsWith('image/')) return 'image'
|
|
@@ -98,203 +85,195 @@ describe('MediaMessage', () => {
|
|
|
98
85
|
expect(player).toHaveAttribute('data-source', 'https://cdn.example.com/clip.mp4')
|
|
99
86
|
})
|
|
100
87
|
|
|
101
|
-
it('
|
|
88
|
+
it('renders MediaPlayer for an audio attachment', () => {
|
|
102
89
|
renderWithProviders(
|
|
103
90
|
<MediaMessage
|
|
104
91
|
message={msg({
|
|
105
92
|
attachments: [
|
|
106
93
|
{
|
|
107
|
-
type: '
|
|
108
|
-
asset_url: 'https://cdn.example.com/
|
|
109
|
-
mime_type: '
|
|
110
|
-
title: 'My Clip',
|
|
94
|
+
type: 'audio',
|
|
95
|
+
asset_url: 'https://cdn.example.com/track.mp3',
|
|
96
|
+
mime_type: 'audio/mpeg',
|
|
111
97
|
},
|
|
112
98
|
],
|
|
113
99
|
})}
|
|
114
100
|
/>
|
|
115
101
|
)
|
|
116
102
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
103
|
+
expect(screen.getByTestId('media-player')).toHaveAttribute(
|
|
104
|
+
'data-source',
|
|
105
|
+
'https://cdn.example.com/track.mp3'
|
|
106
|
+
)
|
|
120
107
|
})
|
|
121
108
|
|
|
122
|
-
it('renders
|
|
109
|
+
it('renders an img for an image attachment', () => {
|
|
123
110
|
renderWithProviders(
|
|
124
111
|
<MediaMessage
|
|
125
112
|
message={msg({
|
|
126
113
|
attachments: [
|
|
127
114
|
{
|
|
128
|
-
type: '
|
|
129
|
-
|
|
130
|
-
mime_type: '
|
|
115
|
+
type: 'image',
|
|
116
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
117
|
+
mime_type: 'image/jpeg',
|
|
118
|
+
title: 'My Photo',
|
|
131
119
|
},
|
|
132
120
|
],
|
|
133
121
|
})}
|
|
134
122
|
/>
|
|
135
123
|
)
|
|
136
124
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
'https://cdn.example.com/track.mp3'
|
|
140
|
-
)
|
|
125
|
+
const image = screen.getByRole('img', { name: 'My Photo' })
|
|
126
|
+
expect(image).toHaveAttribute('src', 'https://cdn.example.com/photo.jpg')
|
|
141
127
|
})
|
|
142
128
|
|
|
143
|
-
it('
|
|
129
|
+
it('renders unknown file type as icon placeholder, not a link', () => {
|
|
144
130
|
renderWithProviders(
|
|
145
131
|
<MediaMessage
|
|
146
132
|
message={msg({
|
|
147
133
|
attachments: [
|
|
148
134
|
{
|
|
149
|
-
type: '
|
|
150
|
-
asset_url: 'https://cdn.example.com/
|
|
151
|
-
mime_type: '
|
|
152
|
-
title: '
|
|
135
|
+
type: 'file',
|
|
136
|
+
asset_url: 'https://cdn.example.com/data.bin',
|
|
137
|
+
mime_type: 'application/octet-stream',
|
|
138
|
+
title: 'Unknown File',
|
|
153
139
|
},
|
|
154
140
|
],
|
|
155
141
|
})}
|
|
156
142
|
/>
|
|
157
143
|
)
|
|
158
144
|
|
|
159
|
-
expect(screen.queryByRole('
|
|
160
|
-
expect(screen.
|
|
145
|
+
expect(screen.queryByRole('link')).not.toBeInTheDocument()
|
|
146
|
+
expect(screen.getByText('Unknown File')).toBeInTheDocument()
|
|
147
|
+
expect(screen.getAllByTestId('type-icon').length).toBeGreaterThanOrEqual(1)
|
|
161
148
|
})
|
|
162
149
|
|
|
163
|
-
it('
|
|
150
|
+
it('shows title and file size in meta row', () => {
|
|
164
151
|
renderWithProviders(
|
|
165
152
|
<MediaMessage
|
|
166
153
|
message={msg({
|
|
167
154
|
attachments: [
|
|
168
155
|
{
|
|
169
|
-
type: '
|
|
170
|
-
|
|
171
|
-
mime_type: '
|
|
172
|
-
title: '
|
|
156
|
+
type: 'video',
|
|
157
|
+
asset_url: 'https://cdn.example.com/clip.mp4',
|
|
158
|
+
mime_type: 'video/mp4',
|
|
159
|
+
title: 'Clip',
|
|
160
|
+
file_size: 2048,
|
|
173
161
|
},
|
|
174
162
|
],
|
|
175
163
|
})}
|
|
176
164
|
/>
|
|
177
165
|
)
|
|
178
166
|
|
|
179
|
-
|
|
180
|
-
expect(
|
|
181
|
-
|
|
182
|
-
// Clicking the image button opens the viewer
|
|
183
|
-
fireEvent.click(screen.getByRole('button', { name: 'My Photo' }))
|
|
184
|
-
expect(HTMLDialogElement.prototype.showModal).toHaveBeenCalled()
|
|
185
|
-
const viewerImages = screen.getAllByRole('img', { name: 'My Photo' })
|
|
186
|
-
expect(viewerImages.some((img) => img.classList.contains('rounded-2xl'))).toBe(true)
|
|
167
|
+
expect(screen.getByText('Clip')).toBeInTheDocument()
|
|
168
|
+
expect(screen.getByText('2.0 KB')).toBeInTheDocument()
|
|
187
169
|
})
|
|
188
170
|
|
|
189
|
-
it('
|
|
171
|
+
it('renders Avatar for a message from another user', () => {
|
|
190
172
|
renderWithProviders(
|
|
191
173
|
<MediaMessage
|
|
174
|
+
isMyMessage={false}
|
|
192
175
|
message={msg({
|
|
193
176
|
attachments: [
|
|
194
177
|
{
|
|
195
178
|
type: 'image',
|
|
196
179
|
image_url: 'https://cdn.example.com/photo.jpg',
|
|
197
180
|
mime_type: 'image/jpeg',
|
|
198
|
-
title: 'My Photo',
|
|
199
181
|
},
|
|
200
182
|
],
|
|
201
183
|
})}
|
|
202
184
|
/>
|
|
203
185
|
)
|
|
204
186
|
|
|
205
|
-
|
|
206
|
-
expect(screen.
|
|
207
|
-
expect(screen.getByRole('button', { name: 'Download' })).toBeInTheDocument()
|
|
187
|
+
expect(screen.getByTestId('avatar')).toBeInTheDocument()
|
|
188
|
+
expect(screen.getByTestId('avatar')).toHaveAttribute('data-user-id', 'user-1')
|
|
208
189
|
})
|
|
209
190
|
|
|
210
|
-
it('
|
|
191
|
+
it('does not render Avatar for own messages', () => {
|
|
211
192
|
renderWithProviders(
|
|
212
193
|
<MediaMessage
|
|
194
|
+
isMyMessage={true}
|
|
213
195
|
message={msg({
|
|
214
196
|
attachments: [
|
|
215
197
|
{
|
|
216
|
-
type: '
|
|
217
|
-
|
|
218
|
-
mime_type: '
|
|
219
|
-
title: 'Annual Report',
|
|
198
|
+
type: 'image',
|
|
199
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
200
|
+
mime_type: 'image/jpeg',
|
|
220
201
|
},
|
|
221
202
|
],
|
|
222
203
|
})}
|
|
223
204
|
/>
|
|
224
205
|
)
|
|
225
206
|
|
|
226
|
-
expect(screen.
|
|
227
|
-
expect(screen.getByText('Annual Report')).toBeInTheDocument()
|
|
207
|
+
expect(screen.queryByTestId('avatar')).not.toBeInTheDocument()
|
|
228
208
|
})
|
|
229
209
|
|
|
230
|
-
it('
|
|
231
|
-
renderWithProviders(
|
|
210
|
+
it('applies the --me class for own messages', () => {
|
|
211
|
+
const { container } = renderWithProviders(
|
|
232
212
|
<MediaMessage
|
|
213
|
+
isMyMessage={true}
|
|
233
214
|
message={msg({
|
|
234
215
|
attachments: [
|
|
235
216
|
{
|
|
236
|
-
type: '
|
|
237
|
-
|
|
238
|
-
mime_type: '
|
|
239
|
-
title: 'Annual Report',
|
|
217
|
+
type: 'image',
|
|
218
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
219
|
+
mime_type: 'image/jpeg',
|
|
240
220
|
},
|
|
241
221
|
],
|
|
242
222
|
})}
|
|
243
223
|
/>
|
|
244
224
|
)
|
|
245
225
|
|
|
246
|
-
|
|
247
|
-
expect(HTMLDialogElement.prototype.showModal).toHaveBeenCalled()
|
|
248
|
-
expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument()
|
|
226
|
+
expect(container.firstChild).toHaveClass('str-chat__message--me')
|
|
249
227
|
})
|
|
250
228
|
|
|
251
|
-
it('
|
|
252
|
-
renderWithProviders(
|
|
229
|
+
it('applies the --other class for messages from other users', () => {
|
|
230
|
+
const { container } = renderWithProviders(
|
|
253
231
|
<MediaMessage
|
|
232
|
+
isMyMessage={false}
|
|
254
233
|
message={msg({
|
|
255
234
|
attachments: [
|
|
256
235
|
{
|
|
257
|
-
type: '
|
|
258
|
-
|
|
259
|
-
mime_type: '
|
|
260
|
-
title: 'Unknown File',
|
|
236
|
+
type: 'image',
|
|
237
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
238
|
+
mime_type: 'image/jpeg',
|
|
261
239
|
},
|
|
262
240
|
],
|
|
263
241
|
})}
|
|
264
242
|
/>
|
|
265
243
|
)
|
|
266
244
|
|
|
267
|
-
|
|
268
|
-
expect(screen.queryByRole('button', { name: 'Open PDF viewer' })).not.toBeInTheDocument()
|
|
269
|
-
// Thumbnail is a plain link (opens in new tab)
|
|
270
|
-
const links = screen.getAllByRole('link')
|
|
271
|
-
expect(links.some((l) => l.getAttribute('href') === 'https://cdn.example.com/data.bin')).toBe(true)
|
|
272
|
-
expect(screen.getByText('Unknown File')).toBeInTheDocument()
|
|
245
|
+
expect(container.firstChild).toHaveClass('str-chat__message--other')
|
|
273
246
|
})
|
|
274
247
|
|
|
275
|
-
it('
|
|
276
|
-
renderWithProviders(
|
|
248
|
+
it('renders nothing when no attachments', () => {
|
|
249
|
+
const { container } = renderWithProviders(
|
|
250
|
+
<MediaMessage message={msg({ attachments: [] })} />
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
expect(container.firstChild).toBeNull()
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it('uses dark card background for sent (Creator) messages', () => {
|
|
257
|
+
const { container } = renderWithProviders(
|
|
277
258
|
<MediaMessage
|
|
259
|
+
isMyMessage={true}
|
|
278
260
|
message={msg({
|
|
279
261
|
attachments: [
|
|
280
262
|
{
|
|
281
|
-
type: '
|
|
282
|
-
|
|
283
|
-
mime_type: '
|
|
284
|
-
title: 'Clip',
|
|
285
|
-
file_size: 2048,
|
|
263
|
+
type: 'image',
|
|
264
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
265
|
+
mime_type: 'image/jpeg',
|
|
286
266
|
},
|
|
287
267
|
],
|
|
288
268
|
})}
|
|
289
269
|
/>
|
|
290
270
|
)
|
|
291
271
|
|
|
292
|
-
expect(
|
|
293
|
-
expect(screen.getByText('2.0 KB')).toBeInTheDocument()
|
|
272
|
+
expect(container.querySelector('.bg-\\[\\#121110\\]')).toBeInTheDocument()
|
|
294
273
|
})
|
|
295
274
|
|
|
296
|
-
it('
|
|
297
|
-
renderWithProviders(
|
|
275
|
+
it('uses light card background for received (Visitor) messages', () => {
|
|
276
|
+
const { container } = renderWithProviders(
|
|
298
277
|
<MediaMessage
|
|
299
278
|
isMyMessage={false}
|
|
300
279
|
message={msg({
|
|
@@ -309,31 +288,30 @@ describe('MediaMessage', () => {
|
|
|
309
288
|
/>
|
|
310
289
|
)
|
|
311
290
|
|
|
312
|
-
expect(
|
|
313
|
-
expect(screen.getByTestId('avatar')).toHaveAttribute('data-user-id', 'user-1')
|
|
291
|
+
expect(container.querySelector('.bg-white')).toBeInTheDocument()
|
|
314
292
|
})
|
|
315
293
|
|
|
316
|
-
it('
|
|
294
|
+
it('shows Download action for received (Visitor) image attachment', () => {
|
|
317
295
|
renderWithProviders(
|
|
318
296
|
<MediaMessage
|
|
319
|
-
isMyMessage={true}
|
|
320
297
|
message={msg({
|
|
321
298
|
attachments: [
|
|
322
299
|
{
|
|
323
300
|
type: 'image',
|
|
324
301
|
image_url: 'https://cdn.example.com/photo.jpg',
|
|
325
302
|
mime_type: 'image/jpeg',
|
|
303
|
+
title: 'My Photo',
|
|
326
304
|
},
|
|
327
305
|
],
|
|
328
306
|
})}
|
|
329
307
|
/>
|
|
330
308
|
)
|
|
331
309
|
|
|
332
|
-
expect(screen.
|
|
310
|
+
expect(screen.getByRole('button', { name: 'Download' })).toBeInTheDocument()
|
|
333
311
|
})
|
|
334
312
|
|
|
335
|
-
it('
|
|
336
|
-
|
|
313
|
+
it('does not show Download button for sent (Creator) image attachment', () => {
|
|
314
|
+
renderWithProviders(
|
|
337
315
|
<MediaMessage
|
|
338
316
|
isMyMessage={true}
|
|
339
317
|
message={msg({
|
|
@@ -342,40 +320,33 @@ describe('MediaMessage', () => {
|
|
|
342
320
|
type: 'image',
|
|
343
321
|
image_url: 'https://cdn.example.com/photo.jpg',
|
|
344
322
|
mime_type: 'image/jpeg',
|
|
323
|
+
title: 'My Photo',
|
|
345
324
|
},
|
|
346
325
|
],
|
|
347
326
|
})}
|
|
348
327
|
/>
|
|
349
328
|
)
|
|
350
329
|
|
|
351
|
-
expect(
|
|
330
|
+
expect(screen.queryByRole('button', { name: 'Download' })).not.toBeInTheDocument()
|
|
352
331
|
})
|
|
353
332
|
|
|
354
|
-
it('
|
|
355
|
-
|
|
333
|
+
it('shows Download action for received audio attachment', () => {
|
|
334
|
+
renderWithProviders(
|
|
356
335
|
<MediaMessage
|
|
357
|
-
isMyMessage={false}
|
|
358
336
|
message={msg({
|
|
359
337
|
attachments: [
|
|
360
338
|
{
|
|
361
|
-
type: '
|
|
362
|
-
|
|
363
|
-
mime_type: '
|
|
339
|
+
type: 'audio',
|
|
340
|
+
asset_url: 'https://cdn.example.com/track.mp3',
|
|
341
|
+
mime_type: 'audio/mpeg',
|
|
342
|
+
title: 'My Track',
|
|
364
343
|
},
|
|
365
344
|
],
|
|
366
345
|
})}
|
|
367
346
|
/>
|
|
368
347
|
)
|
|
369
348
|
|
|
370
|
-
expect(
|
|
371
|
-
})
|
|
372
|
-
|
|
373
|
-
it('renders nothing when no attachments', () => {
|
|
374
|
-
const { container } = renderWithProviders(
|
|
375
|
-
<MediaMessage message={msg({ attachments: [] })} />
|
|
376
|
-
)
|
|
377
|
-
|
|
378
|
-
expect(container.firstChild).toBeNull()
|
|
349
|
+
expect(screen.getByRole('button', { name: 'Download' })).toBeInTheDocument()
|
|
379
350
|
})
|
|
380
351
|
|
|
381
352
|
it('renders a link card for a link attachment', () => {
|
|
@@ -423,98 +394,92 @@ describe('MediaMessage', () => {
|
|
|
423
394
|
expect(screen.getByText('My Linktree')).toBeInTheDocument()
|
|
424
395
|
})
|
|
425
396
|
|
|
426
|
-
it('
|
|
427
|
-
|
|
397
|
+
it('does not show download or expand buttons for link cards', () => {
|
|
398
|
+
renderWithProviders(
|
|
428
399
|
<MediaMessage
|
|
429
|
-
isMyMessage={true}
|
|
430
400
|
message={msg({
|
|
431
401
|
attachments: [
|
|
432
402
|
{
|
|
433
|
-
type: '
|
|
434
|
-
|
|
435
|
-
|
|
403
|
+
type: 'link',
|
|
404
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
405
|
+
title: 'My Linktree',
|
|
436
406
|
},
|
|
437
407
|
],
|
|
438
408
|
})}
|
|
439
409
|
/>
|
|
440
410
|
)
|
|
441
411
|
|
|
442
|
-
expect(
|
|
412
|
+
expect(screen.queryByRole('button', { name: 'Download' })).not.toBeInTheDocument()
|
|
413
|
+
expect(screen.queryByRole('button', { name: 'View full screen' })).not.toBeInTheDocument()
|
|
443
414
|
})
|
|
444
415
|
|
|
445
|
-
it('
|
|
416
|
+
it('MediaMessage.Visitor renders card without chat shell', () => {
|
|
446
417
|
const { container } = renderWithProviders(
|
|
447
|
-
<MediaMessage
|
|
448
|
-
isMyMessage={false}
|
|
418
|
+
<MediaMessage.Visitor
|
|
449
419
|
message={msg({
|
|
450
420
|
attachments: [
|
|
451
421
|
{
|
|
452
422
|
type: 'image',
|
|
453
423
|
image_url: 'https://cdn.example.com/photo.jpg',
|
|
454
424
|
mime_type: 'image/jpeg',
|
|
425
|
+
title: 'Solo',
|
|
455
426
|
},
|
|
456
427
|
],
|
|
457
428
|
})}
|
|
458
429
|
/>
|
|
459
430
|
)
|
|
460
431
|
|
|
461
|
-
expect(container.querySelector('.
|
|
432
|
+
expect(container.querySelector('.str-chat__message')).not.toBeInTheDocument()
|
|
433
|
+
expect(screen.getByRole('button', { name: 'Download' })).toBeInTheDocument()
|
|
462
434
|
})
|
|
463
435
|
|
|
464
|
-
it('
|
|
465
|
-
renderWithProviders(
|
|
466
|
-
<MediaMessage
|
|
436
|
+
it('MediaMessage.Creator renders card without chat shell', () => {
|
|
437
|
+
const { container } = renderWithProviders(
|
|
438
|
+
<MediaMessage.Creator
|
|
467
439
|
message={msg({
|
|
468
440
|
attachments: [
|
|
469
441
|
{
|
|
470
442
|
type: 'image',
|
|
471
443
|
image_url: 'https://cdn.example.com/photo.jpg',
|
|
472
444
|
mime_type: 'image/jpeg',
|
|
473
|
-
title: 'My Photo',
|
|
474
445
|
},
|
|
475
446
|
],
|
|
476
447
|
})}
|
|
477
448
|
/>
|
|
478
449
|
)
|
|
479
450
|
|
|
480
|
-
expect(
|
|
451
|
+
expect(container.querySelector('.str-chat__message')).not.toBeInTheDocument()
|
|
452
|
+
expect(screen.queryByRole('button', { name: 'Download' })).not.toBeInTheDocument()
|
|
481
453
|
})
|
|
482
454
|
|
|
483
|
-
it('
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
type: 'audio',
|
|
490
|
-
asset_url: 'https://cdn.example.com/track.mp3',
|
|
491
|
-
mime_type: 'audio/mpeg',
|
|
492
|
-
title: 'My Track',
|
|
493
|
-
},
|
|
494
|
-
],
|
|
495
|
-
})}
|
|
496
|
-
/>
|
|
497
|
-
)
|
|
498
|
-
|
|
499
|
-
expect(screen.getByRole('button', { name: 'Download' })).toBeInTheDocument()
|
|
500
|
-
})
|
|
455
|
+
it('Download button triggers fetch and uses fallback on failure', async () => {
|
|
456
|
+
const fetchSpy = vi.spyOn(global, 'fetch').mockRejectedValue(new Error('fail'))
|
|
457
|
+
const openSpy = vi.spyOn(window, 'open').mockReturnValue({
|
|
458
|
+
location: { href: '' },
|
|
459
|
+
close: vi.fn(),
|
|
460
|
+
} as unknown as Window)
|
|
501
461
|
|
|
502
|
-
it('does not show download or expand buttons for link cards', () => {
|
|
503
462
|
renderWithProviders(
|
|
504
463
|
<MediaMessage
|
|
505
464
|
message={msg({
|
|
506
465
|
attachments: [
|
|
507
466
|
{
|
|
508
|
-
type: '
|
|
509
|
-
|
|
510
|
-
|
|
467
|
+
type: 'image',
|
|
468
|
+
image_url: 'https://cdn.example.com/photo.jpg',
|
|
469
|
+
mime_type: 'image/jpeg',
|
|
470
|
+
title: 'My Photo',
|
|
511
471
|
},
|
|
512
472
|
],
|
|
513
473
|
})}
|
|
514
474
|
/>
|
|
515
475
|
)
|
|
516
476
|
|
|
517
|
-
|
|
518
|
-
|
|
477
|
+
fireEvent.click(screen.getByRole('button', { name: 'Download' }))
|
|
478
|
+
await vi.waitFor(() => {
|
|
479
|
+
expect(fetchSpy).toHaveBeenCalled()
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
fetchSpy.mockRestore()
|
|
483
|
+
openSpy.mockRestore()
|
|
519
484
|
})
|
|
520
485
|
})
|