diff --git a/src/__tests__/IterableEmbeddedMessageElementsButton.test.ts b/src/__tests__/IterableEmbeddedMessageElementsButton.test.ts new file mode 100644 index 000000000..1524d1c5b --- /dev/null +++ b/src/__tests__/IterableEmbeddedMessageElementsButton.test.ts @@ -0,0 +1,91 @@ +import { IterableEmbeddedMessageElementsButton } from '../embedded/classes/IterableEmbeddedMessageElementsButton'; +import { IterableEmbeddedMessageElementsButtonAction } from '../embedded/classes/IterableEmbeddedMessageElementsButtonAction'; +import { Iterable } from '../core/classes/Iterable'; + +describe('IterableEmbeddedMessageButton', () => { + it('should create an instance with all properties including button action', () => { + Iterable.logger.log( + 'iterableEmbeddedMessageButton_fromDict_all_properties' + ); + + const dict = { + id: 'button-123', + title: 'Click Me!', + action: { type: 'openUrl', data: 'https://example.com' }, + }; + + const button = IterableEmbeddedMessageElementsButton.fromDict(dict); + + expect(button).toBeInstanceOf(IterableEmbeddedMessageElementsButton); + expect(button.id).toBe('button-123'); + expect(button.title).toBe('Click Me!'); + expect(button.action).toBeInstanceOf( + IterableEmbeddedMessageElementsButtonAction + ); + expect(button.action?.type).toBe('openUrl'); + expect(button.action?.data).toBe('https://example.com'); + }); + + it('should create an instance with only required properties', () => { + Iterable.logger.log('iterableEmbeddedMessageButton_fromDict_required_only'); + + const dict = { id: 'button-123' }; + + const button = IterableEmbeddedMessageElementsButton.fromDict(dict); + + expect(button).toBeInstanceOf(IterableEmbeddedMessageElementsButton); + expect(button.id).toBe('button-123'); + expect(button.title).toBeUndefined(); + expect(button.action).toBeUndefined(); + }); + + it('should create an instance with title but no action', () => { + Iterable.logger.log('iterableEmbeddedMessageButton_fromDict_title_only'); + + const dict = { + id: 'button-123', + title: 'Click Me!', + }; + + const button = IterableEmbeddedMessageElementsButton.fromDict(dict); + + expect(button).toBeInstanceOf(IterableEmbeddedMessageElementsButton); + expect(button.id).toBe('button-123'); + expect(button.title).toBe('Click Me!'); + expect(button.action).toBeUndefined(); + }); + + it('should throw an error if id is missing in fromDict', () => { + Iterable.logger.log('iterableEmbeddedMessageButton_fromDict_missing_id'); + + const dict = { + title: 'Click Me!', + action: { type: 'openUrl', data: 'https://example.com' }, + }; + + expect(() => IterableEmbeddedMessageElementsButton.fromDict(dict)).toThrow( + 'id is required' + ); + }); + + it('should handle button action with only type', () => { + Iterable.logger.log( + 'iterableEmbeddedMessageButton_fromDict_action_type_only' + ); + + const dict = { + id: 'button-123', + action: { type: 'close' }, + }; + + const button = IterableEmbeddedMessageElementsButton.fromDict(dict); + + expect(button).toBeInstanceOf(IterableEmbeddedMessageElementsButton); + expect(button.id).toBe('button-123'); + expect(button.action).toBeInstanceOf( + IterableEmbeddedMessageElementsButtonAction + ); + expect(button.action?.type).toBe('close'); + expect(button.action?.data).toBeUndefined(); + }); +}); diff --git a/src/__tests__/IterableEmbeddedMessageElementsButtonAction.test.ts b/src/__tests__/IterableEmbeddedMessageElementsButtonAction.test.ts new file mode 100644 index 000000000..fa172cb7c --- /dev/null +++ b/src/__tests__/IterableEmbeddedMessageElementsButtonAction.test.ts @@ -0,0 +1,40 @@ +import { IterableEmbeddedMessageElementsButtonAction } from '../embedded/classes/IterableEmbeddedMessageElementsButtonAction'; +import { Iterable } from '../core/classes/Iterable'; + +describe('IterableEmbeddedMessageDefaultAction', () => { + it('should create an instance with the correct properties', () => { + Iterable.logger.log( + 'iterableEmbeddedMessageElementsButtonAction_fromDict_valid_dictionary' + ); + + const dict = { type: 'openUrl', data: 'https://example.com' }; + const action = IterableEmbeddedMessageElementsButtonAction.fromDict(dict); + expect(action).toBeInstanceOf(IterableEmbeddedMessageElementsButtonAction); + expect(action.type).toBe('openUrl'); + expect(action.data).toBe('https://example.com'); + }); + + it('should create an instance from a dictionary with data omitted', () => { + Iterable.logger.log( + 'iterableEmbeddedMessageElementsButtonAction_fromDict_valid_dictionary_with_data_omitted' + ); + + const dict = { type: 'action://join', data: '' }; + const action = IterableEmbeddedMessageElementsButtonAction.fromDict(dict); + expect(action).toBeInstanceOf(IterableEmbeddedMessageElementsButtonAction); + expect(action.type).toBe('action://join'); + expect(action.data).toBe(''); + }); + + it('should throw an error if type is missing in fromDict', () => { + Iterable.logger.log( + 'iterableEmbeddedMessageElementsButtonAction_fromDict_invalid_dictionary_missing_type' + ); + + const dict = { data: 'foo' }; + + expect(() => + IterableEmbeddedMessageElementsButtonAction.fromDict(dict) + ).toThrow('type is required'); + }); +}); diff --git a/src/embedded/classes/IterableEmbeddedMessageElementsButton.ts b/src/embedded/classes/IterableEmbeddedMessageElementsButton.ts new file mode 100644 index 000000000..b1481c9e6 --- /dev/null +++ b/src/embedded/classes/IterableEmbeddedMessageElementsButton.ts @@ -0,0 +1,61 @@ +import { IterableEmbeddedMessageElementsButtonAction } from './IterableEmbeddedMessageElementsButtonAction'; + +/** + * IterableEmbeddedMessageElementsButton represents a button in an embedded message. + */ +export class IterableEmbeddedMessageElementsButton { + /** The ID for the embedded message button */ + readonly id: string; + /** The title for the embedded message button */ + readonly title?: string; + /** The action for the embedded message button */ + readonly action?: IterableEmbeddedMessageElementsButtonAction; + + /** + * Creates an instance of IterableEmbeddedMessageButton. + * + * @param id - The ID for the embedded message button. + * @param title - The title for the embedded message button. + * @param action - The action for the embedded message button. + */ + constructor( + id: string, + title?: string, + action?: IterableEmbeddedMessageElementsButtonAction + ) { + this.id = id; + this.title = title; + this.action = action; + } + + /** + * Creates an instance of `IterableEmbeddedMessageButton` from a dictionary object. + * + * @param dict - The dictionary object containing the properties to initialize the `IterableEmbeddedMessageButton` instance. + * @returns A new instance of `IterableEmbeddedMessageButton` initialized with the provided dictionary properties. + */ + static fromDict( + dict: Partial + ): IterableEmbeddedMessageElementsButton { + if (!dict.id) { + throw new Error('id is required'); + } + const action = dict.action + ? IterableEmbeddedMessageElementsButtonAction.fromDict(dict.action) + : undefined; + return new IterableEmbeddedMessageElementsButton( + dict.id, + dict.title, + action + ); + } +} + +/** + * An interface defining the dictionary object containing the properties for the embedded message button. + */ +export interface EmbeddedMessageElementsButtonDict { + id: string; + title?: string; + action?: IterableEmbeddedMessageElementsButtonAction; +} diff --git a/src/embedded/classes/IterableEmbeddedMessageElementsButtonAction.ts b/src/embedded/classes/IterableEmbeddedMessageElementsButtonAction.ts new file mode 100644 index 000000000..c8dd24708 --- /dev/null +++ b/src/embedded/classes/IterableEmbeddedMessageElementsButtonAction.ts @@ -0,0 +1,54 @@ +/** + * IterableEmbeddedMessageElementsButtonAction represents an action defined as a response to user events + * for an embedded message button. + */ +export class IterableEmbeddedMessageElementsButtonAction { + /** + * The type of iterable action + * For custom actions, the type is `action://` prefix followed by a custom action name + */ + readonly type: string; + + /** + * The url for the action when the type is `openUrl` + * For custom actions, data is empty + */ + readonly data?: string; + + /** + * Creates an instance of IterableEmbeddedMessageElementsButtonAction. + * + * @param type - The type of the action. + * @param data - Optional data associated with the action. + */ + constructor(type: string, data?: string) { + this.type = type; + this.data = data; + } + + /** + * Creates an instance of `IterableEmbeddedMessageElementsButtonAction` from a dictionary object. + * + * @param dict - The dictionary object containing the properties to initialize the `IterableEmbeddedMessageElementsButtonAction` instance. + * @returns A new instance of `IterableEmbeddedMessageElementsButtonAction` initialized with the provided dictionary properties. + */ + static fromDict( + dict: Partial + ): IterableEmbeddedMessageElementsButtonAction { + if (!dict.type) { + throw new Error('type is required'); + } + return new IterableEmbeddedMessageElementsButtonAction( + dict.type, + dict.data + ); + } +} + +/** + * An interface defining the dictionary object containing the properties for the embedded message button action. + */ +export interface EmbeddedMessageButtonActionDict { + type: string; + data?: string; +}