Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

from typing import get_args
from unittest.mock import MagicMock

from pyrit.executor.attack.component.prepended_conversation_config import PrependedConversationConfig
from pyrit.message_normalizer import ConversationContextNormalizer
from pyrit.models import ChatMessageRole


def test_default_init_apply_converters_to_all_roles():
config = PrependedConversationConfig()
assert config.apply_converters_to_roles == list(get_args(ChatMessageRole))


def test_default_init_message_normalizer_is_none():
config = PrependedConversationConfig()
assert config.message_normalizer is None


def test_default_init_non_chat_target_behavior():
config = PrependedConversationConfig()
assert config.non_chat_target_behavior == "normalize_first_turn"


def test_get_message_normalizer_returns_default_when_none():
config = PrependedConversationConfig()
normalizer = config.get_message_normalizer()
assert isinstance(normalizer, ConversationContextNormalizer)


def test_get_message_normalizer_returns_custom():
mock_normalizer = MagicMock()
config = PrependedConversationConfig(message_normalizer=mock_normalizer)
assert config.get_message_normalizer() is mock_normalizer


def test_default_class_method():
config = PrependedConversationConfig.default()
assert config.apply_converters_to_roles == list(get_args(ChatMessageRole))
assert config.message_normalizer is None
assert config.non_chat_target_behavior == "raise"


def test_for_non_chat_target_defaults():
config = PrependedConversationConfig.for_non_chat_target()
assert config.apply_converters_to_roles == list(get_args(ChatMessageRole))
assert config.message_normalizer is None
assert config.non_chat_target_behavior == "normalize_first_turn"


def test_for_non_chat_target_with_custom_normalizer():
mock_normalizer = MagicMock()
config = PrependedConversationConfig.for_non_chat_target(message_normalizer=mock_normalizer)
assert config.message_normalizer is mock_normalizer
assert config.non_chat_target_behavior == "normalize_first_turn"


def test_for_non_chat_target_with_specific_roles():
config = PrependedConversationConfig.for_non_chat_target(apply_converters_to_roles=["user"])
assert config.apply_converters_to_roles == ["user"]


def test_default_vs_init_differ_in_behavior():
default_config = PrependedConversationConfig.default()
init_config = PrependedConversationConfig()
assert default_config.non_chat_target_behavior == "raise"
assert init_config.non_chat_target_behavior == "normalize_first_turn"
2 changes: 2 additions & 0 deletions tests/unit/executor/attack/printer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
71 changes: 71 additions & 0 deletions tests/unit/executor/attack/printer/test_attack_result_printer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

import pytest

from pyrit.executor.attack.printer.attack_result_printer import AttackResultPrinter
from pyrit.models import AttackOutcome


class _ConcreteAttackResultPrinter(AttackResultPrinter):
async def print_result_async(self, result, **kwargs):
pass

async def print_conversation_async(self, result, **kwargs):
pass

async def print_summary_async(self, result):
pass


@pytest.fixture
def printer():
return _ConcreteAttackResultPrinter()


def test_get_outcome_icon_success():
assert AttackResultPrinter._get_outcome_icon(AttackOutcome.SUCCESS) == "\u2705"


def test_get_outcome_icon_failure():
assert AttackResultPrinter._get_outcome_icon(AttackOutcome.FAILURE) == "\u274c"


def test_get_outcome_icon_undetermined():
assert AttackResultPrinter._get_outcome_icon(AttackOutcome.UNDETERMINED) == "\u2753"


def test_format_time_milliseconds():
assert AttackResultPrinter._format_time(500) == "500ms"


def test_format_time_zero():
assert AttackResultPrinter._format_time(0) == "0ms"


def test_format_time_boundary_999():
assert AttackResultPrinter._format_time(999) == "999ms"


def test_format_time_seconds():
assert AttackResultPrinter._format_time(1000) == "1.00s"


def test_format_time_seconds_decimal():
assert AttackResultPrinter._format_time(2500) == "2.50s"


def test_format_time_boundary_59999():
assert AttackResultPrinter._format_time(59999) == "60.00s"


def test_format_time_minutes():
assert AttackResultPrinter._format_time(60000) == "1m 0s"


def test_format_time_minutes_and_seconds():
assert AttackResultPrinter._format_time(90000) == "1m 30s"


def test_format_time_multiple_minutes():
assert AttackResultPrinter._format_time(150000) == "2m 30s"
Loading
Loading