From 5ae962496826bed58b80336e91dda3c19d2db12d Mon Sep 17 00:00:00 2001 From: Tristan Lee Date: Mon, 4 Sep 2023 13:26:38 -0500 Subject: [PATCH] added tests, changed __main__ to cli --- pytest.ini | 15 +++++++++ setup.py | 3 +- tests/__init__.py | 0 tests/auth.py | 24 ++++++++++++++ tests/base.py | 15 +++++++++ tests/cli.py | 31 +++++++++++++++++++ tests/conftest.py | 11 +++++++ tiktok_hashtag_analysis/__init__.py | 2 ++ tiktok_hashtag_analysis/auth.py | 1 - tiktok_hashtag_analysis/base.py | 2 +- .../{__main__.py => cli.py} | 0 11 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 pytest.ini create mode 100644 tests/__init__.py create mode 100644 tests/auth.py create mode 100644 tests/base.py create mode 100644 tests/cli.py create mode 100644 tests/conftest.py rename tiktok_hashtag_analysis/{__main__.py => cli.py} (100%) diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..4004079 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,15 @@ +[pytest] +minversion = + 7.0.0 +testpaths = + tests/ +python_files = + *.py +addopts = + -vvv + --cov='tiktok_hashtag_analysis' + --cov-report html:reports/coverage + --html='reports/tests.html' + --self-contained-html +filterwarnings = + ignore:Glyph (.*) missing from current font \ No newline at end of file diff --git a/setup.py b/setup.py index bd6119e..f5d5377 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ setup( url="https://github.com/bellingcat/tiktok-hashtag-analysis", license="MIT License", install_requires=["seaborn", "matplotlib", "TikTokApi", "requests", "yt-dlp"], + extras_require={"test": ["pytest", "pytest-cov", "pytest-html", "pytest-metadata"]}, classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Information Technology", @@ -25,7 +26,7 @@ setup( ], entry_points={ "console_scripts": [ - "tiktok-hashtag-analysis=tiktok_hashtag_analysis.__main__:main", + "tiktok-hashtag-analysis=tiktok_hashtag_analysis.cli:main", ] }, ) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/auth.py b/tests/auth.py new file mode 100644 index 0000000..6d0c078 --- /dev/null +++ b/tests/auth.py @@ -0,0 +1,24 @@ +import pytest + +from tiktok_hashtag_analysis.auth import Authorization + +MS_TOKEN = "thisisafakemstokenfortiktok" + + +def test_auth_input(tmp_path, monkeypatch): + config_file = tmp_path / ".tiktok" + monkeypatch.setattr("builtins.input", lambda _: MS_TOKEN) + auth = Authorization(config_file=config_file) + auth.get_token() + + assert auth.ms_token == MS_TOKEN + + +def test_auth(tmp_path): + config_file = tmp_path / ".tiktok" + auth = Authorization(config_file=config_file) + + auth.dump_token(ms_token=MS_TOKEN) + auth.get_token() + + assert auth.ms_token == MS_TOKEN diff --git a/tests/base.py b/tests/base.py new file mode 100644 index 0000000..c0d2a07 --- /dev/null +++ b/tests/base.py @@ -0,0 +1,15 @@ +from tiktok_hashtag_analysis.base import TikTokDownloader, load_hashtags_from_file + + +def test_scrape(tmp_path, hashtags): + downloader = TikTokDownloader(hashtags=hashtags[:1], data_dir=tmp_path) + downloader.run(download=True, plot=True, table=True, number=20) + + +def test_load_hashtags_from_file(tmp_path, hashtags): + file = tmp_path / "hashtags.txt" + with open(file, "w", encoding="utf-8") as f: + f.write("\n".join(hashtags)) + + loaded_hashtags = load_hashtags_from_file(file=file) + assert loaded_hashtags == hashtags diff --git a/tests/cli.py b/tests/cli.py new file mode 100644 index 0000000..dd58f5e --- /dev/null +++ b/tests/cli.py @@ -0,0 +1,31 @@ +import pytest + +from tiktok_hashtag_analysis.cli import create_parser + +ARGUMENTS = [ + ("file", "hashtags.txt", "--file"), + ("download", True, "--download"), + ("download", True, "-d"), + ("number", 20, "--number"), + ("plot", True, "--plot"), + ("plot", True, "-p"), + ("table", True, "--table"), + ("table", True, "-t"), + ("output_dir", "/tmp/tiktok_download", "--output-dir"), + ("config", "~/.tiktok", "--config"), + ("log", "../logfile.log", "--log"), +] + + +@pytest.mark.parametrize("attribute,value,flag", ARGUMENTS) +def test_parser(hashtags, attribute, value, flag): + argument_list = [*hashtags, flag] + + if not isinstance(value, bool): + argument_list.append(str(value)) + + parser = create_parser() + args = vars(parser.parse_args(argument_list)) + + assert args.get(attribute) == value + assert args.get("hashtags") == hashtags diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..b5c096d --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,11 @@ +import os +import tempfile + +import pytest + +TEST_HASHTAGS = ["embraceeuropa", "francisparkeryockey"] + + +@pytest.fixture(scope="package") +def hashtags(): + return TEST_HASHTAGS diff --git a/tiktok_hashtag_analysis/__init__.py b/tiktok_hashtag_analysis/__init__.py index 8c0d5d5..7a97c27 100644 --- a/tiktok_hashtag_analysis/__init__.py +++ b/tiktok_hashtag_analysis/__init__.py @@ -1 +1,3 @@ __version__ = "2.0.0" + +from .base import TikTokDownloader diff --git a/tiktok_hashtag_analysis/auth.py b/tiktok_hashtag_analysis/auth.py index 5d5ac16..25c2222 100644 --- a/tiktok_hashtag_analysis/auth.py +++ b/tiktok_hashtag_analysis/auth.py @@ -15,7 +15,6 @@ class Authorization: self.config_file = Path.home() / ".tiktok" self.section = "TikTok" - self.get_token() def get_token(self) -> str: """Load the "msToken" cookie taken from TikTok, which the scraper requires.""" diff --git a/tiktok_hashtag_analysis/base.py b/tiktok_hashtag_analysis/base.py index 77623a3..e059dbb 100644 --- a/tiktok_hashtag_analysis/base.py +++ b/tiktok_hashtag_analysis/base.py @@ -109,7 +109,7 @@ class TikTokDownloader: os.makedirs(self.data_dir, exist_ok=True) self.auth = Authorization(config_file=config_file) - self.ms_token = self.auth.ms_token + self.ms_token = self.auth.get_token() def get_hashtag_posts(self, hashtag: str): """Fetch data about posts that used a specified hashtag and merge with diff --git a/tiktok_hashtag_analysis/__main__.py b/tiktok_hashtag_analysis/cli.py similarity index 100% rename from tiktok_hashtag_analysis/__main__.py rename to tiktok_hashtag_analysis/cli.py