Skip to content

Commit f14bf19

Browse files
committed
test: Add comprehensive media content tests for MessageTypeContentTests
Signed-off-by: Alex Klimenko <[email protected]>
1 parent c893629 commit f14bf19

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,158 @@ private List<Media> buildMediaList() {
196196
return List.of(imageMedia, pdfMedia);
197197
}
198198

199+
@Test
200+
public void userMessageWithEmptyMediaList() {
201+
given(this.openAiApi.chatCompletionEntity(this.pomptCaptor.capture(), this.headersCaptor.capture()))
202+
.willReturn(Mockito.mock(ResponseEntity.class));
203+
204+
this.chatModel.call(new Prompt(List.of(UserMessage.builder()
205+
.text("test message")
206+
.media(List.of()) // Empty media list
207+
.build())));
208+
209+
validateStringContent(this.pomptCaptor.getValue());
210+
assertThat(this.headersCaptor.getValue()).isEmpty();
211+
}
212+
213+
@Test
214+
public void userMessageWithEmptyText() {
215+
given(this.openAiApi.chatCompletionEntity(this.pomptCaptor.capture(), this.headersCaptor.capture()))
216+
.willReturn(Mockito.mock(ResponseEntity.class));
217+
218+
this.chatModel.call(new Prompt(List.of(UserMessage.builder().text("").media(this.buildMediaList()).build())));
219+
220+
ChatCompletionRequest request = this.pomptCaptor.getValue();
221+
assertThat(request.messages()).hasSize(1);
222+
var userMessage = request.messages().get(0);
223+
assertThat(userMessage.rawContent()).isInstanceOf(List.class);
224+
225+
@SuppressWarnings("unchecked")
226+
List<Map<String, Object>> mediaContents = (List<Map<String, Object>>) userMessage.rawContent();
227+
228+
// Should have empty text content plus media
229+
assertThat(mediaContents).hasSize(3);
230+
Map<String, Object> textContent = mediaContents.get(0);
231+
assertThat(textContent.get("type")).isEqualTo("text");
232+
assertThat(textContent.get("text")).isEqualTo("");
233+
}
234+
235+
@Test
236+
public void multipleMessagesWithMixedContentTypes() {
237+
given(this.openAiApi.chatCompletionEntity(this.pomptCaptor.capture(), this.headersCaptor.capture()))
238+
.willReturn(Mockito.mock(ResponseEntity.class));
239+
240+
this.chatModel.call(
241+
new Prompt(List.of(new SystemMessage("You are a helpful assistant"), new UserMessage("Simple message"),
242+
UserMessage.builder().text("Message with media").media(this.buildMediaList()).build())));
243+
244+
ChatCompletionRequest request = this.pomptCaptor.getValue();
245+
assertThat(request.messages()).hasSize(3);
246+
247+
// First message - system message with string content
248+
var systemMessage = request.messages().get(0);
249+
assertThat(systemMessage.rawContent()).isInstanceOf(String.class);
250+
assertThat(systemMessage.content()).isEqualTo("You are a helpful assistant");
251+
252+
// Second message - user message with string content
253+
var simpleUserMessage = request.messages().get(1);
254+
assertThat(simpleUserMessage.rawContent()).isInstanceOf(String.class);
255+
assertThat(simpleUserMessage.content()).isEqualTo("Simple message");
256+
257+
// Third message - user message with complex content
258+
var complexUserMessage = request.messages().get(2);
259+
assertThat(complexUserMessage.rawContent()).isInstanceOf(List.class);
260+
}
261+
262+
@Test
263+
public void userMessageWithSingleImageMedia() {
264+
given(this.openAiApi.chatCompletionEntity(this.pomptCaptor.capture(), this.headersCaptor.capture()))
265+
.willReturn(Mockito.mock(ResponseEntity.class));
266+
267+
URI imageUri = URI.create("http://example.com/image.jpg");
268+
Media imageMedia = Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(imageUri).build();
269+
270+
this.chatModel.call(new Prompt(
271+
List.of(UserMessage.builder().text("Describe this image").media(List.of(imageMedia)).build())));
272+
273+
ChatCompletionRequest request = this.pomptCaptor.getValue();
274+
assertThat(request.messages()).hasSize(1);
275+
var userMessage = request.messages().get(0);
276+
assertThat(userMessage.rawContent()).isInstanceOf(List.class);
277+
278+
@SuppressWarnings("unchecked")
279+
List<Map<String, Object>> mediaContents = (List<Map<String, Object>>) userMessage.rawContent();
280+
assertThat(mediaContents).hasSize(2);
281+
282+
// Text content
283+
Map<String, Object> textContent = mediaContents.get(0);
284+
assertThat(textContent.get("type")).isEqualTo("text");
285+
assertThat(textContent.get("text")).isEqualTo("Describe this image");
286+
287+
// Image content
288+
Map<String, Object> imageContent = mediaContents.get(1);
289+
assertThat(imageContent.get("type")).isEqualTo("image_url");
290+
assertThat(imageContent).containsKey("image_url");
291+
}
292+
293+
@Test
294+
public void streamWithMultipleMessagesAndMedia() {
295+
given(this.openAiApi.chatCompletionStream(this.pomptCaptor.capture(), this.headersCaptor.capture()))
296+
.willReturn(this.fluxResponse);
297+
298+
this.chatModel
299+
.stream(new Prompt(List.of(new SystemMessage("System prompt"),
300+
UserMessage.builder().text("User message with media").media(this.buildMediaList()).build())))
301+
.subscribe();
302+
303+
ChatCompletionRequest request = this.pomptCaptor.getValue();
304+
assertThat(request.messages()).hasSize(2);
305+
306+
// System message should be string
307+
assertThat(request.messages().get(0).rawContent()).isInstanceOf(String.class);
308+
309+
// User message should be complex
310+
assertThat(request.messages().get(1).rawContent()).isInstanceOf(List.class);
311+
assertThat(this.headersCaptor.getValue()).isEmpty();
312+
}
313+
314+
// Helper method for testing different image formats
315+
private List<Media> buildImageMediaList() {
316+
URI jpegUri = URI.create("http://example.com/image.jpg");
317+
Media jpegMedia = Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(jpegUri).build();
318+
319+
URI pngUri = URI.create("http://example.com/image.png");
320+
Media pngMedia = Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(pngUri).build();
321+
322+
URI webpUri = URI.create("http://example.com/image.webp");
323+
Media webpMedia = Media.builder().mimeType(MimeType.valueOf("image/webp")).data(webpUri).build();
324+
325+
return List.of(jpegMedia, pngMedia, webpMedia);
326+
}
327+
328+
@Test
329+
public void userMessageWithMultipleImageFormats() {
330+
given(this.openAiApi.chatCompletionEntity(this.pomptCaptor.capture(), this.headersCaptor.capture()))
331+
.willReturn(Mockito.mock(ResponseEntity.class));
332+
333+
this.chatModel.call(new Prompt(
334+
List.of(UserMessage.builder().text("Compare these images").media(this.buildImageMediaList()).build())));
335+
336+
ChatCompletionRequest request = this.pomptCaptor.getValue();
337+
assertThat(request.messages()).hasSize(1);
338+
var userMessage = request.messages().get(0);
339+
assertThat(userMessage.rawContent()).isInstanceOf(List.class);
340+
341+
@SuppressWarnings("unchecked")
342+
List<Map<String, Object>> mediaContents = (List<Map<String, Object>>) userMessage.rawContent();
343+
assertThat(mediaContents).hasSize(4); // text + 3 images
344+
345+
// Verify all are image types
346+
for (int i = 1; i < mediaContents.size(); i++) {
347+
Map<String, Object> imageContent = mediaContents.get(i);
348+
assertThat(imageContent.get("type")).isEqualTo("image_url");
349+
assertThat(imageContent).containsKey("image_url");
350+
}
351+
}
352+
199353
}

0 commit comments

Comments
 (0)