11# Copyright (c) Microsoft Corporation.
22# Licensed under the MIT license.
33
4+ import csv
5+ import json
46import os
57import tempfile
68from collections .abc import Sequence
79from pathlib import Path
810from unittest .mock import MagicMock , patch
911
12+ import pytest
13+
1014from pyrit .common .path import DB_DATA_PATH
1115from pyrit .memory import MemoryExporter , MemoryInterface
1216from pyrit .models import MessagePiece
@@ -103,8 +107,6 @@ def test_export_all_conversations_with_scores_correct_data(sqlite_instance: Memo
103107 assert file_path .exists ()
104108
105109 # Read and verify the exported JSON content
106- import json
107-
108110 with open (file_path ) as f :
109111 exported_data = json .load (f )
110112
@@ -141,8 +143,6 @@ def test_export_all_conversations_with_scores_empty_data(sqlite_instance: Memory
141143 assert file_path .exists ()
142144
143145 # Read and verify the exported JSON content is empty
144- import json
145-
146146 with open (file_path ) as f :
147147 exported_data = json .load (f )
148148
@@ -151,3 +151,57 @@ def test_export_all_conversations_with_scores_empty_data(sqlite_instance: Memory
151151 # Clean up the temp file
152152 if file_path .exists ():
153153 os .remove (file_path )
154+
155+
156+ @pytest .mark .parametrize ("export_type, suffix" , [("json" , ".json" ), ("csv" , ".csv" ), ("md" , ".md" )])
157+ def test_export_all_conversations_with_scores_respects_export_type (
158+ sqlite_instance : MemoryInterface , export_type : str , suffix : str
159+ ):
160+ sqlite_instance .exporter = MemoryExporter ()
161+
162+ with tempfile .NamedTemporaryFile (delete = False , suffix = suffix ) as temp_file :
163+ file_path = Path (temp_file .name )
164+ temp_file .close ()
165+
166+ try :
167+ with (
168+ patch .object (sqlite_instance , "get_message_pieces" ) as mock_get_pieces ,
169+ patch .object (sqlite_instance , "get_prompt_scores" ) as mock_get_scores ,
170+ ):
171+ mock_piece = MagicMock ()
172+ mock_piece .id = "piece_id_1234"
173+ mock_piece .to_dict .return_value = {
174+ "id" : "piece_id_1234" ,
175+ "converted_value" : "sample piece" ,
176+ }
177+
178+ mock_score = MagicMock ()
179+ mock_score .message_piece_id = "piece_id_1234"
180+ mock_score .to_dict .return_value = {"message_piece_id" : "piece_id_1234" , "score_value" : 10 }
181+
182+ mock_get_pieces .return_value = [mock_piece ]
183+ mock_get_scores .return_value = [mock_score ]
184+
185+ sqlite_instance .export_conversations (file_path = file_path , export_type = export_type )
186+
187+ assert file_path .exists ()
188+ exported_content = file_path .read_text (encoding = "utf-8" )
189+ assert "piece_id_1234" in exported_content
190+ assert "sample piece" in exported_content
191+
192+ if export_type == "json" :
193+ exported_data = json .loads (exported_content )
194+ assert len (exported_data ) == 1
195+ assert exported_data [0 ]["id" ] == "piece_id_1234"
196+ elif export_type == "csv" :
197+ with open (file_path , newline = "" ) as exported_file :
198+ reader = csv .DictReader (exported_file )
199+ assert reader .fieldnames == ["id" , "converted_value" , "scores" ]
200+ rows = list (reader )
201+ assert len (rows ) == 1
202+ assert rows [0 ]["id" ] == "piece_id_1234"
203+ elif export_type == "md" :
204+ assert exported_content .startswith ("| id | converted_value | scores |" )
205+ finally :
206+ if file_path .exists ():
207+ os .remove (file_path )
0 commit comments