toot/tests/integration/conftest.py

163 wiersze
4.2 KiB
Python
Czysty Zwykły widok Historia

2023-03-30 08:56:03 +00:00
"""
This module contains integration tests meant to run against a test Mastodon instance.
You can set up a test instance locally by following this guide:
https://docs.joinmastodon.org/dev/setup/
To enable integration tests, export the following environment variables to match
your test server and database:
```
2023-06-28 12:42:44 +00:00
export TOOT_TEST_BASE_URL="localhost:3000"
2023-03-30 08:56:03 +00:00
```
"""
2023-11-21 17:16:23 +00:00
import json
2023-03-30 08:56:03 +00:00
import os
import pytest
import re
import typing as t
2023-03-30 08:56:03 +00:00
import uuid
2023-11-26 17:00:57 +00:00
from click.testing import CliRunner, Result
2023-03-30 08:56:03 +00:00
from pathlib import Path
from toot import api, App, User
from toot.cli import Context, TootObj
2023-03-30 08:56:03 +00:00
2023-06-28 12:55:28 +00:00
def pytest_configure(config):
import toot.settings
toot.settings.DISABLE_SETTINGS = True
# Type alias for run commands
Run = t.Callable[..., Result]
2023-03-30 08:56:03 +00:00
# Mastodon database name, used to confirm user registration without having to click the link
2023-11-30 19:08:59 +00:00
TOOT_TEST_BASE_URL = os.getenv("TOOT_TEST_BASE_URL")
2023-03-30 08:56:03 +00:00
# Toot logo used for testing image upload
TRUMPET = str(Path(__file__).parent.parent.parent / "trumpet.png")
ASSETS_DIR = str(Path(__file__).parent.parent / "assets")
PASSWORD = "83dU29170rjKilKQQwuWhJv3PKnSW59bWx0perjP6i7Nu4rkeh4mRfYuvVLYM3fM"
2023-03-30 08:56:03 +00:00
2023-04-07 09:07:38 +00:00
def create_app(base_url):
instance = api.get_instance(base_url).json()
2023-04-07 09:07:38 +00:00
response = api.create_app(base_url)
return App(instance["uri"], base_url, response["client_id"], response["client_secret"])
2023-03-30 08:56:03 +00:00
def register_account(app: App):
username = str(uuid.uuid4())[-10:]
email = f"{username}@example.com"
response = api.register_account(app, username, email, PASSWORD, "en")
2023-03-30 08:56:03 +00:00
return User(app.instance, username, response["access_token"])
2023-04-07 09:07:38 +00:00
# ------------------------------------------------------------------------------
# Fixtures
# ------------------------------------------------------------------------------
# Host name of a test instance to run integration tests against
# DO NOT USE PUBLIC INSTANCES!!!
@pytest.fixture(scope="session")
def base_url():
2023-11-30 19:08:59 +00:00
if not TOOT_TEST_BASE_URL:
2023-04-07 09:07:38 +00:00
pytest.skip("Skipping integration tests, TOOT_TEST_BASE_URL not set")
2023-11-30 19:08:59 +00:00
return TOOT_TEST_BASE_URL
2023-04-07 09:07:38 +00:00
2023-03-30 08:56:03 +00:00
@pytest.fixture(scope="session")
2023-04-07 09:07:38 +00:00
def app(base_url):
return create_app(base_url)
2023-03-30 08:56:03 +00:00
@pytest.fixture(scope="session")
def user(app):
return register_account(app)
@pytest.fixture(scope="session")
def friend(app):
return register_account(app)
2023-11-21 17:16:23 +00:00
@pytest.fixture(scope="session")
def user_id(app, user):
return api.find_account(app, user, user.username)["id"]
@pytest.fixture(scope="session")
def friend_id(app, user, friend):
return api.find_account(app, user, friend.username)["id"]
2023-11-26 17:00:57 +00:00
@pytest.fixture(scope="session", autouse=True)
def testing_env():
os.environ["TOOT_TESTING"] = "true"
@pytest.fixture(scope="session")
def runner():
return CliRunner(mix_stderr=False)
2023-03-30 08:56:03 +00:00
@pytest.fixture
2023-11-26 17:00:57 +00:00
def run(app, user, runner):
2023-12-03 06:07:18 +00:00
def _run(command, *params, input=None) -> Result:
obj = TootObj(test_ctx=Context(app, user))
return runner.invoke(command, params, obj=obj, input=input)
2023-03-30 08:56:03 +00:00
return _run
2023-12-03 06:07:18 +00:00
@pytest.fixture
def run_as(app, runner):
def _run_as(user, command, *params, input=None) -> Result:
obj = TootObj(test_ctx=Context(app, user))
return runner.invoke(command, params, obj=obj, input=input)
2023-12-03 06:07:18 +00:00
return _run_as
2023-11-21 17:16:23 +00:00
@pytest.fixture
2023-11-28 13:05:44 +00:00
def run_json(app, user, runner):
2023-11-21 17:16:23 +00:00
def _run_json(command, *params):
obj = TootObj(test_ctx=Context(app, user))
result = runner.invoke(command, params, obj=obj)
2023-11-28 13:05:44 +00:00
assert result.exit_code == 0
return json.loads(result.stdout)
2023-11-21 17:16:23 +00:00
return _run_json
2023-03-30 08:56:03 +00:00
@pytest.fixture
2023-11-26 17:00:57 +00:00
def run_anon(runner):
def _run(command, *params) -> Result:
obj = TootObj(test_ctx=Context(None, None))
return runner.invoke(command, params, obj=obj)
2023-03-30 08:56:03 +00:00
return _run
# ------------------------------------------------------------------------------
# Utils
# ------------------------------------------------------------------------------
def posted_status_id(out):
pattern = re.compile(r"Toot posted: http://([^/]+)/([^/]+)/(.+)")
match = re.search(pattern, out)
assert match
_, _, status_id = match.groups()
return status_id
2024-04-21 08:03:10 +00:00
def assert_ok(result: Result):
if result.exit_code != 0:
raise AssertionError(f"Command failed with exit code {result.exit_code}\nStderr: {result.stderr}")