File size: 1,701 Bytes
47a6953
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from __future__ import annotations

from app import demo_gap
from app.models import Tenant


class _Chunk:
    pass


async def test_gap_report_labels_hit_and_miss(db_session, monkeypatch):
    t = Tenant(slug="demo-x", name="X", brand_name="Tienda X", is_demo=True)
    db_session.add(t)
    await db_session.flush()

    # Deterministic retrieval: only the shipping questions are "answered" by the
    # store's pages (score above threshold); everything else is a gap.
    async def fake_search(db, q, k=3, tenant_id=None):
        score = 0.55 if "env" in q.lower() else 0.10
        return [(_Chunk(), score)]

    monkeypatch.setattr(demo_gap.rag_index, "search", fake_search)
    rep = await demo_gap.generate_gap_report(db_session, t, lang="es")

    assert rep["brand"] == "Tienda X"
    assert rep["total"] == len(demo_gap.GAP_QUESTIONS["es"])
    hits = [r for r in rep["questions"] if r["status"] == "hit"]
    assert hits and all("env" in r["q"].lower() for r in hits)  # only shipping = HIT
    assert rep["answered"] == len(hits)
    assert rep["gap_count"] == rep["total"] - len(hits)
    assert all(g not in [h["q"] for h in hits] for g in rep["gaps"])


async def test_gap_report_all_miss_when_nothing_indexed(db_session, monkeypatch):
    t = Tenant(slug="demo-empty", is_demo=True)
    db_session.add(t)
    await db_session.flush()

    async def empty_search(db, q, k=3, tenant_id=None):
        return []  # store crawled nothing useful -> every buyer question is a gap

    monkeypatch.setattr(demo_gap.rag_index, "search", empty_search)
    rep = await demo_gap.generate_gap_report(db_session, t, lang="en")
    assert rep["gap_count"] == rep["total"] and rep["answered"] == 0