-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Add adaptive cards message formatting and unit tests
- Introduced new `adaptive_cards.py` module for formatting messages as adaptive cards, including functions for various block types such as headers, lines, facts, and expandable sections. - Implemented utility functions to format message blocks and handle different styles and colors. - Added comprehensive unit tests for adaptive card formatting, covering various scenarios including headers, icons, text styles, and expandable blocks. - Created fixture files for expected JSON outputs to validate the formatting logic.
1 parent
066e712
commit cc614cf
Showing
27 changed files
with
1,454 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
import uuid | ||
from typing import Any, Dict, List, Optional | ||
|
||
from elementary.messages.blocks import ( | ||
CodeBlock, | ||
DividerBlock, | ||
ExpandableBlock, | ||
FactListBlock, | ||
HeaderBlock, | ||
Icon, | ||
IconBlock, | ||
InlineBlock, | ||
LineBlock, | ||
LinesBlock, | ||
LinkBlock, | ||
TextBlock, | ||
TextStyle, | ||
) | ||
from elementary.messages.message_body import Color, MessageBlock, MessageBody | ||
|
||
ICON_TO_HTML = { | ||
Icon.RED_TRIANGLE: "🔺", | ||
Icon.X: "❌", | ||
Icon.WARNING: "⚠️", | ||
Icon.EXCLAMATION: "❗", | ||
Icon.CHECK: "✅", | ||
Icon.MAGNIFYING_GLASS: "🔎", | ||
Icon.HAMMER_AND_WRENCH: "🛠️", | ||
Icon.POLICE_LIGHT: "🚨", | ||
Icon.INFO: "ℹ️", | ||
Icon.EYE: "👁️", | ||
Icon.GEAR: "⚙️", | ||
Icon.BELL: "🔔", | ||
} | ||
|
||
COLOR_TO_STYLE = { | ||
Color.RED: "Attention", | ||
Color.YELLOW: "Warning", | ||
Color.GREEN: "Good", | ||
} | ||
|
||
|
||
def format_icon(icon: Icon) -> str: | ||
return ICON_TO_HTML[icon] | ||
|
||
|
||
def format_text_block(block: TextBlock) -> str: | ||
if block.style == TextStyle.BOLD: | ||
return f"**{block.text}**" | ||
elif block.style == TextStyle.ITALIC: | ||
return f"_{block.text}_" | ||
else: | ||
return block.text | ||
|
||
|
||
def format_inline_block(block: InlineBlock) -> str: | ||
if isinstance(block, IconBlock): | ||
return format_icon(block.icon) | ||
elif isinstance(block, TextBlock): | ||
return format_text_block(block) | ||
elif isinstance(block, LinkBlock): | ||
return f"[{block.text}]({block.url})" | ||
else: | ||
raise ValueError(f"Unsupported inline block type: {type(block)}") | ||
|
||
|
||
def format_line_block_text(block: LineBlock) -> str: | ||
return block.sep.join([format_inline_block(inline) for inline in block.inlines]) | ||
|
||
|
||
def format_line_block(block: LineBlock) -> Dict[str, Any]: | ||
text = format_line_block_text(block) | ||
|
||
return { | ||
"type": "TextBlock", | ||
"text": text, | ||
"wrap": True, | ||
} | ||
|
||
|
||
def format_lines_block(block: LinesBlock) -> List[Dict[str, Any]]: | ||
return [format_line_block(line_block) for line_block in block.lines] | ||
|
||
|
||
def format_header_block( | ||
block: HeaderBlock, color: Optional[Color] = None | ||
) -> Dict[str, Any]: | ||
return { | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": block.text, | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": True, | ||
} | ||
], | ||
"style": COLOR_TO_STYLE[color] if color else "Default", | ||
} | ||
|
||
|
||
def format_code_block(block: CodeBlock) -> Dict[str, Any]: | ||
return { | ||
"type": "Container", | ||
"style": "emphasis", | ||
"items": [ | ||
{ | ||
"type": "RichTextBlock", | ||
"inlines": [ | ||
{ | ||
"type": "TextRun", | ||
"text": block.text, | ||
"fontType": "Monospace", | ||
} | ||
], | ||
} | ||
], | ||
} | ||
|
||
|
||
def format_fact_list_block(block: FactListBlock) -> Dict[str, Any]: | ||
return { | ||
"type": "FactSet", | ||
"facts": [ | ||
{ | ||
"title": format_line_block_text(fact.title), | ||
"value": format_line_block_text(fact.value), | ||
} | ||
for fact in block.facts | ||
], | ||
} | ||
|
||
|
||
def format_message_block( | ||
block: MessageBlock, color: Optional[Color] = None | ||
) -> List[Dict[str, Any]]: | ||
if isinstance(block, HeaderBlock): | ||
return [format_header_block(block, color)] | ||
elif isinstance(block, CodeBlock): | ||
return [format_code_block(block)] | ||
elif isinstance(block, LinesBlock): | ||
return format_lines_block(block) | ||
elif isinstance(block, FactListBlock): | ||
return [format_fact_list_block(block)] | ||
elif isinstance(block, ExpandableBlock): | ||
return format_expandable_block(block) | ||
else: | ||
raise ValueError(f"Unsupported message block type: {type(block)}") | ||
|
||
|
||
def split_message_blocks_by_divider( | ||
blocks: List[MessageBlock], | ||
) -> List[List[MessageBlock]]: | ||
first_divider_index = next( | ||
(i for i, block in enumerate(blocks) if isinstance(block, DividerBlock)), | ||
None, | ||
) | ||
if first_divider_index is None: | ||
return [blocks] if blocks else [] | ||
return [ | ||
blocks[:first_divider_index], | ||
*split_message_blocks_by_divider(blocks[first_divider_index + 1 :]), | ||
] | ||
|
||
|
||
def format_divided_message_blocks( | ||
blocks: List[MessageBlock], | ||
divider: bool = False, | ||
color: Optional[Color] = None, | ||
) -> Dict[str, Any]: | ||
return { | ||
"type": "Container", | ||
"separator": divider, | ||
"items": [ | ||
item for block in blocks for item in format_message_block(block, color) | ||
], | ||
} | ||
|
||
|
||
def format_expandable_block(block: ExpandableBlock) -> List[Dict[str, Any]]: | ||
block_title = block.title | ||
expandable_target_id = f"expandable-{uuid.uuid4()}" | ||
return [ | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": block_title, | ||
"targetElements": [expandable_target_id], | ||
} | ||
], | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": expandable_target_id, | ||
"items": format_message_blocks(block.body), | ||
"isVisible": block.expanded, | ||
}, | ||
] | ||
|
||
|
||
def format_message_blocks( | ||
blocks: List[MessageBlock], color: Optional[Color] = None | ||
) -> List[Dict[str, Any]]: | ||
if not blocks: | ||
return [] | ||
|
||
message_blocks = split_message_blocks_by_divider(blocks) | ||
# The divider is not a block in adaptive cards, it's a property of the container. | ||
return [ | ||
format_divided_message_blocks(blocks, divider=True, color=color) | ||
for blocks in message_blocks | ||
] | ||
|
||
|
||
def format_adaptive_card_body(message: MessageBody) -> List[Dict[str, Any]]: | ||
return format_message_blocks(message.blocks, message.color) | ||
|
||
|
||
def format_adaptive_card(message: MessageBody, version: str = "1.6") -> Dict[str, Any]: | ||
if version < "1.2" or version > "1.6": | ||
raise ValueError(f"Version {version} is not supported") | ||
return { | ||
"type": "AdaptiveCard", | ||
"body": format_adaptive_card_body(message), | ||
"version": version, | ||
} |
Empty file.
Empty file.
Empty file.
93 changes: 93 additions & 0 deletions
93
tests/unit/messages/formats/adaptive_cards/fixtures/all_blocks_green.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Main Header", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Good" | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Normal text **Bold text** _Italic text_", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- First bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- Second bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "\u2705 Check item", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "FactSet", | ||
"facts": [ | ||
{ | ||
"title": "Status", | ||
"value": "Passed" | ||
}, | ||
{ | ||
"title": "Tags", | ||
"value": "test, example" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Show Details", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000001" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000001", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "\ud83d\udd0e **Details Section**", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Here's some content with a [link](https://example.com)", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": false | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
93 changes: 93 additions & 0 deletions
93
tests/unit/messages/formats/adaptive_cards/fixtures/all_blocks_no_color.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Main Header", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Default" | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Normal text **Bold text** _Italic text_", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- First bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- Second bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "\u2705 Check item", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "FactSet", | ||
"facts": [ | ||
{ | ||
"title": "Status", | ||
"value": "Passed" | ||
}, | ||
{ | ||
"title": "Tags", | ||
"value": "test, example" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Show Details", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000001" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000001", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "\ud83d\udd0e **Details Section**", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Here's some content with a [link](https://example.com)", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": false | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
93 changes: 93 additions & 0 deletions
93
tests/unit/messages/formats/adaptive_cards/fixtures/all_blocks_red.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Main Header", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Attention" | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Normal text **Bold text** _Italic text_", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- First bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- Second bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "\u2705 Check item", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "FactSet", | ||
"facts": [ | ||
{ | ||
"title": "Status", | ||
"value": "Passed" | ||
}, | ||
{ | ||
"title": "Tags", | ||
"value": "test, example" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Show Details", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000001" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000001", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "\ud83d\udd0e **Details Section**", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Here's some content with a [link](https://example.com)", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": false | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
93 changes: 93 additions & 0 deletions
93
tests/unit/messages/formats/adaptive_cards/fixtures/all_blocks_yellow.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Main Header", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Warning" | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Normal text **Bold text** _Italic text_", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- First bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- Second bullet point", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "\u2705 Check item", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "FactSet", | ||
"facts": [ | ||
{ | ||
"title": "Status", | ||
"value": "Passed" | ||
}, | ||
{ | ||
"title": "Tags", | ||
"value": "test, example" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Show Details", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000001" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000001", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "\ud83d\udd0e **Details Section**", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Here's some content with a [link](https://example.com)", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": false | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
17 changes: 17 additions & 0 deletions
17
tests/unit/messages/formats/adaptive_cards/fixtures/all_icons.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "RED_TRIANGLE \ud83d\udd3a X \u274c WARNING \u26a0\ufe0f EXCLAMATION \u2757 CHECK \u2705 MAGNIFYING_GLASS \ud83d\udd0e HAMMER_AND_WRENCH \ud83d\udee0\ufe0f POLICE_LIGHT \ud83d\udea8 INFO \u2139\ufe0f EYE \ud83d\udc41\ufe0f GEAR \u2699\ufe0f BELL \ud83d\udd14", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
32 changes: 32 additions & 0 deletions
32
tests/unit/messages/formats/adaptive_cards/fixtures/bullet_list.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "- First bullet", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "- Second bullet", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "\u2705 Check item 1", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "\u2705 Check item 2", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
28 changes: 28 additions & 0 deletions
28
tests/unit/messages/formats/adaptive_cards/fixtures/code_block_200.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"style": "emphasis", | ||
"items": [ | ||
{ | ||
"type": "RichTextBlock", | ||
"inlines": [ | ||
{ | ||
"type": "TextRun", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, c", | ||
"fontType": "Monospace" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
28 changes: 28 additions & 0 deletions
28
tests/unit/messages/formats/adaptive_cards/fixtures/code_block_50.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"style": "emphasis", | ||
"items": [ | ||
{ | ||
"type": "RichTextBlock", | ||
"inlines": [ | ||
{ | ||
"type": "TextRun", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing", | ||
"fontType": "Monospace" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
28 changes: 28 additions & 0 deletions
28
tests/unit/messages/formats/adaptive_cards/fixtures/code_block_500.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"style": "emphasis", | ||
"items": [ | ||
{ | ||
"type": "RichTextBlock", | ||
"inlines": [ | ||
{ | ||
"type": "TextRun", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adip", | ||
"fontType": "Monospace" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/unit/messages/formats/adaptive_cards/fixtures/colored_header.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Test Header", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Good" | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
44 changes: 44 additions & 0 deletions
44
tests/unit/messages/formats/adaptive_cards/fixtures/divider_blocks.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "First Section", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Default" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Second Section", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Default" | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
42 changes: 42 additions & 0 deletions
42
tests/unit/messages/formats/adaptive_cards/fixtures/expandable_block.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Show More", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000001" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000001", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Hidden content", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": false | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
21 changes: 21 additions & 0 deletions
21
tests/unit/messages/formats/adaptive_cards/fixtures/fact_list.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "FactSet", | ||
"facts": [ | ||
{ | ||
"title": "Status", | ||
"value": "Passed" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
77 changes: 77 additions & 0 deletions
77
tests/unit/messages/formats/adaptive_cards/fixtures/nested_expandable.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Outer Block", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000001" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000001", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "\ud83d\udd0e **Title with Icon**", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "TextBlock", | ||
"text": "Some content with a [link](https://example.com)", | ||
"wrap": true | ||
}, | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.ToggleVisibility", | ||
"title": "Inner Block", | ||
"targetElements": [ | ||
"expandable-00000000-0000-0000-0000-000000000002" | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "Container", | ||
"id": "expandable-00000000-0000-0000-0000-000000000002", | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Inner content", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": true | ||
} | ||
] | ||
} | ||
], | ||
"isVisible": false | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/unit/messages/formats/adaptive_cards/fixtures/simple_header.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "Container", | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Test Header", | ||
"weight": "bolder", | ||
"size": "large", | ||
"wrap": true | ||
} | ||
], | ||
"style": "Default" | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
17 changes: 17 additions & 0 deletions
17
tests/unit/messages/formats/adaptive_cards/fixtures/text_length_1000.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, con", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
17 changes: 17 additions & 0 deletions
17
tests/unit/messages/formats/adaptive_cards/fixtures/text_length_200.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, c", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
17 changes: 17 additions & 0 deletions
17
tests/unit/messages/formats/adaptive_cards/fixtures/text_length_50.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
17 changes: 17 additions & 0 deletions
17
tests/unit/messages/formats/adaptive_cards/fixtures/text_length_500.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adip", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
17 changes: 17 additions & 0 deletions
17
tests/unit/messages/formats/adaptive_cards/fixtures/text_styles.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "Container", | ||
"separator": true, | ||
"items": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Normal text **Bold text** _Italic text_", | ||
"wrap": true | ||
} | ||
] | ||
} | ||
], | ||
"version": "1.6" | ||
} |
373 changes: 373 additions & 0 deletions
373
tests/unit/messages/formats/adaptive_cards/test_adaptive_cards.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,373 @@ | ||
""" | ||
Tests for adaptive cards message format. | ||
The expected results are saved as JSON files in the resources/ directory. | ||
These files can be viewed and tested using: | ||
1. VS Code's Adaptive Cards extension | ||
2. Adaptive Cards Designer (https://adaptivecards.io/designer/) - useful for checking how cards | ||
look across different products, devices, themes and schema versions | ||
""" | ||
|
||
import uuid | ||
from pathlib import Path | ||
from typing import List, Union | ||
|
||
import pytest | ||
|
||
from elementary.messages.block_builders import BulletListBlock | ||
from elementary.messages.blocks import ( | ||
CodeBlock, | ||
DividerBlock, | ||
ExpandableBlock, | ||
FactBlock, | ||
FactListBlock, | ||
HeaderBlock, | ||
Icon, | ||
IconBlock, | ||
LineBlock, | ||
LinesBlock, | ||
LinkBlock, | ||
TextBlock, | ||
TextStyle, | ||
) | ||
from elementary.messages.formats.adaptive_cards import format_adaptive_card | ||
from elementary.messages.message_body import Color, MessageBody | ||
from tests.unit.messages.utils import assert_expected_json, get_expected_json_path | ||
|
||
FIXTURES_DIR = Path(__file__).resolve().parent / "fixtures" | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def mock_uuid(monkeypatch): | ||
class MockUUID: | ||
def __init__(self): | ||
self.counter = 0 | ||
|
||
def __call__(self): | ||
self.counter += 1 | ||
return uuid.UUID( | ||
f"00000000-0000-0000-0000-{self.counter:012d}" # noqa: E231 | ||
) | ||
|
||
mock = MockUUID() | ||
monkeypatch.setattr(uuid, "uuid4", mock) | ||
return mock | ||
|
||
|
||
def test_format_message_body_simple_header(): | ||
message_body = MessageBody(blocks=[HeaderBlock(text="Test Header")], color=None) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "simple_header.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_colored_header(): | ||
message_body = MessageBody( | ||
blocks=[HeaderBlock(text="Test Header")], color=Color.GREEN | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "colored_header.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_all_icons(): | ||
icon_blocks: List[Union[TextBlock, IconBlock]] = [] | ||
for icon in Icon: | ||
icon_blocks.append(TextBlock(text=icon.name)) | ||
icon_blocks.append(IconBlock(icon=icon)) | ||
message_body = MessageBody( | ||
blocks=[LinesBlock(lines=[LineBlock(inlines=icon_blocks)])] | ||
) | ||
result = format_adaptive_card(message_body) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "all_icons.json") | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_text_styles(): | ||
message_body = MessageBody( | ||
blocks=[ | ||
LinesBlock( | ||
lines=[ | ||
LineBlock( | ||
inlines=[ | ||
TextBlock(text="Normal text"), | ||
TextBlock(text="Bold text", style=TextStyle.BOLD), | ||
TextBlock(text="Italic text", style=TextStyle.ITALIC), | ||
] | ||
) | ||
] | ||
) | ||
] | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "text_styles.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_fact_list(): | ||
message_body = MessageBody( | ||
blocks=[ | ||
FactListBlock( | ||
facts=[ | ||
FactBlock( | ||
title=LineBlock(inlines=[TextBlock(text="Status")]), | ||
value=LineBlock(inlines=[TextBlock(text="Passed")]), | ||
), | ||
] | ||
) | ||
] | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "fact_list.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_expandable_block(): | ||
message_body = MessageBody( | ||
blocks=[ | ||
ExpandableBlock( | ||
title="Show More", | ||
body=[ | ||
LinesBlock( | ||
lines=[LineBlock(inlines=[TextBlock(text="Hidden content")])] | ||
) | ||
], | ||
expanded=False, | ||
) | ||
] | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "expandable_block.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_divider_blocks(): | ||
message_body = MessageBody( | ||
blocks=[ | ||
HeaderBlock(text="First Section"), | ||
DividerBlock(), | ||
HeaderBlock(text="Second Section"), | ||
] | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "divider_blocks.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_bullet_lists(): | ||
message_body = MessageBody( | ||
blocks=[ | ||
BulletListBlock( | ||
icon="-", | ||
lines=[ | ||
LineBlock(inlines=[TextBlock(text="First bullet")]), | ||
LineBlock(inlines=[TextBlock(text="Second bullet")]), | ||
], | ||
), | ||
BulletListBlock( | ||
icon=Icon.CHECK, | ||
lines=[ | ||
LineBlock(inlines=[TextBlock(text="Check item 1")]), | ||
LineBlock(inlines=[TextBlock(text="Check item 2")]), | ||
], | ||
), | ||
] | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "bullet_list.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
def test_format_message_body_nested_expandable(): | ||
message_body = MessageBody( | ||
blocks=[ | ||
ExpandableBlock( | ||
title="Outer Block", | ||
body=[ | ||
LinesBlock( | ||
lines=[ | ||
LineBlock( | ||
inlines=[ | ||
IconBlock(icon=Icon.MAGNIFYING_GLASS), | ||
TextBlock( | ||
text="Title with Icon", style=TextStyle.BOLD | ||
), | ||
] | ||
), | ||
LineBlock( | ||
inlines=[ | ||
TextBlock(text="Some content with a"), | ||
LinkBlock(text="link", url="https://example.com"), | ||
] | ||
), | ||
] | ||
), | ||
ExpandableBlock( | ||
title="Inner Block", | ||
body=[ | ||
LinesBlock( | ||
lines=[ | ||
LineBlock(inlines=[TextBlock(text="Inner content")]) | ||
] | ||
) | ||
], | ||
expanded=True, | ||
), | ||
], | ||
expanded=False, | ||
) | ||
] | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, "nested_expandable.json") | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"color,expected_file", | ||
[ | ||
pytest.param(None, "all_blocks_no_color.json", id="no_color"), | ||
pytest.param(Color.RED, "all_blocks_red.json", id="red"), | ||
pytest.param(Color.YELLOW, "all_blocks_yellow.json", id="yellow"), | ||
pytest.param(Color.GREEN, "all_blocks_green.json", id="green"), | ||
], | ||
) | ||
def test_format_message_body_all_blocks(color, expected_file): | ||
"""Test a comprehensive message that includes all block types with different colors.""" | ||
message_body = MessageBody( | ||
blocks=[ | ||
HeaderBlock(text="Main Header"), | ||
LinesBlock( | ||
lines=[ | ||
LineBlock( | ||
inlines=[ | ||
TextBlock(text="Normal text"), | ||
TextBlock(text="Bold text", style=TextStyle.BOLD), | ||
TextBlock(text="Italic text", style=TextStyle.ITALIC), | ||
] | ||
) | ||
] | ||
), | ||
BulletListBlock( | ||
icon="-", | ||
lines=[ | ||
LineBlock(inlines=[TextBlock(text="First bullet point")]), | ||
LineBlock(inlines=[TextBlock(text="Second bullet point")]), | ||
], | ||
), | ||
BulletListBlock( | ||
icon=Icon.CHECK, | ||
lines=[LineBlock(inlines=[TextBlock(text="Check item")])], | ||
), | ||
FactListBlock( | ||
facts=[ | ||
FactBlock( | ||
title=LineBlock(inlines=[TextBlock(text="Status")]), | ||
value=LineBlock(inlines=[TextBlock(text="Passed")]), | ||
), | ||
FactBlock( | ||
title=LineBlock(inlines=[TextBlock(text="Tags")]), | ||
value=LineBlock(inlines=[TextBlock(text="test, example")]), | ||
), | ||
] | ||
), | ||
ExpandableBlock( | ||
title="Show Details", | ||
body=[ | ||
LinesBlock( | ||
lines=[ | ||
LineBlock( | ||
inlines=[ | ||
IconBlock(icon=Icon.MAGNIFYING_GLASS), | ||
TextBlock( | ||
text="Details Section", style=TextStyle.BOLD | ||
), | ||
] | ||
), | ||
LineBlock( | ||
inlines=[ | ||
TextBlock(text="Here's some content with a"), | ||
LinkBlock(text="link", url="https://example.com"), | ||
] | ||
), | ||
] | ||
) | ||
], | ||
expanded=False, | ||
), | ||
], | ||
color=color, | ||
) | ||
expected_json_path = get_expected_json_path(FIXTURES_DIR, expected_file) | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"version,should_raise", | ||
[ | ||
pytest.param("1.6", False, id="supported_version"), | ||
pytest.param("1.1", True, id="unsupported_version_low"), | ||
pytest.param("1.7", True, id="unsupported_version_high"), | ||
], | ||
) | ||
def test_format_version_validation(version, should_raise): | ||
message_body = MessageBody(blocks=[HeaderBlock(text="Test")]) | ||
|
||
if should_raise: | ||
try: | ||
format_adaptive_card(message_body, version=version) | ||
assert False, f"Expected ValueError for version {version}" | ||
except ValueError: | ||
pass | ||
else: | ||
result = format_adaptive_card(message_body, version=version) | ||
assert result["version"] == version | ||
assert result["type"] == "AdaptiveCard" | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"text_length", | ||
[ | ||
pytest.param(50, id="short_code"), | ||
pytest.param(200, id="medium_code"), | ||
pytest.param(500, id="long_code"), | ||
], | ||
) | ||
def test_format_message_body_code_block(text_length: int): | ||
lorem_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " * ( | ||
(text_length + 49) // 50 | ||
) | ||
lorem_text = lorem_text[:text_length] | ||
|
||
message_body = MessageBody(blocks=[CodeBlock(text=lorem_text)]) | ||
expected_json_path = get_expected_json_path( | ||
FIXTURES_DIR, f"code_block_{text_length}.json" | ||
) | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"text_length", | ||
[ | ||
pytest.param(50, id="short_text"), | ||
pytest.param(200, id="medium_text"), | ||
pytest.param(500, id="long_text"), | ||
pytest.param(1000, id="very_long_text"), | ||
], | ||
) | ||
def test_format_message_body_text_length(text_length: int): | ||
lorem_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " * ( | ||
(text_length + 49) // 50 | ||
) | ||
lorem_text = lorem_text[:text_length] | ||
|
||
message_body = MessageBody( | ||
blocks=[LinesBlock(lines=[LineBlock(inlines=[TextBlock(text=lorem_text)])])] | ||
) | ||
expected_json_path = get_expected_json_path( | ||
FIXTURES_DIR, f"text_length_{text_length}.json" | ||
) | ||
result = format_adaptive_card(message_body) | ||
assert_expected_json(result, expected_json_path) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import json | ||
import os | ||
from pathlib import Path | ||
|
||
from elementary.utils.log import get_logger | ||
|
||
logger = get_logger(__name__) | ||
|
||
|
||
# Set to True to override the expected JSON files with the actual results | ||
# This is useful for updating the expected JSON files with the actual results, for development purposes only! | ||
OVERRIDE = os.getenv("OVERRIDE", "false").lower() == "true" | ||
|
||
|
||
def get_expected_json_path(fixture_dir: Path, filename: str) -> Path: | ||
path = fixture_dir / filename | ||
if not path.exists(): | ||
path.write_text(json.dumps({})) | ||
return path | ||
|
||
|
||
def assert_expected_json(result: dict, expected_json_path: Path) -> None: | ||
if OVERRIDE: | ||
logger.warning(f"Overriding expected JSON file: {expected_json_path}") | ||
print("writing to file", OVERRIDE) | ||
expected_json_path.write_text(json.dumps(result, indent=2)) | ||
expected = json.loads(expected_json_path.read_text()) | ||
assert json.dumps(result, indent=2) == json.dumps(expected, indent=2) |