nikeshn commited on
Commit
ce7ca31
·
verified ·
1 Parent(s): 33448b9

Upload test_khazna.py

Browse files
Files changed (1) hide show
  1. tests/test_khazna.py +47 -0
tests/test_khazna.py CHANGED
@@ -42,6 +42,7 @@ DB = [
42
  ro("a4", "Solar desalination membranes", 2023, typ="thesis", abstract="solar desalination", ku=("Ali", "Hassan", "p2")),
43
  ro("a5", "Graphene oxide for desalination", 2022, abstract="graphene membranes desalination", ku=("Jane", "Smith", "p1"), ext=("x1", "x2")),
44
  ro("a6", "Urban PM2.5 sensor readings", 2021, typ="dataset", abstract="pollution sensor readings Abu Dhabi", ext=()),
 
45
  ]
46
  EXT_ORGS = {"x1": {"uuid": "x1", "name": {"en_GB": "Massachusetts Institute of Technology"}, "type": {"term": {"en_GB": "University"}},
47
  "address": {"country": {"term": {"en_GB": "United States"}}}},
@@ -61,6 +62,12 @@ PERSONS = {
61
  "staffOrganizationAssociations": [{"jobTitle": {"term": {"en_GB": "Associate Professor"}}, "organization": {"uuid": "o1"}}],
62
  "keywordGroups": [{"keywords": [{"freeKeywords": ["membranes", "desalination"]}]}]},
63
  "p2": {"uuid": "p2", "name": {"firstName": "Ali", "lastName": "Hassan"}, "visibility": {"key": "FREE"}},
 
 
 
 
 
 
64
  }
65
  ORGS = {"o1": {"uuid": "o1", "name": {"en_GB": "Department of Chemical Engineering"}, "type": {"term": {"en_GB": "Department"}}, "visibility": {"key": "FREE"}},
66
  "o2": {"uuid": "o2", "name": {"en_GB": "Center for Membranes and Advanced Water Technology"}, "type": {"term": {"en_GB": "Research Centre"}}, "visibility": {"key": "FREE"}}}
@@ -269,6 +276,7 @@ def test_endpoint_scopes_widget_ratelimit_and_dataset_403():
269
  assert d["intent"] == "expert_search" and d["search_results"][0]["kind"] == "person"
270
  assert "email" not in json.dumps(d)
271
  assert "/en/persons/?search=desalination" in d["portal_search_url"]
 
272
  d = tc.post("/agent", json={"question": "membranes", "scope": "organisations"}).json()
273
  assert d["search_results"][0]["kind"] == "organisation"
274
  DATASETS_ENABLED["on"] = False
@@ -429,3 +437,42 @@ def test_agent_new_scopes_end_to_end():
429
  assert d["search_results"][0]["kind"] == "collaborator" and d["search_results"][0]["joint_outputs"] == 2
430
  d = tc.post("/agent", json={"question": "hydrogen storage", "scope": "publications"}).json()
431
  assert {f["scope"] for f in d["follow_up_suggestions"]} == {"persons", "theses", "projects", "collaborations"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  ro("a4", "Solar desalination membranes", 2023, typ="thesis", abstract="solar desalination", ku=("Ali", "Hassan", "p2")),
43
  ro("a5", "Graphene oxide for desalination", 2022, abstract="graphene membranes desalination", ku=("Jane", "Smith", "p1"), ext=("x1", "x2")),
44
  ro("a6", "Urban PM2.5 sensor readings", 2021, typ="dataset", abstract="pollution sensor readings Abu Dhabi", ext=()),
45
+ ro("a7", "Deep learning for seismic imaging", 2024, abstract="seismic inversion with neural networks", ku=("Kumar", "Padmanabhan", "k1"), ext=()),
46
  ]
47
  EXT_ORGS = {"x1": {"uuid": "x1", "name": {"en_GB": "Massachusetts Institute of Technology"}, "type": {"term": {"en_GB": "University"}},
48
  "address": {"country": {"term": {"en_GB": "United States"}}}},
 
62
  "staffOrganizationAssociations": [{"jobTitle": {"term": {"en_GB": "Associate Professor"}}, "organization": {"uuid": "o1"}}],
63
  "keywordGroups": [{"keywords": [{"freeKeywords": ["membranes", "desalination"]}]}]},
64
  "p2": {"uuid": "p2", "name": {"firstName": "Ali", "lastName": "Hassan"}, "visibility": {"key": "FREE"}},
65
+ # several "Kumar"s in different name positions, plus a prefix-only match
66
+ "k1": {"uuid": "k1", "name": {"firstName": "Kumar", "lastName": "Padmanabhan"}, "visibility": {"key": "FREE"},
67
+ "staffOrganizationAssociations": [{"jobTitle": {"term": {"en_GB": "Professor"}}, "organization": {"uuid": "o1"}}]},
68
+ "k2": {"uuid": "k2", "name": {"firstName": "Rajesh", "lastName": "Kumar"}, "visibility": {"key": "FREE"}},
69
+ "k3": {"uuid": "k3", "name": {"firstName": "Anil Kumar", "lastName": "Sharma"}, "visibility": {"key": "FREE"}},
70
+ "k4": {"uuid": "k4", "name": {"firstName": "Kumaran", "lastName": "Iyer"}, "visibility": {"key": "FREE"}},
71
  }
72
  ORGS = {"o1": {"uuid": "o1", "name": {"en_GB": "Department of Chemical Engineering"}, "type": {"term": {"en_GB": "Department"}}, "visibility": {"key": "FREE"}},
73
  "o2": {"uuid": "o2", "name": {"en_GB": "Center for Membranes and Advanced Water Technology"}, "type": {"term": {"en_GB": "Research Centre"}}, "visibility": {"key": "FREE"}}}
 
276
  assert d["intent"] == "expert_search" and d["search_results"][0]["kind"] == "person"
277
  assert "email" not in json.dumps(d)
278
  assert "/en/persons/?search=desalination" in d["portal_search_url"]
279
+ assert "searchBy" not in d["portal_search_url"]
280
  d = tc.post("/agent", json={"question": "membranes", "scope": "organisations"}).json()
281
  assert d["search_results"][0]["kind"] == "organisation"
282
  DATASETS_ENABLED["on"] = False
 
437
  assert d["search_results"][0]["kind"] == "collaborator" and d["search_results"][0]["joint_outputs"] == 2
438
  d = tc.post("/agent", json={"question": "hydrogen storage", "scope": "publications"}).json()
439
  assert {f["scope"] for f in d["follow_up_suggestions"]} == {"persons", "theses", "projects", "collaborations"}
440
+
441
+
442
+ def test_match_people_positions_and_prefix():
443
+ from pure_client import normalize_person
444
+ people = [normalize_person(PERSONS[k], PORTAL) for k in ("k1", "k2", "k3", "k4")]
445
+ matches, full = pipeline.match_people("KUMAR", people)
446
+ assert [p["uuid"] for p in matches] == ["k2", "k3", "k1"] or {p["uuid"] for p in matches} == {"k1", "k2", "k3"}
447
+ assert matches[0]["uuid"] == "k2" # surname matches are listed first
448
+ assert "k4" not in {p["uuid"] for p in matches} # 'Kumaran' only used when no exact match exists
449
+ assert full == []
450
+ m, f = pipeline.match_people("Kumar Padmanabhan", people)
451
+ assert [p["uuid"] for p in f] == ["k1"]
452
+ m, f = pipeline.match_people("Kumara", people) # prefix fallback
453
+ assert [p["uuid"] for p in m] == ["k4"]
454
+
455
+
456
+ def test_ambiguous_name_asks_to_choose_then_explores_choice():
457
+ os.environ["PURE_API_KEY"] = "test-key"
458
+ import app as appmod
459
+ from fastapi.testclient import TestClient
460
+ with TestClient(appmod.app) as tc:
461
+ appmod.pure = client()
462
+ appmod._hits.clear()
463
+ d = tc.post("/agent", json={"question": "Kumar", "scope": "persons"}).json()
464
+ assert d["intent"] == "author_clarify" and d["clarify"] is True
465
+ assert d["portal_search_url"] == "https://khazna.ku.ac.ae/en/persons/?search=Kumar"
466
+ assert {x["uuid"] for x in d["search_results"]} == {"k1", "k2", "k3"}
467
+ assert all(x["choose"] for x in d["search_results"]) and "3 KU researchers" in d["answer"]
468
+ assert d["search_results"][[x["uuid"] for x in d["search_results"]].index("k1")]["organisations"][0]["name"].startswith("Department")
469
+ # the user picks one → that exact person, no second clarification
470
+ d2 = tc.post("/agent", json={"question": d["original_question"], "scope": "persons", "person_uuid": "k1"}).json()
471
+ assert d2["intent"] == "author_search" and d2["person"]["uuid"] == "k1"
472
+ assert [x["uuid"] for x in d2["search_results"]] == ["a7"]
473
+ # a full unique name goes straight through
474
+ d3 = tc.post("/agent", json={"question": "Kumar Padmanabhan", "scope": "persons"}).json()
475
+ assert d3["intent"] == "author_search" and d3["person"]["uuid"] == "k1"
476
+ # a non-matching / single name still works as before
477
+ d4 = tc.post("/agent", json={"question": "Jane Smith", "scope": "persons"}).json()
478
+ assert d4["person"]["name"] == "Jane Smith"