Skip to content

Commit 1b550f5

Browse files
authored
Merge pull request #122 from VirtualFlyBrain/fix/preview-id-pattern
Preview every id shape, not just the underscored ones
2 parents 13ce518 + 5dc1db3 commit 1b550f5

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

‎src/test/test_link_preview.py‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,27 @@ def _class_with_example():
4444

4545
# --- id validation -----------------------------------------------------------
4646

47-
@pytest.mark.parametrize("value", ["FBbt_00003748", "VFB_jrchjrch", "VFBexp_FBtp0000001", "GO_0001872"])
48-
def test_is_term_id_accepts_vfb_shapes(value):
47+
@pytest.mark.parametrize("value", [
48+
# underscored ontology ids
49+
"FBbt_00003748", "VFB_jrchjrch", "VFBexp_FBtp0000001", "GO_0001872",
50+
"GENO_0000346", "FBdv_00007133", "FBbi_00000537",
51+
# FlyBase ids -- no underscore at all
52+
"FBgn0038978", "FBtp0106402", "FBti0004391", "FBrf0247641", "FBal0331598",
53+
# dataset / publication names
54+
"Court2017", "Chiang2010", "Robie2017",
55+
])
56+
def test_is_term_id_accepts_every_shape_get_term_info_resolves(value):
4957
assert link_preview.is_term_id(value)
5058

5159

52-
@pytest.mark.parametrize("value", ["", None, "medulla", "<script>", "../x", "VFB jrch", "_leading"])
53-
def test_is_term_id_rejects_free_text(value):
60+
@pytest.mark.parametrize("value", [
61+
"", None, "<script>", "../x", "VFB jrch", "_leading", "x",
62+
# FlyBase links VFB thumbnails by label rather than id; that must not be
63+
# mistaken for a term.
64+
"P{VT057232-GAL4} expression pattern in adult VNS on Virtual Fly Brain",
65+
"VFB_00101384/thumbnail.png",
66+
])
67+
def test_is_term_id_rejects_junk(value):
5468
assert not link_preview.is_term_id(value)
5569

5670

‎src/vfbquery/ha_api.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4197,7 +4197,13 @@ async def _term_info_for_preview(request, short_form):
41974197
if response.status != 200:
41984198
return None
41994199
info = json.loads(response.body)
4200-
return info if info and info.get("Id") else None
4200+
# get_term_info answers 200 with an empty shell for an id it does not know
4201+
# (every field null), so presence is not enough: without a Name there is
4202+
# nothing to put on a card, and the caller should fall back to its own
4203+
# redirect rather than be handed a blank preview.
4204+
if not info or not info.get("Id") or not info.get("Name"):
4205+
return None
4206+
return info
42014207

42024208

42034209
async def handle_get_preview(request):

‎src/vfbquery/link_preview.py‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,17 @@
2121
MAX_DESCRIPTION = 300
2222

2323
_MARKDOWN_LINK = re.compile(r"\[([^\]]*)\]\([^)\s]*\)")
24-
_ID_PATTERN = re.compile(r"^[A-Za-z][A-Za-z0-9]*_[A-Za-z0-9_]+$")
24+
# Deliberately broad: VFB ids are not one shape. Underscored ontology ids
25+
# (FBbt_00003748, VFB_jrchjrch, GO_0016811, VFBexp_FBtp0088219) sit alongside
26+
# FlyBase ids with no underscore at all (FBgn0038978, FBtp0106402, FBrf0247641)
27+
# and dataset/publication names (Court2017, Chiang2010) -- all of which
28+
# get_term_info resolves. An earlier pattern required an underscore and so
29+
# silently refused a preview for every FlyBase id and every dataset.
30+
#
31+
# Over-matching is cheap: an id with no term behind it comes back with a null
32+
# Id and is refused as a 404, which is what lets a caller fall back to its
33+
# ordinary redirect. Under-matching is the expensive mistake.
34+
_ID_PATTERN = re.compile(r"^[A-Za-z][A-Za-z0-9_]+$")
2535

2636

2737
def is_term_id(value):

0 commit comments

Comments
 (0)