diff --git a/Makefile b/Makefile index 7825fe4..96c230f 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ lock: ## Update poetry.lock poetry lock run: ## Run project - poetry run katran-master + poetry run check-filter build: clean ## Build package poetry build diff --git a/check_filter/__init__.py b/check_filter/__init__.py index a2017f9..6d0eae7 100644 --- a/check_filter/__init__.py +++ b/check_filter/__init__.py @@ -5,3 +5,5 @@ __version__ = "2.0.3" __author__ = "Arash Hatami " __epilog__ = "Made with :heart: in [green]Iran[/green]" + +from .check import DomainChecker diff --git a/check_filter/check.py b/check_filter/check.py index 3788d48..d2eab85 100644 --- a/check_filter/check.py +++ b/check_filter/check.py @@ -1,28 +1,39 @@ """It's the checker module for filtering status""" import os -import dns.resolver +import dns.asyncresolver -blocked_ips = {'10.10.34.34', '10.10.34.35', '10.10.34.36'} -resolver = dns.resolver.Resolver() -resolver.nameservers = [ - '178.22.122.100' if 'CI' in os.environ else '8.8.8.8' -] -headers = ['Address', 'Status'] +class DomainChecker: + """ + Checks if the domain is blocked or not + """ + headers = ['Address', 'Status'] -def check(domain: str) -> bool: - """Check if domain is blocked + def __init__(self, blocked_ips=None): + self.blocked_ips = blocked_ips or { + '10.10.34.34', + '10.10.34.35', + '10.10.34.36', + } - Args: - domain (str): The domain's name + self.resolver = dns.asyncresolver.Resolver(configure=False) + self.resolver.nameservers = [ + '178.22.122.100' if 'CI' in os.environ else '8.8.8.8' + ] - Returns: - bool: Blocking status - """ - try: - answer = resolver.resolve(domain) - ip_list = [data.address for data in answer] - except dns.resolver.NXDOMAIN: - ip_list = [] + async def acheck(self, domain: str) -> tuple[str, bool]: + """Check if domain is blocked + + Args: + domain (str): The domain's name + + Returns: + tuple: (Domain's name, Blocking status) + """ + try: + answer = await self.resolver.resolve(domain) + ip_list = [data.address for data in answer] + except dns.resolver.NXDOMAIN: + ip_list = [] - return not any(ip in blocked_ips for ip in ip_list) + return domain, not any(ip in self.blocked_ips for ip in ip_list) diff --git a/check_filter/cli.py b/check_filter/cli.py index 381e207..9627374 100644 --- a/check_filter/cli.py +++ b/check_filter/cli.py @@ -1,4 +1,5 @@ """This module provides the CheckFilter CLI.""" +import asyncio from typing import Optional import typer @@ -9,7 +10,6 @@ __version__, __description__, __epilog__, - check, utils ) @@ -34,13 +34,12 @@ def domain(domain: str) -> None: Args: domain (str): Domain's name """ - if utils.validate_domain(domain): - p(f"[yellow]Checking [italic]{domain}[/italic] ...[/yellow]") - result = check.check(domain=domain) - p(utils.print_result(domain=domain, result=result)) - return + if not utils.validate_domain(domain): + p(f"[red]The `{domain}` is not a valid domain name![/red]") + raise typer.Exit() - p(f"[red]The `{domain}` is not a valid domain name![/red]") + p(f"[yellow]Checking [italic]{domain}[/italic] ...[/yellow]") + asyncio.run(utils.print_result([domain])) @app.command(epilog=__epilog__) @@ -51,17 +50,15 @@ def domains(domains: str) -> None: Args: domains (str): A comma separated list of domains """ - result = [] p("[yellow]Checking domains ...[/yellow]") + domains = domains.split(",") + domain_validity_checks = [ + utils.validate_domain(domain) for domain in domains + ] + if not all(domain_validity_checks): + raise typer.Exit() - for domain in domains.split(","): - if utils.validate_domain(domain): - status = check.check(domain=domain) - result.append([domain, status]) - else: - p(f"[red]The `{domain}` is not a valid domain name![/red]") - - utils.print_table(result) + asyncio.run(utils.print_result(domains)) @app.command(epilog=__epilog__) @@ -74,28 +71,31 @@ def file(path: str): """ p("[yellow]Checking domains ...[/yellow]") with open(file=path, encoding="utf-8", mode='r') as file: - sites = [site.strip() for site in file] - result = [] + domains = [domain.strip() for domain in file] + + domain_validity_checks = [ + utils.validate_domain(domain) for domain in domains + ] + if not all(domain_validity_checks): + raise typer.Exit() - for domain in sites: - if utils.validate_domain(domain): - status = check.check(domain=domain) - result.append([domain, status]) - else: - p(f"[red]The `{domain}` is not a valid domain name![/red]") - utils.print_table(result) + asyncio.run(utils.print_result(domains)) @app.callback() def main( - version: Optional[bool] = typer.Option( # pylint: disable=unused-argument - None, - "--version", - "-v", - help="Show the application's version.", - callback=_version_callback, - is_eager=True, - ) + version: Optional[bool] = typer.Option( # pylint: disable=unused-argument + None, + "--version", + "-v", + help="Show the application's version.", + callback=_version_callback, + is_eager=True, + ) ) -> None: """It's the version printer for CLI""" return + + +if __name__ == "__main__": + app() diff --git a/check_filter/utils.py b/check_filter/utils.py index bb18da5..29cd04c 100644 --- a/check_filter/utils.py +++ b/check_filter/utils.py @@ -1,10 +1,13 @@ """Utils module""" +import asyncio import validators +from rich import print as p from rich.console import Console +from rich.live import Live from rich.table import Table -console = Console() +from check_filter import DomainChecker def validate_domain(domain: str) -> bool: @@ -13,30 +16,17 @@ def validate_domain(domain: str) -> bool: Args: domain (str): Domain's name - Returns: - bool: Result of validation + Returns: is domain valid """ - return validators.domain(domain) + is_valid = validators.domain(domain) + if not is_valid: + p(f"[red]The `{domain}` is not a valid domain name![/red]") + return is_valid -def print_result(domain: str, result: bool) -> str: - """Print a pretty result for CLI - - Args: - domain (str): Domain's name - result (bool): Blocking result - - Returns: - str: Printable result - """ - if result: - return f"\nThe `[italic]{domain}[/italic]` is [green]free[/green] in Iran :smiley:" - return f"\nThe `[italic]{domain}[/italic]` is [red]blocked[/red] in Iran :x:" - - -def print_table(domains: list) -> None: - """Print a pretty table for CLI +async def print_result(domains: list) -> None: + """Print a pretty result for CLI Args: domains (list): List of [domain, status] of blocking result @@ -45,9 +35,20 @@ def print_table(domains: list) -> None: table.add_column("Domain", justify="left", no_wrap=True) table.add_column("Status", justify="left", no_wrap=True) - for domain in domains: - table.add_row( - f"[red]{domain[0]}[/red]" if not domain[1] else domain[0], - "[green]Free[/green]" if domain[1] else "[red]Blocked[/red] :x:") + domain_checker = DomainChecker() + + tasks = set() + + with Live(table, auto_refresh=False) as live_table: + for d in domains: + tasks.add(asyncio.create_task( + domain_checker.acheck(d), + name=f"domain-check-{d}", + )) - console.print("\n", table) + for future in asyncio.as_completed(tasks): + domain, status = await future + table.add_row( + f"[red]{domain}[/red]" if not status else domain, + "[green]Free[/green]" if status else "[red]Blocked[/red] :x:") + live_table.refresh() diff --git a/poetry.lock b/poetry.lock index 6330c46..9cbeb75 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "astroid" -version = "3.0.1" +version = "3.0.2" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.8.0" files = [ - {file = "astroid-3.0.1-py3-none-any.whl", hash = "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca"}, - {file = "astroid-3.0.1.tar.gz", hash = "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e"}, + {file = "astroid-3.0.2-py3-none-any.whl", hash = "sha256:d6e62862355f60e716164082d6b4b041d38e2a8cf1c7cd953ded5108bac8ff5c"}, + {file = "astroid-3.0.2.tar.gz", hash = "sha256:4a61cf0a59097c7bb52689b0fd63717cd2a8a14dc9f1eee97b82d814881c8c91"}, ] [package.dependencies] @@ -16,13 +16,13 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "click" -version = "8.1.6" +version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, - {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] @@ -74,13 +74,13 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] [[package]] name = "exceptiongroup" -version = "1.1.2" +version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, - {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] @@ -99,20 +99,17 @@ files = [ [[package]] name = "isort" -version = "5.12.0" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] name = "markdown-it-py" @@ -162,39 +159,39 @@ files = [ [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] name = "platformdirs" -version = "3.9.1" +version = "4.1.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.9.1-py3-none-any.whl", hash = "sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"}, - {file = "platformdirs-3.9.1.tar.gz", hash = "sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"}, + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] @@ -203,17 +200,18 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pygments" -version = "2.15.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" @@ -267,15 +265,33 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-asyncio" +version = "0.23.3" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-asyncio-0.23.3.tar.gz", hash = "sha256:af313ce900a62fbe2b1aed18e37ad757f1ef9940c6b6a88e2954de38d6b1fb9f"}, + {file = "pytest_asyncio-0.23.3-py3-none-any.whl", hash = "sha256:37a9d912e8338ee7b4a3e917381d1c95bfc8682048cb0fbc35baba316ec1faba"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + [[package]] name = "rich" -version = "13.4.2" +version = "13.7.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.4.2-py3-none-any.whl", hash = "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec"}, - {file = "rich-13.4.2.tar.gz", hash = "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898"}, + {file = "rich-13.7.0-py3-none-any.whl", hash = "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235"}, + {file = "rich-13.7.0.tar.gz", hash = "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa"}, ] [package.dependencies] @@ -288,13 +304,13 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "shellingham" -version = "1.5.0.post1" +version = "1.5.4" description = "Tool to Detect Surrounding Shell" optional = false python-versions = ">=3.7" files = [ - {file = "shellingham-1.5.0.post1-py2.py3-none-any.whl", hash = "sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744"}, - {file = "shellingham-1.5.0.post1.tar.gz", hash = "sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28"}, + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, ] [[package]] @@ -310,13 +326,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.11.8" +version = "0.12.3" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, - {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, + {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"}, + {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"}, ] [[package]] @@ -345,13 +361,13 @@ test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6. [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] [[package]] @@ -379,4 +395,4 @@ tooling-extras = ["pyaml (>=23.7.0)", "pypandoc-binary (>=1.11)", "pytest (>=7.4 [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "ee1449e976e01455d97c463b107379ef82e86e1501d76784af31d16d2ff68965" +content-hash = "be435e6ece03e1a3387b47592de45806e55c2654e5e76131db02bd35053c9001" diff --git a/pyproject.toml b/pyproject.toml index d14ed21..848449e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,10 +29,12 @@ validators = ">=0.21,<0.23" [tool.poetry.group.test.dependencies] pytest = "^7" +pytest-asyncio = "^0.23.3" [tool.poetry.group.dev.dependencies] pylint = "^3.0.0" pytest = "^7" +pytest-asyncio = "^0.23.3" [tool.poetry.scripts] check-filter = "check_filter.cli:app" @@ -40,6 +42,10 @@ check-filter = "check_filter.cli:app" [tool.poetry.urls] "Bug Tracker" = "https://github.com/hatamiarash7/CheckFiltering/issues" +[tool.pytest.ini_options] +asyncio_mode="auto" +testpaths = ["tests"] + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/tests/test_check.py b/tests/test_check.py index b2115c6..72d804e 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -1,11 +1,20 @@ import pytest import dns -from check_filter import check +from check_filter import DomainChecker -def test_check(): - assert check.check("google.com") is True - assert check.check("instagram.com") is False +@pytest.mark.asyncio +async def test_check(): + domain_checker = DomainChecker() + + google_results = await domain_checker.acheck("google.com") + instagram_results = await domain_checker.acheck("instagram.com") + + assert google_results[0] == "google.com" + assert google_results[1] is True + + assert instagram_results[0] == "instagram.com" + assert instagram_results[1] is False with pytest.raises(dns.resolver.NoAnswer): - check.check("") + await domain_checker.acheck("") diff --git a/tests/test_cli.py b/tests/test_cli.py index fd6debd..b05b3b4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -17,11 +17,11 @@ def test_cli_callbacks(): def test_cli_commands(tmp_path): result = runner.invoke(cli.app, ["domain", "example.com"]) assert result.exit_code == 0 - assert "The `example.com` is free in Iran 😃" in result.stdout + assert "│ example.com │ Free │" in result.stdout result = runner.invoke(cli.app, ["domain", "twitter.com"]) assert result.exit_code == 0 - assert "The `twitter.com` is blocked in Iran ❌" in result.stdout + assert "│ twitter.com │ Blocked ❌ │" in result.stdout result = runner.invoke(cli.app, ["domains", "example.com,twitter.com"]) assert result.exit_code == 0 diff --git a/tests/test_utils.py b/tests/test_utils.py index a8b1294..c0f2335 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,23 +1,18 @@ import pytest -from validators.utils import ValidationFailure +from validators.utils import ValidationError from check_filter import utils -@pytest.mark.xfail(raises=ValidationFailure) +@pytest.mark.xfail(raises=ValidationError) def test_validate_domain(): assert utils.validate_domain("domain.com") is True utils.validate_domain("domain") is False utils.validate_domain("") is False -def test_print_result(): - assert utils.print_result( - "domain.com", True) == "\nThe `[italic]domain.com[/italic]` is [green]free[/green] in Iran :smiley:" - assert utils.print_result( - "domain.com", False) == "\nThe `[italic]domain.com[/italic]` is [red]blocked[/red] in Iran :x:" - - -def test_print_table(capsys): - assert utils.print_table([["example.com", True]]) is None +@pytest.mark.asyncio +async def test_print_result(capsys): + res = await utils.print_result(["example.com"]) + assert res is None captured = capsys.readouterr() assert captured.out.__contains__("example.com │ Free")