Skip to content

Commit a8d3008

Browse files
committed
test: add unit tests for IterableEmbeddedView component rendering and props passing
1 parent d74383f commit a8d3008

1 file changed

Lines changed: 373 additions & 0 deletions

File tree

Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { render } from '@testing-library/react-native';
3+
4+
import { IterableEmbeddedViewType } from '../enums/IterableEmbeddedViewType';
5+
import { IterableEmbeddedView } from './IterableEmbeddedView';
6+
import { IterableEmbeddedBanner } from './IterableEmbeddedBanner';
7+
import { IterableEmbeddedCard } from './IterableEmbeddedCard';
8+
import { IterableEmbeddedNotification } from './IterableEmbeddedNotification';
9+
10+
// Mock the child components
11+
jest.mock('./IterableEmbeddedBanner', () => ({
12+
IterableEmbeddedBanner: jest.fn(() => null),
13+
}));
14+
15+
jest.mock('./IterableEmbeddedCard', () => ({
16+
IterableEmbeddedCard: jest.fn(() => null),
17+
}));
18+
19+
jest.mock('./IterableEmbeddedNotification', () => ({
20+
IterableEmbeddedNotification: jest.fn(() => null),
21+
}));
22+
23+
describe('IterableEmbeddedView', () => {
24+
const mockMessage = {
25+
metadata: {
26+
messageId: 'test-message-123',
27+
campaignId: 123456,
28+
placementId: 'test-placement',
29+
},
30+
elements: {
31+
title: 'Test Title',
32+
body: 'Test Body',
33+
},
34+
} as any;
35+
36+
const mockConfig = {
37+
backgroundColor: '#FFFFFF',
38+
borderRadius: 8,
39+
} as any;
40+
41+
const mockOnButtonClick = jest.fn();
42+
43+
beforeEach(() => {
44+
jest.clearAllMocks();
45+
});
46+
47+
describe('View Type Rendering', () => {
48+
it('should render IterableEmbeddedCard when viewType is Card', () => {
49+
render(
50+
<IterableEmbeddedView
51+
viewType={IterableEmbeddedViewType.Card}
52+
message={mockMessage}
53+
/>
54+
);
55+
56+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
57+
expect(IterableEmbeddedBanner).not.toHaveBeenCalled();
58+
expect(IterableEmbeddedNotification).not.toHaveBeenCalled();
59+
});
60+
61+
it('should render IterableEmbeddedNotification when viewType is Notification', () => {
62+
render(
63+
<IterableEmbeddedView
64+
viewType={IterableEmbeddedViewType.Notification}
65+
message={mockMessage}
66+
/>
67+
);
68+
69+
expect(IterableEmbeddedNotification).toHaveBeenCalledTimes(1);
70+
expect(IterableEmbeddedCard).not.toHaveBeenCalled();
71+
expect(IterableEmbeddedBanner).not.toHaveBeenCalled();
72+
});
73+
74+
it('should render IterableEmbeddedBanner when viewType is Banner', () => {
75+
render(
76+
<IterableEmbeddedView
77+
viewType={IterableEmbeddedViewType.Banner}
78+
message={mockMessage}
79+
/>
80+
);
81+
82+
expect(IterableEmbeddedBanner).toHaveBeenCalledTimes(1);
83+
expect(IterableEmbeddedCard).not.toHaveBeenCalled();
84+
expect(IterableEmbeddedNotification).not.toHaveBeenCalled();
85+
});
86+
87+
it('should render null for invalid viewType', () => {
88+
render(
89+
<IterableEmbeddedView
90+
viewType={999 as IterableEmbeddedViewType}
91+
message={mockMessage}
92+
/>
93+
);
94+
95+
expect(IterableEmbeddedCard).not.toHaveBeenCalled();
96+
expect(IterableEmbeddedBanner).not.toHaveBeenCalled();
97+
expect(IterableEmbeddedNotification).not.toHaveBeenCalled();
98+
});
99+
100+
it('should render null for undefined viewType', () => {
101+
render(
102+
<IterableEmbeddedView
103+
viewType={undefined as any}
104+
message={mockMessage}
105+
/>
106+
);
107+
108+
expect(IterableEmbeddedCard).not.toHaveBeenCalled();
109+
expect(IterableEmbeddedBanner).not.toHaveBeenCalled();
110+
expect(IterableEmbeddedNotification).not.toHaveBeenCalled();
111+
});
112+
});
113+
114+
describe('Props Passing', () => {
115+
it('should pass message prop to Card component', () => {
116+
render(
117+
<IterableEmbeddedView
118+
viewType={IterableEmbeddedViewType.Card}
119+
message={mockMessage}
120+
/>
121+
);
122+
123+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
124+
expect(callArgs).toMatchObject({
125+
message: mockMessage,
126+
});
127+
});
128+
129+
it('should pass message prop to Banner component', () => {
130+
render(
131+
<IterableEmbeddedView
132+
viewType={IterableEmbeddedViewType.Banner}
133+
message={mockMessage}
134+
/>
135+
);
136+
137+
const callArgs = (IterableEmbeddedBanner as jest.Mock).mock.calls[0][0];
138+
expect(callArgs).toMatchObject({
139+
message: mockMessage,
140+
});
141+
});
142+
143+
it('should pass message prop to Notification component', () => {
144+
render(
145+
<IterableEmbeddedView
146+
viewType={IterableEmbeddedViewType.Notification}
147+
message={mockMessage}
148+
/>
149+
);
150+
151+
const callArgs = (IterableEmbeddedNotification as jest.Mock).mock
152+
.calls[0][0];
153+
expect(callArgs).toMatchObject({
154+
message: mockMessage,
155+
});
156+
});
157+
158+
it('should pass config prop to child component', () => {
159+
render(
160+
<IterableEmbeddedView
161+
viewType={IterableEmbeddedViewType.Card}
162+
message={mockMessage}
163+
config={mockConfig}
164+
/>
165+
);
166+
167+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
168+
expect(callArgs).toMatchObject({
169+
message: mockMessage,
170+
config: mockConfig,
171+
});
172+
});
173+
174+
it('should pass onButtonClick prop to child component', () => {
175+
render(
176+
<IterableEmbeddedView
177+
viewType={IterableEmbeddedViewType.Card}
178+
message={mockMessage}
179+
onButtonClick={mockOnButtonClick}
180+
/>
181+
);
182+
183+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
184+
expect(callArgs).toMatchObject({
185+
message: mockMessage,
186+
onButtonClick: mockOnButtonClick,
187+
});
188+
});
189+
190+
it('should pass all props to child component', () => {
191+
render(
192+
<IterableEmbeddedView
193+
viewType={IterableEmbeddedViewType.Card}
194+
message={mockMessage}
195+
config={mockConfig}
196+
onButtonClick={mockOnButtonClick}
197+
/>
198+
);
199+
200+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
201+
expect(callArgs).toMatchObject({
202+
message: mockMessage,
203+
config: mockConfig,
204+
onButtonClick: mockOnButtonClick,
205+
});
206+
});
207+
});
208+
209+
describe('Component Memoization', () => {
210+
it('should memoize component selection based on viewType', () => {
211+
const { rerender } = render(
212+
<IterableEmbeddedView
213+
viewType={IterableEmbeddedViewType.Card}
214+
message={mockMessage}
215+
/>
216+
);
217+
218+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
219+
220+
// Re-render with same viewType but different message
221+
const newMessage = {
222+
...mockMessage,
223+
metadata: {
224+
...mockMessage.metadata,
225+
messageId: 'different-id',
226+
},
227+
};
228+
229+
rerender(
230+
<IterableEmbeddedView
231+
viewType={IterableEmbeddedViewType.Card}
232+
message={newMessage}
233+
/>
234+
);
235+
236+
// Should still render Card component (memoization means same component reference)
237+
// Card should be called again with new props
238+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(2);
239+
const lastCallArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[1][0];
240+
expect(lastCallArgs).toMatchObject({
241+
message: newMessage,
242+
});
243+
});
244+
245+
it('should update component when viewType changes', () => {
246+
const { rerender } = render(
247+
<IterableEmbeddedView
248+
viewType={IterableEmbeddedViewType.Card}
249+
message={mockMessage}
250+
/>
251+
);
252+
253+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
254+
expect(IterableEmbeddedBanner).not.toHaveBeenCalled();
255+
256+
// Re-render with different viewType
257+
rerender(
258+
<IterableEmbeddedView
259+
viewType={IterableEmbeddedViewType.Banner}
260+
message={mockMessage}
261+
/>
262+
);
263+
264+
expect(IterableEmbeddedBanner).toHaveBeenCalledTimes(1);
265+
// Card was called only once (from initial render)
266+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
267+
});
268+
});
269+
270+
describe('Edge Cases', () => {
271+
it('should handle null config gracefully', () => {
272+
render(
273+
<IterableEmbeddedView
274+
viewType={IterableEmbeddedViewType.Card}
275+
message={mockMessage}
276+
config={null}
277+
/>
278+
);
279+
280+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
281+
expect(callArgs).toMatchObject({
282+
message: mockMessage,
283+
config: null,
284+
});
285+
});
286+
287+
it('should handle undefined config gracefully', () => {
288+
render(
289+
<IterableEmbeddedView
290+
viewType={IterableEmbeddedViewType.Card}
291+
message={mockMessage}
292+
config={undefined}
293+
/>
294+
);
295+
296+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
297+
expect(callArgs).toMatchObject({
298+
message: mockMessage,
299+
config: undefined,
300+
});
301+
});
302+
303+
it('should handle missing onButtonClick gracefully', () => {
304+
render(
305+
<IterableEmbeddedView
306+
viewType={IterableEmbeddedViewType.Card}
307+
message={mockMessage}
308+
/>
309+
);
310+
311+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
312+
const callArgs = (IterableEmbeddedCard as jest.Mock).mock.calls[0][0];
313+
expect(callArgs).toMatchObject({
314+
message: mockMessage,
315+
});
316+
});
317+
318+
it('should handle numeric viewType values correctly', () => {
319+
// Test with numeric value 0 (Banner)
320+
render(<IterableEmbeddedView viewType={0} message={mockMessage} />);
321+
expect(IterableEmbeddedBanner).toHaveBeenCalledTimes(1);
322+
323+
jest.clearAllMocks();
324+
325+
// Test with numeric value 1 (Card)
326+
render(<IterableEmbeddedView viewType={1} message={mockMessage} />);
327+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
328+
329+
jest.clearAllMocks();
330+
331+
// Test with numeric value 2 (Notification)
332+
render(<IterableEmbeddedView viewType={2} message={mockMessage} />);
333+
expect(IterableEmbeddedNotification).toHaveBeenCalledTimes(1);
334+
});
335+
});
336+
337+
describe('Component Type Verification', () => {
338+
it('should render correct component type for each enum value', () => {
339+
// Verify Banner enum value
340+
const bannerResult = render(
341+
<IterableEmbeddedView
342+
viewType={IterableEmbeddedViewType.Banner}
343+
message={mockMessage}
344+
/>
345+
);
346+
expect(IterableEmbeddedBanner).toHaveBeenCalledTimes(1);
347+
bannerResult.unmount();
348+
349+
jest.clearAllMocks();
350+
351+
// Verify Card enum value
352+
const cardResult = render(
353+
<IterableEmbeddedView
354+
viewType={IterableEmbeddedViewType.Card}
355+
message={mockMessage}
356+
/>
357+
);
358+
expect(IterableEmbeddedCard).toHaveBeenCalledTimes(1);
359+
cardResult.unmount();
360+
361+
jest.clearAllMocks();
362+
363+
// Verify Notification enum value
364+
render(
365+
<IterableEmbeddedView
366+
viewType={IterableEmbeddedViewType.Notification}
367+
message={mockMessage}
368+
/>
369+
);
370+
expect(IterableEmbeddedNotification).toHaveBeenCalledTimes(1);
371+
});
372+
});
373+
});

0 commit comments

Comments
 (0)