# retoor <retoor@molodetz.nl>

from devplacepy.services.dbapi import validate


def test_classify_select_with_clauses():
    v = validate.classify(
        "SELECT u.uid FROM users u JOIN posts p ON p.user_uid = u.uid WHERE u.role = 'Admin' LIMIT 5"
    )
    assert v.statement_type == "select"
    assert v.is_select is True
    assert v.has_where and v.has_join and v.has_limit
    assert v.suspicious == []
    assert "users" in v.tables and "posts" in v.tables


def test_classify_select_without_clauses_is_suspicious():
    v = validate.classify("SELECT * FROM users")
    assert v.is_select is True
    assert any("WHERE" in note for note in v.suspicious)


def test_classify_rejects_mutations():
    for sql, kind in (
        ("DELETE FROM posts", "delete"),
        ("UPDATE users SET role = 'Admin'", "update"),
        ("INSERT INTO posts (uid) VALUES ('x')", "insert"),
        ("DROP TABLE users", "ddl"),
    ):
        v = validate.classify(sql)
        assert v.statement_type == kind
        assert v.is_select is False


def test_classify_multiple_statements():
    v = validate.classify("SELECT 1; DROP TABLE users")
    assert any("Multiple statements" in note for note in v.suspicious)


def test_classify_blocks_attach_pragma():
    v = validate.classify("ATTACH DATABASE 'x.db' AS y")
    assert v.is_select is False
    assert any("ATTACH" in note for note in v.suspicious)


def test_classify_parse_error_sets_error():
    v = validate.classify("SELEKT FROM WHERE")
    assert v.error is not None


def test_validate_select_accepts_real_select(local_db):
    v = validate.validate_select("SELECT uid, username FROM users LIMIT 3")
    assert v.valid is True
    assert v.error is None


def test_validate_select_rejects_non_select(local_db):
    v = validate.validate_select("DELETE FROM posts")
    assert v.valid is False
    assert "SELECT" in v.error


def test_validate_select_dry_run_catches_bad_table(local_db):
    v = validate.validate_select("SELECT * FROM no_such_table_zzz LIMIT 1")
    assert v.valid is False
    assert "no such table" in v.error


def test_run_select_returns_rows_and_truncation(local_db):
    rows, truncated = validate.run_select("SELECT 1 AS n", 10)
    assert rows == [{"n": 1}]
    assert truncated is False


def test_run_select_truncates(local_db):
    rows, truncated = validate.run_select(
        "SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3", 2
    )
    assert len(rows) == 2
    assert truncated is True


def test_transpile_returns_sql():
    assert "SELECT" in validate.transpile("SELECT 1").upper()
