diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index 23325110..00000000 --- a/.codecov.yml +++ /dev/null @@ -1,57 +0,0 @@ -codecov: - require_ci_to_pass: yes - notify: - after_n_builds: 6 - wait_for_ci: yes - -coverage: - precision: 2 - round: down - range: "70...100" - status: - project: - default: false - bot: - paths: - - 'modmail/' - # basic - target: auto - threshold: 5% - base: auto - flags: - - unit - # advanced settings - branches: - - main - if_ci_failed: ignore #success, failure, error, ignore - informational: true - only_pulls: true - patch: - default: - # basic - target: auto - threshold: 5% - base: auto - # advanced - branches: - - main - if_ci_failed: ignore #success, failure, error, ignore - informational: true - only_pulls: true - - -parsers: - gcov: - branch_detection: - conditional: yes - loop: yes - method: no - macro: no - -comment: - layout: "reach,diff,flags,files,footer" - behavior: default - require_changes: no - -github_checks: - annotations: false diff --git a/.github/workflows/lint_test.yml b/.github/workflows/lint_test.yml index 6db38e31..4a7bceed 100644 --- a/.github/workflows/lint_test.yml +++ b/.github/workflows/lint_test.yml @@ -92,11 +92,14 @@ jobs: # black and flake8 action. As pre-commit does not support user installs, # we set PIP_USER=0 to not do a user install. - name: Run pre-commit hooks + id: pre-commit run: export PIP_USER=0; SKIP="no-commit-to-branch,black,flake8" pre-commit run --all-files # Run black seperately as we don't want to reformat the files # just error if something isn't formatted correctly. - name: Check files with black + id: black + if: always() && (steps.pre-commit.outcome == 'success' || steps.pre-commit.outcome == 'failure') run: black . --check --diff --color # Run flake8 and have it format the linting errors in the format of @@ -108,6 +111,8 @@ jobs: # Format used: # ::error file={filename},line={line},col={col}::{message} - name: Run flake8 + id: flake8 + if: always() && (steps.pre-commit.outcome == 'success' || steps.pre-commit.outcome == 'failure') run: "flake8 \ --format='::error file=%(path)s,line=%(row)d,col=%(col)d::\ [flake8] %(code)s: %(text)s'" @@ -162,12 +167,50 @@ jobs: # This is saved to ./.coverage to be used by codecov to link a # coverage report to github. - name: Run tests and generate coverage report - run: python -m pytest -n auto --dist loadfile --cov --disable-warnings -q + id: run_tests + run: python -m pytest tests -n auto --dist loadfile --cov --disable-warnings -q - # This step will publish the coverage reports to codecov.io and + # This step will publish the coverage reports to coveralls.io and # print a "job" link in the output of the GitHub Action - - name: Publish coverage report to codecov.io - run: python -m codecov + - name: Publish coverage report to coveralls.io + # upload coverage even if a test run failed + # this is a test, and may be removed in the future + if: always() && (steps.run_tests.outcome == 'success' || steps.run_tests.outcome == 'failure') + # important that we don't fail the workflow when coveralls is down + continue-on-error: true + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_FLAG_NAME: coverage-${{ runner.os }}-python-${{ env.PYTHON_VERSION }} + COVERALLS_PARALLEL: true + COVERALLS_SERVICE_NAME: github + run: python -m coveralls + + coveralls-finish: + name: Indicate completion to coveralls.io + runs-on: ubuntu-latest + needs: test + # we don't want to fail the workflow when coveralls is down + continue-on-error: true + # we always want to ensure we attempt to send a finish to coveralls + if: always() + steps: + # Set up a consistent version of Python + - name: Set up Python 3.9 + id: python + uses: actions/setup-python@v2 + with: + python-version: '3.9' + - name: Coveralls Finished + continue-on-error: true + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_SERVICE_NAME: github + # NOTE: this has a small thing where this will not always be the same with the poetry.lock file + # given how this is installed for one api request, its not worth pinning to me. + # any bugs caused by this can be solved when they occur + run: | + python3 -m pip install --upgrade coveralls + python3 -m coveralls --finish artifact: name: Generate Artifact diff --git a/README.md b/README.md index 2e521aee..214746f2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # Discord Modmail [![Lint & Test](https://img.shields.io/github/workflow/status/discord-modmail/modmail/Lint%20&%20Test/main?label=Lint+%26+Test&logo=github&style=flat)](https://github.com/discord-modmail/modmail/actions/workflows/lint_test.yml "Lint and Test") -[![Code Coverage](https://img.shields.io/codecov/c/gh/discord-modmail/modmail/main?logo=codecov&style=flat&label=Code+Coverage)](https://app.codecov.io/gh/discord-modmail/modmail "Code Coverage") -[![Codacy Grade](https://img.shields.io/codacy/grade/78be21a49835484595aea556d5920638?logo=codacy&style=flat&label=Code+Quality)](https://www.codacy.com/gh/discord-modmail/modmail/dashboard "Codacy Grade") +[![Code Coverage](https://img.shields.io/coveralls/github/discord-modmail/modmail?logo=coveralls&style=flat&label=Code+Coverage)](https://coveralls.io/github/discord-modmail/modmail) [![Python](https://img.shields.io/static/v1?label=Python&message=3.8+%7C+3.9&color=blue&logo=Python&style=flat)](https://www.python.org/downloads/ "Python 3.8 | 3.9") [![License](https://img.shields.io/github/license/discord-modmail/modmail?style=flat&label=License)](./LICENSE "License file") [![Code Style](https://img.shields.io/static/v1?label=Code%20Style&message=black&color=000000&style=flat)](https://github.com/psf/black "The uncompromising python formatter") diff --git a/modmail/__init__.py b/modmail/__init__.py index 9377ffd2..1c3966eb 100644 --- a/modmail/__init__.py +++ b/modmail/__init__.py @@ -1,5 +1,7 @@ +import asyncio import logging import logging.handlers +import os from pathlib import Path import coloredlogs @@ -7,6 +9,12 @@ from modmail.log import ModmailLogger +# On windows aiodns's asyncio support relies on APIs like add_reader (which aiodns uses) +# are not guaranteed to be available, and in particular are not available when using the +# ProactorEventLoop on Windows, this method is only supported with Windows SelectorEventLoop +if os.name == "nt": + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + logging.TRACE = 5 logging.NOTICE = 25 logging.addLevelName(logging.TRACE, "TRACE") diff --git a/modmail/bot.py b/modmail/bot.py index de27ea08..06de9ea1 100644 --- a/modmail/bot.py +++ b/modmail/bot.py @@ -1,12 +1,12 @@ import asyncio import logging import signal +import socket import typing as t -from typing import Any +import aiohttp import arrow import discord -from aiohttp import ClientSession from discord import Activity, AllowedMentions, Intents from discord.client import _cleanup_loop from discord.ext import commands @@ -41,9 +41,12 @@ class ModmailBot(commands.Bot): def __init__(self, **kwargs): self.config = CONFIG self.start_time: t.Optional[arrow.Arrow] = None # arrow.utcnow() - self.http_session: t.Optional[ClientSession] = None + self.http_session: t.Optional[aiohttp.ClientSession] = None self.dispatcher = Dispatcher() + self._connector = None + self._resolver = None + status = discord.Status.online activity = Activity(type=discord.ActivityType.listening, name="users dming me!") # listen to messages mentioning the bot or matching the prefix @@ -65,6 +68,24 @@ def __init__(self, **kwargs): **kwargs, ) + async def create_connectors(self, *args, **kwargs) -> None: + """Re-create the connector and set up sessions before logging into Discord.""" + # Use asyncio for DNS resolution instead of threads so threads aren't spammed. + self._resolver = aiohttp.AsyncResolver() + + # Use AF_INET as its socket family to prevent HTTPS related problems both locally + # and in production. + self._connector = aiohttp.TCPConnector( + resolver=self._resolver, + family=socket.AF_INET, + ) + + # Client.login() will call HTTPClient.static_login() which will create a session using + # this connector attribute. + self.http.connector = self._connector + + self.http_session = aiohttp.ClientSession(connector=self._connector) + async def start(self, token: str, reconnect: bool = True) -> None: """ Start the bot. @@ -74,8 +95,8 @@ async def start(self, token: str, reconnect: bool = True) -> None: """ try: # create the aiohttp session - self.http_session = ClientSession(loop=self.loop) - self.logger.trace("Created ClientSession.") + await self.create_connectors() + self.logger.trace("Created aiohttp.ClientSession.") # set start time to when we started the bot. # This is now, since we're about to connect to the gateway. # This should also be before we load any extensions, since if they have a load time, it should @@ -122,7 +143,7 @@ def run(self, *args, **kwargs) -> None: except NotImplementedError: pass - def stop_loop_on_completion(f: Any) -> None: + def stop_loop_on_completion(f: t.Any) -> None: loop.stop() future = asyncio.ensure_future(self.start(*args, **kwargs), loop=loop) @@ -164,10 +185,16 @@ async def close(self) -> None: except Exception: self.logger.error(f"Exception occured while removing cog {cog.name}", exc_info=True) + await super().close() + if self.http_session: await self.http_session.close() - await super().close() + if self._connector: + await self._connector.close() + + if self._resolver: + await self._resolver.close() def load_extensions(self) -> None: """Load all enabled extensions.""" diff --git a/poetry.lock b/poetry.lock index 71294634..936ceab3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -31,6 +31,17 @@ yarl = ">=1.0,<2.0" [package.extras] speedups = ["aiodns", "brotlipy", "cchardet"] +[[package]] +name = "aioresponses" +version = "0.7.2" +description = "Mock out requests made by ClientSession from aiohttp package" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +aiohttp = ">=2.0.0,<4.0.0" + [[package]] name = "arrow" version = "1.1.1" @@ -84,21 +95,6 @@ python-versions = ">=2.7" docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-flake8", "pytest-cov", "pytest-black (>=0.3.7)", "pytest-mypy", "pytest-checkdocs (>=2.4)", "pytest-enabler (>=1.0.1)"] -[[package]] -name = "bandit" -version = "1.7.0" -description = "Security oriented static analyser for python code." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.dependencies] -colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} -GitPython = ">=1.0.1" -PyYAML = ">=5.3.1" -six = ">=1.10.0" -stevedore = ">=1.20.0" - [[package]] name = "black" version = "21.8b0" @@ -202,18 +198,6 @@ python-versions = ">=3.6" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -[[package]] -name = "codecov" -version = "2.1.12" -description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -coverage = "*" -requests = ">=2.7.9" - [[package]] name = "colorama" version = "0.4.4" @@ -238,7 +222,7 @@ cron = ["capturer (>=2.4)"] [[package]] name = "coverage" -version = "6.0.2" +version = "6.1.2" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -250,6 +234,22 @@ tomli = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] toml = ["tomli"] +[[package]] +name = "coveralls" +version = "3.3.1" +description = "Show coverage stats online via coveralls.io" +category = "dev" +optional = false +python-versions = ">= 3.5" + +[package.dependencies] +coverage = ">=4.1,<6.0.0 || >6.1,<6.1.1 || >6.1.1,<7.0" +docopt = ">=0.6.1" +requests = ">=1.0.0" + +[package.extras] +yaml = ["PyYAML (>=3.10)"] + [[package]] name = "discord.py" version = "2.0.0a0" @@ -278,6 +278,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "docopt" +version = "0.6.2" +description = "Pythonic argument parser, that will make you smile" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "execnet" version = "1.9.0" @@ -321,20 +329,6 @@ python-versions = ">=3.6.1,<4.0.0" [package.dependencies] flake8 = ">=3.7,<4.0" -[[package]] -name = "flake8-bandit" -version = "2.1.2" -description = "Automated security testing with bandit and flake8." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -bandit = "*" -flake8 = "*" -flake8-polyfill = "*" -pycodestyle = "*" - [[package]] name = "flake8-bugbear" version = "20.11.1" @@ -436,29 +430,6 @@ python-dateutil = ">=2.8.1" [package.extras] dev = ["twine", "markdown", "flake8"] -[[package]] -name = "gitdb" -version = "4.0.7" -description = "Git Object Database" -category = "dev" -optional = false -python-versions = ">=3.4" - -[package.dependencies] -smmap = ">=3.0.1,<5" - -[[package]] -name = "gitpython" -version = "3.1.20" -description = "Python Git Library" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} - [[package]] name = "humanfriendly" version = "10.0" @@ -688,14 +659,6 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -[[package]] -name = "pbr" -version = "5.6.0" -description = "Python Build Reasonableness" -category = "dev" -optional = false -python-versions = ">=2.6" - [[package]] name = "pep8-naming" version = "0.12.1" @@ -1050,14 +1013,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -[[package]] -name = "smmap" -version = "4.0.0" -description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "snowballstemmer" version = "2.1.0" @@ -1066,17 +1021,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "stevedore" -version = "3.4.0" -description = "Manage dynamic plugins for Python applications" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pbr = ">=2.0.0,<2.1.0 || >2.1.0" - [[package]] name = "taskipy" version = "1.8.1" @@ -1206,7 +1150,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "b85bebf7a796b0b37e647fd7289589ea03a147c155839dfd1bcd561ead1fde92" +content-hash = "aaa5181c8d94a936811266da090c02a531780a7beaf35985198b82a06f5b306b" [metadata.files] aiodns = [ @@ -1252,6 +1196,10 @@ aiohttp = [ {file = "aiohttp-3.7.4.post0-cp39-cp39-win_amd64.whl", hash = "sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe"}, {file = "aiohttp-3.7.4.post0.tar.gz", hash = "sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf"}, ] +aioresponses = [ + {file = "aioresponses-0.7.2-py2.py3-none-any.whl", hash = "sha256:2f8ff624543066eb465b0238de68d29231e8488f41dc4b5a9dae190982cdae50"}, + {file = "aioresponses-0.7.2.tar.gz", hash = "sha256:82e495d118b74896aa5b4d47e17effb5e2cc783e510ae395ceade5e87cabe89a"}, +] arrow = [ {file = "arrow-1.1.1-py3-none-any.whl", hash = "sha256:77a60a4db5766d900a2085ce9074c5c7b8e2c99afeaa98ad627637ff6f292510"}, {file = "arrow-1.1.1.tar.gz", hash = "sha256:dee7602f6c60e3ec510095b5e301441bc56288cb8f51def14dcb3079f623823a"}, @@ -1272,10 +1220,6 @@ attrs = [ {file = "backports.entry_points_selectable-1.1.0-py2.py3-none-any.whl", hash = "sha256:a6d9a871cde5e15b4c4a53e3d43ba890cc6861ec1332c9c2428c92f977192acc"}, {file = "backports.entry_points_selectable-1.1.0.tar.gz", hash = "sha256:988468260ec1c196dab6ae1149260e2f5472c9110334e5d51adcb77867361f6a"}, ] -bandit = [ - {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"}, - {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"}, -] black = [ {file = "black-21.8b0-py3-none-any.whl", hash = "sha256:2a0f9a8c2b2a60dbcf1ccb058842fb22bdbbcb2f32c6cc02d9578f90b92ce8b7"}, {file = "black-21.8b0.tar.gz", hash = "sha256:570608d28aa3af1792b98c4a337dbac6367877b47b12b88ab42095cfc1a627c2"}, @@ -1422,11 +1366,6 @@ click = [ {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, ] -codecov = [ - {file = "codecov-2.1.12-py2.py3-none-any.whl", hash = "sha256:585dc217dc3d8185198ceb402f85d5cb5dbfa0c5f350a5abcdf9e347776a5b47"}, - {file = "codecov-2.1.12-py3.8.egg", hash = "sha256:782a8e5352f22593cbc5427a35320b99490eb24d9dcfa2155fd99d2b75cfb635"}, - {file = "codecov-2.1.12.tar.gz", hash = "sha256:a0da46bb5025426da895af90938def8ee12d37fcbcbbbc15b6dc64cf7ebc51c1"}, -] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, @@ -1436,45 +1375,66 @@ coloredlogs = [ {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, ] coverage = [ - {file = "coverage-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1549e1d08ce38259de2bc3e9a0d5f3642ff4a8f500ffc1b2df73fd621a6cdfc0"}, - {file = "coverage-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcae10fccb27ca2a5f456bf64d84110a5a74144be3136a5e598f9d9fb48c0caa"}, - {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:53a294dc53cfb39c74758edaa6305193fb4258a30b1f6af24b360a6c8bd0ffa7"}, - {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8251b37be1f2cd9c0e5ccd9ae0380909c24d2a5ed2162a41fcdbafaf59a85ebd"}, - {file = "coverage-6.0.2-cp310-cp310-win32.whl", hash = "sha256:db42baa892cba723326284490283a68d4de516bfb5aaba369b4e3b2787a778b7"}, - {file = "coverage-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:bbffde2a68398682623d9dd8c0ca3f46fda074709b26fcf08ae7a4c431a6ab2d"}, - {file = "coverage-6.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:60e51a3dd55540bec686d7fff61b05048ca31e804c1f32cbb44533e6372d9cc3"}, - {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a6a9409223a27d5ef3cca57dd7cd4dfcb64aadf2fad5c3b787830ac9223e01a"}, - {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4b34ae4f51bbfa5f96b758b55a163d502be3dcb24f505d0227858c2b3f94f5b9"}, - {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3bbda1b550e70fa6ac40533d3f23acd4f4e9cb4e6e77251ce77fdf41b3309fb2"}, - {file = "coverage-6.0.2-cp36-cp36m-win32.whl", hash = "sha256:4e28d2a195c533b58fc94a12826f4431726d8eb029ac21d874345f943530c122"}, - {file = "coverage-6.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a82d79586a0a4f5fd1cf153e647464ced402938fbccb3ffc358c7babd4da1dd9"}, - {file = "coverage-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3be1206dc09fb6298de3fce70593e27436862331a85daee36270b6d0e1c251c4"}, - {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cd3828bbe1a40070c11fe16a51df733fd2f0cb0d745fb83b7b5c1f05967df7"}, - {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d036dc1ed8e1388e995833c62325df3f996675779541f682677efc6af71e96cc"}, - {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04560539c19ec26995ecfb3d9307ff154fbb9a172cb57e3b3cfc4ced673103d1"}, - {file = "coverage-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:e4fb7ced4d9dec77d6cf533acfbf8e1415fe799430366affb18d69ee8a3c6330"}, - {file = "coverage-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:77b1da5767ed2f44611bc9bc019bc93c03fa495728ec389759b6e9e5039ac6b1"}, - {file = "coverage-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61b598cbdbaae22d9e34e3f675997194342f866bb1d781da5d0be54783dce1ff"}, - {file = "coverage-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e9040a43d2017f2787b28d365a4bb33fcd792c7ff46a047a04094dc0e2a30d"}, - {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9f1627e162e3864a596486774876415a7410021f4b67fd2d9efdf93ade681afc"}, - {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e7a0b42db2a47ecb488cde14e0f6c7679a2c5a9f44814393b162ff6397fcdfbb"}, - {file = "coverage-6.0.2-cp38-cp38-win32.whl", hash = "sha256:a1b73c7c4d2a42b9d37dd43199c5711d91424ff3c6c22681bc132db4a4afec6f"}, - {file = "coverage-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:1db67c497688fd4ba85b373b37cc52c50d437fd7267520ecd77bddbd89ea22c9"}, - {file = "coverage-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f184bf38e74f152eed7f87e345b51f3ab0b703842f447c22efe35e59942c24"}, - {file = "coverage-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1cf1deb3d5544bd942356364a2fdc8959bad2b6cf6eb17f47d301ea34ae822"}, - {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad9b8c1206ae41d46ec7380b78ba735ebb77758a650643e841dd3894966c31d0"}, - {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:381d773d896cc7f8ba4ff3b92dee4ed740fb88dfe33b6e42efc5e8ab6dfa1cfe"}, - {file = "coverage-6.0.2-cp39-cp39-win32.whl", hash = "sha256:424c44f65e8be58b54e2b0bd1515e434b940679624b1b72726147cfc6a9fc7ce"}, - {file = "coverage-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:abbff240f77347d17306d3201e14431519bf64495648ca5a49571f988f88dee9"}, - {file = "coverage-6.0.2-pp36-none-any.whl", hash = "sha256:7092eab374346121805fb637572483270324407bf150c30a3b161fc0c4ca5164"}, - {file = "coverage-6.0.2-pp37-none-any.whl", hash = "sha256:30922626ce6f7a5a30bdba984ad21021529d3d05a68b4f71ea3b16bda35b8895"}, - {file = "coverage-6.0.2.tar.gz", hash = "sha256:6807947a09510dc31fa86f43595bf3a14017cd60bf633cc746d52141bfa6b149"}, + {file = "coverage-6.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:675adb3b3380967806b3cbb9c5b00ceb29b1c472692100a338730c1d3e59c8b9"}, + {file = "coverage-6.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95a58336aa111af54baa451c33266a8774780242cab3704b7698d5e514840758"}, + {file = "coverage-6.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0a595a781f8e186580ff8e3352dd4953b1944289bec7705377c80c7e36c4d6c"}, + {file = "coverage-6.1.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d3c5f49ce6af61154060640ad3b3281dbc46e2e0ef2fe78414d7f8a324f0b649"}, + {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:310c40bed6b626fd1f463e5a83dba19a61c4eb74e1ac0d07d454ebbdf9047e9d"}, + {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a4d48e42e17d3de212f9af44f81ab73b9378a4b2b8413fd708d0d9023f2bbde4"}, + {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ffa545230ca2ad921ad066bf8fd627e7be43716b6e0fcf8e32af1b8188ccb0ab"}, + {file = "coverage-6.1.2-cp310-cp310-win32.whl", hash = "sha256:cd2d11a59afa5001ff28073ceca24ae4c506da4355aba30d1e7dd2bd0d2206dc"}, + {file = "coverage-6.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:96129e41405887a53a9cc564f960d7f853cc63d178f3a182fdd302e4cab2745b"}, + {file = "coverage-6.1.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1de9c6f5039ee2b1860b7bad2c7bc3651fbeb9368e4c4d93e98a76358cdcb052"}, + {file = "coverage-6.1.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:80cb70264e9a1d04b519cdba3cd0dc42847bf8e982a4d55c769b9b0ee7cdce1e"}, + {file = "coverage-6.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:ba6125d4e55c0b8e913dad27b22722eac7abdcb1f3eab1bd090eee9105660266"}, + {file = "coverage-6.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8492d37acdc07a6eac6489f6c1954026f2260a85a4c2bb1e343fe3d35f5ee21a"}, + {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66af99c7f7b64d050d37e795baadf515b4561124f25aae6e1baa482438ecc388"}, + {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ebcc03e1acef4ff44f37f3c61df478d6e469a573aa688e5a162f85d7e4c3860d"}, + {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98d44a8136eebbf544ad91fef5bd2b20ef0c9b459c65a833c923d9aa4546b204"}, + {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c18725f3cffe96732ef96f3de1939d81215fd6d7d64900dcc4acfe514ea4fcbf"}, + {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c8e9c4bcaaaa932be581b3d8b88b677489975f845f7714efc8cce77568b6711c"}, + {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:06d009e8a29483cbc0520665bc46035ffe9ae0e7484a49f9782c2a716e37d0a0"}, + {file = "coverage-6.1.2-cp36-cp36m-win32.whl", hash = "sha256:e5432d9c329b11c27be45ee5f62cf20a33065d482c8dec1941d6670622a6fb8f"}, + {file = "coverage-6.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:82fdcb64bf08aa5db881db061d96db102c77397a570fbc112e21c48a4d9cb31b"}, + {file = "coverage-6.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:94f558f8555e79c48c422045f252ef41eb43becdd945e9c775b45ebfc0cbd78f"}, + {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:046647b96969fda1ae0605f61288635209dd69dcd27ba3ec0bf5148bc157f954"}, + {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cc799916b618ec9fd00135e576424165691fec4f70d7dc12cfaef09268a2478c"}, + {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62646d98cf0381ffda301a816d6ac6c35fc97aa81b09c4c52d66a15c4bef9d7c"}, + {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:27a3df08a855522dfef8b8635f58bab81341b2fb5f447819bc252da3aa4cf44c"}, + {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:610c0ba11da8de3a753dc4b1f71894f9f9debfdde6559599f303286e70aeb0c2"}, + {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:35b246ae3a2c042dc8f410c94bcb9754b18179cdb81ff9477a9089dbc9ecc186"}, + {file = "coverage-6.1.2-cp37-cp37m-win32.whl", hash = "sha256:0cde7d9fe2fb55ff68ebe7fb319ef188e9b88e0a3d1c9c5db7dd829cd93d2193"}, + {file = "coverage-6.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:958ac66272ff20e63d818627216e3d7412fdf68a2d25787b89a5c6f1eb7fdd93"}, + {file = "coverage-6.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a300b39c3d5905686c75a369d2a66e68fd01472ea42e16b38c948bd02b29e5bd"}, + {file = "coverage-6.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d3855d5d26292539861f5ced2ed042fc2aa33a12f80e487053aed3bcb6ced13"}, + {file = "coverage-6.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:586d38dfc7da4a87f5816b203ff06dd7c1bb5b16211ccaa0e9788a8da2b93696"}, + {file = "coverage-6.1.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a34fccb45f7b2d890183a263578d60a392a1a218fdc12f5bce1477a6a68d4373"}, + {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bc1ee1318f703bc6c971da700d74466e9b86e0c443eb85983fb2a1bd20447263"}, + {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3f546f48d5d80a90a266769aa613bc0719cb3e9c2ef3529d53f463996dd15a9d"}, + {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd92ece726055e80d4e3f01fff3b91f54b18c9c357c48fcf6119e87e2461a091"}, + {file = "coverage-6.1.2-cp38-cp38-win32.whl", hash = "sha256:24ed38ec86754c4d5a706fbd5b52b057c3df87901a8610d7e5642a08ec07087e"}, + {file = "coverage-6.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:97ef6e9119bd39d60ef7b9cd5deea2b34869c9f0b9777450a7e3759c1ab09b9b"}, + {file = "coverage-6.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e5a8c947a2a89c56655ecbb789458a3a8e3b0cbf4c04250331df8f647b3de59"}, + {file = "coverage-6.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a39590d1e6acf6a3c435c5d233f72f5d43b585f5be834cff1f21fec4afda225"}, + {file = "coverage-6.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9d2c2e3ce7b8cc932a2f918186964bd44de8c84e2f9ef72dc616f5bb8be22e71"}, + {file = "coverage-6.1.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3348865798c077c695cae00da0924136bb5cc501f236cfd6b6d9f7a3c94e0ec4"}, + {file = "coverage-6.1.2-cp39-cp39-win32.whl", hash = "sha256:fae3fe111670e51f1ebbc475823899524e3459ea2db2cb88279bbfb2a0b8a3de"}, + {file = "coverage-6.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:af45eea024c0e3a25462fade161afab4f0d9d9e0d5a5d53e86149f74f0a35ecc"}, + {file = "coverage-6.1.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:eab14fdd410500dae50fd14ccc332e65543e7b39f6fc076fe90603a0e5d2f929"}, + {file = "coverage-6.1.2.tar.gz", hash = "sha256:d9a635114b88c0ab462e0355472d00a180a5fbfd8511e7f18e4ac32652e7d972"}, +] +coveralls = [ + {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"}, + {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"}, ] "discord.py" = [] distlib = [ {file = "distlib-0.3.2-py2.py3-none-any.whl", hash = "sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c"}, {file = "distlib-0.3.2.zip", hash = "sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736"}, ] +docopt = [ + {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, +] execnet = [ {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, @@ -1491,9 +1451,6 @@ flake8-annotations = [ {file = "flake8-annotations-2.6.2.tar.gz", hash = "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515"}, {file = "flake8_annotations-2.6.2-py3-none-any.whl", hash = "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f"}, ] -flake8-bandit = [ - {file = "flake8_bandit-2.1.2.tar.gz", hash = "sha256:687fc8da2e4a239b206af2e54a90093572a60d0954f3054e23690739b0b0de3b"}, -] flake8-bugbear = [ {file = "flake8-bugbear-20.11.1.tar.gz", hash = "sha256:528020129fea2dea33a466b9d64ab650aa3e5f9ffc788b70ea4bc6cf18283538"}, {file = "flake8_bugbear-20.11.1-py36.py37.py38-none-any.whl", hash = "sha256:f35b8135ece7a014bc0aee5b5d485334ac30a6da48494998cc1fabf7ec70d703"}, @@ -1524,14 +1481,6 @@ flake8-todo = [ ghp-import = [ {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, ] -gitdb = [ - {file = "gitdb-4.0.7-py3-none-any.whl", hash = "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0"}, - {file = "gitdb-4.0.7.tar.gz", hash = "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"}, -] -gitpython = [ - {file = "GitPython-3.1.20-py3-none-any.whl", hash = "sha256:b1e1c269deab1b08ce65403cf14e10d2ef1f6c89e33ea7c5e5bb0222ea593b8a"}, - {file = "GitPython-3.1.20.tar.gz", hash = "sha256:df0e072a200703a65387b0cfdf0466e3bab729c0458cf6b7349d0e9877636519"}, -] humanfriendly = [ {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, @@ -1738,10 +1687,6 @@ pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] -pbr = [ - {file = "pbr-5.6.0-py2.py3-none-any.whl", hash = "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4"}, - {file = "pbr-5.6.0.tar.gz", hash = "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd"}, -] pep8-naming = [ {file = "pep8-naming-0.12.1.tar.gz", hash = "sha256:bb2455947757d162aa4cad55dba4ce029005cd1692f2899a21d51d8630ca7841"}, {file = "pep8_naming-0.12.1-py2.py3-none-any.whl", hash = "sha256:4a8daeaeb33cfcde779309fc0c9c0a68a3bbe2ad8a8308b763c5068f86eb9f37"}, @@ -2001,18 +1946,10 @@ six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -smmap = [ - {file = "smmap-4.0.0-py2.py3-none-any.whl", hash = "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2"}, - {file = "smmap-4.0.0.tar.gz", hash = "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182"}, -] snowballstemmer = [ {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"}, {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"}, ] -stevedore = [ - {file = "stevedore-3.4.0-py3-none-any.whl", hash = "sha256:920ce6259f0b2498aaa4545989536a27e4e4607b8318802d7ddc3a533d3d069e"}, - {file = "stevedore-3.4.0.tar.gz", hash = "sha256:59b58edb7f57b11897f150475e7bc0c39c5381f0b8e3fa9f5c20ce6c89ec4aa1"}, -] taskipy = [ {file = "taskipy-1.8.1-py3-none-any.whl", hash = "sha256:2b98f499966e40175d1f1306a64587f49dfa41b90d0d86c8f28b067cc58d0a56"}, {file = "taskipy-1.8.1.tar.gz", hash = "sha256:7a2404125817e45d80e13fa663cae35da6e8ba590230094e815633653e25f98f"}, diff --git a/pyproject.toml b/pyproject.toml index 245c8fad..c2d4b071 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,6 @@ taskipy = "^1.6.0" black = "^21.7b0" flake8 = "~=3.8" flake8-annotations = "~=2.3" -flake8-bandit = "^2.1.2" flake8-bugbear = "~=20.1" flake8-docstrings = "~=1.5" flake8-isort = "^4.0.0" @@ -44,8 +43,9 @@ flake8-todo = "~=0.7" isort = "^5.9.2" pep8-naming = "~=0.11" # testing -codecov = "^2.1.11" +aioresponses = "^0.7.2" coverage = { extras = ["toml"], version = "^6.0.2" } +coveralls = "^3.3.1" pytest = "^6.2.4" pytest-asyncio = "^0.15.1" pytest-cov = "^3.0.0" @@ -65,7 +65,7 @@ build-backend = "poetry.core.masonry.api" [tool.coverage.run] branch = true -source_pkgs = ['modmail', 'tests.modmail'] +source_pkgs = ['modmail', 'tests'] omit = ["modmail/plugins/**.*"] [tool.pytest.ini_options] @@ -81,13 +81,13 @@ include = '\.pyi?$' [tool.taskipy.tasks] start = { cmd = "python -m modmail", help = "Run bot" } black = { cmd = "black --check .", help = "dry run of black" } -codecov-validate = { cmd = "curl --data-binary @.codecov.yml https://codecov.io/validate", help = "Validate `.codecov.yml` with their api." } cov-server = { cmd = "coverage html", help = "Start an http.server for viewing coverage data." } post_cov-server = "python -m http.server 8012 --bind 127.0.0.1 --directory htmlcov" docs = { cmd = "mkdocs serve", help = "Run the docs on a local automatically reloading server" } export = { cmd = "python -m scripts.export_requirements", help = "Export the requirements from poetry.lock to requirements.txt" } flake8 = { cmd = "python -m flake8", help = "Lints code with flake8" } lint = { cmd = "pre-commit run --all-files", help = "Checks all files for CI errors" } +lock = { cmd = 'poetry lock --no-update && task export --docs', help = 'Relock the dependencies without updating them. Also runs the export scripts' } precommit = { cmd = "pre-commit install --install-hooks", help = "Installs the precommit hook" } report = { cmd = "coverage report", help = "Show coverage report from previously run tests." } scripts = { cmd = 'python -m scripts', help = 'Run the scripts wrapper cli.' } diff --git a/tests/conftest.py b/tests/conftest.py index 5871ed8e..40c3ae9c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1 +1,29 @@ +import aiohttp +import aioresponses import pytest + + +@pytest.fixture +def aioresponse(): + """Fixture to mock aiohttp responses.""" + with aioresponses.aioresponses() as aioresponse: + yield aioresponse + + +@pytest.fixture +@pytest.mark.asyncio +async def http_session(aioresponse) -> aiohttp.ClientSession: + """ + Fixture function for a aiohttp.ClientSession. + + Requests fixture aioresponse to ensure that all client sessions do not make actual requests. + """ + resolver = aiohttp.AsyncResolver() + connector = aiohttp.TCPConnector(resolver=resolver) + client_session = aiohttp.ClientSession(connector=connector) + + yield client_session + + await client_session.close() + await connector.close() + await resolver.close() diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py new file mode 100644 index 00000000..906c3301 --- /dev/null +++ b/tests/test_fixtures.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import aiohttp +import pytest + + +if TYPE_CHECKING: + import aioresponses + + +class TestSessionFixture: + """Grouping for aiohttp.ClientSession fixture tests.""" + + @pytest.mark.asyncio + async def test_session_fixture_no_requests(self, http_session: aiohttp.ClientSession): + """ + Test all requests fail. + + This means that aioresponses is being requested by the http_session fixture. + """ + url = "https://github.com/" + + with pytest.raises(aiohttp.ClientConnectionError): + await http_session.get(url) + + @pytest.mark.asyncio + async def test_session_fixture_mock_requests( + self, aioresponse: aioresponses.aioresponses, http_session: aiohttp.ClientSession + ): + """ + Test all requests fail. + + This means that aioresponses is being requested by the http_session fixture. + """ + url = "https://github.com/" + status = 200 + aioresponse.get(url, status=status) + + async with http_session.get(url) as resp: + assert status == resp.status