Skip to content

Commit 947ca58

Browse files
committed
Revert "Merge remote-tracking branch 'upstream/main'"
This reverts commit e954045, reversing changes made to f17dfa1.
1 parent e954045 commit 947ca58

File tree

12 files changed

+2
-1029
lines changed

12 files changed

+2
-1029
lines changed

advisors/spring-ai-advisors-vector-store/src/test/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisorTests.java

Lines changed: 0 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -243,163 +243,4 @@ public void qaAdvisorTakesUserParameterizedUserMessagesIntoAccountForSimilarityS
243243
Assertions.assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery);
244244
}
245245

246-
@Test
247-
public void qaAdvisorWithMultipleFilterParameters() {
248-
given(this.chatModel.call(this.promptCaptor.capture()))
249-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Filtered response"))),
250-
ChatResponseMetadata.builder().build()));
251-
252-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
253-
.willReturn(List.of(new Document("doc1"), new Document("doc2")));
254-
255-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
256-
.searchRequest(SearchRequest.builder().topK(10).build())
257-
.build();
258-
259-
var chatClient = ChatClient.builder(this.chatModel)
260-
.defaultAdvisors(qaAdvisor)
261-
.build();
262-
263-
chatClient.prompt()
264-
.user("Complex query")
265-
.advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "type == 'Documentation' AND status == 'Published'"))
266-
.call()
267-
.chatResponse();
268-
269-
var capturedFilter = this.vectorSearchCaptor.getValue().getFilterExpression();
270-
assertThat(capturedFilter).isNotNull();
271-
// The filter should be properly constructed with AND operation
272-
assertThat(capturedFilter.toString()).contains("type");
273-
assertThat(capturedFilter.toString()).contains("Documentation");
274-
}
275-
276-
@Test
277-
public void qaAdvisorWithDifferentSimilarityThresholds() {
278-
given(this.chatModel.call(this.promptCaptor.capture()))
279-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("High threshold response"))),
280-
ChatResponseMetadata.builder().build()));
281-
282-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
283-
.willReturn(List.of(new Document("relevant doc")));
284-
285-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
286-
.searchRequest(SearchRequest.builder().similarityThreshold(0.95).topK(3).build())
287-
.build();
288-
289-
var chatClient = ChatClient.builder(this.chatModel)
290-
.defaultAdvisors(qaAdvisor)
291-
.build();
292-
293-
chatClient.prompt()
294-
.user("Specific question requiring high similarity")
295-
.call()
296-
.chatResponse();
297-
298-
assertThat(this.vectorSearchCaptor.getValue().getSimilarityThreshold()).isEqualTo(0.95);
299-
assertThat(this.vectorSearchCaptor.getValue().getTopK()).isEqualTo(3);
300-
}
301-
302-
@Test
303-
public void qaAdvisorWithComplexParameterizedTemplate() {
304-
given(this.chatModel.call(this.promptCaptor.capture()))
305-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Complex template response"))),
306-
ChatResponseMetadata.builder().build()));
307-
308-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
309-
.willReturn(List.of(new Document("template doc")));
310-
311-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
312-
.searchRequest(SearchRequest.builder().build())
313-
.build();
314-
315-
var chatClient = ChatClient.builder(this.chatModel)
316-
.defaultAdvisors(qaAdvisor)
317-
.build();
318-
319-
var complexTemplate = "Please analyze {topic} considering {aspect1} and {aspect2} for user {userId}";
320-
chatClient.prompt()
321-
.user(u -> u.text(complexTemplate)
322-
.param("topic", "machine learning")
323-
.param("aspect1", "performance")
324-
.param("aspect2", "scalability")
325-
.param("userId", "user1"))
326-
.call()
327-
.chatResponse();
328-
329-
var expectedQuery = "Please analyze machine learning considering performance and scalability for user user1";
330-
assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery);
331-
332-
Message userMessage = this.promptCaptor.getValue().getInstructions().get(0);
333-
assertThat(userMessage.getText()).contains(expectedQuery);
334-
assertThat(userMessage.getText()).doesNotContain("{topic}");
335-
assertThat(userMessage.getText()).doesNotContain("{aspect1}");
336-
assertThat(userMessage.getText()).doesNotContain("{aspect2}");
337-
assertThat(userMessage.getText()).doesNotContain("{userId}");
338-
}
339-
340-
@Test
341-
public void qaAdvisorWithDocumentsContainingMetadata() {
342-
given(this.chatModel.call(this.promptCaptor.capture()))
343-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Metadata response"))),
344-
ChatResponseMetadata.builder().build()));
345-
346-
var docWithMetadata1 = new Document("First document content", Map.of("source", "wiki", "author", "John"));
347-
var docWithMetadata2 = new Document("Second document content", Map.of("source", "manual", "version", "2.1"));
348-
349-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
350-
.willReturn(List.of(docWithMetadata1, docWithMetadata2));
351-
352-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
353-
.searchRequest(SearchRequest.builder().topK(2).build())
354-
.build();
355-
356-
var chatClient = ChatClient.builder(this.chatModel)
357-
.defaultAdvisors(qaAdvisor)
358-
.build();
359-
360-
chatClient.prompt()
361-
.user("Question about documents with metadata")
362-
.call()
363-
.chatResponse();
364-
365-
Message userMessage = this.promptCaptor.getValue().getInstructions().get(0);
366-
assertThat(userMessage.getText()).contains("First document content");
367-
assertThat(userMessage.getText()).contains("Second document content");
368-
}
369-
370-
@Test
371-
public void qaAdvisorBuilderValidation() {
372-
// Test that builder validates required parameters
373-
Assertions.assertThatThrownBy(() -> QuestionAnswerAdvisor.builder(null))
374-
.isInstanceOf(IllegalArgumentException.class);
375-
376-
// Test successful builder creation
377-
var advisor = QuestionAnswerAdvisor.builder(this.vectorStore).build();
378-
assertThat(advisor).isNotNull();
379-
}
380-
381-
@Test
382-
public void qaAdvisorWithZeroTopK() {
383-
given(this.chatModel.call(this.promptCaptor.capture()))
384-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Zero docs response"))),
385-
ChatResponseMetadata.builder().build()));
386-
387-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
388-
.willReturn(List.of());
389-
390-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
391-
.searchRequest(SearchRequest.builder().topK(0).build())
392-
.build();
393-
394-
var chatClient = ChatClient.builder(this.chatModel)
395-
.defaultAdvisors(qaAdvisor)
396-
.build();
397-
398-
chatClient.prompt()
399-
.user("Question with zero topK")
400-
.call()
401-
.chatResponse();
402-
403-
assertThat(this.vectorSearchCaptor.getValue().getTopK()).isEqualTo(0);
404-
}
405246
}

advisors/spring-ai-advisors-vector-store/src/test/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisorTests.java

Lines changed: 0 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -206,155 +206,4 @@ void whenBuilderWithCustomSystemPromptTemplateThenSuccess() {
206206
assertThat(advisor).isNotNull();
207207
}
208208

209-
@Test
210-
void whenBuilderWithEmptyStringConversationIdThenThrow() {
211-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
212-
213-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore).conversationId("").build())
214-
.isInstanceOf(IllegalArgumentException.class)
215-
.hasMessageContaining("defaultConversationId cannot be null or empty");
216-
}
217-
218-
@Test
219-
void whenBuilderWithWhitespaceOnlyConversationIdThenThrow() {
220-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
221-
222-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore).conversationId("\t\n\r ").build())
223-
.isInstanceOf(IllegalArgumentException.class)
224-
.hasMessageContaining("defaultConversationId cannot be null or empty");
225-
}
226-
227-
@Test
228-
void whenBuilderWithSpecialCharactersInConversationIdThenSuccess() {
229-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
230-
231-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
232-
.conversationId("[email protected]")
233-
.build();
234-
235-
assertThat(advisor).isNotNull();
236-
}
237-
238-
@Test
239-
void whenBuilderWithMaxIntegerTopKThenSuccess() {
240-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
241-
242-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
243-
.defaultTopK(Integer.MAX_VALUE)
244-
.build();
245-
246-
assertThat(advisor).isNotNull();
247-
}
248-
249-
@Test
250-
void whenBuilderWithNegativeTopKThenThrow() {
251-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
252-
253-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore).defaultTopK(-100).build())
254-
.isInstanceOf(IllegalArgumentException.class)
255-
.hasMessageContaining("topK must be greater than 0");
256-
}
257-
258-
@Test
259-
void whenBuilderChainedWithAllParametersThenSuccess() {
260-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
261-
Scheduler scheduler = Mockito.mock(Scheduler.class);
262-
PromptTemplate systemPromptTemplate = Mockito.mock(PromptTemplate.class);
263-
264-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
265-
.conversationId("chained-test")
266-
.defaultTopK(42)
267-
.scheduler(scheduler)
268-
.systemPromptTemplate(systemPromptTemplate)
269-
.build();
270-
271-
assertThat(advisor).isNotNull();
272-
}
273-
274-
@Test
275-
void whenBuilderParametersSetInDifferentOrderThenSuccess() {
276-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
277-
Scheduler scheduler = Mockito.mock(Scheduler.class);
278-
PromptTemplate systemPromptTemplate = Mockito.mock(PromptTemplate.class);
279-
280-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
281-
.systemPromptTemplate(systemPromptTemplate)
282-
.defaultTopK(7)
283-
.scheduler(scheduler)
284-
.conversationId("order-test")
285-
.build();
286-
287-
assertThat(advisor).isNotNull();
288-
}
289-
290-
@Test
291-
void whenBuilderWithOverriddenParametersThenUseLastValue() {
292-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
293-
294-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
295-
.conversationId("first-id")
296-
.conversationId("second-id") // This should override the first
297-
.defaultTopK(5)
298-
.defaultTopK(10) // This should override the first
299-
.build();
300-
301-
assertThat(advisor).isNotNull();
302-
}
303-
304-
@Test
305-
void whenBuilderReusedThenCreatesSeparateInstances() {
306-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
307-
308-
// Simulate builder reuse (if the builder itself is stateful)
309-
var builder = VectorStoreChatMemoryAdvisor.builder(vectorStore).conversationId("shared-config");
310-
311-
VectorStoreChatMemoryAdvisor advisor1 = builder.build();
312-
VectorStoreChatMemoryAdvisor advisor2 = builder.build();
313-
314-
assertThat(advisor1).isNotNull();
315-
assertThat(advisor2).isNotNull();
316-
assertThat(advisor1).isNotSameAs(advisor2);
317-
}
318-
319-
@Test
320-
void whenBuilderWithLongConversationIdThenSuccess() {
321-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
322-
String longId = "a".repeat(1000); // 1000 character conversation ID
323-
324-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
325-
.conversationId(longId)
326-
.build();
327-
328-
assertThat(advisor).isNotNull();
329-
}
330-
331-
@Test
332-
void whenBuilderCalledWithNullAfterValidValueThenThrow() {
333-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
334-
335-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore)
336-
.conversationId("valid-id")
337-
.conversationId(null) // Set to null after valid value
338-
.build()).isInstanceOf(IllegalArgumentException.class)
339-
.hasMessageContaining("defaultConversationId cannot be null or empty");
340-
}
341-
342-
@Test
343-
void whenBuilderWithTopKBoundaryValuesThenSuccess() {
344-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
345-
346-
// Test with value 1 (minimum valid)
347-
VectorStoreChatMemoryAdvisor advisor1 = VectorStoreChatMemoryAdvisor.builder(vectorStore)
348-
.defaultTopK(1)
349-
.build();
350-
351-
// Test with a reasonable upper bound
352-
VectorStoreChatMemoryAdvisor advisor2 = VectorStoreChatMemoryAdvisor.builder(vectorStore)
353-
.defaultTopK(10000)
354-
.build();
355-
356-
assertThat(advisor1).isNotNull();
357-
assertThat(advisor2).isNotNull();
358-
}
359-
360209
}

models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/MimeTypeDetectorTests.java

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@
2626
import org.junit.jupiter.params.provider.Arguments;
2727
import org.junit.jupiter.params.provider.MethodSource;
2828

29-
import org.junit.jupiter.params.provider.ValueSource;
29+
import org.springframework.ai.google.genai.MimeTypeDetector;
3030
import org.springframework.core.io.PathResource;
3131
import org.springframework.util.MimeType;
3232

3333
import static org.assertj.core.api.Assertions.assertThat;
34-
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
35-
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
3634
import static org.springframework.ai.google.genai.MimeTypeDetector.GEMINI_MIME_TYPES;
3735

3836
/**
@@ -92,49 +90,4 @@ void getMimeTypeByString(String extension, MimeType expectedMimeType) {
9290
assertThat(mimeType).isEqualTo(expectedMimeType);
9391
}
9492

95-
@ParameterizedTest
96-
@ValueSource(strings = { " ", "\t", "\n" })
97-
void getMimeTypeByStringWithInvalidInputShouldThrowException(String invalidPath) {
98-
assertThatThrownBy(() -> MimeTypeDetector.getMimeType(invalidPath)).isInstanceOf(IllegalArgumentException.class)
99-
.hasMessageContaining("Unable to detect the MIME type");
100-
}
101-
102-
@ParameterizedTest
103-
@ValueSource(strings = { "JPG", "PNG", "GIF" })
104-
void getMimeTypeByStringWithUppercaseExtensionsShouldWork(String uppercaseExt) {
105-
String upperFileName = "test." + uppercaseExt;
106-
String lowerFileName = "test." + uppercaseExt.toLowerCase();
107-
108-
// Should throw for uppercase (not in map) but work for lowercase
109-
assertThatThrownBy(() -> MimeTypeDetector.getMimeType(upperFileName))
110-
.isInstanceOf(IllegalArgumentException.class);
111-
112-
// Lowercase should work if it's a supported extension
113-
if (GEMINI_MIME_TYPES.containsKey(uppercaseExt.toLowerCase())) {
114-
assertThatCode(() -> MimeTypeDetector.getMimeType(lowerFileName)).doesNotThrowAnyException();
115-
}
116-
}
117-
118-
@ParameterizedTest
119-
@ValueSource(strings = { "test.jpg", "test.png", "test.gif" })
120-
void getMimeTypeSupportedFileAcrossDifferentMethodsShouldBeConsistent(String fileName) {
121-
MimeType stringResult = MimeTypeDetector.getMimeType(fileName);
122-
MimeType fileResult = MimeTypeDetector.getMimeType(new File(fileName));
123-
MimeType pathResult = MimeTypeDetector.getMimeType(Path.of(fileName));
124-
125-
// All methods should return the same result for supported extensions
126-
assertThat(stringResult).isEqualTo(fileResult);
127-
assertThat(stringResult).isEqualTo(pathResult);
128-
}
129-
130-
@ParameterizedTest
131-
@ValueSource(strings = { "https://example.com/documents/file.pdf", "https://example.com/data/file.json",
132-
"https://example.com/files/document.txt" })
133-
void getMimeTypeByURIWithUnsupportedExtensionsShouldThrowException(String url) {
134-
URI uri = URI.create(url);
135-
136-
assertThatThrownBy(() -> MimeTypeDetector.getMimeType(uri)).isInstanceOf(IllegalArgumentException.class)
137-
.hasMessageContaining("Unable to detect the MIME type");
138-
}
139-
14093
}

0 commit comments

Comments
 (0)