Skip to content

Commit ab18101

Browse files
committed
test: simple test for the normalize structure, ensuring same function
Signed-off-by: Carl Flottmann <[email protected]>
1 parent 09c0322 commit ab18101

File tree

3 files changed

+272
-0
lines changed

3 files changed

+272
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<html>
2+
<head>
3+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🕵️</text></svg>">
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
5+
</head>
6+
<body>
7+
<main>
8+
<h1><a href="/">Inspector</a></h1>
9+
<form action="/">
10+
<input type="text" name="project" placeholder="Project name" value="posthog" autocomplete="off">
11+
<input type="submit">
12+
</form>
13+
<hr>
14+
<h2>
15+
<a href="/project/posthog">posthog</a>
16+
(<a href="https://pypi.org/project/posthog">View this project on PyPI</a>)
17+
</h2>
18+
<h3>
19+
<a href="/project/posthog/6.7.4">posthog==6.7.4</a>
20+
(<a href="https://pypi.org/project/posthog/6.7.4">View this release on PyPI</a>)
21+
</h3>
22+
<h4>
23+
<a href="/project/posthog/6.7.4/packages/0f/40/d7f585e09e47f492ebaeb8048a8e2ce5d9f49a3896856a7a975cbc1484fa/posthog-6.7.4.tar.gz/">posthog-6.7.4.tar.gz</a>
24+
</h4>
25+
<ul>
26+
<li><a href="./posthog-6.7.4/LICENSE">./posthog-6.7.4/LICENSE</a></li>
27+
<li><a href="./posthog-6.7.4/MANIFEST.in">./posthog-6.7.4/MANIFEST.in</a></li>
28+
<li><a href="./posthog-6.7.4/PKG-INFO">./posthog-6.7.4/PKG-INFO</a></li>
29+
<li><a href="./posthog-6.7.4/README.md">./posthog-6.7.4/README.md</a></li>
30+
<li><a href="./posthog-6.7.4/posthog/__init__.py">./posthog-6.7.4/posthog/__init__.py</a></li>
31+
<li><a href="./posthog-6.7.4/posthog/ai/__init__.py">./posthog-6.7.4/posthog/ai/__init__.py</a></li>
32+
<li><a href="./posthog-6.7.4/posthog/ai/anthropic/__init__.py">./posthog-6.7.4/posthog/ai/anthropic/__init__.py</a></li>
33+
<li><a href="./posthog-6.7.4/posthog/ai/anthropic/anthropic.py">./posthog-6.7.4/posthog/ai/anthropic/anthropic.py</a></li>
34+
<li><a href="./posthog-6.7.4/posthog/ai/anthropic/anthropic_async.py">./posthog-6.7.4/posthog/ai/anthropic/anthropic_async.py</a></li>
35+
<li><a href="./posthog-6.7.4/posthog/ai/anthropic/anthropic_converter.py">./posthog-6.7.4/posthog/ai/anthropic/anthropic_converter.py</a></li>
36+
<li><a href="./posthog-6.7.4/posthog/ai/anthropic/anthropic_providers.py">./posthog-6.7.4/posthog/ai/anthropic/anthropic_providers.py</a></li>
37+
<li><a href="./posthog-6.7.4/posthog/ai/gemini/__init__.py">./posthog-6.7.4/posthog/ai/gemini/__init__.py</a></li>
38+
<li><a href="./posthog-6.7.4/posthog/ai/gemini/gemini.py">./posthog-6.7.4/posthog/ai/gemini/gemini.py</a></li>
39+
<li><a href="./posthog-6.7.4/posthog/ai/gemini/gemini_converter.py">./posthog-6.7.4/posthog/ai/gemini/gemini_converter.py</a></li>
40+
<li><a href="./posthog-6.7.4/posthog/ai/langchain/__init__.py">./posthog-6.7.4/posthog/ai/langchain/__init__.py</a></li>
41+
<li><a href="./posthog-6.7.4/posthog/ai/langchain/callbacks.py">./posthog-6.7.4/posthog/ai/langchain/callbacks.py</a></li>
42+
<li><a href="./posthog-6.7.4/posthog/ai/openai/__init__.py">./posthog-6.7.4/posthog/ai/openai/__init__.py</a></li>
43+
<li><a href="./posthog-6.7.4/posthog/ai/openai/openai.py">./posthog-6.7.4/posthog/ai/openai/openai.py</a></li>
44+
<li><a href="./posthog-6.7.4/posthog/ai/openai/openai_async.py">./posthog-6.7.4/posthog/ai/openai/openai_async.py</a></li>
45+
<li><a href="./posthog-6.7.4/posthog/ai/openai/openai_converter.py">./posthog-6.7.4/posthog/ai/openai/openai_converter.py</a></li>
46+
<li><a href="./posthog-6.7.4/posthog/ai/openai/openai_providers.py">./posthog-6.7.4/posthog/ai/openai/openai_providers.py</a></li>
47+
<li><a href="./posthog-6.7.4/posthog/ai/sanitization.py">./posthog-6.7.4/posthog/ai/sanitization.py</a></li>
48+
<li><a href="./posthog-6.7.4/posthog/ai/types.py">./posthog-6.7.4/posthog/ai/types.py</a></li>
49+
<li><a href="./posthog-6.7.4/posthog/ai/utils.py">./posthog-6.7.4/posthog/ai/utils.py</a></li>
50+
<li><a href="./posthog-6.7.4/posthog/args.py">./posthog-6.7.4/posthog/args.py</a></li>
51+
<li><a href="./posthog-6.7.4/posthog/client.py">./posthog-6.7.4/posthog/client.py</a></li>
52+
<li><a href="./posthog-6.7.4/posthog/consumer.py">./posthog-6.7.4/posthog/consumer.py</a></li>
53+
<li><a href="./posthog-6.7.4/posthog/contexts.py">./posthog-6.7.4/posthog/contexts.py</a></li>
54+
<li><a href="./posthog-6.7.4/posthog/exception_capture.py">./posthog-6.7.4/posthog/exception_capture.py</a></li>
55+
<li><a href="./posthog-6.7.4/posthog/exception_utils.py">./posthog-6.7.4/posthog/exception_utils.py</a></li>
56+
<li><a href="./posthog-6.7.4/posthog/feature_flags.py">./posthog-6.7.4/posthog/feature_flags.py</a></li>
57+
<li><a href="./posthog-6.7.4/posthog/integrations/__init__.py">./posthog-6.7.4/posthog/integrations/__init__.py</a></li>
58+
<li><a href="./posthog-6.7.4/posthog/integrations/django.py">./posthog-6.7.4/posthog/integrations/django.py</a></li>
59+
<li><a href="./posthog-6.7.4/posthog/poller.py">./posthog-6.7.4/posthog/poller.py</a></li>
60+
<li><a href="./posthog-6.7.4/posthog/py.typed">./posthog-6.7.4/posthog/py.typed</a></li>
61+
<li><a href="./posthog-6.7.4/posthog/request.py">./posthog-6.7.4/posthog/request.py</a></li>
62+
<li><a href="./posthog-6.7.4/posthog/test/__init__.py">./posthog-6.7.4/posthog/test/__init__.py</a></li>
63+
<li><a href="./posthog-6.7.4/posthog/test/test_before_send.py">./posthog-6.7.4/posthog/test/test_before_send.py</a></li>
64+
<li><a href="./posthog-6.7.4/posthog/test/test_client.py">./posthog-6.7.4/posthog/test/test_client.py</a></li>
65+
<li><a href="./posthog-6.7.4/posthog/test/test_consumer.py">./posthog-6.7.4/posthog/test/test_consumer.py</a></li>
66+
<li><a href="./posthog-6.7.4/posthog/test/test_contexts.py">./posthog-6.7.4/posthog/test/test_contexts.py</a></li>
67+
<li><a href="./posthog-6.7.4/posthog/test/test_exception_capture.py">./posthog-6.7.4/posthog/test/test_exception_capture.py</a></li>
68+
<li><a href="./posthog-6.7.4/posthog/test/test_feature_flag.py">./posthog-6.7.4/posthog/test/test_feature_flag.py</a></li>
69+
<li><a href="./posthog-6.7.4/posthog/test/test_feature_flag_result.py">./posthog-6.7.4/posthog/test/test_feature_flag_result.py</a></li>
70+
<li><a href="./posthog-6.7.4/posthog/test/test_feature_flags.py">./posthog-6.7.4/posthog/test/test_feature_flags.py</a></li>
71+
<li><a href="./posthog-6.7.4/posthog/test/test_module.py">./posthog-6.7.4/posthog/test/test_module.py</a></li>
72+
<li><a href="./posthog-6.7.4/posthog/test/test_request.py">./posthog-6.7.4/posthog/test/test_request.py</a></li>
73+
<li><a href="./posthog-6.7.4/posthog/test/test_size_limited_dict.py">./posthog-6.7.4/posthog/test/test_size_limited_dict.py</a></li>
74+
<li><a href="./posthog-6.7.4/posthog/test/test_types.py">./posthog-6.7.4/posthog/test/test_types.py</a></li>
75+
<li><a href="./posthog-6.7.4/posthog/test/test_utils.py">./posthog-6.7.4/posthog/test/test_utils.py</a></li>
76+
<li><a href="./posthog-6.7.4/posthog/types.py">./posthog-6.7.4/posthog/types.py</a></li>
77+
<li><a href="./posthog-6.7.4/posthog/utils.py">./posthog-6.7.4/posthog/utils.py</a></li>
78+
<li><a href="./posthog-6.7.4/posthog/version.py">./posthog-6.7.4/posthog/version.py</a></li>
79+
<li><a href="./posthog-6.7.4/posthog.egg-info/PKG-INFO">./posthog-6.7.4/posthog.egg-info/PKG-INFO</a></li>
80+
<li><a href="./posthog-6.7.4/posthog.egg-info/SOURCES.txt">./posthog-6.7.4/posthog.egg-info/SOURCES.txt</a></li>
81+
<li><a href="./posthog-6.7.4/posthog.egg-info/dependency_links.txt">./posthog-6.7.4/posthog.egg-info/dependency_links.txt</a></li>
82+
<li><a href="./posthog-6.7.4/posthog.egg-info/requires.txt">./posthog-6.7.4/posthog.egg-info/requires.txt</a></li>
83+
<li><a href="./posthog-6.7.4/posthog.egg-info/top_level.txt">./posthog-6.7.4/posthog.egg-info/top_level.txt</a></li>
84+
<li><a href="./posthog-6.7.4/pyproject.toml">./posthog-6.7.4/pyproject.toml</a></li>
85+
<li><a href="./posthog-6.7.4/setup.cfg">./posthog-6.7.4/setup.cfg</a></li>
86+
<li><a href="./posthog-6.7.4/setup.py">./posthog-6.7.4/setup.py</a></li>
87+
</ul>
88+
</main>
89+
<footer>
90+
<small>Source: <a href="https://github.com/pypi/inspector">https://github.com/pypi/inspector</a></small>
91+
</footer>
92+
</body>
93+
</html>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<html>
2+
<head>
3+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🕵️</text></svg>">
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
5+
</head>
6+
<body>
7+
<main>
8+
<h1><a href="/">Inspector</a></h1>
9+
<form action="/">
10+
<input type="text" name="project" placeholder="Project name" value="posthog" autocomplete="off">
11+
<input type="submit">
12+
</form>
13+
<hr>
14+
<h2>
15+
<a href="/project/posthog">posthog</a>
16+
(<a href="https://pypi.org/project/posthog">View this project on PyPI</a>)
17+
</h2>
18+
<h3>
19+
<a href="/project/posthog/6.7.4">posthog==6.7.4</a>
20+
(<a href="https://pypi.org/project/posthog/6.7.4">View this release on PyPI</a>)
21+
</h3>
22+
<h4>
23+
<a href="/project/posthog/6.7.4/packages/bb/95/e795059ef73d480a7f11f1be201087f65207509525920897fb514a04914c/posthog-6.7.4-py3-none-any.whl/">posthog-6.7.4-py3-none-any.whl</a>
24+
</h4>
25+
<ul>
26+
<li><a href="./posthog/__init__.py">./posthog/__init__.py</a></li>
27+
<li><a href="./posthog/args.py">./posthog/args.py</a></li>
28+
<li><a href="./posthog/client.py">./posthog/client.py</a></li>
29+
<li><a href="./posthog/consumer.py">./posthog/consumer.py</a></li>
30+
<li><a href="./posthog/contexts.py">./posthog/contexts.py</a></li>
31+
<li><a href="./posthog/exception_capture.py">./posthog/exception_capture.py</a></li>
32+
<li><a href="./posthog/exception_utils.py">./posthog/exception_utils.py</a></li>
33+
<li><a href="./posthog/feature_flags.py">./posthog/feature_flags.py</a></li>
34+
<li><a href="./posthog/poller.py">./posthog/poller.py</a></li>
35+
<li><a href="./posthog/py.typed">./posthog/py.typed</a></li>
36+
<li><a href="./posthog/request.py">./posthog/request.py</a></li>
37+
<li><a href="./posthog/types.py">./posthog/types.py</a></li>
38+
<li><a href="./posthog/utils.py">./posthog/utils.py</a></li>
39+
<li><a href="./posthog/version.py">./posthog/version.py</a></li>
40+
<li><a href="./posthog/ai/__init__.py">./posthog/ai/__init__.py</a></li>
41+
<li><a href="./posthog/ai/sanitization.py">./posthog/ai/sanitization.py</a></li>
42+
<li><a href="./posthog/ai/types.py">./posthog/ai/types.py</a></li>
43+
<li><a href="./posthog/ai/utils.py">./posthog/ai/utils.py</a></li>
44+
<li><a href="./posthog/ai/anthropic/__init__.py">./posthog/ai/anthropic/__init__.py</a></li>
45+
<li><a href="./posthog/ai/anthropic/anthropic.py">./posthog/ai/anthropic/anthropic.py</a></li>
46+
<li><a href="./posthog/ai/anthropic/anthropic_async.py">./posthog/ai/anthropic/anthropic_async.py</a></li>
47+
<li><a href="./posthog/ai/anthropic/anthropic_converter.py">./posthog/ai/anthropic/anthropic_converter.py</a></li>
48+
<li><a href="./posthog/ai/anthropic/anthropic_providers.py">./posthog/ai/anthropic/anthropic_providers.py</a></li>
49+
<li><a href="./posthog/ai/gemini/__init__.py">./posthog/ai/gemini/__init__.py</a></li>
50+
<li><a href="./posthog/ai/gemini/gemini.py">./posthog/ai/gemini/gemini.py</a></li>
51+
<li><a href="./posthog/ai/gemini/gemini_converter.py">./posthog/ai/gemini/gemini_converter.py</a></li>
52+
<li><a href="./posthog/ai/langchain/__init__.py">./posthog/ai/langchain/__init__.py</a></li>
53+
<li><a href="./posthog/ai/langchain/callbacks.py">./posthog/ai/langchain/callbacks.py</a></li>
54+
<li><a href="./posthog/ai/openai/__init__.py">./posthog/ai/openai/__init__.py</a></li>
55+
<li><a href="./posthog/ai/openai/openai.py">./posthog/ai/openai/openai.py</a></li>
56+
<li><a href="./posthog/ai/openai/openai_async.py">./posthog/ai/openai/openai_async.py</a></li>
57+
<li><a href="./posthog/ai/openai/openai_converter.py">./posthog/ai/openai/openai_converter.py</a></li>
58+
<li><a href="./posthog/ai/openai/openai_providers.py">./posthog/ai/openai/openai_providers.py</a></li>
59+
<li><a href="./posthog/integrations/__init__.py">./posthog/integrations/__init__.py</a></li>
60+
<li><a href="./posthog/integrations/django.py">./posthog/integrations/django.py</a></li>
61+
<li><a href="./posthog/test/__init__.py">./posthog/test/__init__.py</a></li>
62+
<li><a href="./posthog/test/test_before_send.py">./posthog/test/test_before_send.py</a></li>
63+
<li><a href="./posthog/test/test_client.py">./posthog/test/test_client.py</a></li>
64+
<li><a href="./posthog/test/test_consumer.py">./posthog/test/test_consumer.py</a></li>
65+
<li><a href="./posthog/test/test_contexts.py">./posthog/test/test_contexts.py</a></li>
66+
<li><a href="./posthog/test/test_exception_capture.py">./posthog/test/test_exception_capture.py</a></li>
67+
<li><a href="./posthog/test/test_feature_flag.py">./posthog/test/test_feature_flag.py</a></li>
68+
<li><a href="./posthog/test/test_feature_flag_result.py">./posthog/test/test_feature_flag_result.py</a></li>
69+
<li><a href="./posthog/test/test_feature_flags.py">./posthog/test/test_feature_flags.py</a></li>
70+
<li><a href="./posthog/test/test_module.py">./posthog/test/test_module.py</a></li>
71+
<li><a href="./posthog/test/test_request.py">./posthog/test/test_request.py</a></li>
72+
<li><a href="./posthog/test/test_size_limited_dict.py">./posthog/test/test_size_limited_dict.py</a></li>
73+
<li><a href="./posthog/test/test_types.py">./posthog/test/test_types.py</a></li>
74+
<li><a href="./posthog/test/test_utils.py">./posthog/test/test_utils.py</a></li>
75+
<li><a href="./posthog-6.7.4.dist-info/licenses/LICENSE">./posthog-6.7.4.dist-info/licenses/LICENSE</a></li>
76+
<li><a href="./posthog-6.7.4.dist-info/METADATA">./posthog-6.7.4.dist-info/METADATA</a></li>
77+
<li><a href="./posthog-6.7.4.dist-info/WHEEL">./posthog-6.7.4.dist-info/WHEEL</a></li>
78+
<li><a href="./posthog-6.7.4.dist-info/top_level.txt">./posthog-6.7.4.dist-info/top_level.txt</a></li>
79+
<li><a href="./posthog-6.7.4.dist-info/RECORD">./posthog-6.7.4.dist-info/RECORD</a></li>
80+
</ul>
81+
</main>
82+
<footer>
83+
<small>Source: <a href="https://github.com/pypi/inspector">https://github.com/pypi/inspector</a></small>
84+
</footer>
85+
</body>
86+
</html>

tests/malware_analyzer/pypi/test_similar_projects.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,96 @@
33

44
"""Tests for the SimilarProjectAnalyzer heuristic."""
55
# pylint: disable=redefined-outer-name
6+
7+
import os
8+
from collections.abc import Callable, Generator
9+
from unittest.mock import MagicMock, patch
10+
11+
import pytest
12+
13+
from macaron.malware_analyzer.pypi_heuristics.metadata.similar_projects import SimilarProjectAnalyzer
14+
15+
TEST_SDIST_LINK = (
16+
"https://inspector.pypi.io/project/posthog/6.7.4/packages/0f/40/"
17+
"d7f585e09e47f492ebaeb8048a8e2ce5d9f49a3896856a7a975cbc1484fa/posthog-6.7.4.tar.gz/"
18+
)
19+
TEST_WHL_LINK = (
20+
"https://inspector.pypi.io/project/posthog/6.7.4/packages/bb/95/"
21+
"e795059ef73d480a7f11f1be201087f65207509525920897fb514a04914c/posthog-6.7.4-py3-none-any.whl/"
22+
)
23+
24+
25+
@pytest.fixture()
26+
def mock_send_get_http_raw() -> Generator[Callable]:
27+
"""Mock the send_get_http_raw function for inspector HTML.
28+
29+
Returns
30+
-------
31+
Generator[Callable, None, None]
32+
A mocked send_get_http_raw function that can just be included as a function parameter to work.
33+
"""
34+
html_samples_path = os.path.join(
35+
os.path.dirname(os.path.abspath(__file__)), "resources", "inspector_html_samples", "posthog"
36+
)
37+
38+
with open(os.path.join(html_samples_path, "posthog-6.7.4-tar-inspector.html"), "rb") as file:
39+
tarfile_inspector = file.read()
40+
with open(os.path.join(html_samples_path, "posthog-6.7.4-whl-inspector.html"), "rb") as file:
41+
wheel_inspector = file.read()
42+
43+
tarfile_response = MagicMock()
44+
tarfile_response.content = tarfile_inspector
45+
wheel_response = MagicMock()
46+
wheel_response.content = wheel_inspector
47+
48+
def mock_send_get_http_raw_side_effect(url: str) -> bytes | None:
49+
if url == TEST_SDIST_LINK:
50+
return tarfile_response
51+
if url == TEST_WHL_LINK:
52+
return wheel_response
53+
return None
54+
55+
with patch(
56+
"macaron.slsa_analyzer.package_registry.pypi_registry.send_get_http_raw",
57+
side_effect=mock_send_get_http_raw_side_effect,
58+
) as mock_send_get_http_raw:
59+
yield mock_send_get_http_raw
60+
61+
62+
@pytest.fixture()
63+
def analyzer() -> SimilarProjectAnalyzer:
64+
"""Pytest fixture to create a SimilarProjectAnalyzer instance."""
65+
analyzer_instance = SimilarProjectAnalyzer()
66+
return analyzer_instance
67+
68+
69+
def test_get_normalized_structure(
70+
analyzer: SimilarProjectAnalyzer,
71+
mock_send_get_http_raw: Callable, # pylint: disable=unused-argument
72+
pypi_package_json: MagicMock,
73+
) -> None:
74+
"""Test the get_normalized_structure function to ensure it extracts the same structure for a wheel and tarball.
75+
76+
Parameters
77+
----------
78+
pypi_package_json: PyPIPackageJsonAsset
79+
The PyPI package JSON asset object.
80+
analyzer: SimilarProjectAnalyzer
81+
An instantiated similar projects analyzer.
82+
mock_send_get_http_raw: Callable
83+
A mocked send_get_http_raw function to return inspector html.
84+
"""
85+
pypi_package_json.component_version = "6.7.4"
86+
pypi_package_json.component_name = "posthog"
87+
88+
pypi_package_json.inspector_asset.package_sdist_link = TEST_SDIST_LINK
89+
pypi_package_json.inspector_asset.package_link_reachability = {TEST_SDIST_LINK: True}
90+
pypi_package_json.inspector_asset.package_whl_links = []
91+
sdist_structure = analyzer.get_normalized_structure(pypi_package_json)
92+
93+
pypi_package_json.inspector_asset.package_sdist_link = ""
94+
pypi_package_json.inspector_asset.package_whl_links = [TEST_WHL_LINK]
95+
pypi_package_json.inspector_asset.package_link_reachability = {TEST_WHL_LINK: True}
96+
wheel_structure = analyzer.get_normalized_structure(pypi_package_json)
97+
98+
assert sdist_structure == wheel_structure

0 commit comments

Comments
 (0)