"""Global search matches multi-word queries by WORD (every word, any order or
field), not just the exact contiguous phrase.

Regression: 'CSF Roles' returned nothing because search did a single
ilike('%CSF Roles%'). Now each word must match (ORed across fields), so a record
with both words - even reversed or split - is found; a record with only one is
not.
"""
from shopdb.core.models import AssetType, Asset


def _seed(client, db, auth_headers, assetnumber, name):
    if not AssetType.query.filter_by(assettype='computer').first():
        db.session.add(AssetType(assettype='computer', pluginname='computer',
                                 tablename='computer', description='c'))
        db.session.commit()
    r = client.post('/api/computers', json={'assetnumber': assetnumber},
                    headers=auth_headers)
    assert r.status_code == 201, r.get_json()
    asset = Asset.query.filter_by(assetnumber=assetnumber).first()
    asset.name = name
    db.session.commit()


def _titles(client, auth_headers, term):
    r = client.get(f'/api/search?q={term}', headers=auth_headers)
    assert r.status_code == 200, r.get_json()
    return {h['title'] for h in r.get_json()['data']['results']}


def test_multiword_matches_all_words_any_order(client, db, auth_headers):
    _seed(client, db, auth_headers, 'MW-1', 'CSF Roles Alpha')      # contiguous
    _seed(client, db, auth_headers, 'MW-2', 'Roles for the CSF Beta')  # split/reversed
    _seed(client, db, auth_headers, 'MW-3', 'CSF only')             # one word only

    titles = _titles(client, auth_headers, 'CSF Roles')
    assert 'CSF Roles Alpha' in titles          # exact phrase still works
    assert 'Roles for the CSF Beta' in titles   # words split/reversed now match
    assert 'CSF only' not in titles             # missing a word -> excluded
