"""Characterization tests for the Knowledge Base API.

Written before extracting Knowledge Base into a plugin (pinning-flask-behavior):
the endpoints must behave identically whether KB is a core blueprint or a plugin
blueprint, since both register at /api/knowledgebase.
"""


def test_create_list_get_article(client, db, auth_headers):
    """Create an article, see it in the list, fetch it by id."""
    created = client.post('/api/knowledgebase',
                          json={'shortdescription': 'How to reset a printer',
                                'linkurl': 'https://kb.example/printer-reset',
                                'keywords': 'printer reset'},
                          headers=auth_headers)
    assert created.status_code == 201, created.get_json()
    linkid = created.get_json()['data']['linkid']

    listing = client.get('/api/knowledgebase', headers=auth_headers)
    assert listing.status_code == 200
    ids = [a['linkid'] for a in listing.get_json()['data']]
    assert linkid in ids

    fetched = client.get(f'/api/knowledgebase/{linkid}', headers=auth_headers)
    assert fetched.status_code == 200
    assert fetched.get_json()['data']['shortdescription'] == 'How to reset a printer'


def test_create_requires_shortdescription(client, db, auth_headers):
    """shortdescription is required."""
    resp = client.post('/api/knowledgebase',
                       json={'linkurl': 'https://kb.example/x'},
                       headers=auth_headers)
    assert resp.status_code == 400


def test_search_matches_topic_appname(client, db, auth_headers):
    """Searching a topic (Application name) returns every article under it, not
    just the one whose title/keywords happen to contain the word.

    Regression: KB list search omitted the topic, so a topic-only match (e.g.
    'Spotfire' as the app) surfaced a single article instead of all of them.
    """
    from shopdb.core.models import Application

    app_row = Application(appname='Spotfire')
    db.session.add(app_row)
    db.session.flush()

    # Two articles whose title/keywords do NOT contain 'Spotfire' - only the
    # topic (appid) ties them to it - plus one that does mention it directly.
    for payload in [
        {'shortdescription': 'Dashboard login steps', 'keywords': 'login',
         'linkurl': 'https://kb.example/a', 'appid': app_row.appid},
        {'shortdescription': 'Export a visualization', 'keywords': 'export',
         'linkurl': 'https://kb.example/b', 'appid': app_row.appid},
        {'shortdescription': 'Spotfire install guide', 'keywords': 'install',
         'linkurl': 'https://kb.example/c', 'appid': app_row.appid},
    ]:
        resp = client.post('/api/knowledgebase', json=payload, headers=auth_headers)
        assert resp.status_code == 201, resp.get_json()

    listing = client.get('/api/knowledgebase?search=Spotfire', headers=auth_headers)
    assert listing.status_code == 200
    urls = {a['linkurl'] for a in listing.get_json()['data']}
    assert {'https://kb.example/a', 'https://kb.example/b',
            'https://kb.example/c'} <= urls
