v2kit 0.1__tar.gz → 0.3__tar.gz

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.
Files changed (44) hide show
  1. {v2kit-0.1 → v2kit-0.3}/AUTHORS.md +1 -1
  2. v2kit-0.3/CHANGELOG.md +52 -0
  3. {v2kit-0.1 → v2kit-0.3}/PKG-INFO +85 -11
  4. {v2kit-0.1 → v2kit-0.3}/README.md +52 -8
  5. {v2kit-0.1 → v2kit-0.3}/SECURITY.md +2 -2
  6. v2kit-0.1/dev-requirements.txt → v2kit-0.3/requirements-dev.txt +2 -0
  7. {v2kit-0.1 → v2kit-0.3}/setup.py +6 -17
  8. v2kit-0.3/tests/test_errors.py +202 -0
  9. {v2kit-0.1 → v2kit-0.3}/tests/test_functions.py +98 -13
  10. v2kit-0.3/tests/test_shadowsocks.py +17 -0
  11. v2kit-0.3/tests/test_socks.py +69 -0
  12. v2kit-0.3/tests/test_trojan.py +17 -0
  13. v2kit-0.3/tests/test_vless.py +58 -0
  14. v2kit-0.3/tests/test_vmess.py +32 -0
  15. v2kit-0.3/v2kit/__init__.py +36 -0
  16. v2kit-0.3/v2kit/errors.py +14 -0
  17. v2kit-0.3/v2kit/functions.py +136 -0
  18. v2kit-0.3/v2kit/models/__init__.py +9 -0
  19. v2kit-0.3/v2kit/models/base.py +108 -0
  20. v2kit-0.3/v2kit/models/shadowsocks.py +168 -0
  21. v2kit-0.3/v2kit/models/socks.py +172 -0
  22. v2kit-0.3/v2kit/models/trojan.py +140 -0
  23. v2kit-0.3/v2kit/models/vless.py +141 -0
  24. v2kit-0.3/v2kit/models/vmess.py +217 -0
  25. v2kit-0.3/v2kit/params.py +31 -0
  26. v2kit-0.3/v2kit/parsers.py +190 -0
  27. v2kit-0.3/v2kit/utils.py +66 -0
  28. v2kit-0.3/v2kit/validators.py +181 -0
  29. {v2kit-0.1 → v2kit-0.3}/v2kit.egg-info/PKG-INFO +85 -11
  30. v2kit-0.3/v2kit.egg-info/SOURCES.txt +34 -0
  31. v2kit-0.1/CHANGELOG.md +0 -22
  32. v2kit-0.1/requirements.txt +0 -1
  33. v2kit-0.1/tests/test_errors.py +0 -85
  34. v2kit-0.1/v2kit/__init__.py +0 -17
  35. v2kit-0.1/v2kit/functions.py +0 -106
  36. v2kit-0.1/v2kit/params.py +0 -19
  37. v2kit-0.1/v2kit/utils.py +0 -162
  38. v2kit-0.1/v2kit.egg-info/SOURCES.txt +0 -20
  39. {v2kit-0.1 → v2kit-0.3}/LICENSE +0 -0
  40. {v2kit-0.1 → v2kit-0.3}/MANIFEST.in +0 -0
  41. {v2kit-0.1 → v2kit-0.3}/setup.cfg +0 -0
  42. {v2kit-0.1 → v2kit-0.3}/v2kit/__main__.py +0 -0
  43. {v2kit-0.1 → v2kit-0.3}/v2kit.egg-info/dependency_links.txt +0 -0
  44. {v2kit-0.1 → v2kit-0.3}/v2kit.egg-info/top_level.txt +0 -0
@@ -5,7 +5,7 @@
5
5
 
6
6
  # Other Contributors
7
7
  ----------
8
- - [ChatGPT](https://chat.openai.com/) ++
8
+ - [Gemini](https://gemini.google.com) ++
9
9
 
10
10
  ++ Graphic designer
11
11
 
v2kit-0.3/CHANGELOG.md ADDED
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+ ## [0.3] - 2026-06-16
9
+ ### Added
10
+ - Logo
11
+ - `SocksConfig` class
12
+ - `is_socks` function
13
+ ### Changed
14
+ - `README.md` updated
15
+ - Test system modified
16
+ - Dependencies structure modified
17
+ - All config models moved to `models` folder
18
+ ## [0.2] - 2026-06-04
19
+ ### Added
20
+ - `VMESSConfig` class
21
+ - `VLESSConfig` class
22
+ - `TrojanConfig` class
23
+ - `ShadowsocksConfig` class
24
+ - `V2kitError` class
25
+ - `V2kitValidationError` class
26
+ - `V2kitParseError` class
27
+ - `parse` function
28
+ ### Changed
29
+ - `README.md` updated
30
+ - Test system modified
31
+ - `is_vmess` function `config` parameter renamed to `uri`
32
+ - `is_vless` function `config` parameter renamed to `uri`
33
+ - `is_trojan` function `config` parameter renamed to `uri`
34
+ - `is_shadowsocks` function `config` parameter renamed to `uri`
35
+ - `encode_subscription` function `configs` parameter renamed to `entries`
36
+ ## [0.1] - 2026-05-16
37
+ ### Added
38
+ - `is_vmess` function
39
+ - `is_vless` function
40
+ - `is_trojan` function
41
+ - `is_shadowsocks` function
42
+ - `relabel` function
43
+ - `encode_subscription` function
44
+ - `decode_subscription` function
45
+
46
+ [Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.3...dev
47
+ [0.3]: https://github.com/sepandhaghighi/v2kit/compare/v0.2...v0.3
48
+ [0.2]: https://github.com/sepandhaghighi/v2kit/compare/v0.1...v0.2
49
+ [0.1]: https://github.com/sepandhaghighi/v2kit/compare/bb5a2cb...v0.1
50
+
51
+
52
+
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: v2kit
3
- Version: 0.1
3
+ Version: 0.3
4
4
  Summary: V2Kit: A Lightweight Toolkit for V2Ray Config Manipulation
5
5
  Home-page: https://github.com/sepandhaghighi/v2kit
6
- Download-URL: https://github.com/sepandhaghighi/v2kit/tarball/v0.1
6
+ Download-URL: https://github.com/sepandhaghighi/v2kit/tarball/v0.3
7
7
  Author: Sepand Haghighi
8
8
  Author-email: me@sepand.tech
9
9
  License: MIT
@@ -44,11 +44,13 @@ Dynamic: summary
44
44
 
45
45
 
46
46
  <div align="center">
47
+ <img src="https://github.com/sepandhaghighi/v2kit/raw/main/otherfiles/logo.png" width="350">
47
48
  <h1>V2Kit: A Lightweight Toolkit for V2Ray Config Manipulation</h1>
48
49
  <br/>
49
50
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/built%20with-Python3-green.svg" alt="built with Python3"></a>
50
51
  <a href="https://github.com/sepandhaghighi/v2kit"><img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/sepandhaghighi/v2kit"></a>
51
52
  <a href="https://badge.fury.io/py/v2kit"><img src="https://badge.fury.io/py/v2kit.svg" alt="PyPI version"></a>
53
+ <a href="https://codecov.io/gh/sepandhaghighi/v2kit"><img src="https://codecov.io/gh/sepandhaghighi/v2kit/graph/badge.svg?token=ytuuYF0NmT"></a>
52
54
  </div>
53
55
 
54
56
  ## Overview
@@ -83,38 +85,80 @@ V2Kit is a lightweight and extensible Python toolkit for working with V2Ray prox
83
85
  </tr>
84
86
  </table>
85
87
 
88
+ <table>
89
+ <tr>
90
+ <td align="center">Code Quality</td>
91
+ <td align="center"><a href="https://app.codacy.com/gh/sepandhaghighi/v2kit/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/c0b30b55e04740b2894fe1aa4eef6589"></a></td>
92
+ <td align="center"><a href="https://www.codefactor.io/repository/github/sepandhaghighi/v2kit"><img src="https://www.codefactor.io/repository/github/sepandhaghighi/v2kit/badge" alt="CodeFactor"></a></td>
93
+ </tr>
94
+ </table>
95
+
86
96
  ## Installation
87
97
 
88
98
  ### Source Code
89
- - Download [Version 0.1](https://github.com/sepandhaghighi/v2kit/archive/v0.1.zip) or [Latest Source](https://github.com/sepandhaghighi/v2kit/archive/dev.zip)
99
+ - Download [Version 0.3](https://github.com/sepandhaghighi/v2kit/archive/v0.3.zip) or [Latest Source](https://github.com/sepandhaghighi/v2kit/archive/dev.zip)
90
100
  - `pip install .`
91
101
 
92
102
  ### PyPI
93
103
 
94
104
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
95
- - `pip install v2kit==0.1`
105
+ - `pip install v2kit==0.3`
106
+
107
+ ## Supported Protocols
108
+
109
+ V2Kit currently supports the following protocols:
110
+
111
+ | Protocol | Detection | Parsing | Relabeling | Config Model |
112
+ | ----------- | --------- | ------- | ---------- | ------------ |
113
+ | VMESS | ✅ | ✅ | ✅ | ✅ |
114
+ | VLESS | ✅ | ✅ | ✅ | ✅ |
115
+ | Trojan | ✅ | ✅ | ✅ | ✅ |
116
+ | Shadowsocks | ✅ | ✅ | ✅ | ✅ |
117
+ | SOCKS | ✅ | ✅ | ✅ | ✅ |
96
118
 
97
119
 
98
120
  ## Usage
99
121
 
122
+ ### URI Utilities
123
+
100
124
  ```python
101
125
  from v2kit import (
102
126
  decode_subscription,
103
127
  encode_subscription,
104
128
  is_vmess,
129
+ parse,
105
130
  relabel,
106
131
  )
107
132
 
108
- config = "vmess://eyJhZGQiOiIxMjcuMC4wLjEiLCJwcyI6Im9sZCJ9"
133
+ uri = "vmess://eyJhZGQiOiIxMjcuMC4wLjEiLCJwcyI6Im9sZCJ9"
134
+
135
+ new_uri = relabel(uri, "Germany-1")
136
+
137
+ if is_vmess(new_uri):
138
+ print("VMESS URI detected")
109
139
 
110
- new_config = relabel(config, "Germany-1")
140
+ config = parse(new_uri)
111
141
 
112
- if is_vmess(new_config):
113
- print("VMESS config detected")
142
+ config.update_label("Germany-2")
114
143
 
115
- subscription = encode_subscription([new_config])
144
+ subscription = encode_subscription([config])
116
145
 
117
- configs = decode_subscription(subscription)
146
+ uris = decode_subscription(subscription)
147
+ ```
148
+
149
+ ### Configs
150
+
151
+ ```python
152
+ from v2kit import VMESSConfig
153
+
154
+ config = VMESSConfig(
155
+ uuid="550e8400-e29b-41d4-a716-446655440000",
156
+ address="example.com",
157
+ port=443,
158
+ label="Germany-1",
159
+ )
160
+
161
+ uri = config.to_uri()
118
162
  ```
119
163
 
120
164
  ## Issues & Bug Reports
@@ -166,6 +210,34 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
166
210
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
167
211
 
168
212
  ## [Unreleased]
213
+ ## [0.3] - 2026-06-16
214
+ ### Added
215
+ - Logo
216
+ - `SocksConfig` class
217
+ - `is_socks` function
218
+ ### Changed
219
+ - `README.md` updated
220
+ - Test system modified
221
+ - Dependencies structure modified
222
+ - All config models moved to `models` folder
223
+ ## [0.2] - 2026-06-04
224
+ ### Added
225
+ - `VMESSConfig` class
226
+ - `VLESSConfig` class
227
+ - `TrojanConfig` class
228
+ - `ShadowsocksConfig` class
229
+ - `V2kitError` class
230
+ - `V2kitValidationError` class
231
+ - `V2kitParseError` class
232
+ - `parse` function
233
+ ### Changed
234
+ - `README.md` updated
235
+ - Test system modified
236
+ - `is_vmess` function `config` parameter renamed to `uri`
237
+ - `is_vless` function `config` parameter renamed to `uri`
238
+ - `is_trojan` function `config` parameter renamed to `uri`
239
+ - `is_shadowsocks` function `config` parameter renamed to `uri`
240
+ - `encode_subscription` function `configs` parameter renamed to `entries`
169
241
  ## [0.1] - 2026-05-16
170
242
  ### Added
171
243
  - `is_vmess` function
@@ -176,7 +248,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
176
248
  - `encode_subscription` function
177
249
  - `decode_subscription` function
178
250
 
179
- [Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.1...dev
251
+ [Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.3...dev
252
+ [0.3]: https://github.com/sepandhaghighi/v2kit/compare/v0.2...v0.3
253
+ [0.2]: https://github.com/sepandhaghighi/v2kit/compare/v0.1...v0.2
180
254
  [0.1]: https://github.com/sepandhaghighi/v2kit/compare/bb5a2cb...v0.1
181
255
 
182
256
 
@@ -1,9 +1,11 @@
1
1
  <div align="center">
2
+ <img src="https://github.com/sepandhaghighi/v2kit/raw/main/otherfiles/logo.png" width="350">
2
3
  <h1>V2Kit: A Lightweight Toolkit for V2Ray Config Manipulation</h1>
3
4
  <br/>
4
5
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/built%20with-Python3-green.svg" alt="built with Python3"></a>
5
6
  <a href="https://github.com/sepandhaghighi/v2kit"><img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/sepandhaghighi/v2kit"></a>
6
7
  <a href="https://badge.fury.io/py/v2kit"><img src="https://badge.fury.io/py/v2kit.svg" alt="PyPI version"></a>
8
+ <a href="https://codecov.io/gh/sepandhaghighi/v2kit"><img src="https://codecov.io/gh/sepandhaghighi/v2kit/graph/badge.svg?token=ytuuYF0NmT"></a>
7
9
  </div>
8
10
 
9
11
  ## Overview
@@ -38,38 +40,80 @@ V2Kit is a lightweight and extensible Python toolkit for working with V2Ray prox
38
40
  </tr>
39
41
  </table>
40
42
 
43
+ <table>
44
+ <tr>
45
+ <td align="center">Code Quality</td>
46
+ <td align="center"><a href="https://app.codacy.com/gh/sepandhaghighi/v2kit/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/c0b30b55e04740b2894fe1aa4eef6589"></a></td>
47
+ <td align="center"><a href="https://www.codefactor.io/repository/github/sepandhaghighi/v2kit"><img src="https://www.codefactor.io/repository/github/sepandhaghighi/v2kit/badge" alt="CodeFactor"></a></td>
48
+ </tr>
49
+ </table>
50
+
41
51
  ## Installation
42
52
 
43
53
  ### Source Code
44
- - Download [Version 0.1](https://github.com/sepandhaghighi/v2kit/archive/v0.1.zip) or [Latest Source](https://github.com/sepandhaghighi/v2kit/archive/dev.zip)
54
+ - Download [Version 0.3](https://github.com/sepandhaghighi/v2kit/archive/v0.3.zip) or [Latest Source](https://github.com/sepandhaghighi/v2kit/archive/dev.zip)
45
55
  - `pip install .`
46
56
 
47
57
  ### PyPI
48
58
 
49
59
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
50
- - `pip install v2kit==0.1`
60
+ - `pip install v2kit==0.3`
61
+
62
+ ## Supported Protocols
63
+
64
+ V2Kit currently supports the following protocols:
65
+
66
+ | Protocol | Detection | Parsing | Relabeling | Config Model |
67
+ | ----------- | --------- | ------- | ---------- | ------------ |
68
+ | VMESS | ✅ | ✅ | ✅ | ✅ |
69
+ | VLESS | ✅ | ✅ | ✅ | ✅ |
70
+ | Trojan | ✅ | ✅ | ✅ | ✅ |
71
+ | Shadowsocks | ✅ | ✅ | ✅ | ✅ |
72
+ | SOCKS | ✅ | ✅ | ✅ | ✅ |
51
73
 
52
74
 
53
75
  ## Usage
54
76
 
77
+ ### URI Utilities
78
+
55
79
  ```python
56
80
  from v2kit import (
57
81
  decode_subscription,
58
82
  encode_subscription,
59
83
  is_vmess,
84
+ parse,
60
85
  relabel,
61
86
  )
62
87
 
63
- config = "vmess://eyJhZGQiOiIxMjcuMC4wLjEiLCJwcyI6Im9sZCJ9"
88
+ uri = "vmess://eyJhZGQiOiIxMjcuMC4wLjEiLCJwcyI6Im9sZCJ9"
89
+
90
+ new_uri = relabel(uri, "Germany-1")
64
91
 
65
- new_config = relabel(config, "Germany-1")
92
+ if is_vmess(new_uri):
93
+ print("VMESS URI detected")
66
94
 
67
- if is_vmess(new_config):
68
- print("VMESS config detected")
95
+ config = parse(new_uri)
69
96
 
70
- subscription = encode_subscription([new_config])
97
+ config.update_label("Germany-2")
98
+
99
+ subscription = encode_subscription([config])
100
+
101
+ uris = decode_subscription(subscription)
102
+ ```
103
+
104
+ ### Configs
105
+
106
+ ```python
107
+ from v2kit import VMESSConfig
108
+
109
+ config = VMESSConfig(
110
+ uuid="550e8400-e29b-41d4-a716-446655440000",
111
+ address="example.com",
112
+ port=443,
113
+ label="Germany-1",
114
+ )
71
115
 
72
- configs = decode_subscription(subscription)
116
+ uri = config.to_uri()
73
117
  ```
74
118
 
75
119
  ## Issues & Bug Reports
@@ -4,8 +4,8 @@
4
4
 
5
5
  | Version | Supported |
6
6
  | ------------- | ------------------ |
7
- | 0.1 | :white_check_mark: |
8
- | < 0.1 | :x: |
7
+ | 0.3 | :white_check_mark: |
8
+ | < 0.3 | :x: |
9
9
 
10
10
  ## Reporting a Vulnerability
11
11
 
@@ -4,3 +4,5 @@ setuptools>=40.8.0
4
4
  vulture>=1.0
5
5
  bandit>=1.5.1
6
6
  pydocstyle>=6.3.0
7
+ build>=1.1.1
8
+ twine>=4.0.2
@@ -1,17 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Setup module."""
3
- from typing import List
4
- try:
5
- from setuptools import setup
6
- except ImportError:
7
- from distutils.core import setup
8
-
9
-
10
- def get_requires() -> List[str]:
11
- """Read requirements.txt."""
12
- requirements = open("requirements.txt", "r").read()
13
- return list(filter(lambda x: x != "", requirements.split()))
14
-
3
+ from setuptools import setup
15
4
 
16
5
  def read_description() -> str:
17
6
  """Read README.md and CHANGELOG.md."""
@@ -32,8 +21,8 @@ def read_description() -> str:
32
21
 
33
22
  setup(
34
23
  name='v2kit',
35
- packages=['v2kit'],
36
- version='0.1',
24
+ packages=['v2kit', 'v2kit.models'],
25
+ version='0.3',
37
26
  description='V2Kit: A Lightweight Toolkit for V2Ray Config Manipulation',
38
27
  long_description=read_description(),
39
28
  long_description_content_type='text/markdown',
@@ -41,11 +30,11 @@ setup(
41
30
  author='Sepand Haghighi',
42
31
  author_email='me@sepand.tech',
43
32
  url='https://github.com/sepandhaghighi/v2kit',
44
- download_url='https://github.com/sepandhaghighi/v2kit/tarball/v0.1',
45
- keywords="v2ray v2ray-config v2ray-tools vmess vless trojan shadowsocks proxy subscription network",
33
+ download_url='https://github.com/sepandhaghighi/v2kit/tarball/v0.3',
34
+ keywords='v2ray v2ray-config v2ray-tools vmess vless trojan shadowsocks proxy subscription network',
46
35
  project_urls={
47
36
  'Source': 'https://github.com/sepandhaghighi/v2kit'},
48
- install_requires=get_requires(),
37
+ install_requires=[],
49
38
  python_requires='>=3.8',
50
39
  classifiers=[
51
40
  'Development Status :: 3 - Alpha',
@@ -0,0 +1,202 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import pytest
4
+ from v2kit import VMESSConfig, VLESSConfig, TrojanConfig, ShadowsocksConfig, SocksConfig
5
+ from v2kit import relabel, encode_subscription, decode_subscription, parse
6
+ from v2kit import V2kitError, V2kitValidationError, V2kitParseError
7
+ from v2kit.validators import _validate_uri
8
+
9
+
10
+ INVALID_PROTOCOL = "http://example.com"
11
+
12
+ INVALID_VMESS = "vmess://invalid-base64"
13
+
14
+ VALID_VLESS = (
15
+ "vless://1c4b4bca-e3ff-4ca8-a062-6f399ad3cf45@example.com:443"
16
+ "?security=tls#test"
17
+ )
18
+
19
+ VALID_UUID = (
20
+ "1c4b4bca-e3ff-4ca8-a062-6f399ad3cf45"
21
+ )
22
+
23
+
24
+ def test_validate_uri_non_string():
25
+ with pytest.raises(V2kitValidationError):
26
+ _validate_uri(123)
27
+
28
+
29
+ def test_validate_uri_empty():
30
+ with pytest.raises(V2kitValidationError):
31
+ _validate_uri("")
32
+
33
+
34
+ def test_validate_uri_missing_scheme():
35
+ with pytest.raises(V2kitValidationError):
36
+ _validate_uri("invalid-config")
37
+
38
+
39
+ def test_validate_uri_unsupported_protocol():
40
+ with pytest.raises(V2kitValidationError):
41
+ _validate_uri(INVALID_PROTOCOL)
42
+
43
+
44
+ def test_validate_invalid_vmess():
45
+ with pytest.raises(V2kitValidationError):
46
+ _validate_uri(INVALID_VMESS)
47
+
48
+
49
+ def test_relabel_invalid_config():
50
+ with pytest.raises(V2kitValidationError):
51
+ relabel("invalid", "label")
52
+
53
+
54
+ def test_relabel_empty_label():
55
+ with pytest.raises(V2kitValidationError):
56
+ relabel(VALID_VLESS, "")
57
+
58
+
59
+ def test_relabel_non_string_label():
60
+ with pytest.raises(V2kitValidationError):
61
+ relabel(VALID_VLESS, 123)
62
+
63
+
64
+ def test_encode_subscription_invalid_config():
65
+ configs = [
66
+ VALID_VLESS,
67
+ "invalid-config",
68
+ ]
69
+
70
+ with pytest.raises(V2kitValidationError):
71
+ encode_subscription(configs)
72
+
73
+
74
+ def test_decode_subscription_non_string():
75
+ with pytest.raises(V2kitValidationError):
76
+ decode_subscription(123)
77
+
78
+
79
+ def test_decode_subscription_invalid_data():
80
+ with pytest.raises(Exception):
81
+ decode_subscription("invalid-base64")
82
+
83
+
84
+ def test_decode_subscription_invalid_config():
85
+ invalid_subscription = (
86
+ "aW52YWxpZC1jb25maWc="
87
+ )
88
+
89
+ with pytest.raises(V2kitValidationError):
90
+ decode_subscription(invalid_subscription)
91
+
92
+
93
+ def test_exception_hierarchy():
94
+ assert issubclass(
95
+ V2kitValidationError,
96
+ V2kitError,
97
+ )
98
+
99
+ assert issubclass(
100
+ V2kitParseError,
101
+ V2kitValidationError,
102
+ )
103
+
104
+
105
+ def test_parse_invalid_uri():
106
+ with pytest.raises(V2kitParseError):
107
+ parse("invalid")
108
+
109
+
110
+ def test_parse_unsupported_protocol():
111
+ with pytest.raises(V2kitParseError):
112
+ parse("http://example.com")
113
+
114
+
115
+ def test_vless_invalid_uuid():
116
+ with pytest.raises(V2kitValidationError):
117
+ VLESSConfig(
118
+ uuid="invalid",
119
+ address="example.com",
120
+ port=443,
121
+ )
122
+
123
+
124
+ def test_vless_invalid_port():
125
+ with pytest.raises(V2kitValidationError):
126
+ VLESSConfig(
127
+ uuid=VALID_UUID,
128
+ address="example.com",
129
+ port=70000,
130
+ )
131
+
132
+
133
+ def test_vless_empty_address():
134
+ with pytest.raises(V2kitValidationError):
135
+ VLESSConfig(
136
+ uuid=VALID_UUID,
137
+ address="",
138
+ port=443,
139
+ )
140
+
141
+
142
+ def test_vmess_invalid_alter_id():
143
+ with pytest.raises(V2kitValidationError):
144
+ VMESSConfig(
145
+ uuid=VALID_UUID,
146
+ address="example.com",
147
+ port=443,
148
+ alter_id=-1,
149
+ )
150
+
151
+
152
+ def test_trojan_empty_password():
153
+ with pytest.raises(V2kitValidationError):
154
+ TrojanConfig(
155
+ password="",
156
+ address="example.com",
157
+ port=443,
158
+ )
159
+
160
+
161
+ def test_shadowsocks_empty_encryption():
162
+ with pytest.raises(V2kitValidationError):
163
+ ShadowsocksConfig(
164
+ encryption="",
165
+ password="secret",
166
+ address="example.com",
167
+ port=8388,
168
+ )
169
+
170
+
171
+ def test_socks_invalid_port():
172
+ with pytest.raises(V2kitValidationError):
173
+ SocksConfig(
174
+ address="example.com",
175
+ port=70000,
176
+ )
177
+
178
+
179
+ def test_socks_empty_address():
180
+ with pytest.raises(V2kitValidationError):
181
+ SocksConfig(
182
+ address="",
183
+ port=1080,
184
+ )
185
+
186
+
187
+ def test_socks_invalid_username():
188
+ with pytest.raises(V2kitValidationError):
189
+ SocksConfig(
190
+ address="example.com",
191
+ port=1080,
192
+ username="",
193
+ )
194
+
195
+
196
+ def test_socks_invalid_password():
197
+ with pytest.raises(V2kitValidationError):
198
+ SocksConfig(
199
+ address="example.com",
200
+ port=1080,
201
+ password="",
202
+ )