diff --git a/src/inApp/classes/IterableHtmlInAppContent.test.ts b/src/inApp/classes/IterableHtmlInAppContent.test.ts
new file mode 100644
index 000000000..3a836472a
--- /dev/null
+++ b/src/inApp/classes/IterableHtmlInAppContent.test.ts
@@ -0,0 +1,402 @@
+import { IterableEdgeInsets } from '../../core';
+
+import { IterableInAppContentType } from '../enums';
+import { IterableHtmlInAppContent } from './IterableHtmlInAppContent';
+import type { IterableHtmlInAppContentRaw } from '../types';
+
+describe('IterableHtmlInAppContent', () => {
+ describe('constructor', () => {
+ it('should create instance with valid parameters', () => {
+ // GIVEN valid parameters
+ const edgeInsets = new IterableEdgeInsets(10, 20, 30, 40);
+ const html = '
Hello World
';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should have the correct properties
+ expect(content.edgeInsets).toBe(edgeInsets);
+ expect(content.html).toBe(html);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance with empty HTML', () => {
+ // GIVEN empty HTML
+ const edgeInsets = new IterableEdgeInsets(0, 0, 0, 0);
+ const html = '';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should have empty HTML
+ expect(content.html).toBe('');
+ expect(content.edgeInsets).toBe(edgeInsets);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance with complex HTML', () => {
+ // GIVEN complex HTML content
+ const edgeInsets = new IterableEdgeInsets(5, 10, 15, 20);
+ const html = `
+
+
+ Test
+
+
+
+
+
Welcome
+
This is a test message
+
+
+
+ `;
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should have the complex HTML
+ expect(content.html).toBe(html);
+ expect(content.edgeInsets).toBe(edgeInsets);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance with HTML containing special characters', () => {
+ // GIVEN HTML with special characters
+ const edgeInsets = new IterableEdgeInsets(1, 2, 3, 4);
+ const html = 'Hello & Welcome! "Test" <tag>
';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should preserve special characters
+ expect(content.html).toBe(html);
+ expect(content.edgeInsets).toBe(edgeInsets);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance with HTML containing JavaScript', () => {
+ // GIVEN HTML with JavaScript
+ const edgeInsets = new IterableEdgeInsets(10, 10, 10, 10);
+ const html = `
+
+
+
Content with script
+
+ `;
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should preserve the JavaScript
+ expect(content.html).toBe(html);
+ expect(content.edgeInsets).toBe(edgeInsets);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+ });
+
+ describe('fromDict', () => {
+ it('should create instance from valid dictionary', () => {
+ // GIVEN a valid dictionary
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: 10,
+ left: 20,
+ bottom: 30,
+ right: 40,
+ },
+ html: 'Hello World
',
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should have the correct properties
+ expect(content.html).toBe('Hello World
');
+ expect(content.edgeInsets.top).toBe(10);
+ expect(content.edgeInsets.left).toBe(20);
+ expect(content.edgeInsets.bottom).toBe(30);
+ expect(content.edgeInsets.right).toBe(40);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance from dictionary with empty HTML', () => {
+ // GIVEN a dictionary with empty HTML
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: 0,
+ left: 0,
+ bottom: 0,
+ right: 0,
+ },
+ html: '',
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should have empty HTML
+ expect(content.html).toBe('');
+ expect(content.edgeInsets.top).toBe(0);
+ expect(content.edgeInsets.left).toBe(0);
+ expect(content.edgeInsets.bottom).toBe(0);
+ expect(content.edgeInsets.right).toBe(0);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance from dictionary with complex HTML', () => {
+ // GIVEN a dictionary with complex HTML
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: 5,
+ left: 10,
+ bottom: 15,
+ right: 20,
+ },
+ html: `
+
+ Test
+
+
+
Title
+
Paragraph with bold text
+
+
+
+ `,
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should have the complex HTML
+ expect(content.html).toBe(dict.html);
+ expect(content.edgeInsets.top).toBe(5);
+ expect(content.edgeInsets.left).toBe(10);
+ expect(content.edgeInsets.bottom).toBe(15);
+ expect(content.edgeInsets.right).toBe(20);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance from dictionary with negative edge insets', () => {
+ // GIVEN a dictionary with negative edge insets
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: -5,
+ left: -10,
+ bottom: -15,
+ right: -20,
+ },
+ html: 'Negative insets
',
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should have negative edge insets
+ expect(content.html).toBe('Negative insets
');
+ expect(content.edgeInsets.top).toBe(-5);
+ expect(content.edgeInsets.left).toBe(-10);
+ expect(content.edgeInsets.bottom).toBe(-15);
+ expect(content.edgeInsets.right).toBe(-20);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should create instance from dictionary with decimal edge insets', () => {
+ // GIVEN a dictionary with decimal edge insets
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: 1.5,
+ left: 2.7,
+ bottom: 3.9,
+ right: 4.1,
+ },
+ html: 'Decimal insets
',
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should have decimal edge insets
+ expect(content.html).toBe('Decimal insets
');
+ expect(content.edgeInsets.top).toBe(1.5);
+ expect(content.edgeInsets.left).toBe(2.7);
+ expect(content.edgeInsets.bottom).toBe(3.9);
+ expect(content.edgeInsets.right).toBe(4.1);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+ });
+
+ describe('property access', () => {
+ it('should allow property modification', () => {
+ // GIVEN an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(
+ new IterableEdgeInsets(10, 20, 30, 40),
+ 'Original
'
+ );
+
+ // WHEN modifying properties
+ const newEdgeInsets = new IterableEdgeInsets(100, 200, 300, 400);
+ content.edgeInsets = newEdgeInsets;
+ content.html = 'Modified
';
+
+ // THEN the properties should be updated
+ expect(content.edgeInsets).toBe(newEdgeInsets);
+ expect(content.html).toBe('Modified
');
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should maintain type property as html', () => {
+ // GIVEN an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(
+ new IterableEdgeInsets(10, 20, 30, 40),
+ 'Test
'
+ );
+
+ // THEN the type should always be html
+ expect(content.type).toBe(IterableInAppContentType.html);
+
+ // AND it should remain html even after property changes
+ content.html = 'Changed
';
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+ });
+
+ describe('edge cases', () => {
+ it('should handle HTML with only whitespace', () => {
+ // GIVEN HTML with only whitespace
+ const edgeInsets = new IterableEdgeInsets(10, 20, 30, 40);
+ const html = ' \n\t ';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should preserve the whitespace
+ expect(content.html).toBe(' \n\t ');
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should handle HTML with unicode characters', () => {
+ // GIVEN HTML with unicode characters
+ const edgeInsets = new IterableEdgeInsets(5, 5, 5, 5);
+ const html = 'Hello δΈη π π
';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should preserve unicode characters
+ expect(content.html).toBe('Hello δΈη π π
');
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should handle very long HTML content', () => {
+ // GIVEN very long HTML content
+ const edgeInsets = new IterableEdgeInsets(1, 1, 1, 1);
+ const longHtml = '' + 'x'.repeat(10000) + '
';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, longHtml);
+
+ // THEN it should handle the long content
+ expect(content.html).toBe(longHtml);
+ expect(content.html.length).toBe(longHtml.length); // Should match the original length
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should handle HTML with malformed tags', () => {
+ // GIVEN HTML with malformed tags
+ const edgeInsets = new IterableEdgeInsets(10, 10, 10, 10);
+ const html = 'Unclosed tag
Another unclosed Nested
';
+
+ // WHEN creating an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(edgeInsets, html);
+
+ // THEN it should preserve the malformed HTML
+ expect(content.html).toBe(html);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+ });
+
+ describe('interface compliance', () => {
+ it('should implement IterableInAppContent interface', () => {
+ // GIVEN an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(
+ new IterableEdgeInsets(10, 20, 30, 40),
+ 'Test
'
+ );
+
+ // THEN it should have the required type property
+ expect(content).toHaveProperty('type');
+ expect(typeof content.type).toBe('number');
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should be assignable to IterableInAppContent', () => {
+ // GIVEN an IterableHtmlInAppContent instance
+ const content = new IterableHtmlInAppContent(
+ new IterableEdgeInsets(10, 20, 30, 40),
+ 'Test
'
+ );
+
+ // WHEN assigning to IterableInAppContent
+ const inAppContent: { type: IterableInAppContentType } = content;
+
+ // THEN it should work without type errors
+ expect(inAppContent.type).toBe(IterableInAppContentType.html);
+ });
+ });
+
+ describe('fromDict with edge cases', () => {
+ it('should handle dictionary with NaN edge insets', () => {
+ // GIVEN a dictionary with NaN edge insets
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: NaN,
+ left: NaN,
+ bottom: NaN,
+ right: NaN,
+ },
+ html: 'NaN insets
',
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should handle NaN values
+ expect(content.html).toBe('NaN insets
');
+ expect(content.edgeInsets.top).toBeNaN();
+ expect(content.edgeInsets.left).toBeNaN();
+ expect(content.edgeInsets.bottom).toBeNaN();
+ expect(content.edgeInsets.right).toBeNaN();
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+
+ it('should handle dictionary with Infinity edge insets', () => {
+ // GIVEN a dictionary with Infinity edge insets
+ const dict: IterableHtmlInAppContentRaw = {
+ edgeInsets: {
+ top: Infinity,
+ left: -Infinity,
+ bottom: Infinity,
+ right: -Infinity,
+ },
+ html: 'Infinity insets
',
+ };
+
+ // WHEN creating from dictionary
+ const content = IterableHtmlInAppContent.fromDict(dict);
+
+ // THEN it should handle Infinity values
+ expect(content.html).toBe('Infinity insets
');
+ expect(content.edgeInsets.top).toBe(Infinity);
+ expect(content.edgeInsets.left).toBe(-Infinity);
+ expect(content.edgeInsets.bottom).toBe(Infinity);
+ expect(content.edgeInsets.right).toBe(-Infinity);
+ expect(content.type).toBe(IterableInAppContentType.html);
+ });
+ });
+});