@pushwoosh/dumb-components 2.9.11 → 2.9.13

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.
Files changed (78) hide show
  1. package/Skeleton/styles.js +2 -0
  2. package/package.json +4 -6
  3. package/Banner/__tests__/Banner.test.d.ts +0 -1
  4. package/Banner/__tests__/Banner.test.js +0 -57
  5. package/Button/__tests__/Button.test.d.ts +0 -1
  6. package/Button/__tests__/Button.test.js +0 -27
  7. package/Calendar/__tests__/CalendarMonthSlider.test.d.ts +0 -1
  8. package/Calendar/__tests__/CalendarMonthSlider.test.js +0 -85
  9. package/Calendar/__tests__/CellBox.test.d.ts +0 -1
  10. package/Calendar/__tests__/CellBox.test.js +0 -34
  11. package/Calendar/__tests__/helpers.test.d.ts +0 -1
  12. package/Calendar/__tests__/helpers.test.js +0 -143
  13. package/CardMetric/__tests__/CardMetric.test.d.ts +0 -1
  14. package/CardMetric/__tests__/CardMetric.test.js +0 -31
  15. package/Chip/__tests__/Chip.test.d.ts +0 -1
  16. package/Chip/__tests__/Chip.test.js +0 -101
  17. package/DateTimePicker/__tests__/YearView.test.d.ts +0 -1
  18. package/DateTimePicker/__tests__/YearView.test.js +0 -15
  19. package/DropdownMenu/__tests__/DropdownMenuItem.test.d.ts +0 -1
  20. package/DropdownMenu/__tests__/DropdownMenuItem.test.js +0 -109
  21. package/EditableField/__tests__/EditableField.test.d.ts +0 -1
  22. package/EditableField/__tests__/EditableField.test.js +0 -19
  23. package/EmailTemplatePreview/__tests__/clickMap.test.d.ts +0 -1
  24. package/EmailTemplatePreview/__tests__/clickMap.test.js +0 -168
  25. package/ExternalImagePreview/__tests__/ExternalImagePreview.test.d.ts +0 -1
  26. package/ExternalImagePreview/__tests__/ExternalImagePreview.test.js +0 -18
  27. package/InboxPreview/__tests__/helpers.test.d.ts +0 -1
  28. package/InboxPreview/__tests__/helpers.test.js +0 -201
  29. package/NativeRichMediaPreview/__tests__/NativeRichMediaPreview.test.d.ts +0 -1
  30. package/NativeRichMediaPreview/__tests__/NativeRichMediaPreview.test.js +0 -81
  31. package/PageHeader/__tests__/PageHeader.test.d.ts +0 -1
  32. package/PageHeader/__tests__/PageHeader.test.js +0 -37
  33. package/PushPreview/__tests__/PushPreview.test.d.ts +0 -1
  34. package/PushPreview/__tests__/PushPreview.test.js +0 -26
  35. package/PushStoriesPreview/__tests__/PushStoriesPreview.test.d.ts +0 -1
  36. package/PushStoriesPreview/__tests__/PushStoriesPreview.test.js +0 -234
  37. package/RadioCard/__tests__/RadioCard.test.d.ts +0 -1
  38. package/RadioCard/__tests__/RadioCard.test.js +0 -23
  39. package/RichmediaPreview/__tests__/RichmediaPreview.test.d.ts +0 -1
  40. package/RichmediaPreview/__tests__/RichmediaPreview.test.js +0 -21
  41. package/SandboxedHtmlFrame/__tests__/SandboxedHtmlFrame.test.d.ts +0 -1
  42. package/SandboxedHtmlFrame/__tests__/SandboxedHtmlFrame.test.js +0 -57
  43. package/Skeleton/__tests__/Skeleton.test.d.ts +0 -1
  44. package/Skeleton/__tests__/Skeleton.test.js +0 -56
  45. package/Spinner/__tests__/Spinner.test.d.ts +0 -1
  46. package/Spinner/__tests__/Spinner.test.js +0 -15
  47. package/Switch/__tests__/Switch.test.d.ts +0 -1
  48. package/Switch/__tests__/Switch.test.js +0 -44
  49. package/Tabs/__tests__/TabBar.test.d.ts +0 -1
  50. package/Tabs/__tests__/TabBar.test.js +0 -36
  51. package/Toast/__tests__/Toast.test.d.ts +0 -1
  52. package/Toast/__tests__/Toast.test.js +0 -20
  53. package/WhatsAppPreview/__tests__/WhatsAppAttachment.test.d.ts +0 -1
  54. package/WhatsAppPreview/__tests__/WhatsAppAttachment.test.js +0 -53
  55. package/WhatsAppPreview/__tests__/WhatsAppPreview.test.d.ts +0 -1
  56. package/WhatsAppPreview/__tests__/WhatsAppPreview.test.js +0 -55
  57. package/WhatsAppPreview/__tests__/attachment.test.d.ts +0 -1
  58. package/WhatsAppPreview/__tests__/attachment.test.js +0 -103
  59. package/WhatsAppPreview/__tests__/parseWhatsAppMarkup.test.d.ts +0 -1
  60. package/WhatsAppPreview/__tests__/parseWhatsAppMarkup.test.js +0 -59
  61. package/helpers/__tests__/barcodeUrl.test.d.ts +0 -1
  62. package/helpers/__tests__/barcodeUrl.test.js +0 -43
  63. package/helpers/__tests__/timezones.test.d.ts +0 -1
  64. package/helpers/__tests__/timezones.test.js +0 -188
  65. package/hooks/__tests__/useLayer.test.d.ts +0 -1
  66. package/hooks/__tests__/useLayer.test.js +0 -71
  67. package/polyglot/__tests__/filters.test.d.ts +0 -1
  68. package/polyglot/__tests__/filters.test.js +0 -152
  69. package/polyglot/__tests__/helpers.test.d.ts +0 -1
  70. package/polyglot/__tests__/helpers.test.js +0 -176
  71. package/polyglot/__tests__/parser.test.d.ts +0 -1
  72. package/polyglot/__tests__/parser.test.js +0 -108
  73. package/polyglot/__tests__/render.test.d.ts +0 -1
  74. package/polyglot/__tests__/render.test.js +0 -285
  75. package/shared/dropdownField/__tests__/useDropdownPosition.test.d.ts +0 -1
  76. package/shared/dropdownField/__tests__/useDropdownPosition.test.js +0 -60
  77. package/shared/dynamicContent/__tests__/token.test.d.ts +0 -1
  78. package/shared/dynamicContent/__tests__/token.test.js +0 -32
@@ -1 +0,0 @@
1
- export {};
@@ -1,19 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { render, screen } from '@testing-library/react';
3
- import { Color } from '@pushwoosh/kit-constants';
4
- import { EditableField } from '../EditableField';
5
- describe('EditableField', () => {
6
- it('paints the open field without an `open` attribute on the div', () => {
7
- render(_jsx(EditableField, {
8
- value: "Campaign",
9
- open: true,
10
- onToggleOpen: jest.fn(),
11
- onSubmit: jest.fn(),
12
- onCancel: jest.fn(),
13
- children: "Editor"
14
- }));
15
- const field = screen.getByText('Campaign').closest('div');
16
- expect(field).not.toHaveAttribute('open');
17
- expect(getComputedStyle(field).background.replace(/\s/g, '')).toBe(Color.MAIN.replace(/\s/g, ''));
18
- });
19
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,168 +0,0 @@
1
- import { CLICK_MAP_BADGE_ATTRIBUTE, CLICK_MAP_HEAT_ATTRIBUTE, decorateClickMap, matchClickMapItems } from '../clickMap';
2
- const PROMO = 'http://spartak.com/matchtowin';
3
- const TICKETS = 'https://tickets.spartak.com/zones/18956';
4
- const SHOP = 'https://shop.spartak.com/';
5
- const HTML = `
6
- <a href="${PROMO}?utm_source=email&amp;utm_content=img"><img src="banner.png" alt=""></a>
7
- <p>Подробности на <a href="${PROMO}?utm_source=email">странице акции</a>.</p>
8
- <a href="${PROMO}?utm_source=email"><strong>Перейти на страницу акции</strong></a>
9
- <a href="${TICKETS}?utm_source=email">Купить билеты</a>
10
- <a href="${TICKETS}?utm_source=email">Купить билеты</a>
11
- <a href="[% param.url_unsub %]">Отписаться</a>
12
- <a data-pw-lid="aaaa11112222" href="${SHOP}">В магазин</a>
13
- <a data-pw-lid="bbbb33334444" href="${SHOP}">В магазин</a>
14
- `;
15
- const item = (key, link, title, clicks, linkId) => ({
16
- key,
17
- link,
18
- title,
19
- clicks,
20
- linkId
21
- });
22
- function createDocument() {
23
- const frameDocument = document.implementation.createHTMLDocument('preview');
24
- frameDocument.body.innerHTML = HTML;
25
- return frameDocument;
26
- }
27
- describe('matchClickMapItems', () => {
28
- it('tells anchors with the same link apart by their text and lands image links on the text-less anchor', () => {
29
- const frameDocument = createDocument();
30
- const items = [item('button', PROMO, 'Перейти на страницу акции', 1631), item('text', PROMO, 'странице акции', 398), item('image', PROMO, '', 172)];
31
- const {
32
- matches,
33
- placement
34
- } = matchClickMapItems(frameDocument, items);
35
- expect(placement).toEqual({
36
- placed: ['button', 'text', 'image'],
37
- pooled: [],
38
- unplaced: []
39
- });
40
- expect(matches.map(({
41
- anchor,
42
- items: matched
43
- }) => [anchor.textContent?.trim(), matched.map(row => row.key)])).toEqual([['Перейти на страницу акции', ['button']], ['странице акции', ['text']], ['', ['image']]]);
44
- });
45
- it('ignores the query string of both sides when matching links', () => {
46
- const {
47
- placement
48
- } = matchClickMapItems(createDocument(), [item('text', `${PROMO}?utm_source=other&x=1`, 'странице акции', 1)]);
49
- expect(placement.placed).toEqual(['text']);
50
- });
51
- it('pools a row over every anchor that shares link and text', () => {
52
- const {
53
- matches,
54
- placement
55
- } = matchClickMapItems(createDocument(), [item('tickets', TICKETS, 'Купить билеты', 258)]);
56
- expect(placement).toEqual({
57
- placed: [],
58
- pooled: ['tickets'],
59
- unplaced: []
60
- });
61
- expect(matches).toHaveLength(2);
62
- });
63
- it('falls back to every anchor of the link when the recorded text matches none of them', () => {
64
- const {
65
- matches,
66
- placement
67
- } = matchClickMapItems(createDocument(), [item('promo', PROMO, 'Use this template →', 10)]);
68
- expect(placement.pooled).toEqual(['promo']);
69
- expect(matches).toHaveLength(3);
70
- });
71
- it('tells identical anchors apart by the stamped link id', () => {
72
- const {
73
- matches,
74
- placement
75
- } = matchClickMapItems(createDocument(), [item('top', SHOP, 'В магазин', 40, 'aaaa11112222'), item('bottom', SHOP, 'В магазин', 9, 'bbbb33334444')]);
76
- expect(placement).toEqual({
77
- placed: ['top', 'bottom'],
78
- pooled: [],
79
- unplaced: []
80
- });
81
- expect(matches.map(({
82
- anchor,
83
- items: matched
84
- }) => [anchor.getAttribute('data-pw-lid'), matched.map(row => row.key)])).toEqual([['aaaa11112222', ['top']], ['bbbb33334444', ['bottom']]]);
85
- });
86
- it('falls back to link and text when the template no longer carries the recorded link id', () => {
87
- const {
88
- matches,
89
- placement
90
- } = matchClickMapItems(createDocument(), [item('old', SHOP, 'В магазин', 3, 'cccc55556666'), item('unstamped', PROMO, 'странице акции', 1)]);
91
- expect(placement).toEqual({
92
- placed: ['unstamped'],
93
- pooled: ['old'],
94
- unplaced: []
95
- });
96
- expect(matches).toHaveLength(3);
97
- });
98
- it('reports rows whose link is not in the template as unplaced', () => {
99
- const {
100
- matches,
101
- placement
102
- } = matchClickMapItems(createDocument(), [item('gone', 'https://old.example.com/', 'x', 5)]);
103
- expect(placement).toEqual({
104
- placed: [],
105
- pooled: [],
106
- unplaced: ['gone']
107
- });
108
- expect(matches).toHaveLength(0);
109
- });
110
- });
111
- describe('decorateClickMap', () => {
112
- it('draws one badge per matched anchor, highlights the active row and cleans up after itself', () => {
113
- const frameDocument = createDocument();
114
- const onPlaced = jest.fn();
115
- const onSelect = jest.fn();
116
- const items = [item('button', PROMO, 'Перейти на страницу акции', 1631), item('image', PROMO, '', 172), item('gone', 'https://old.example.com/', 'x', 5)];
117
- const cleanup = decorateClickMap(frameDocument, {
118
- items,
119
- activeKey: 'button',
120
- onPlaced,
121
- onSelect
122
- });
123
- const badges = [...frameDocument.querySelectorAll(`[${CLICK_MAP_BADGE_ATTRIBUTE}]`)];
124
- expect(badges.map(badge => [badge.getAttribute(CLICK_MAP_BADGE_ATTRIBUTE), badge.textContent])).toEqual([['button', '1.6K'], ['image', '172']]);
125
- expect(badges[0].style.backgroundColor).not.toBe(badges[1].style.backgroundColor);
126
- expect(frameDocument.querySelector('a strong')?.parentElement?.style.outline).toContain('solid');
127
- expect(onPlaced).toHaveBeenCalledWith({
128
- placed: ['button', 'image'],
129
- pooled: [],
130
- unplaced: ['gone']
131
- });
132
- badges[1].click();
133
- expect(onSelect).toHaveBeenCalledWith('image');
134
- cleanup();
135
- expect(frameDocument.querySelectorAll(`[${CLICK_MAP_BADGE_ATTRIBUTE}]`)).toHaveLength(0);
136
- expect(frameDocument.querySelector('a strong')?.parentElement?.style.outline).toBe('');
137
- });
138
- });
139
- describe('decorateClickMap in heat mode', () => {
140
- it('tints every matched anchor by its share of clicks and counts only the active one', () => {
141
- const frameDocument = createDocument();
142
- const items = [item('button', PROMO, 'Перейти на страницу акции', 1000), item('image', PROMO, '', 250), item('gone', 'https://old.example.com/', 'x', 5)];
143
- const cleanup = decorateClickMap(frameDocument, {
144
- items,
145
- mode: 'heat',
146
- activeKey: 'image'
147
- });
148
- const heats = [...frameDocument.querySelectorAll(`[${CLICK_MAP_HEAT_ATTRIBUTE}]`)];
149
- const badges = [...frameDocument.querySelectorAll(`[${CLICK_MAP_BADGE_ATTRIBUTE}]`)];
150
- const alpha = heat => Number(heat.style.backgroundColor.match(/[\d.]+\)$/)?.[0].slice(0, -1));
151
- expect(heats.map(heat => heat.getAttribute(CLICK_MAP_HEAT_ATTRIBUTE))).toEqual(['button', 'image']);
152
- expect(alpha(heats[0])).toBeGreaterThan(alpha(heats[1]));
153
- expect(badges.map(badge => [badge.getAttribute(CLICK_MAP_BADGE_ATTRIBUTE), badge.textContent])).toEqual([['image', '250']]);
154
- cleanup();
155
- expect(frameDocument.querySelectorAll(`[${CLICK_MAP_HEAT_ATTRIBUTE}], [${CLICK_MAP_BADGE_ATTRIBUTE}]`)).toHaveLength(0);
156
- });
157
- it('selects a row by clicking its heat overlay', () => {
158
- const frameDocument = createDocument();
159
- const onSelect = jest.fn();
160
- decorateClickMap(frameDocument, {
161
- items: [item('text', PROMO, 'странице акции', 1)],
162
- mode: 'heat',
163
- onSelect
164
- });
165
- frameDocument.querySelector(`[${CLICK_MAP_HEAT_ATTRIBUTE}]`)?.click();
166
- expect(onSelect).toHaveBeenCalledWith('text');
167
- });
168
- });
@@ -1,18 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { render, screen } from '@testing-library/react';
3
- import { ExternalImagePreview } from '../ExternalImagePreview';
4
- describe('ExternalImagePreview', () => {
5
- it('sizes the image by CSS, not by width/height attributes', () => {
6
- render(_jsx(ExternalImagePreview, {
7
- src: "https://example.com/a.png",
8
- width: 120,
9
- height: 80,
10
- placeholder: _jsx("i", {})
11
- }));
12
- const img = screen.getByRole('img');
13
- expect(img).not.toHaveAttribute('width');
14
- expect(img).not.toHaveAttribute('height');
15
- expect(getComputedStyle(img).width).toBe('120px');
16
- expect(getComputedStyle(img).height).toBe('80px');
17
- });
18
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,201 +0,0 @@
1
- import { MAX_CAROUSEL_SLIDES } from '../constants';
2
- import { getEmptyLayout, getPreviewContent, getPreviewTexts, getValidSlides, isEmptyContent, resolveInboxLayout } from '../helpers';
3
- const HERO = 'https://cdn.example.com/hero.jpg';
4
- const SLIDE = {
5
- imageUrl: 'https://cdn.example.com/slide.jpg'
6
- };
7
- describe('resolveInboxLayout', () => {
8
- it('renders the requested layout when it can', () => {
9
- expect(resolveInboxLayout({
10
- layoutType: 'classic',
11
- title: 't',
12
- body: 'b'
13
- })).toBe('classic');
14
- expect(resolveInboxLayout({
15
- layoutType: 'banner',
16
- bannerUrl: HERO
17
- })).toBe('banner');
18
- expect(resolveInboxLayout({
19
- layoutType: 'captioned',
20
- title: 't',
21
- body: 'b',
22
- bannerUrl: HERO
23
- })).toBe('captioned');
24
- expect(resolveInboxLayout({
25
- layoutType: 'carousel',
26
- title: 't',
27
- body: 'b',
28
- carousel: [SLIDE]
29
- })).toBe('carousel');
30
- });
31
- it('degrades banner and captioned without a hero image into classic', () => {
32
- expect(resolveInboxLayout({
33
- layoutType: 'banner'
34
- })).toBe('classic');
35
- expect(resolveInboxLayout({
36
- layoutType: 'captioned',
37
- title: 't',
38
- body: 'b'
39
- })).toBe('classic');
40
- });
41
- it('degrades captioned and carousel without title or body into classic', () => {
42
- expect(resolveInboxLayout({
43
- layoutType: 'captioned',
44
- body: 'b',
45
- bannerUrl: HERO
46
- })).toBe('classic');
47
- expect(resolveInboxLayout({
48
- layoutType: 'captioned',
49
- title: 't',
50
- bannerUrl: HERO
51
- })).toBe('classic');
52
- expect(resolveInboxLayout({
53
- layoutType: 'carousel',
54
- body: 'b',
55
- carousel: [SLIDE]
56
- })).toBe('classic');
57
- expect(resolveInboxLayout({
58
- layoutType: 'carousel',
59
- title: 't',
60
- carousel: [SLIDE]
61
- })).toBe('classic');
62
- });
63
- it('degrades a carousel without valid slides into classic', () => {
64
- expect(resolveInboxLayout({
65
- layoutType: 'carousel',
66
- title: 't',
67
- body: 'b'
68
- })).toBe('classic');
69
- expect(resolveInboxLayout({
70
- layoutType: 'carousel',
71
- title: 't',
72
- body: 'b',
73
- carousel: [{
74
- caption: 'no image'
75
- }]
76
- })).toBe('classic');
77
- });
78
- it('uses the icon as the hero fallback', () => {
79
- expect(resolveInboxLayout({
80
- layoutType: 'banner',
81
- iconUrl: HERO
82
- })).toBe('banner');
83
- });
84
- it('applies the SDK heuristic to unknown or absent layouts', () => {
85
- expect(resolveInboxLayout({
86
- bannerUrl: HERO
87
- })).toBe('banner');
88
- expect(resolveInboxLayout({
89
- title: 't',
90
- body: 'b',
91
- bannerUrl: HERO
92
- })).toBe('captioned');
93
- expect(resolveInboxLayout({
94
- title: 't',
95
- body: 'b'
96
- })).toBe('classic');
97
- expect(resolveInboxLayout({
98
- layoutType: 'video',
99
- title: 't',
100
- body: 'b'
101
- })).toBe('classic');
102
- });
103
- });
104
- describe('getValidSlides', () => {
105
- it('drops slides without an image and keeps at most the SDK limit', () => {
106
- const slides = [...Array.from({
107
- length: MAX_CAROUSEL_SLIDES + 2
108
- }, (_, index) => ({
109
- imageUrl: `https://cdn.example.com/${index}.jpg`
110
- })), {
111
- caption: 'no image'
112
- }];
113
- const valid = getValidSlides(slides);
114
- expect(valid).toHaveLength(MAX_CAROUSEL_SLIDES);
115
- expect(valid.every(slide => !!slide.imageUrl)).toBe(true);
116
- });
117
- });
118
- describe('getPreviewContent', () => {
119
- const en = {
120
- title: 'en'
121
- };
122
- const de = {
123
- title: 'de'
124
- };
125
- it('prefers the explicit content over the localized map', () => {
126
- expect(getPreviewContent(de, {
127
- en
128
- }, 'en')).toBe(de);
129
- });
130
- it('picks by language with default/en/first fallbacks', () => {
131
- expect(getPreviewContent(null, {
132
- en,
133
- de
134
- }, 'de')).toBe(de);
135
- expect(getPreviewContent(null, {
136
- en,
137
- de
138
- }, 'fr')).toBe(en);
139
- expect(getPreviewContent(null, {
140
- de
141
- }, 'fr')).toBe(de);
142
- expect(getPreviewContent(null, undefined, 'en')).toBeNull();
143
- expect(getPreviewContent(null, {}, 'en')).toBeNull();
144
- });
145
- });
146
- describe('empty state', () => {
147
- it('detects content with nothing to render', () => {
148
- expect(isEmptyContent({
149
- layoutType: 'captioned'
150
- })).toBe(true);
151
- expect(isEmptyContent({
152
- carousel: [{
153
- caption: 'no image'
154
- }]
155
- })).toBe(true);
156
- expect(isEmptyContent({
157
- title: 't'
158
- })).toBe(false);
159
- expect(isEmptyContent({
160
- bannerUrl: 'https://cdn.example.com/hero.jpg'
161
- })).toBe(false);
162
- });
163
- it('shows the placeholder of the requested layout, classic for unknown', () => {
164
- expect(getEmptyLayout({
165
- layoutType: 'banner'
166
- })).toBe('banner');
167
- expect(getEmptyLayout({
168
- layoutType: 'video'
169
- })).toBe('classic');
170
- expect(getEmptyLayout({})).toBe('classic');
171
- });
172
- });
173
- describe('getPreviewTexts', () => {
174
- it('moves the body into the title slot for classic without a title', () => {
175
- expect(getPreviewTexts({
176
- body: 'b'
177
- }, 'classic')).toEqual({
178
- title: 'b',
179
- body: ''
180
- });
181
- expect(getPreviewTexts({
182
- title: 't',
183
- body: 'b'
184
- }, 'classic')).toEqual({
185
- title: 't',
186
- body: 'b'
187
- });
188
- });
189
- it('keeps the fields as-is for media layouts', () => {
190
- expect(getPreviewTexts({
191
- body: 'b'
192
- }, 'captioned')).toEqual({
193
- title: '',
194
- body: 'b'
195
- });
196
- expect(getPreviewTexts({}, 'classic')).toEqual({
197
- title: '',
198
- body: ''
199
- });
200
- });
201
- });
@@ -1,81 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { fireEvent, render, screen } from '@testing-library/react';
3
- import { NativeRichMediaPreview } from '../NativeRichMediaPreview';
4
- const lightContent = {
5
- displayType: 'modal',
6
- modal: {
7
- showClose: true,
8
- dimBackground: true,
9
- background: '#FFFFFFFF',
10
- title: {
11
- text: 'Hi',
12
- color: '#4B5057FF'
13
- },
14
- buttons: []
15
- }
16
- };
17
- const darkableContent = {
18
- ...lightContent,
19
- modal: {
20
- ...lightContent.modal,
21
- dark: {
22
- background: '#14161AFF',
23
- title: {
24
- color: '#F2F4F7FF'
25
- }
26
- }
27
- }
28
- };
29
- const themeChip = () => screen.getByLabelText('Switch light and dark');
30
- const renderPreview = (props = {}) => render(_jsx(NativeRichMediaPreview, {
31
- content: darkableContent,
32
- width: 304,
33
- height: 659,
34
- withThemeToggle: true,
35
- ...props
36
- }));
37
- describe('NativeRichMediaPreview theme toggle', () => {
38
- it('keeps its own theme when uncontrolled', () => {
39
- renderPreview();
40
- expect(themeChip()).toHaveAttribute('aria-pressed', 'false');
41
- fireEvent.click(themeChip());
42
- expect(themeChip()).toHaveAttribute('aria-pressed', 'true');
43
- });
44
- it('follows the theme prop instead of a click when controlled', () => {
45
- const onThemeChange = jest.fn();
46
- const {
47
- rerender
48
- } = renderPreview({
49
- theme: 'dark',
50
- onThemeChange
51
- });
52
- expect(themeChip()).toHaveAttribute('aria-pressed', 'true');
53
- fireEvent.click(themeChip());
54
- expect(onThemeChange).toHaveBeenCalledWith('light');
55
- expect(themeChip()).toHaveAttribute('aria-pressed', 'true');
56
- rerender(_jsx(NativeRichMediaPreview, {
57
- content: darkableContent,
58
- width: 304,
59
- height: 659,
60
- withThemeToggle: true,
61
- theme: "light",
62
- onThemeChange: onThemeChange
63
- }));
64
- expect(themeChip()).toHaveAttribute('aria-pressed', 'false');
65
- });
66
- it('reports the controlled theme even when the content has no dark overlay', () => {
67
- renderPreview({
68
- content: lightContent,
69
- theme: 'dark',
70
- onThemeChange: jest.fn()
71
- });
72
- expect(themeChip()).toHaveAttribute('aria-pressed', 'true');
73
- expect(themeChip()).not.toBeDisabled();
74
- });
75
- it('disables the chip on content without a dark overlay when uncontrolled', () => {
76
- renderPreview({
77
- content: lightContent
78
- });
79
- expect(themeChip()).toBeDisabled();
80
- });
81
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,37 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { render, screen } from '@testing-library/react';
3
- import { PageHeader } from '../components/PageHeader';
4
- import { PageHeaderSkeleton } from '../components/PageHeaderSkeleton';
5
- describe('PageHeader', () => {
6
- it('spaces the more-actions box only when there are actions', () => {
7
- const {
8
- rerender
9
- } = render(_jsx(PageHeader, {
10
- title: "Page",
11
- moreActions: _jsx("span", {
12
- children: "More"
13
- }),
14
- onSubmit: jest.fn()
15
- }));
16
- expect(getComputedStyle(screen.getByText('More').parentElement).marginRight).toBe('16px');
17
- rerender(_jsx(PageHeader, {
18
- title: "Page",
19
- moreActions: _jsx("span", {
20
- children: "More"
21
- })
22
- }));
23
- expect(getComputedStyle(screen.getByText('More').parentElement).marginRight).toBe('0px');
24
- });
25
- it('sizes the skeleton blocks without width/height attributes', () => {
26
- const {
27
- container
28
- } = render(_jsx(PageHeaderSkeleton, {}));
29
- const sized = Array.from(container.querySelectorAll('div')).filter(el => getComputedStyle(el).width === '68px');
30
- expect(sized).toHaveLength(2);
31
- sized.forEach(el => {
32
- expect(el).not.toHaveAttribute('width');
33
- expect(el).not.toHaveAttribute('height');
34
- expect(getComputedStyle(el).height).toBe('36px');
35
- });
36
- });
37
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,26 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { render, screen } from '@testing-library/react';
3
- import { Color } from '@pushwoosh/kit-constants';
4
- import { PushPreview } from '../PushPreview';
5
- describe('PushPreview', () => {
6
- it('wraps the extended description and keeps view off the DOM', () => {
7
- const {
8
- container
9
- } = render(_jsx(PushPreview, {
10
- view: "extended",
11
- pushPreset: null
12
- }));
13
- const description = screen.getByText('Message is empty…');
14
- expect(container.querySelector('[view]')).toBeNull();
15
- expect(getComputedStyle(description).whiteSpace).toBe('normal');
16
- });
17
- it('greys out the silent-push texts without a `locked` attribute', () => {
18
- const {
19
- container
20
- } = render(_jsx(PushPreview, {
21
- view: "silent"
22
- }));
23
- expect(container.querySelector('[locked]')).toBeNull();
24
- expect(getComputedStyle(screen.getByText('Silent push notification')).color.replace(/\s/g, '')).toBe(Color.LOCKED.replace(/\s/g, ''));
25
- });
26
- });