pyproxytools 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,119 @@
1
+ """
2
+ test_shortcuts.py
3
+
4
+ This module contains unit tests for the `shortcuts.py` module.
5
+ It verifies the correct functionality of loading shortcuts and resolving aliases.
6
+
7
+ Tested Functions:
8
+ - load_shortcuts: Ensures that the shortcut file is correctly loaded
9
+ and the alias-URL mappings are correct.
10
+ - shortcuts_process: Ensures that alias requests are correctly processed
11
+ and resolved to their corresponding URLs.
12
+
13
+ Test Cases:
14
+ - TestLoadShortcuts: Checks the correct loading of alias-URL mappings from the file.
15
+ - TestShortcutsProcess: Verifies that alias requests are correctly resolved to URLs.
16
+ - TestLoadShortcutsFileNotFound: Verifies that a FileNotFoundError is raised
17
+ when the shortcuts file is missing.
18
+ - TestShortcutsProcessWithAliasRequest: Verifies that the process correctly
19
+ resolves alias requests to URLs.
20
+ - TestShortcutsProcessFileMonitor: Verifies that the file monitor thread correctly
21
+ updates the shortcuts when the file is changed.
22
+ """
23
+
24
+ import unittest
25
+ import multiprocessing
26
+ from unittest.mock import patch, mock_open
27
+ from pyproxy.modules.shortcuts import load_shortcuts, shortcuts_process
28
+
29
+
30
+ class TestShortcuts(unittest.TestCase):
31
+ """
32
+ Test suite for the shortcuts module.
33
+ """
34
+
35
+ def setUp(self):
36
+ """Sets up the common resources for tests."""
37
+ self.queue = multiprocessing.Queue()
38
+ self.result_queue = multiprocessing.Queue()
39
+
40
+ def tearDown(self):
41
+ """Cleans up after each test."""
42
+ while not self.queue.empty():
43
+ self.queue.get_nowait()
44
+ while not self.result_queue.empty():
45
+ self.result_queue.get_nowait()
46
+
47
+ def test_load_shortcuts(self):
48
+ """Tests if the shortcuts are correctly loaded from the file."""
49
+ with patch(
50
+ "builtins.open",
51
+ new_callable=mock_open,
52
+ read_data="alias1=http://example.com\nalias2=http://test.com",
53
+ ):
54
+ shortcuts = load_shortcuts("shortcuts.txt")
55
+ self.assertEqual(shortcuts["alias1"], "http://example.com")
56
+ self.assertEqual(shortcuts["alias2"], "http://test.com")
57
+ self.assertIsInstance(shortcuts, dict)
58
+
59
+ @patch("builtins.open", side_effect=FileNotFoundError("File not found"))
60
+ def test_load_shortcuts_file_not_found(self, _mock_file):
61
+ """Tests that a FileNotFoundError is raised when the shortcuts file is missing."""
62
+ with self.assertRaises(FileNotFoundError):
63
+ load_shortcuts("invalid_file.txt")
64
+
65
+ def _test_shortcuts_process_helper(
66
+ self, alias, expected_url, patch_data="alias1=http://example.com"
67
+ ):
68
+ """Helper method to test shortcuts_process with different alias requests."""
69
+ with patch("builtins.open", new_callable=mock_open, read_data=patch_data):
70
+ process = multiprocessing.Process(
71
+ target=shortcuts_process,
72
+ args=(self.queue, self.result_queue, "shortcuts.txt"),
73
+ )
74
+ process.start()
75
+
76
+ self.queue.put(alias)
77
+
78
+ result = self.result_queue.get(timeout=2)
79
+ self.assertEqual(result, expected_url)
80
+
81
+ process.terminate()
82
+ process.join()
83
+
84
+ def test_shortcuts_process(self):
85
+ """Tests if alias requests are correctly resolved to URLs."""
86
+ self._test_shortcuts_process_helper("alias1", "http://example.com")
87
+
88
+ def test_shortcuts_process_invalid_alias(self):
89
+ """Tests if an invalid alias returns None."""
90
+ self._test_shortcuts_process_helper("invalid_alias", None)
91
+
92
+ def test_shortcuts_process_with_multiple_aliases(self):
93
+ """Tests if multiple alias requests are correctly resolved."""
94
+ with patch(
95
+ "builtins.open",
96
+ new_callable=mock_open,
97
+ read_data="alias1=http://example.com\nalias2=http://test.com",
98
+ ):
99
+ process = multiprocessing.Process(
100
+ target=shortcuts_process,
101
+ args=(self.queue, self.result_queue, "shortcuts.txt"),
102
+ )
103
+ process.start()
104
+
105
+ self.queue.put("alias1")
106
+ self.queue.put("alias2")
107
+
108
+ result1 = self.result_queue.get(timeout=2)
109
+ result2 = self.result_queue.get(timeout=2)
110
+
111
+ self.assertEqual(result1, "http://example.com")
112
+ self.assertEqual(result2, "http://test.com")
113
+
114
+ process.terminate()
115
+ process.join()
116
+
117
+
118
+ if __name__ == "__main__":
119
+ unittest.main()
File without changes
@@ -0,0 +1,110 @@
1
+ """
2
+ tests.utils.test_crypto.py
3
+
4
+ This module contains unit tests for the `crypto.py` module in the `pyproxy.utils` package.
5
+ """
6
+
7
+ import unittest
8
+ import os
9
+ import tempfile
10
+ from OpenSSL import crypto
11
+ from pyproxy.utils.crypto import generate_certificate
12
+
13
+
14
+ class TestCrypto(unittest.TestCase):
15
+ """
16
+ Test suite for the crypto module.
17
+ """
18
+
19
+ def setUp(self):
20
+ """
21
+ Set up a fake CA certificate and private key for testing.
22
+ """
23
+ self.certs_folder = tempfile.mkdtemp()
24
+ self.domain = "example.com"
25
+ self.ca_cert_path = os.path.join(self.certs_folder, "ca_cert.pem")
26
+ self.ca_key_path = os.path.join(self.certs_folder, "ca_key.pem")
27
+
28
+ self._generate_fake_ca()
29
+
30
+ def _generate_fake_ca(self):
31
+ """
32
+ Generate a fake self-signed CA certificate and key for testing purposes.
33
+ """
34
+ ca_key = crypto.PKey()
35
+ ca_key.generate_key(crypto.TYPE_RSA, 2048)
36
+
37
+ ca_cert = crypto.X509()
38
+ ca_cert.set_serial_number(1000)
39
+ ca_cert.get_subject().CN = "Fake CA"
40
+ ca_cert.gmtime_adj_notBefore(0)
41
+ ca_cert.gmtime_adj_notAfter(365 * 24 * 60 * 60)
42
+ ca_cert.set_issuer(ca_cert.get_subject())
43
+ ca_cert.set_pubkey(ca_key)
44
+
45
+ ca_cert.sign(ca_key, "sha256")
46
+
47
+ with open(self.ca_cert_path, "wb") as cert_file:
48
+ cert_file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, ca_cert))
49
+ with open(self.ca_key_path, "wb") as key_file:
50
+ key_file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, ca_key))
51
+
52
+ def test_generate_certificate(self):
53
+ """
54
+ Test the `generate_certificate` function to ensure it generates a certificate
55
+ and private key file for a given domain.
56
+ """
57
+ if not self.certs_folder.endswith("/"):
58
+ self.certs_folder += "/"
59
+ cert_path, key_path = generate_certificate(
60
+ self.domain, self.certs_folder, self.ca_cert_path, self.ca_key_path
61
+ )
62
+
63
+ expected_cert_path = os.path.join(self.certs_folder, f"{self.domain}.pem")
64
+ expected_key_path = os.path.join(self.certs_folder, f"{self.domain}.key")
65
+
66
+ self.assertEqual(cert_path, expected_cert_path)
67
+ self.assertEqual(key_path, expected_key_path)
68
+
69
+ self.assertTrue(os.path.exists(cert_path))
70
+ self.assertTrue(os.path.exists(key_path))
71
+
72
+ with open(cert_path, "rb") as cert_file:
73
+ cert_data = cert_file.read()
74
+ cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_data)
75
+
76
+ with open(key_path, "rb") as key_file:
77
+ key_data = key_file.read()
78
+ key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_data)
79
+
80
+ self.assertEqual(
81
+ crypto.dump_publickey(crypto.FILETYPE_PEM, cert.get_pubkey()),
82
+ crypto.dump_publickey(crypto.FILETYPE_PEM, key),
83
+ )
84
+
85
+ def tearDown(self):
86
+ """
87
+ Cleanup method executed after each test.
88
+
89
+ - Deletes the generated certificate and key files if they exist.
90
+ - Removes the fake CA files.
91
+ """
92
+ cert_path = os.path.join(self.certs_folder, f"{self.domain}.pem")
93
+ key_path = os.path.join(self.certs_folder, f"{self.domain}.key")
94
+
95
+ if os.path.exists(cert_path):
96
+ os.remove(cert_path)
97
+ if os.path.exists(key_path):
98
+ os.remove(key_path)
99
+
100
+ if os.path.exists(self.ca_cert_path):
101
+ os.remove(self.ca_cert_path)
102
+ if os.path.exists(self.ca_key_path):
103
+ os.remove(self.ca_key_path)
104
+
105
+ if os.path.exists(self.certs_folder):
106
+ os.rmdir(self.certs_folder)
107
+
108
+
109
+ if __name__ == "__main__":
110
+ unittest.main()
@@ -0,0 +1,69 @@
1
+ """
2
+ tests.utils.test_http_req.py
3
+
4
+ This module contains unit tests for the `http_req.py` module in the `pyproxy.utils` package.
5
+ """
6
+
7
+ import unittest
8
+ from pyproxy.utils.http_req import extract_headers, parse_url
9
+
10
+
11
+ class TestHttpReq(unittest.TestCase):
12
+ """
13
+ Test suite for the HTTP request utilities.
14
+ """
15
+
16
+ def test_extract_headers(self):
17
+ """
18
+ Test the `extract_headers` function to ensure it correctly parses the headers
19
+ from an HTTP request string.
20
+ """
21
+
22
+ request_str = """GET / HTTP/1.1
23
+ Host: example.com
24
+ User-Agent: Mozilla/5.0
25
+ Accept: */*
26
+
27
+ """
28
+ expected_headers = {
29
+ "Host": "example.com",
30
+ "User-Agent": "Mozilla/5.0",
31
+ "Accept": "*/*",
32
+ }
33
+
34
+ headers = extract_headers(request_str)
35
+ self.assertEqual(headers, expected_headers)
36
+
37
+ def test_parse_url(self):
38
+ """
39
+ Test the `parse_url` function to ensure it correctly extracts the host and port
40
+ from a URL.
41
+ """
42
+
43
+ url = "http://example.com:8080/path/to/resource"
44
+ expected_host, expected_port = "example.com", 8080
45
+ host, port = parse_url(url)
46
+ self.assertEqual(host, expected_host)
47
+ self.assertEqual(port, expected_port)
48
+
49
+ url = "http://example.com/path/to/resource"
50
+ expected_host, expected_port = "example.com", 80
51
+ host, port = parse_url(url)
52
+ self.assertEqual(host, expected_host)
53
+ self.assertEqual(port, expected_port)
54
+
55
+ url = "example.com:9090"
56
+ expected_host, expected_port = "example.com", 9090
57
+ host, port = parse_url(url)
58
+ self.assertEqual(host, expected_host)
59
+ self.assertEqual(port, expected_port)
60
+
61
+ url = "example.com"
62
+ expected_host, expected_port = "example.com", 80
63
+ host, port = parse_url(url)
64
+ self.assertEqual(host, expected_host)
65
+ self.assertEqual(port, expected_port)
66
+
67
+
68
+ if __name__ == "__main__":
69
+ unittest.main()
@@ -0,0 +1,68 @@
1
+ """
2
+ tests.utils.test_logger.py
3
+
4
+ This module contains unit tests for the `logger.py` module.
5
+ It verifies the correct configuration of both console and file loggers.
6
+ """
7
+
8
+ import unittest
9
+ import logging
10
+ import os
11
+ from unittest.mock import patch, MagicMock
12
+ from pyproxy.utils.logger import configure_console_logger, configure_file_logger
13
+
14
+
15
+ class TestLogger(unittest.TestCase):
16
+ """
17
+ Test suite for the logger module.
18
+ """
19
+
20
+ @patch("sys.stdout")
21
+ def test_configure_console_logger(self, mock_stdout):
22
+ """
23
+ Test that the console logger is correctly configured.
24
+
25
+ - Ensures the logger has at least one handler.
26
+ - Checks that the log level is set to INFO.
27
+ - Verifies that the handler is a StreamHandler.
28
+ """
29
+ logger = configure_console_logger()
30
+
31
+ self.assertTrue(logger.hasHandlers())
32
+ self.assertEqual(logger.level, logging.INFO)
33
+ handler_types = [type(handler) for handler in logger.handlers]
34
+ self.assertIn(logging.StreamHandler, handler_types)
35
+
36
+ @patch("logging.FileHandler")
37
+ def test_configure_file_logger(self, mock_file_handler):
38
+ """
39
+ Test that the file logger is correctly configured.
40
+
41
+ - Uses a mock for FileHandler to avoid creating actual files.
42
+ - Ensures the logger has at least one handler.
43
+ - Checks that the log level is set to INFO.
44
+ - Verifies that FileHandler is called with the correct log file path.
45
+ """
46
+ mock_handler_instance = MagicMock()
47
+ mock_file_handler.return_value = mock_handler_instance
48
+
49
+ log_path = "logs/test.log"
50
+ logger = configure_file_logger(log_path, "TestLogger")
51
+
52
+ self.assertTrue(logger.hasHandlers())
53
+ self.assertEqual(logger.level, logging.INFO)
54
+ mock_file_handler.assert_called_once_with(log_path)
55
+
56
+ def tearDown(self):
57
+ """
58
+ Cleanup method executed after each test.
59
+
60
+ - Deletes the test log file if it exists.
61
+ """
62
+ log_file = "logs/test.log"
63
+ if os.path.exists(log_file):
64
+ os.remove(log_file)
65
+
66
+
67
+ if __name__ == "__main__":
68
+ unittest.main()