@@ -220,3 +220,139 @@ async def test_folder_title_pattern_with_md_extension(link_resolver, test_entiti
220220 entity = await link_resolver .resolve_link ("components/core-service" )
221221 assert entity is not None
222222 assert entity .permalink == "components/core-service"
223+
224+
225+ # Tests for strict mode parameter combinations
226+ @pytest .mark .asyncio
227+ async def test_strict_mode_parameter_combinations (link_resolver , test_entities ):
228+ """Test all combinations of use_search and strict parameters."""
229+
230+ # Test queries
231+ exact_match = "Auth Service" # Should always work (unique title)
232+ fuzzy_match = "Auth Serv" # Should only work with fuzzy search enabled
233+ non_existent = "Does Not Exist" # Should never work
234+
235+ # Case 1: use_search=True, strict=False (default behavior - fuzzy matching allowed)
236+ result = await link_resolver .resolve_link (exact_match , use_search = True , strict = False )
237+ assert result is not None
238+ assert result .permalink == "components/auth-service"
239+
240+ result = await link_resolver .resolve_link (fuzzy_match , use_search = True , strict = False )
241+ assert result is not None # Should find "Auth Service" via fuzzy matching
242+ assert result .permalink == "components/auth-service"
243+
244+ result = await link_resolver .resolve_link (non_existent , use_search = True , strict = False )
245+ assert result is None
246+
247+ # Case 2: use_search=True, strict=True (exact matches only, even with search enabled)
248+ result = await link_resolver .resolve_link (exact_match , use_search = True , strict = True )
249+ assert result is not None
250+ assert result .permalink == "components/auth-service"
251+
252+ result = await link_resolver .resolve_link (fuzzy_match , use_search = True , strict = True )
253+ assert result is None # Should NOT find via fuzzy matching in strict mode
254+
255+ result = await link_resolver .resolve_link (non_existent , use_search = True , strict = True )
256+ assert result is None
257+
258+ # Case 3: use_search=False, strict=False (no search, exact repository matches only)
259+ result = await link_resolver .resolve_link (exact_match , use_search = False , strict = False )
260+ assert result is not None
261+ assert result .permalink == "components/auth-service"
262+
263+ result = await link_resolver .resolve_link (fuzzy_match , use_search = False , strict = False )
264+ assert result is None # No search means no fuzzy matching
265+
266+ result = await link_resolver .resolve_link (non_existent , use_search = False , strict = False )
267+ assert result is None
268+
269+ # Case 4: use_search=False, strict=True (redundant but should work same as case 3)
270+ result = await link_resolver .resolve_link (exact_match , use_search = False , strict = True )
271+ assert result is not None
272+ assert result .permalink == "components/auth-service"
273+
274+ result = await link_resolver .resolve_link (fuzzy_match , use_search = False , strict = True )
275+ assert result is None # No search means no fuzzy matching
276+
277+ result = await link_resolver .resolve_link (non_existent , use_search = False , strict = True )
278+ assert result is None
279+
280+
281+ @pytest .mark .asyncio
282+ async def test_exact_match_types_in_strict_mode (link_resolver , test_entities ):
283+ """Test that all types of exact matches work in strict mode."""
284+
285+ # 1. Exact permalink match
286+ result = await link_resolver .resolve_link ("components/core-service" , strict = True )
287+ assert result is not None
288+ assert result .permalink == "components/core-service"
289+
290+ # 2. Exact title match
291+ result = await link_resolver .resolve_link ("Core Service" , strict = True )
292+ assert result is not None
293+ assert result .permalink == "components/core-service"
294+
295+ # 3. Exact file path match
296+ result = await link_resolver .resolve_link ("components/Core Service.md" , strict = True )
297+ assert result is not None
298+ assert result .permalink == "components/core-service"
299+
300+ # 4. Folder/title pattern with .md extension added
301+ result = await link_resolver .resolve_link ("components/Core Service" , strict = True )
302+ assert result is not None
303+ assert result .permalink == "components/core-service"
304+
305+ # 5. Non-markdown file (Image.png)
306+ result = await link_resolver .resolve_link ("Image.png" , strict = True )
307+ assert result is not None
308+ assert result .title == "Image.png"
309+
310+
311+ @pytest .mark .asyncio
312+ async def test_fuzzy_matching_blocked_in_strict_mode (link_resolver , test_entities ):
313+ """Test that various fuzzy matching scenarios are blocked in strict mode."""
314+
315+ # Partial matches that would work in normal mode
316+ fuzzy_queries = [
317+ "Auth Serv" , # Partial title
318+ "auth-service" , # Lowercase permalink variation
319+ "Core" , # Single word from title
320+ "Service" , # Common word
321+ "Serv" , # Partial word
322+ ]
323+
324+ for query in fuzzy_queries :
325+ # Should NOT work in strict mode
326+ strict_result = await link_resolver .resolve_link (query , strict = True )
327+ assert strict_result is None , f"Query '{ query } ' should return None in strict mode"
328+
329+
330+ @pytest .mark .asyncio
331+ async def test_link_normalization_with_strict_mode (link_resolver , test_entities ):
332+ """Test that link normalization still works in strict mode."""
333+
334+ # Test bracket removal and alias handling in strict mode
335+ queries_and_expected = [
336+ ("[[Core Service]]" , "components/core-service" ),
337+ ("[[Core Service|Main]]" , "components/core-service" ), # Alias should be ignored
338+ (" [[ Core Service ]] " , "components/core-service" ), # Extra whitespace
339+ ]
340+
341+ for query , expected_permalink in queries_and_expected :
342+ result = await link_resolver .resolve_link (query , strict = True )
343+ assert result is not None , f"Query '{ query } ' should find entity in strict mode"
344+ assert result .permalink == expected_permalink
345+
346+
347+ @pytest .mark .asyncio
348+ async def test_duplicate_title_handling_in_strict_mode (link_resolver , test_entities ):
349+ """Test how duplicate titles are handled in strict mode."""
350+
351+ # "Core Service" appears twice in test data (components/core-service and components2/core-service)
352+ # In strict mode, if there are multiple exact title matches, it should still return the first one
353+ # (same behavior as normal mode for exact matches)
354+
355+ result = await link_resolver .resolve_link ("Core Service" , strict = True )
356+ assert result is not None
357+ # Should return the first match (components/core-service based on test fixture order)
358+ assert result .permalink == "components/core-service"
0 commit comments