tests: centralize script path setup in conftest.py

Add a pytest-discovered tests/conftest.py for the last30days scripts path and
remove duplicate per-file sys.path.insert boilerplate from tests.

Normalize affected imports to rely on the shared scripts path and remove the
now-unneeded E402 suppressions.
This commit is contained in:
Yong-yuan-X
2026-05-20 23:16:07 +08:00
parent 850c7e0185
commit e74b0e1e93
84 changed files with 194 additions and 578 deletions
+22 -27
View File
@@ -1,19 +1,15 @@
"""Tests for Chrome cookie extraction on macOS."""
import hashlib
import os
import sqlite3
import subprocess
import sys
import tempfile
from pathlib import Path
from unittest import mock
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "skills" / "last30days"))
from scripts.lib.chrome_cookies import (
from lib.chrome_cookies import (
CHROME_COOKIES_DB,
CHROME_IV_HEX,
CHROME_KEY_LENGTH,
@@ -27,7 +23,6 @@ from scripts.lib.chrome_cookies import (
extract_chrome_cookies_macos,
)
# ---------------------------------------------------------------------------
# Helpers — create real encrypted cookie values using known key + system openssl
# ---------------------------------------------------------------------------
@@ -112,11 +107,11 @@ def _create_chrome_cookies_db(path: str, cookies: list[tuple], db_version: int =
conn.commit()
conn.close()
# ---------------------------------------------------------------------------
# PKCS7 padding tests
# ---------------------------------------------------------------------------
class TestPkcs7Padding:
def test_valid_padding_1(self):
# 1 byte of padding
@@ -143,11 +138,11 @@ class TestPkcs7Padding:
def test_empty_data(self):
assert _remove_pkcs7_padding(b"") is None
# ---------------------------------------------------------------------------
# Key derivation test
# ---------------------------------------------------------------------------
class TestKeyDerivation:
def test_derive_aes_key_deterministic(self):
key1 = _derive_aes_key(b"my_passphrase")
@@ -160,11 +155,11 @@ class TestKeyDerivation:
key2 = _derive_aes_key(b"passphrase_b")
assert key1 != key2
# ---------------------------------------------------------------------------
# Decryption test (real openssl, known key)
# ---------------------------------------------------------------------------
class TestDecryption:
def test_decrypt_v10_roundtrip(self):
"""Encrypt then decrypt — verifies the full pipeline works."""
@@ -197,28 +192,28 @@ class TestDecryption:
"""v10 prefix with no ciphertext should return None."""
assert _decrypt_v10_value(b"v10", KNOWN_AES_KEY, db_version=20) is None
# ---------------------------------------------------------------------------
# Chrome not installed → returns None
# ---------------------------------------------------------------------------
class TestChromeNotInstalled:
def test_db_not_found(self):
with mock.patch(
"scripts.lib.chrome_cookies.CHROME_COOKIES_DB",
"lib.chrome_cookies.CHROME_COOKIES_DB",
Path("/nonexistent/path/Cookies"),
):
result = extract_chrome_cookies_macos(".x.com", ["auth_token"])
assert result is None
# ---------------------------------------------------------------------------
# Keychain access denied → returns None
# ---------------------------------------------------------------------------
class TestKeychainDenied:
def test_security_command_fails(self):
with mock.patch("scripts.lib.chrome_cookies.subprocess.run") as mock_run:
with mock.patch("lib.chrome_cookies.subprocess.run") as mock_run:
mock_run.return_value = subprocess.CompletedProcess(
args=[], returncode=44, stdout="", stderr="security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain."
)
@@ -226,27 +221,27 @@ class TestKeychainDenied:
assert result is None
def test_security_command_not_found(self):
with mock.patch("scripts.lib.chrome_cookies.subprocess.run", side_effect=FileNotFoundError):
with mock.patch("lib.chrome_cookies.subprocess.run", side_effect=FileNotFoundError):
result = _get_chrome_encryption_key()
assert result is None
# ---------------------------------------------------------------------------
# openssl not found → returns None
# ---------------------------------------------------------------------------
class TestOpensslNotFound:
def test_openssl_missing(self):
encrypted = _encrypt_value_v10("test", KNOWN_AES_KEY)
with mock.patch("scripts.lib.chrome_cookies.subprocess.run", side_effect=FileNotFoundError):
with mock.patch("lib.chrome_cookies.subprocess.run", side_effect=FileNotFoundError):
result = _decrypt_v10_value(encrypted, KNOWN_AES_KEY, db_version=20)
assert result is None
# ---------------------------------------------------------------------------
# Unencrypted cookie values → returned as-is
# ---------------------------------------------------------------------------
class TestUnencryptedCookies:
def test_plain_value_returned(self, tmp_path):
"""Unencrypted cookies (value column populated) returned without decryption."""
@@ -256,18 +251,18 @@ class TestUnencryptedCookies:
(".x.com", "ct0", "plain_ct0_value", b""),
])
with mock.patch("scripts.lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch("lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
# No keychain needed for unencrypted values
with mock.patch("scripts.lib.chrome_cookies._get_chrome_encryption_key", return_value=None):
with mock.patch("lib.chrome_cookies._get_chrome_encryption_key", return_value=None):
result = extract_chrome_cookies_macos(".x.com", ["auth_token", "ct0"])
assert result == {"auth_token": "plain_token_value", "ct0": "plain_ct0_value"}
# ---------------------------------------------------------------------------
# Full integration: mock DB with real v10 encryption, mock Keychain
# ---------------------------------------------------------------------------
class TestFullExtraction:
def test_encrypted_cookies_extracted(self, tmp_path):
"""End-to-end: create DB with real v10-encrypted values, extract them."""
@@ -284,9 +279,9 @@ class TestFullExtraction:
(".other.com", "other", "", b""), # unrelated cookie
])
with mock.patch("scripts.lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch("lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch(
"scripts.lib.chrome_cookies._get_chromium_encryption_key",
"lib.chrome_cookies._get_chromium_encryption_key",
return_value=KNOWN_PASSPHRASE,
):
result = extract_chrome_cookies_macos(".x.com", ["auth_token", "ct0"])
@@ -301,8 +296,8 @@ class TestFullExtraction:
(".other.com", "session", "val", b""),
])
with mock.patch("scripts.lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch("scripts.lib.chrome_cookies._get_chrome_encryption_key", return_value=None):
with mock.patch("lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch("lib.chrome_cookies._get_chrome_encryption_key", return_value=None):
result = extract_chrome_cookies_macos(".x.com", ["auth_token"])
assert result is None
@@ -317,9 +312,9 @@ class TestFullExtraction:
(".x.com", "auth_token", "", encrypted_auth),
], db_version=24)
with mock.patch("scripts.lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch("lib.chrome_cookies.CHROME_COOKIES_DB", Path(db_path)):
with mock.patch(
"scripts.lib.chrome_cookies._get_chromium_encryption_key",
"lib.chrome_cookies._get_chromium_encryption_key",
return_value=KNOWN_PASSPHRASE,
):
result = extract_chrome_cookies_macos(".x.com", ["auth_token"])
@@ -327,11 +322,11 @@ class TestFullExtraction:
assert result is not None
assert result["auth_token"] == auth_val
# ---------------------------------------------------------------------------
# DB version detection
# ---------------------------------------------------------------------------
class TestDbVersion:
def test_reads_version_from_meta(self, tmp_path):
db_path = str(tmp_path / "test.db")