# Trouve-KA — tests de la recherche hybride (RRF, corps kNN) # Author: Simon-Pierre Boucher # Contact: contact@spboucher.ai from trouveka.ranking import build_knn_body, rrf_fuse def _hit(_id: str, **extra): return {"_id": _id, "_source": {"url": f"https://x.qc/{_id}"}, **extra} def test_rrf_doc_present_dans_les_deux_gagne(): lexical = [_hit("a"), _hit("b"), _hit("c")] knn = [_hit("b"), _hit("d")] fused = rrf_fuse(lexical, knn) assert fused[0]["_id"] == "b" # présent dans les deux listes assert {h["_id"] for h in fused} == {"a", "b", "c", "d"} def test_rrf_conserve_le_highlight_lexical(): lexical = [_hit("a", highlight={"body": ["x"]})] knn = [_hit("a")] fused = rrf_fuse(lexical, knn) assert "highlight" in fused[0] def test_rrf_listes_vides(): assert rrf_fuse([], []) == [] assert [h["_id"] for h in rrf_fuse([_hit("a")], [])] == ["a"] def test_knn_body_filtres_appliques(): body = build_knn_body([0.1] * 4, filters=[{"term": {"language": "fr"}}], size=30) knn = body["query"]["knn"]["embedding"] assert knn["k"] == 30 assert knn["filter"]["bool"]["filter"][0]["term"]["language"] == "fr" def test_knn_body_sans_filtre(): body = build_knn_body([0.1] * 4, filters=[], size=10) assert "filter" not in body["query"]["knn"]["embedding"]