File: conftest.py

package info (click to toggle)
toot 0.51.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,108 kB
  • sloc: python: 9,284; makefile: 41
file content (175 lines) | stat: -rw-r--r-- 4,508 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
"""
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:

```
export TOOT_TEST_BASE_URL="localhost:3000"
```
"""

import json
import os
import pytest
import re
import typing as t
import uuid

from click.testing import CliRunner, Result
from pathlib import Path
from toot import api, App, User
from toot.cli import Context, TootObj


def pytest_configure(config):
    import toot.settings
    toot.settings.DISABLE_SETTINGS = True


# Type alias for run commands
Run = t.Callable[..., Result]

# Mastodon database name, used to confirm user registration without having to click the link
TOOT_TEST_BASE_URL = os.getenv("TOOT_TEST_BASE_URL")

# 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"


def create_app(base_url):
    instance = api.get_instance(base_url).json()
    response = api.create_app(base_url)
    return App(instance["uri"], base_url, response["client_id"], response["client_secret"])


def register_account(app: App):
    username = str(uuid.uuid4())[-10:]
    email = f"{username}@example.com"

    response = api.register_account(app, username, email, PASSWORD, "en")
    return User(app.instance, username, response["access_token"])


# ------------------------------------------------------------------------------
# Fixtures
# ------------------------------------------------------------------------------


# Host name of a test instance to run integration tests against
# DO NOT USE PUBLIC INSTANCES!!!
@pytest.fixture(scope="session")
def base_url():
    if not TOOT_TEST_BASE_URL:
        pytest.skip("Skipping integration tests, TOOT_TEST_BASE_URL not set")

    return TOOT_TEST_BASE_URL


@pytest.fixture(scope="session")
def app(base_url):
    return create_app(base_url)


@pytest.fixture()
def user(app):
    return register_account(app)


@pytest.fixture()
def friend(app):
    return register_account(app)


@pytest.fixture()
def user_id(app, user):
    return api.find_account(app, user, user.username)["id"]


@pytest.fixture()
def friend_id(app, user, friend):
    return api.find_account(app, user, friend.username)["id"]


@pytest.fixture(scope="session", autouse=True)
def testing_env():
    os.environ["TOOT_TESTING"] = "true"


@pytest.fixture(scope="session")
def runner():
    return CliRunner()


@pytest.fixture
def run(app, user, runner):
    def _run(command, *params, input=None) -> Result:
        obj = TootObj(test_ctx=Context(app, user))
        return runner.invoke(command, params, obj=obj, input=input)
    return _run


@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)
    return _run_as


@pytest.fixture
def run_json(app, user, runner):
    def _run_json(command, *params):
        obj = TootObj(test_ctx=Context(app, user))
        result = runner.invoke(command, params, obj=obj)
        assert_ok(result)
        return json.loads(result.stdout)
    return _run_json


@pytest.fixture
def run_anon(runner):
    def _run(command, *params) -> Result:
        obj = TootObj(test_ctx=Context(None, None))
        return runner.invoke(command, params, obj=obj)
    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


def assert_ok(result: Result):
    if result.exit_code != 0:
        raise AssertionError(
            f"Command failed with exit code {result.exit_code}\n"
            f"stderr: {result.stderr}\n"
            f"exception: {result.exception}"
        )


def assert_error(result: Result, error: str):
    assert result.exit_code != 0
    assert error in strip_ansi(result.stderr)


def strip_ansi(string: str):
    return re.sub(r"\x1b\[[0-9;]*[A-Za-z]", "", string)