55
66import openai
77import pytest
8+ from django .core .exceptions import ObjectDoesNotExist
89
910from apps .ai .agent .tools .rag .generator import Generator
1011
@@ -102,6 +103,10 @@ def test_generate_answer_success(self):
102103 with (
103104 patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
104105 patch ("openai.OpenAI" ) as mock_openai ,
106+ patch (
107+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
108+ return_value = "System prompt" ,
109+ ),
105110 ):
106111 mock_client = MagicMock ()
107112 mock_response = MagicMock ()
@@ -128,6 +133,10 @@ def test_generate_answer_with_custom_model(self):
128133 with (
129134 patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
130135 patch ("openai.OpenAI" ) as mock_openai ,
136+ patch (
137+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
138+ return_value = "System prompt" ,
139+ ),
131140 ):
132141 mock_client = MagicMock ()
133142 mock_response = MagicMock ()
@@ -150,6 +159,10 @@ def test_generate_answer_openai_error(self):
150159 with (
151160 patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
152161 patch ("openai.OpenAI" ) as mock_openai ,
162+ patch (
163+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
164+ return_value = "System prompt" ,
165+ ),
153166 ):
154167 mock_client = MagicMock ()
155168 mock_client .chat .completions .create .side_effect = openai .OpenAIError ("API Error" )
@@ -167,6 +180,10 @@ def test_generate_answer_with_empty_chunks(self):
167180 with (
168181 patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
169182 patch ("openai.OpenAI" ) as mock_openai ,
183+ patch (
184+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
185+ return_value = "System prompt" ,
186+ ),
170187 ):
171188 mock_client = MagicMock ()
172189 mock_response = MagicMock ()
@@ -184,14 +201,123 @@ def test_generate_answer_with_empty_chunks(self):
184201 assert "No context provided" in call_args [1 ]["messages" ][1 ]["content" ]
185202
186203 def test_system_prompt_content (self ):
187- """Test that system prompt contains expected content."""
188- assert "OWASP Foundation" in Generator .SYSTEM_PROMPT
189- assert "context" in Generator .SYSTEM_PROMPT .lower ()
190- assert "professional" in Generator .SYSTEM_PROMPT .lower ()
191- assert "latitude and longitude" in Generator .SYSTEM_PROMPT .lower ()
204+ """Test that system prompt passed to OpenAI comes from Prompt getter."""
205+ with (
206+ patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
207+ patch ("openai.OpenAI" ) as mock_openai ,
208+ patch (
209+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
210+ return_value = "OWASP Foundation system prompt" ,
211+ ) as mock_prompt_getter ,
212+ ):
213+ mock_client = MagicMock ()
214+ mock_response = MagicMock ()
215+ mock_response .choices = [MagicMock ()]
216+ mock_response .choices [0 ].message .content = "Answer"
217+ mock_client .chat .completions .create .return_value = mock_response
218+ mock_openai .return_value = mock_client
219+
220+ generator = Generator ()
221+ generator .generate_answer ("Q" , [])
222+
223+ call_args = mock_client .chat .completions .create .call_args
224+ assert call_args [1 ]["messages" ][0 ]["role" ] == "system"
225+ assert call_args [1 ]["messages" ][0 ]["content" ] == "OWASP Foundation system prompt"
226+ mock_prompt_getter .assert_called_once ()
227+
228+ def test_generate_answer_missing_system_prompt (self ):
229+ """Test answer generation when system prompt is missing."""
230+ with (
231+ patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
232+ patch ("openai.OpenAI" ) as mock_openai ,
233+ patch (
234+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
235+ return_value = None ,
236+ ),
237+ ):
238+ mock_client = MagicMock ()
239+ mock_openai .return_value = mock_client
240+
241+ generator = Generator ()
242+
243+ chunks = [{"source_name" : "Test" , "text" : "Test content" }]
244+
245+ with pytest .raises (
246+ ObjectDoesNotExist , match = "Prompt with key 'rag-system-prompt' not found"
247+ ):
248+ generator .generate_answer ("Test query" , chunks )
249+
250+ def test_generate_answer_empty_system_prompt (self ):
251+ """Test answer generation when system prompt is empty."""
252+ with (
253+ patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
254+ patch ("openai.OpenAI" ) as mock_openai ,
255+ patch (
256+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
257+ return_value = " " ,
258+ ),
259+ ):
260+ mock_client = MagicMock ()
261+ mock_openai .return_value = mock_client
262+
263+ generator = Generator ()
264+
265+ chunks = [{"source_name" : "Test" , "text" : "Test content" }]
266+
267+ with pytest .raises (
268+ ObjectDoesNotExist , match = "Prompt with key 'rag-system-prompt' not found"
269+ ):
270+ generator .generate_answer ("Test query" , chunks )
271+
272+ def test_generate_answer_empty_openai_response (self ):
273+ """Test answer generation when OpenAI returns empty content."""
274+ with (
275+ patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
276+ patch ("openai.OpenAI" ) as mock_openai ,
277+ patch (
278+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
279+ return_value = "System prompt" ,
280+ ),
281+ ):
282+ mock_client = MagicMock ()
283+ mock_response = MagicMock ()
284+ mock_response .choices = [MagicMock ()]
285+ mock_response .choices [0 ].message .content = ""
286+ mock_client .chat .completions .create .return_value = mock_response
287+ mock_openai .return_value = mock_client
288+
289+ generator = Generator ()
290+
291+ chunks = [{"source_name" : "Test" , "text" : "Test content" }]
292+ result = generator .generate_answer ("Test query" , chunks )
293+
294+ assert result == ""
295+
296+ def test_generate_answer_none_openai_response (self ):
297+ """Test answer generation when OpenAI returns None content."""
298+ with (
299+ patch .dict (os .environ , {"DJANGO_OPEN_AI_SECRET_KEY" : "test-key" }),
300+ patch ("openai.OpenAI" ) as mock_openai ,
301+ patch (
302+ "apps.core.models.prompt.Prompt.get_rag_system_prompt" ,
303+ return_value = "System prompt" ,
304+ ),
305+ ):
306+ mock_client = MagicMock ()
307+ mock_response = MagicMock ()
308+ mock_response .choices = [MagicMock ()]
309+ mock_response .choices [0 ].message .content = None
310+ mock_client .chat .completions .create .return_value = mock_response
311+ mock_openai .return_value = mock_client
312+
313+ generator = Generator ()
314+
315+ chunks = [{"source_name" : "Test" , "text" : "Test content" }]
316+
317+ with pytest .raises (AttributeError ):
318+ generator .generate_answer ("Test query" , chunks )
192319
193320 def test_constants (self ):
194321 """Test class constants have expected values."""
195322 assert Generator .MAX_TOKENS == 2000
196- assert isinstance (Generator .SYSTEM_PROMPT , str )
197- assert len (Generator .SYSTEM_PROMPT ) > 0
323+ assert Generator .TEMPERATURE == 0.4
0 commit comments