From faae3f7846051071ef2836b51c3a62a9dc635674 Mon Sep 17 00:00:00 2001 From: Dmitry Afanasyev Date: Sun, 14 Aug 2022 01:01:01 +0300 Subject: [PATCH] add tests --- .github/workflows/poetry-test.yml | 75 +++++ app/core/parse_web.py | 2 +- app/tests/__init__.py | 0 app/tests/conftest.py | 63 ++++ app/tests/dataset.py | 535 ++++++++++++++++++++++++++++++ app/tests/test_parse_web.py | 17 + poetry.lock | 40 ++- pyproject.toml | 8 +- setup.cfg | 3 +- 9 files changed, 728 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/poetry-test.yml create mode 100644 app/tests/__init__.py create mode 100644 app/tests/conftest.py create mode 100644 app/tests/dataset.py create mode 100644 app/tests/test_parse_web.py diff --git a/.github/workflows/poetry-test.yml b/.github/workflows/poetry-test.yml new file mode 100644 index 0000000..2bf23e4 --- /dev/null +++ b/.github/workflows/poetry-test.yml @@ -0,0 +1,75 @@ +name: test + +on: + push: + branches-ignore: + - test + tags-ignore: + - "*" + pull_request: + branches: + - 'release/**' + +jobs: + build: + runs-on: ubuntu-latest + steps: + #---------------------------------------------- + # check-out repo and set-up python + #---------------------------------------------- + - name: Check out repository + uses: actions/checkout@v2 + - name: Set up python + id: setup-python + uses: actions/setup-python@v2 + with: + python-version: '3.10' + #---------------------------------------------- + # ----- install & configure poetry ----- + #---------------------------------------------- + - name: Install poetry + env: # Keep in sync with `POETRY_VERSION` in `Dockerfile` + POETRY_VERSION: "1.1.13" + run: | + curl -sSL "https://install.python-poetry.org" | python - + # Adding `poetry` to `$PATH`: + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Set up cache + uses: actions/cache@v3 + with: + path: .venv + key: venv-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }} + #---------------------------------------------- + # load cached venv if cache exists + #---------------------------------------------- + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v2 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} + #---------------------------------------------- + # install dependencies if cache does not exist + #---------------------------------------------- + - name: Install dependencies + run: | + poetry config virtualenvs.in-project true + poetry install + poetry run pip install -U pip + #---------------------------------------------- + # run test suite + #---------------------------------------------- + - name: Run tests + run: | + source .venv/bin/activate + poetry run pytest -vv --exitfirst + - name: Coverage report + run: | + poetry run coverage run -m pytest + poetry run coverage report + - name: Extended checks + run: | + poetry run poetry check + poetry run pip check + poetry run safety check --full-report \ No newline at end of file diff --git a/app/core/parse_web.py b/app/core/parse_web.py index 07dc8dc..2c2c87a 100644 --- a/app/core/parse_web.py +++ b/app/core/parse_web.py @@ -44,7 +44,7 @@ def configure_firefox_driver(private_window: bool = False) -> WebDriver: return firefox_driver -def parse_site(driver: WebDriver, url: str, message: str) -> str: +async def parse_site(driver: WebDriver, url: str, message: str) -> str: driver.get(url) time.sleep(4) elements = driver.find_elements( diff --git a/app/tests/__init__.py b/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/conftest.py b/app/tests/conftest.py new file mode 100644 index 0000000..1f80bf9 --- /dev/null +++ b/app/tests/conftest.py @@ -0,0 +1,63 @@ +import asyncio +from typing import Any + +import aresponses +import pytest +from aiogram import Bot + +BOT_ID = 123456789 +TOKEN = f'{BOT_ID}:AABBCCDDEEFFaabbccddeeff-1234567890' + + +class FakeTelegram(aresponses.ResponsesMockServer): + def __init__( + self, message_data: dict[str, Any], bot: Bot = None, **kwargs: Any + ) -> None: + super().__init__(**kwargs) + self._body, self._headers = self.parse_data(message_data) + + if isinstance(bot, Bot): + Bot.set_current(bot) + + async def __aenter__(self) -> None: + await super().__aenter__() + _response = self.Response( + text=self._body, headers=self._headers, status=200, reason='OK' + ) + self.add(self.ANY, response=_response) + + async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: + if hasattr(self, 'monkeypatch'): + self.monkeypatch.undo() + await super().__aexit__(exc_type, exc_val, exc_tb) + + @staticmethod + def parse_data(message_data: dict[str, Any]) -> tuple[str, dict[str, str]]: + from aiogram.utils import json + from aiogram.utils.payload import _normalize + + _body = '{"ok":true,"result":' + json.dumps(_normalize(message_data)) + '}' + _headers = { + 'Server': 'nginx/1.12.2', + 'Date': 'Tue, 03 Apr 2018 16:59:54 GMT', + 'Content-Type': 'application/json', + 'Content-Length': str(len(_body)), + 'Connection': 'keep-alive', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Expose-Headers': 'Content-Length,Content-Type,Date,Server,Connection', + 'Strict-Transport-Security': 'max-age=31536000; includeSubdomains', + } + return _body, _headers + + +@pytest.fixture(name='bot') +async def bot_fixture() -> Bot: + """Bot fixture.""" + + bot = Bot(TOKEN) + yield bot + session = await bot.get_session() + if session and not session.closed: + await session.close() + await asyncio.sleep(0.2) diff --git a/app/tests/dataset.py b/app/tests/dataset.py new file mode 100644 index 0000000..04394c3 --- /dev/null +++ b/app/tests/dataset.py @@ -0,0 +1,535 @@ +"""" +Dict data set for Telegram message types +""" + +USER = { + "id": 12345678, + "is_bot": False, + "first_name": "FirstName", + "last_name": "LastName", + "username": "username", + "language_code": "ru", +} + +CHAT = { + "id": 12345678, + "first_name": "FirstName", + "last_name": "LastName", + "username": "username", + "type": "private", +} + +CHAT_PHOTO = { + "small_file_id": "small_file_id", + "small_file_unique_id": "small_file_unique_id", + "big_file_id": "big_file_id", + "big_file_unique_id": "big_file_unique_id", +} + + +PHOTO = { + "file_id": "AgADBAADFak0G88YZAf8OAug7bHyS9x2ZxkABHVfpJywcloRAAGAAQABAg", + "file_size": 1101, + "width": 90, + "height": 51, +} + +AUDIO = { + "duration": 236, + "mime_type": "audio/mpeg3", + "title": "The Best Song", + "performer": "The Best Singer", + "file_id": "CQADAgADbQEAAsnrIUpNoRRNsH7_hAI", + "file_size": 9507774, +} + +BOT_COMMAND = { + "command": "start", + "description": "Start bot", +} + +CHAT_MEMBER = { + "user": USER, + "status": "administrator", + "can_be_edited": False, + "can_manage_chat": True, + "can_change_info": True, + "can_delete_messages": True, + "can_invite_users": True, + "can_restrict_members": True, + "can_pin_messages": True, + "can_promote_members": False, + "can_manage_voice_chats": True, + "is_anonymous": False, +} + +CHAT_MEMBER_OWNER = { + "user": USER, + "status": "creator", + "is_anonymous": False, +} + +CONTACT = { + "phone_number": "88005553535", + "first_name": "John", + "last_name": "Smith", +} + +DICE = {"value": 6} + +DOCUMENT = { + "file_name": "test.docx", + "mime_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "file_id": "BQADAgADpgADy_JxS66XQTBRHFleAg", + "file_size": 21331, +} + +ANIMATION = { + "file_name": "a9b0e0ca537aa344338f80978f0896b7.gif.mp4", + "mime_type": "video/mp4", + "thumb": PHOTO, + "file_id": "CgADBAAD4DUAAoceZAe2WiE9y0crrAI", + "file_size": 65837, +} + +ENTITY_BOLD = { + "offset": 5, + "length": 2, + "type": "bold", +} + +ENTITY_ITALIC = { + "offset": 8, + "length": 1, + "type": "italic", +} + +ENTITY_LINK = { + "offset": 10, + "length": 6, + "type": "text_link", + "url": "http://google.com/", +} + +ENTITY_CODE = { + "offset": 17, + "length": 7, + "type": "code", +} + +ENTITY_PRE = { + "offset": 30, + "length": 4, + "type": "pre", +} + +ENTITY_MENTION = { + "offset": 47, + "length": 9, + "type": "mention", +} + +GAME = { + "title": "Karate Kido", + "description": "No trees were harmed in the making of this game :)", + "photo": [PHOTO, PHOTO, PHOTO], + "animation": ANIMATION, +} + +INVOICE = { + "title": "Working Time Machine", + "description": "Want to visit your great-great-great-grandparents? " + "Make a fortune at the races? " + "Shake hands with Hammurabi and take a stroll in the Hanging Gardens? " + "Order our Working Time Machine today!", + "start_parameter": "time-machine-example", + "currency": "USD", + "total_amount": 6250, +} + +LOCATION = { + "latitude": 50.693416, + "longitude": 30.624605, +} + +VENUE = { + "location": LOCATION, + "title": "Venue Name", + "address": "Venue Address", + "foursquare_id": "4e6f2cec483bad563d150f98", +} + +SHIPPING_ADDRESS = { + "country_code": "US", + "state": "State", + "city": "DefaultCity", + "street_line1": "Central", + "street_line2": "Middle", + "post_code": "424242", +} + +STICKER = { + "width": 512, + "height": 512, + "emoji": "🛠", + "set_name": "StickerSet", + "thumb": { + "file_id": "AAbbCCddEEffGGhh1234567890", + "file_size": 1234, + "width": 128, + "height": 128, + }, + "file_id": "AAbbCCddEEffGGhh1234567890", + "file_size": 12345, +} + +SUCCESSFUL_PAYMENT = { + "currency": "USD", + "total_amount": 6250, + "invoice_payload": "HAPPY FRIDAYS COUPON", + "telegram_payment_charge_id": "_", + "provider_payment_charge_id": "12345678901234_test", +} + +VIDEO = { + "duration": 52, + "width": 853, + "height": 480, + "mime_type": "video/quicktime", + "thumb": PHOTO, + "file_id": "BAADAgpAADdawy_JxS72kRvV3cortAg", + "file_size": 10099782, +} + +VIDEO_NOTE = { + "duration": 4, + "length": 240, + "thumb": PHOTO, + "file_id": "AbCdEfGhIjKlMnOpQrStUvWxYz", + "file_size": 186562, +} + +VOICE = { + "duration": 1, + "mime_type": "audio/ogg", + "file_id": "AwADawAgADADy_JxS2gopIVIIxlhAg", + "file_size": 4321, +} + +CALLBACK_QUERY = {} # type: ignore + +CHANNEL_POST = {} # type: ignore + +CHOSEN_INLINE_RESULT = {} # type: ignore + +EDITED_CHANNEL_POST = {} # type: ignore + +EDITED_MESSAGE = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508825372, + "edit_date": 1508825379, + "text": "hi there (edited)", +} + +FORWARDED_MESSAGE = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1522828529, + "forward_from_chat": CHAT, + "forward_from_message_id": 123, + "forward_date": 1522749037, + "text": "Forwarded text with entities from public channel ", + "entities": [ + ENTITY_BOLD, + ENTITY_CODE, + ENTITY_ITALIC, + ENTITY_LINK, + ENTITY_LINK, + ENTITY_MENTION, + ENTITY_PRE, + ], +} + +INLINE_QUERY = {} # type: ignore + +MESSAGE = { + "message_id": 11223, + "from": USER, + "chat": CHAT, + "date": 1508709711, + "text": "Hi, world!", +} + +MESSAGE_WITH_AUDIO = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508739776, + "audio": AUDIO, + "caption": "This is my favourite song", +} + +MESSAGE_WITH_AUTHOR_SIGNATURE = {} # type: ignore + +MESSAGE_WITH_CHANNEL_CHAT_CREATED = {} # type: ignore + +MESSAGE_WITH_CONTACT = { + "message_id": 56006, + "from": USER, + "chat": CHAT, + "date": 1522850298, + "contact": CONTACT, +} + +MESSAGE_WITH_DELETE_CHAT_PHOTO = {} # type: ignore + +MESSAGE_WITH_DICE = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508768012, + "dice": DICE, +} + +MESSAGE_WITH_DOCUMENT = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508768012, + "document": DOCUMENT, + "caption": "Read my document", +} + +MESSAGE_WITH_EDIT_DATE = {} # type: ignore + +MESSAGE_WITH_ENTITIES = {} # type: ignore + +MESSAGE_WITH_GAME = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508824810, + "game": GAME, +} + +MESSAGE_WITH_GROUP_CHAT_CREATED = {} # type: ignore + +MESSAGE_WITH_INVOICE = { + "message_id": 9772, + "from": USER, + "chat": CHAT, + "date": 1508761719, + "invoice": INVOICE, +} + +MESSAGE_WITH_LEFT_CHAT_MEMBER = {} # type: ignore + +MESSAGE_WITH_LOCATION = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508755473, + "location": LOCATION, +} + +MESSAGE_WITH_MIGRATE_TO_CHAT_ID = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1526943253, + "migrate_to_chat_id": -1234567890987, +} + +MESSAGE_WITH_MIGRATE_FROM_CHAT_ID = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1526943253, + "migrate_from_chat_id": -123456789, +} + +MESSAGE_WITH_NEW_CHAT_MEMBERS = {} # type: ignore + +MESSAGE_WITH_NEW_CHAT_PHOTO = {} # type: ignore + +MESSAGE_WITH_NEW_CHAT_TITLE = {} # type: ignore + +MESSAGE_WITH_PHOTO = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508825154, + "photo": [PHOTO, PHOTO, PHOTO, PHOTO], + "caption": "photo description", +} + +MESSAGE_WITH_MEDIA_GROUP = { + "message_id": 55966, + "from": USER, + "chat": CHAT, + "date": 1522843665, + "media_group_id": "12182749320567362", + "photo": [PHOTO, PHOTO, PHOTO, PHOTO], +} + +MESSAGE_WITH_PINNED_MESSAGE = {} # type: ignore + +MESSAGE_WITH_REPLY_TO_MESSAGE = {} # type: ignore + +MESSAGE_WITH_STICKER = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508771450, + "sticker": STICKER, +} + +MESSAGE_WITH_SUCCESSFUL_PAYMENT = { + "message_id": 9768, + "from": USER, + "chat": CHAT, + "date": 1508761169, + "successful_payment": SUCCESSFUL_PAYMENT, +} + +MESSAGE_WITH_SUPERGROUP_CHAT_CREATED = {} # type: ignore + +MESSAGE_WITH_VENUE = { + "message_id": 56004, + "from": USER, + "chat": CHAT, + "date": 1522849819, + "location": LOCATION, + "venue": VENUE, +} + +MESSAGE_WITH_VIDEO = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508756494, + "video": VIDEO, + "caption": "description", +} + +MESSAGE_WITH_VIDEO_NOTE = { + "message_id": 55934, + "from": USER, + "chat": CHAT, + "date": 1522835890, + "video_note": VIDEO_NOTE, +} + +MESSAGE_WITH_VOICE = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508768403, + "voice": VOICE, +} + +CHANNEL = { + "type": "channel", + "username": "best_channel_ever", + "id": -1001065170817, +} + +MESSAGE_FROM_CHANNEL = { + "message_id": 123432, + "from": None, + "chat": CHANNEL, + "date": 1508768405, + "text": "Hi, world!", +} + +PRE_CHECKOUT_QUERY = { + "id": "262181558630368727", + "from": USER, + "currency": "USD", + "total_amount": 6250, + "invoice_payload": "HAPPY FRIDAYS COUPON", +} + +REPLY_MESSAGE = { + "message_id": 12345, + "from": USER, + "chat": CHAT, + "date": 1508751866, + "reply_to_message": MESSAGE, + "text": "Reply to quoted message", +} + +SHIPPING_QUERY = { + "id": "262181558684397422", + "from": USER, + "invoice_payload": "HAPPY FRIDAYS COUPON", + "shipping_address": SHIPPING_ADDRESS, +} + +USER_PROFILE_PHOTOS = { + "total_count": 1, + "photos": [ + [PHOTO, PHOTO, PHOTO], + ], +} + +FILE = { + "file_id": "XXXYYYZZZ", + "file_size": 5254, + "file_path": "voice/file_8", +} + +INVITE_LINK = 'https://t.me/joinchat/AbCdEfjKILDADwdd123' + +UPDATE = { + "update_id": 123456789, + "message": MESSAGE, +} + +WEBHOOK_INFO = { + "url": "", + "has_custom_certificate": False, + "pending_update_count": 0, +} + +REPLY_KEYBOARD_MARKUP = { + "keyboard": [[{"text": "something here"}]], + "resize_keyboard": True, +} + +CHAT_PERMISSIONS = { + "can_send_messages": True, + "can_send_media_messages": True, + "can_send_polls": True, + "can_send_other_messages": True, + "can_add_web_page_previews": True, + "can_change_info": True, + "can_invite_users": True, + "can_pin_messages": True, +} + +CHAT_LOCATION = { + "location": LOCATION, + "address": "address", +} + +FULL_CHAT = { + **CHAT, + "photo": CHAT_PHOTO, + "bio": "bio", + "has_private_forwards": False, + "description": "description", + "invite_link": "invite_link", + "pinned_message": MESSAGE, + "permissions": CHAT_PERMISSIONS, + "slow_mode_delay": 10, + "message_auto_delete_time": 60, + "has_protected_content": True, + "sticker_set_name": "sticker_set_name", + "can_set_sticker_set": True, + "linked_chat_id": -1234567890, + "location": CHAT_LOCATION, +} diff --git a/app/tests/test_parse_web.py b/app/tests/test_parse_web.py new file mode 100644 index 0000000..0d92fd4 --- /dev/null +++ b/app/tests/test_parse_web.py @@ -0,0 +1,17 @@ +import pytest +from aiogram import Bot, types +from app.tests.conftest import FakeTelegram +from app.tests.dataset import USER + +pytestmark = [ + pytest.mark.asyncio, +] + + +async def test_parse_site(bot: Bot) -> None: + user = types.User(**USER) + + async with FakeTelegram(message_data=USER): + result = await bot.me + + assert result == user diff --git a/poetry.lock b/poetry.lock index 8c0fa55..efe37ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,6 +1,6 @@ [[package]] name = "aiogram" -version = "2.21" +version = "2.22" description = "Is a pretty simple and fully asynchronous framework for Telegram Bot API" category = "main" optional = false @@ -12,8 +12,8 @@ Babel = ">=2.9.1,<2.10.0" certifi = ">=2021.10.8" [package.extras] -fast = ["uvloop (>=0.16.0,<0.17.0)", "ujson (>=1.35)"] proxy = ["aiohttp-socks (>=0.5.3,<0.6.0)"] +fast = ["ujson (>=1.35)", "uvloop (>=0.16.0,<0.17.0)"] [[package]] name = "aiohttp" @@ -97,6 +97,18 @@ tornado = ["tornado (>=4.3)"] twisted = ["twisted"] zookeeper = ["kazoo"] +[[package]] +name = "aresponses" +version = "2.1.6" +description = "Asyncio response mocking. Similar to the responses library used for 'requests'" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +aiohttp = ">=3.1.0,<4.0.0" +pytest-asyncio = "*" + [[package]] name = "astor" version = "0.8.1" @@ -375,7 +387,7 @@ python-versions = "*" [[package]] name = "executing" -version = "0.9.1" +version = "0.10.0" description = "Get the currently executing AST node of a frame, and other information" category = "dev" optional = false @@ -1389,7 +1401,7 @@ typing-extensions = ">=3.7.4" [[package]] name = "stack-data" -version = "0.3.0" +version = "0.4.0" description = "Extract data from python stack frames and tracebacks for informative displays" category = "dev" optional = false @@ -1401,7 +1413,7 @@ executing = "*" pure-eval = "*" [package.extras] -tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"] +tests = ["cython", "littleutils", "pygments", "typeguard", "pytest"] [[package]] name = "stevedore" @@ -1645,12 +1657,12 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "5f54515db5c6ab1feb3c7fd62f3981ce3f217c2082e7da3b1554267dc341c338" +content-hash = "429b7926e38d696263b3886755fbb33c3ac01faae3d2f124f7d5d38f6b20361e" [metadata.files] aiogram = [ - {file = "aiogram-2.21-py3-none-any.whl", hash = "sha256:33ee61db550f6fc455e2d74d8911af31108e3c398eda03c2f91b0a7cb32a97d9"}, - {file = "aiogram-2.21.tar.gz", hash = "sha256:390ac56a629cd0d151d544e3b87d539ee49f734ccc7a1a7e375c33f436e556e0"}, + {file = "aiogram-2.22-py3-none-any.whl", hash = "sha256:af5eda881f72d9ad378d93e7c084c11daf6d20834a1799eb7a656b516420b734"}, + {file = "aiogram-2.22.tar.gz", hash = "sha256:92bef502b2f14b58fef2b534bc90319e0789fcfbd63e8d91c719236f1f33a3f7"}, ] aiohttp = [ {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8"}, @@ -1742,6 +1754,10 @@ apscheduler = [ {file = "APScheduler-3.9.1-py2.py3-none-any.whl", hash = "sha256:ddc25a0ddd899de44d7f451f4375fb971887e65af51e41e5dcf681f59b8b2c9a"}, {file = "APScheduler-3.9.1.tar.gz", hash = "sha256:65e6574b6395498d371d045f2a8a7e4f7d50c6ad21ef7313d15b1c7cf20df1e3"}, ] +aresponses = [ + {file = "aresponses-2.1.6-py3-none-any.whl", hash = "sha256:06525f6911063f0f8d370cbc96bd273e6cddc89c7b5163ddf91e0c8abf148a32"}, + {file = "aresponses-2.1.6.tar.gz", hash = "sha256:231dfa0756e39ca9f1e82212038f98e773d1ed9c0993caf2667e25ba535697ca"}, +] astor = [ {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, @@ -1978,8 +1994,8 @@ eradicate = [ {file = "eradicate-2.1.0.tar.gz", hash = "sha256:aac7384ab25b1bf21c4c012de9b4bf8398945a14c98c911545b2ea50ab558014"}, ] executing = [ - {file = "executing-0.9.1-py2.py3-none-any.whl", hash = "sha256:4ce4d6082d99361c0231fc31ac1a0f56979363cc6819de0b1410784f99e49105"}, - {file = "executing-0.9.1.tar.gz", hash = "sha256:ea278e2cf90cbbacd24f1080dd1f0ac25b71b2e21f50ab439b7ba45dd3195587"}, + {file = "executing-0.10.0-py2.py3-none-any.whl", hash = "sha256:9c745f80cda11eb22b62cbecf21156491a794eb56ab06f9d286a44e62822b24e"}, + {file = "executing-0.10.0.tar.gz", hash = "sha256:d1cd87c2e371e9966261410c5b3769d6df2f9e4a79a83eebd2662dd3388f9833"}, ] filelock = [ {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, @@ -2566,8 +2582,8 @@ sqlalchemy2-stubs = [ {file = "sqlalchemy2_stubs-0.0.2a25-py3-none-any.whl", hash = "sha256:9104894cee3159906079c4a31c2a66fbedfc72a381c51dfd1d8ebae8ffd7f2ca"}, ] stack-data = [ - {file = "stack_data-0.3.0-py3-none-any.whl", hash = "sha256:aa1d52d14d09c7a9a12bb740e6bdfffe0f5e8f4f9218d85e7c73a8c37f7ae38d"}, - {file = "stack_data-0.3.0.tar.gz", hash = "sha256:77bec1402dcd0987e9022326473fdbcc767304892a533ed8c29888dacb7dddbc"}, + {file = "stack_data-0.4.0-py3-none-any.whl", hash = "sha256:b94fed36d725cfabc6d09ed5886913e35eed9009766a1af1d5941b9da3a94aaa"}, + {file = "stack_data-0.4.0.tar.gz", hash = "sha256:a90ae7e260f7d15aefeceb46f0a028d4ccb9eb8856475c53e341945342d41ea7"}, ] stevedore = [ {file = "stevedore-4.0.0-py3-none-any.whl", hash = "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8"}, diff --git a/pyproject.toml b/pyproject.toml index fc99d3b..7ad9aea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ tomlkit = "^0.7.2" bandit = "1.7.4" requests = "^2.26.0" SQLAlchemy = {version = "^1.4", extras = ["mypy"]} +aresponses = "^2.1" pyupgrade = "^2.24.0" isort = "^5.9.3" @@ -33,7 +34,7 @@ mypy = "^0.961" types-PyMySQL = "^1.0.11" types-python-dateutil = "^2.8.4" -pytest = "^6.0" +pytest = "^6.2.4" pytest-asyncio = "^0.15.1" pytest-deadfixtures = "^2.2.1" pytest-testmon = "^1.1.2" @@ -68,6 +69,7 @@ multi_line_output = 3 src_paths = ["LenokWinServer",] [tool.mypy] +python_version = "3.10" strict = true ignore_missing_imports = true allow_subclassing_any = true @@ -79,6 +81,7 @@ allow_untyped_decorators = true warn_return_any = false plugins = ["sqlalchemy.ext.mypy.plugin"] + [tool.coverage.run] relative_files = true @@ -87,3 +90,6 @@ filterwarnings = [ "error", "ignore::DeprecationWarning", ] + +[tool.black] +skip-string-normalization = true \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 2dbab74..051975e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,12 +23,13 @@ ignore = per-file-ignores = ; too complex queries */repositories.py: ECE001 - tests/*: TAE001, S101, S311 + ./app/tests/*: TAE001, S101, S311 tests/*/factories/*: S5720 [mypy] # Mypy configuration: # https://mypy.readthedocs.io/en/latest/config_file.html +python_version = 3.10 allow_redefinition = False check_untyped_defs = True disallow_untyped_decorators = False