157 lines
5.6 KiB
Python
157 lines
5.6 KiB
Python
"""Offline test for wp_svn_eternal — SVN listing parsing + file scan + DB write + dedup.
|
|
|
|
Uses real fixture files (no network). Proves:
|
|
a) fetch_svn_list parses trunk HTML correctly
|
|
b) scan_text finds keys in injected sample file
|
|
c) junk filter drops garbage candidates
|
|
d) db_add inserts + dedupes
|
|
"""
|
|
import hashlib, os, sys, sqlite3, tempfile, unittest
|
|
|
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
FIXTURE_TRUNK = os.path.join(BASE, "tests", "wp_svn_trunk_fixture.html")
|
|
FIXTURE_FILE = os.path.join(BASE, "tests", "wp_svn_file_fixture.txt")
|
|
|
|
DB_CONTRACT_SQL = """CREATE TABLE IF NOT EXISTS keys (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
hash TEXT UNIQUE,
|
|
val TEXT, prov TEXT, status TEXT DEFAULT "NEW",
|
|
plan TEXT, price TEXT, remaining TEXT,
|
|
found TEXT, repo TEXT)"""
|
|
|
|
|
|
class TestWpSvn(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.tmp = tempfile.NamedTemporaryFile(suffix=".db", delete=False)
|
|
self.tmp.close()
|
|
conn = sqlite3.connect(self.tmp.name)
|
|
conn.execute(DB_CONTRACT_SQL)
|
|
conn.commit()
|
|
conn.close()
|
|
self.old_kf_db = os.environ.get("KF_DB")
|
|
os.environ["KF_DB"] = self.tmp.name
|
|
|
|
def tearDown(self):
|
|
if "wp_svn_eternal" in sys.modules:
|
|
m = sys.modules["wp_svn_eternal"]
|
|
try:
|
|
m.conn.close()
|
|
except Exception:
|
|
pass
|
|
if self.old_kf_db:
|
|
os.environ["KF_DB"] = self.old_kf_db
|
|
else:
|
|
os.environ.pop("KF_DB", None)
|
|
try:
|
|
os.unlink(self.tmp.name)
|
|
except PermissionError:
|
|
pass
|
|
|
|
def _import(self):
|
|
if "wp_svn_eternal" in sys.modules:
|
|
del sys.modules["wp_svn_eternal"]
|
|
if BASE not in sys.path:
|
|
sys.path.insert(0, BASE)
|
|
import wp_svn_eternal as m
|
|
m.conn = sqlite3.connect(self.tmp.name, timeout=120,
|
|
check_same_thread=False, isolation_level=None)
|
|
m.conn.execute(DB_CONTRACT_SQL)
|
|
m.conn.commit()
|
|
return m
|
|
|
|
def test_parse_trunk_listing(self):
|
|
"""(a) Replicate fetch_svn_list parser on real trunk HTML."""
|
|
m = self._import()
|
|
with open(FIXTURE_TRUNK, encoding="utf-8") as fh:
|
|
html = fh.read()
|
|
|
|
files, dirs = [], []
|
|
for li in __import__("re").finditer(
|
|
r'<li><a\s+href="([^"]+)">([^<]*)</a></li>', html):
|
|
href = li.group(1)
|
|
name = li.group(2)
|
|
if name == ".." or not name:
|
|
continue
|
|
if href.endswith("/"):
|
|
dirs.append(name.rstrip("/"))
|
|
elif not href.startswith("?"):
|
|
files.append(name)
|
|
|
|
self.assertIn("akismet.php", files)
|
|
self.assertIn("_inc", dirs)
|
|
self.assertIn("abilities", dirs)
|
|
self.assertIn("readme.txt", files)
|
|
self.assertIn("changelog.txt", files)
|
|
self.assertGreater(len(files) + len(dirs), 10)
|
|
|
|
def test_scan_finds_keys(self):
|
|
"""(b) scan_text extracts injected keys from fixture file."""
|
|
m = self._import()
|
|
with open(FIXTURE_FILE, encoding="utf-8") as fh:
|
|
text = fh.read()
|
|
results = m.scan_text(text)
|
|
found_keys = [k for prov, k in results if isinstance(k, str)]
|
|
|
|
self.assertTrue(
|
|
any("LongKeyBodyAvoidGarbageFilterCheckPassOpenaiTestSkProjValidCharsHereForSixtyPlusMoreNow" in k
|
|
for k in found_keys),
|
|
f"Expected injected key in results, got first 5: {found_keys[:5]}"
|
|
)
|
|
|
|
def test_junk_filter(self):
|
|
"""(c) GARBAGE-filtered keys are dropped by db_add."""
|
|
m = self._import()
|
|
with open(FIXTURE_FILE, encoding="utf-8") as fh:
|
|
text = fh.read()
|
|
results = m.scan_text(text)
|
|
self.assertGreater(len(results), 1,
|
|
"Need at least 2 scan results to test filtering")
|
|
|
|
before = m.total
|
|
for prov, key in results:
|
|
if isinstance(key, tuple):
|
|
key = key[0]
|
|
m.db_add(key, prov, "wp:test-slug")
|
|
added = m.total - before
|
|
|
|
conn = sqlite3.connect(self.tmp.name)
|
|
rows = conn.execute("SELECT val FROM keys").fetchall()
|
|
conn.close()
|
|
vals = [r[0] for r in rows]
|
|
|
|
for v in vals:
|
|
self.assertFalse("xxxxxxxxxxxx" in v,
|
|
f"Garbage key leaked: {v[:30]}")
|
|
self.assertGreater(added, 0,
|
|
"Should have added at least one key")
|
|
self.assertLess(added, len(results),
|
|
"Junk filter should have removed garbage entries")
|
|
|
|
def test_db_add_dedup(self):
|
|
"""(d) db_add dedupes on repeat insert."""
|
|
m = self._import()
|
|
key = "sk-proj-TestDedupLongKeyBodyPassFilterCheckOpenaiApiTestValidSixtyPlusCharsHereMoreNowXyz"
|
|
self.assertGreater(len(key), 60)
|
|
m.db_add(key, "OPENAI", "wp:test-slug")
|
|
|
|
h = hashlib.sha1(key.encode()).hexdigest()[:16]
|
|
conn = sqlite3.connect(self.tmp.name)
|
|
row = conn.execute(
|
|
"SELECT COUNT(*) FROM keys WHERE hash=?", (h,)).fetchone()
|
|
self.assertEqual(row[0], 1,
|
|
"First insert should create one row")
|
|
|
|
# Second insert of same key: ON CONFLICT WHERE status IN ('DEAD','ERR')
|
|
# won't match (status='NEW'), no duplicate row created
|
|
m.db_add(key, "OPENAI", "wp:test-slug")
|
|
row2 = conn.execute(
|
|
"SELECT COUNT(*) FROM keys WHERE hash=?", (h,)).fetchone()
|
|
conn.close()
|
|
self.assertEqual(row2[0], 1,
|
|
"Dedup failed: duplicate row created")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2) |