@@ -58,7 +58,9 @@ describe("QdrantVectorStore", () => {
5858 it ( "should correctly initialize QdrantClient and collectionName in constructor" , ( ) => {
5959 expect ( QdrantClient ) . toHaveBeenCalledTimes ( 1 )
6060 expect ( QdrantClient ) . toHaveBeenCalledWith ( {
61- url : mockQdrantUrl ,
61+ host : "mock-qdrant" ,
62+ https : false ,
63+ port : 6333 ,
6264 apiKey : mockApiKey ,
6365 headers : {
6466 "User-Agent" : "Roo-Code" ,
@@ -75,7 +77,9 @@ describe("QdrantVectorStore", () => {
7577 const vectorStoreWithDefaults = new QdrantVectorStore ( mockWorkspacePath , undefined as any , mockVectorSize )
7678
7779 expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
78- url : "http://localhost:6333" , // Should use default QDRANT_URL
80+ host : "localhost" ,
81+ https : false ,
82+ port : 6333 ,
7983 apiKey : undefined ,
8084 headers : {
8185 "User-Agent" : "Roo-Code" ,
@@ -87,14 +91,252 @@ describe("QdrantVectorStore", () => {
8791 const vectorStoreWithoutKey = new QdrantVectorStore ( mockWorkspacePath , mockQdrantUrl , mockVectorSize )
8892
8993 expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
90- url : mockQdrantUrl ,
94+ host : "mock-qdrant" ,
95+ https : false ,
96+ port : 6333 ,
9197 apiKey : undefined ,
9298 headers : {
9399 "User-Agent" : "Roo-Code" ,
94100 } ,
95101 } )
96102 } )
97103
104+ describe ( "URL Parsing and Explicit Port Handling" , ( ) => {
105+ describe ( "HTTPS URL handling" , ( ) => {
106+ it ( "should use explicit port 443 for HTTPS URLs without port (fixes the main bug)" , ( ) => {
107+ const vectorStore = new QdrantVectorStore (
108+ mockWorkspacePath ,
109+ "https://qdrant.ashbyfam.com" ,
110+ mockVectorSize ,
111+ )
112+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
113+ host : "qdrant.ashbyfam.com" ,
114+ https : true ,
115+ port : 443 ,
116+ apiKey : undefined ,
117+ headers : {
118+ "User-Agent" : "Roo-Code" ,
119+ } ,
120+ } )
121+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "https://qdrant.ashbyfam.com" )
122+ } )
123+
124+ it ( "should use explicit port for HTTPS URLs with explicit port" , ( ) => {
125+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "https://example.com:9000" , mockVectorSize )
126+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
127+ host : "example.com" ,
128+ https : true ,
129+ port : 9000 ,
130+ apiKey : undefined ,
131+ headers : {
132+ "User-Agent" : "Roo-Code" ,
133+ } ,
134+ } )
135+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "https://example.com:9000" )
136+ } )
137+
138+ it ( "should use port 443 for HTTPS URLs with paths and query parameters" , ( ) => {
139+ const vectorStore = new QdrantVectorStore (
140+ mockWorkspacePath ,
141+ "https://example.com/api/v1?key=value" ,
142+ mockVectorSize ,
143+ )
144+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
145+ host : "example.com" ,
146+ https : true ,
147+ port : 443 ,
148+ apiKey : undefined ,
149+ headers : {
150+ "User-Agent" : "Roo-Code" ,
151+ } ,
152+ } )
153+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "https://example.com/api/v1?key=value" )
154+ } )
155+ } )
156+
157+ describe ( "HTTP URL handling" , ( ) => {
158+ it ( "should use explicit port 80 for HTTP URLs without port" , ( ) => {
159+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "http://example.com" , mockVectorSize )
160+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
161+ host : "example.com" ,
162+ https : false ,
163+ port : 80 ,
164+ apiKey : undefined ,
165+ headers : {
166+ "User-Agent" : "Roo-Code" ,
167+ } ,
168+ } )
169+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://example.com" )
170+ } )
171+
172+ it ( "should use explicit port for HTTP URLs with explicit port" , ( ) => {
173+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "http://localhost:8080" , mockVectorSize )
174+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
175+ host : "localhost" ,
176+ https : false ,
177+ port : 8080 ,
178+ apiKey : undefined ,
179+ headers : {
180+ "User-Agent" : "Roo-Code" ,
181+ } ,
182+ } )
183+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://localhost:8080" )
184+ } )
185+
186+ it ( "should use port 80 for HTTP URLs while preserving paths and query parameters" , ( ) => {
187+ const vectorStore = new QdrantVectorStore (
188+ mockWorkspacePath ,
189+ "http://example.com/api/v1?key=value" ,
190+ mockVectorSize ,
191+ )
192+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
193+ host : "example.com" ,
194+ https : false ,
195+ port : 80 ,
196+ apiKey : undefined ,
197+ headers : {
198+ "User-Agent" : "Roo-Code" ,
199+ } ,
200+ } )
201+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://example.com/api/v1?key=value" )
202+ } )
203+ } )
204+
205+ describe ( "Hostname handling" , ( ) => {
206+ it ( "should convert hostname to http with port 80" , ( ) => {
207+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "qdrant.example.com" , mockVectorSize )
208+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
209+ host : "qdrant.example.com" ,
210+ https : false ,
211+ port : 80 ,
212+ apiKey : undefined ,
213+ headers : {
214+ "User-Agent" : "Roo-Code" ,
215+ } ,
216+ } )
217+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://qdrant.example.com" )
218+ } )
219+
220+ it ( "should handle hostname:port format with explicit port" , ( ) => {
221+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "localhost:6333" , mockVectorSize )
222+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
223+ host : "localhost" ,
224+ https : false ,
225+ port : 6333 ,
226+ apiKey : undefined ,
227+ headers : {
228+ "User-Agent" : "Roo-Code" ,
229+ } ,
230+ } )
231+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://localhost:6333" )
232+ } )
233+
234+ it ( "should handle explicit HTTP URLs correctly" , ( ) => {
235+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "http://localhost:9000" , mockVectorSize )
236+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
237+ host : "localhost" ,
238+ https : false ,
239+ port : 9000 ,
240+ apiKey : undefined ,
241+ headers : {
242+ "User-Agent" : "Roo-Code" ,
243+ } ,
244+ } )
245+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://localhost:9000" )
246+ } )
247+ } )
248+
249+ describe ( "IP address handling" , ( ) => {
250+ it ( "should convert IP address to http with port 80" , ( ) => {
251+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "192.168.1.100" , mockVectorSize )
252+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
253+ host : "192.168.1.100" ,
254+ https : false ,
255+ port : 80 ,
256+ apiKey : undefined ,
257+ headers : {
258+ "User-Agent" : "Roo-Code" ,
259+ } ,
260+ } )
261+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://192.168.1.100" )
262+ } )
263+
264+ it ( "should handle IP:port format with explicit port" , ( ) => {
265+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "192.168.1.100:6333" , mockVectorSize )
266+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
267+ host : "192.168.1.100" ,
268+ https : false ,
269+ port : 6333 ,
270+ apiKey : undefined ,
271+ headers : {
272+ "User-Agent" : "Roo-Code" ,
273+ } ,
274+ } )
275+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://192.168.1.100:6333" )
276+ } )
277+ } )
278+
279+ describe ( "Edge cases" , ( ) => {
280+ it ( "should handle undefined URL with host-based config" , ( ) => {
281+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , undefined as any , mockVectorSize )
282+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
283+ host : "localhost" ,
284+ https : false ,
285+ port : 6333 ,
286+ apiKey : undefined ,
287+ headers : {
288+ "User-Agent" : "Roo-Code" ,
289+ } ,
290+ } )
291+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://localhost:6333" )
292+ } )
293+
294+ it ( "should handle empty string URL with host-based config" , ( ) => {
295+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "" , mockVectorSize )
296+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
297+ host : "localhost" ,
298+ https : false ,
299+ port : 6333 ,
300+ apiKey : undefined ,
301+ headers : {
302+ "User-Agent" : "Roo-Code" ,
303+ } ,
304+ } )
305+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://localhost:6333" )
306+ } )
307+
308+ it ( "should handle whitespace-only URL with host-based config" , ( ) => {
309+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , " " , mockVectorSize )
310+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
311+ host : "localhost" ,
312+ https : false ,
313+ port : 6333 ,
314+ apiKey : undefined ,
315+ headers : {
316+ "User-Agent" : "Roo-Code" ,
317+ } ,
318+ } )
319+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://localhost:6333" )
320+ } )
321+ } )
322+
323+ describe ( "Invalid URL fallback" , ( ) => {
324+ it ( "should treat invalid URLs as hostnames with port 80" , ( ) => {
325+ const vectorStore = new QdrantVectorStore ( mockWorkspacePath , "invalid-url-format" , mockVectorSize )
326+ expect ( QdrantClient ) . toHaveBeenLastCalledWith ( {
327+ host : "invalid-url-format" ,
328+ https : false ,
329+ port : 80 ,
330+ apiKey : undefined ,
331+ headers : {
332+ "User-Agent" : "Roo-Code" ,
333+ } ,
334+ } )
335+ expect ( ( vectorStore as any ) . qdrantUrl ) . toBe ( "http://invalid-url-format" )
336+ } )
337+ } )
338+ } )
339+
98340 describe ( "initialize" , ( ) => {
99341 it ( "should create a new collection if none exists and return true" , async ( ) => {
100342 // Mock getCollection to throw a 404-like error
0 commit comments