diff --git a/.gitignore b/.gitignore index 89631af..b238af2 100644 --- a/.gitignore +++ b/.gitignore @@ -239,4 +239,6 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ -.ruff_cache/ \ No newline at end of file +.ruff_cache/ +/docs/output/ +/docs/generated/ diff --git a/README.rst b/README.rst index 15b6ff6..31bab97 100644 --- a/README.rst +++ b/README.rst @@ -6,7 +6,7 @@ API-client for https://github.com/axllent/mailpit written in Python ------------------------------------------------------------------- :Authors: - Lars Liedtke + Lars Liedtke :Version: 0.10.3 @@ -18,6 +18,21 @@ We are working with `Odoo `_ and I wanted to test I remembered `mailhog `_, which I discovered to be abandoned. Searching for an alternative, I found Mailpit - for which I decided to write an API-client in my free time. +------- +Install +------- +If you want to use the library with ``unittest``: + +.. code-block:: bash + + pip install mailpit-api-client + +If you want to use the library with ``pytest``: + +.. code-block:: bash + + pip install mailpit-api-client[pytest] + ----- Usage ----- @@ -50,14 +65,33 @@ The model-classes' attributes are named the same as Mailpit's responses, as docu For examples have a look at the link:tests[tests] -== Testing +------- +Testing +------- -To make testing easier I plan to provide testhelpers like TestCase-classes of ``unittest`` and ``pytest``-fixtures. +To make testing easier there are test-helpers inside the ``mailpit.testing`` package. -=== unittest -tbd +________ +unittest +________ + +In order to provide some convenience a test-case class has been created with the name ``EMailTestCase`` deriving from ``unittest.TestCase``, which is meant to be inherited from, as you would do from ``TestCase``: + +.. code-block:: python + + from mailpit.testing.unittest import EMailTestCase + + class MyTest(EMailTestCase): + + def test_sending_email(): + ... + +The class adds a few methods and attributes, so that you are able to assert, if your message has been sent, or if two messages are equal. + +______ +pytest +______ -=== pytest tbd .. [1] If you have it running differently, you have to adjust the URL you pass. diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..1c19fc3 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = output + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/__init__.py b/docs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/docs/about.rst b/docs/about.rst new file mode 100644 index 0000000..05e21c0 --- /dev/null +++ b/docs/about.rst @@ -0,0 +1,32 @@ +===== +About +===== + +:Authors: + Lars Liedtke +:Version: + 0.10.3 + +For work, I thought about introducing integration testing. +We are working with `Odoo `_ and I wanted to test if e-mails created by Odoo really were sent. +I remembered `mailhog `_, which I discovered to be abandoned. +Searching for an alternative, I found Mailpit - for which I decided to write an API-client in my free time. + +------- +Mailpit +------- +Mailpit is software written Go, intended to be a testing tool for E-Mail. +It acts as a receiving E-Mail server and offers a Web Frontend as well as an API. +With it you can configure the software you want to test to send its E-Mail Messages to Mailpit and check via the frontend or the API if your software sent mail, correctly sent it, and using the frontend, how mail will be rendered. +If you want to learn more about Mailpit, have a look at its `README `_ and at its `Wiki `_ + +---------- +API-Client +---------- +This API-Client uses Mailpit's API in order to provide classes and methods in Python, which are providing access to the API endpoints and the information returned of messages stored in Mailpit. +More information can be found in :doc:`usage`. + +Additionally there are ``unittest`` Test-Cases and ``pytest`` Fixtures, which can be used to write (integration-) tests. +These helpers can be used to e.g. trigger sending an E-Mail message in a test and then +to check, if the message has been received by Mailpit. If it has not been received by mailpit your test will fail. +More information can be found in :doc:`testing/testing`. \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..e6ba503 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,43 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +import sys +import os + +sys.path.insert(0, os.path.abspath("..")) + +import mailpit + +project = "mailpit-api-client" +copyright = "2023, Lars Liedtke" +author = "Lars Liedtke" +release = "0.10.1" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +source_path = "mailpit" + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "alabaster" +html_static_path = ["_static"] + +intersphinx_mapping = { + "pytest": ("https://docs.pytest.org/en/stable", None), + "python": ("https://docs.python.org/3/", None), +} diff --git a/docs/development.rst b/docs/development.rst new file mode 100644 index 0000000..4d57e7a --- /dev/null +++ b/docs/development.rst @@ -0,0 +1,17 @@ +=========== +Development +=========== + +-------------------- +Install dependencies +-------------------- + +.. code-block:: python + + pip install -e ".[docs,test,pytest,build]" + +.. code-block:: bash + + make clean + sphinx-apidoc -d 4 -eM -f -o generated ../mailpit + make html diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..8d6bf31 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,26 @@ +.. mailpit-api-client documentation master file, created by + sphinx-quickstart on Thu Jun 8 19:55:21 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to mailpit-api-client's documentation! +============================================== + +.. toctree:: + :maxdepth: 4 + :caption: Contents: + + about + installation + usage + testing/testing + development + generated/modules + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..cdd4300 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,66 @@ +============ +Installation +============ + +This documentation assumes you are familiar with `pip `_ and how to use it on your operating system. + +Additionally consider using virtual environments, be it with `venv `_, `virtualenvwrapper `_, `pipx `_, `poetry `_ or whatever else you'd like to use. + +---- +PyPI +---- +You can find the Project on `PyPI `_ under ``_ + +It can simply be installed: + +________ +unittest +________ + +If you want to use it with `unittest `_ +simply type + +.. code-block:: bash + + pip install maiilpit-api-client + +______ +pytest +______ + +If you want to install it with `pytest `_, type + +.. code-block:: bash + + pip install mailpit-api-client[pytest] + +This will have pytest as additional dependency. + +------ +GitHub +------ +You can install it from `GitHub `_ directly as well + +________ +unittest +________ +.. code-block:: bash + + pip install https://github.com/Corvan/mailpit-api-client.git + +______ +pytest +______ +.. code-block:: bash + + pip install https://github.com/Corvan/mailpit-api-client.git[pytest] + +______________________ +Cloning git repository +______________________ + +Or if you want to clone the repository + +.. code-block:: bash + + git clone https://github.com/Corvan/mailpit-api-client.git \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..954237b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/testing/pytest.rst b/docs/testing/pytest.rst new file mode 100644 index 0000000..db98b73 --- /dev/null +++ b/docs/testing/pytest.rst @@ -0,0 +1,43 @@ +====== +pytest +====== +In order to provide some convenience a :py:func:`pytest.fixtures ` has +been created. + +------------------- +Mailpit-API fixture +------------------- +:py:func:`~mailpit.testing.pytest.mailpit_api` is a :py:mod:`pytest` :py:func:`fixture `, that sets up an API connection and returns it as :py:class:`~mailpit.client.api.API` object. + +The fixture has got a scope of ``session`` and it will call :py:meth:`API.delete_messages() ` with an empty list to delete all messages, when it goes out of scope. + +As with other pytest plugins you have to enable this library in your ``conftest.py``: + +.. code-block:: python + + pytest_plugins = ["mailpit.testing.pytest"] + + +Now it is possible to use the fixture: + +.. code-block:: python + + def test_example(mailpit_api): + mailpit_api.get_messages([]) + + +The fixture has got a default of ``http://localhost:8025``. +In order to pass the api url to this fixture, you have to parametrize your test function with the ``indirect`` parameter set to ``True``. + +.. code-block:: python + + import pytest + + api_url = "localhost:8025" + + @pytest.mark.parametrize("mailpit_api", [api_url], indirect=True) + def test_example(mailpit_api): + mailpit_api.get_messages([]) + + + diff --git a/docs/testing/testing.rst b/docs/testing/testing.rst new file mode 100644 index 0000000..0ae0c54 --- /dev/null +++ b/docs/testing/testing.rst @@ -0,0 +1,11 @@ +======= +Testing +======= +To make testing easier there are test-helpers inside the :py:mod:`mailpit.testing` package. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + unittest + pytest \ No newline at end of file diff --git a/docs/testing/unittest.rst b/docs/testing/unittest.rst new file mode 100644 index 0000000..bc3a07b --- /dev/null +++ b/docs/testing/unittest.rst @@ -0,0 +1,97 @@ +======== +unittest +======== +In order to provide some convenience a test-case class has been created with the name :py:class:`~mailpit.testing.unittest.EMailTestCase` deriving from :py:class:`unittest.TestCase`, which is meant to be inherited from, as you would do from :py:class:`~unittest.TestCase`: + +.. code-block:: python + + from mailpit.testing.unittest import EMailTestCase + + class MyTest(EMailTestCase): + + def test_send_message(self): + ... + +The class adds a few methods and attributes, so that you are able to assert, if your message has been sent, or if two messages are equal. + +---------- +Attributes +---------- + +_______ +api_url +_______ +If your Mailpit ist not running on ``localhost:8025``, you can set the classattribute :py:attr:`~mailpit.testing.unittest.EmailTestCase.api_url` to a different URL: + +.. code-block:: python + + from mailpit.testing.unittest import EMailTestCase + + class MyTest(EMailTestCase): + + api_url = "http://my.mailpit.example:8080" + + def test_send_message(self): + ... + + +___ +api +___ + +Classes inherited from :py:class:`~mailpit.testing.unittest.EMailTestCase` will connect to the Mailpit-API automatically on creation. +They will provide you with the :py:attr:`~mailpit.testing.unittest.EmailTestCase.api` attribute, which is an instance of :py:class:`~mailpit.client.api.API`: + +.. code-block:: python + + from mailpit.testing.unittest import EMailTestCase + + class MyTest(EMailTestCase): + + def test_send_message(self): + messages = self.api.get_messages([]) + ... + +------------------------- +Assert messages are equal +------------------------- +In order to check, whether two E-Mail messages are equal you can use :py:meth:`~mailpit.testing.unittest.EmailTestCase.assertMessageEqual` + +.. code-block:: python + + from mailpit.testing.unittest import EMailTestCase + + class MyTest(EMailTestCase): + + def test_messages_equal(self): + message1 = self.api.get_message("MessageID1") + message2 = self.api.get.message("MessageID2") + + self.assertMessageEqual(message1, message2) + +-------------------------------- +Assert message has been received +-------------------------------- +In order to check, whether an E-Mail message has been received by Mailpit, you can use + :py:meth:~mailpit.testing.unittest.EmailTestCase.assertMessageReceived` + +.. code-block:: python + + import email + import smtplib + from mailpit.testing.unittest import EMailTestCase + + class MyTest(EMailTestCase): + + def test_messages_received(self): + smtp_server = smtplib.SMTP("localhost", 1025) + with open(f"tests/mail/email_without_attachment.eml") as fp: + mail = email.message_from_file(fp) + smtp_server.send_message( + mail, + from_addr="Sender Smith ", + to_addrs="Recipient Ross ", + ) + self.assertMessageReceived( + "20220727034441.7za34h6ljuzfpmj6@localhost.localhost" + ) diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..8e8e53f --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,32 @@ +===== +Usage +===== +this library - as is Mailpit - is mostly meant for testing. Giving the url of Mailpit to a tool to send e-mail messages to and then use this client to check on the API if the mail was sent. + +------ +Client +------ + +The client itself consists of the class :py:class:`mailpit.client.api.API`, that offers methods, which query the API-Endpoints and are named respectively. +To use this class, simply try something like this. +You have to have Mailpit running on localhost for this [1]_ . + +.. code-block:: python + + import mailpit.client.api + api = mailpit.client.api.API("localhost:8025") + messages = api.get_messages() + +Additionally, there are some model-classes that wrap the API's responses. +For example with + +.. code-block:: python + + messages = api.get_messages() + +messages will be an instance of :py:class:`mailpit.client.models.Messages`. +The model-classes' attributes are named the same as Mailpit's responses, as documented in the API's `README.md `_, but as is convention in Python in Snakecase. + +For examples have a look at the link:tests[tests] + +.. [1] If you have it running differently, you have to adjust the URL you pass. \ No newline at end of file diff --git a/mailpit/client/models.py b/mailpit/client/models.py index 425a439..429abe2 100644 --- a/mailpit/client/models.py +++ b/mailpit/client/models.py @@ -1,3 +1,6 @@ +"""Definitions of model classes, that wrap Mailpit's API data-structures. Defined with +:py:mod:`dataclasses` and :py:mod:`dataclasses_json`, in order to use them as json over +the API and be used as objects in the Python domain.""" import dataclasses as _dc import datetime as _dt import decimal as _d @@ -16,15 +19,15 @@ @_dj.dataclass_json @_dc.dataclass(init=True) class Contact: - """ - class representing a mail contact splitting 'Test User into - its name and address parts - """ + """Represents a mail contact splitting 'Test User into + its name and address parts""" # pylint: disable=too-few-public-methods name: str = _dc.field(init=True, metadata=_dj.config(field_name="Name")) + """Contact's Name""" address: str = _dc.field(init=True, metadata=_dj.config(field_name="Address")) + """Contact's E-Mail address""" def __lt__(self, other): return f"{other.name} {other.address}".__lt__(f"{self.name} {self.address}") @@ -35,19 +38,21 @@ def __hash__(self): @_dc.dataclass(init=True) class Attachment(_dj.DataClassJsonMixin): - """ - class representing an attachment of a message - """ + """Represents an attachment of a :py:class:`Message`""" # pylint: disable=too-few-public-methods part_id: str = _dc.field(init=True, metadata=_dj.config(field_name="PartID")) + """Attachment's part ID""" file_name: str = _dc.field(init=True, metadata=_dj.config(field_name="FileName")) + """Attachment's file name""" content_type: str = _dc.field( init=True, metadata=_dj.config(field_name="ContentType") ) + """Attachment's MIME content-type""" content_id: str = _dc.field(init=True, metadata=_dj.config(field_name="ContentID")) size: int = _dc.field(init=True, metadata=_dj.config(field_name="Size")) + """Attachment's size in bytes""" def __lt__(self, other: "Attachment"): return ( @@ -67,37 +72,35 @@ def __hash__(self): @_dc.dataclass(init=True) class Message(_dj.DataClassJsonMixin): - """ - class representing a Message returned by the message-endpoint - """ + """Represents a message returned by the message-endpoint""" # pylint: disable=too-many-instance-attributes # pylint: disable=too-few-public-methods # pylint: disable=invalid-name id: str = _dc.field(init=True, metadata=_dj.config(field_name="ID")) - """The message's database ID, of Mailpit's message-database""" + """Message's database ID, of Mailpit's message-database""" message_id: str = _dc.field(init=True, metadata=_dj.config(field_name="MessageID")) - """The message's RFC-5322 message-id""" + """Message's RFC-5322 message-id""" read: bool = _dc.field(init=True, metadata=_dj.config(field_name="Read")) - """always true (message marked read on open)""" + """Always true (message marked read on open)""" from_: Optional[Contact] = _dc.field( init=True, metadata=_dj.config(field_name="From") ) - """The :Contact: the message is from""" + """The :py:class`Contact`: the message is from""" to: list[Contact] = _dc.field(init=True, metadata=_dj.config(field_name="To")) - """Message To-Header, the list of :Contact: the message is addressed to""" + """Message's To-Header, the list of :Contact: the message is addressed to""" cc: Optional[list[Contact]] = _dc.field( init=True, metadata=_dj.config(field_name="Cc") ) - """Message CC-Header, the list of :Contact: that the message is coal-copied to""" + """Message's CC-Header, the list of :Contact: that the message is coal-copied to""" bcc: Optional[list[Contact]] = _dc.field( init=True, metadata=_dj.config(field_name="Bcc") ) - """Message BCC-Header, the list of :Contact:, that the message is blindly + """Message's BCC-Header, the list of :Contact:, that the message is blindly coal-copied to""" subject: str = _dc.field(init=True, metadata=_dj.config(field_name="Subject")) - """Message subject""" + """Message's subject""" date: _dt.date = _dc.field( init=True, metadata=_dj.config( @@ -113,7 +116,7 @@ class representing a Message returned by the message-endpoint html: Optional[str] = _dc.field(init=True, metadata=_dj.config(field_name="HTML")) """HTML MIME part (if exists)""" size: int = _dc.field(init=True, metadata=_dj.config(field_name="Size")) - """Total size of raw email""" + """Total size of raw email in bytes""" inline: list[Attachment] = _dc.field( init=True, metadata=_dj.config(field_name="Inline") ) @@ -254,9 +257,8 @@ def datetime_decoder(isoformat: str) -> _dt.datetime: @_dc.dataclass(init=True) class MessageSummary(_dj.DataClassJsonMixin): - """ - class representing a single message that has been returned by the messages endpoint - """ + """class representing a single message that has been returned by the messages + endpoint""" # pylint: disable=too-many-instance-attributes # pylint: disable=too-few-public-methods @@ -296,9 +298,7 @@ class representing a single message that has been returned by the messages endpo @_dc.dataclass(init=True) class Messages(_dj.DataClassJsonMixin): # pylint: disable=too-few-public-methods - """ - class representing the returns of the messages endpoint - """ + """class representing the returns of the messages endpoint""" total: int = _dc.field(init=True) """Total messages in mailbox""" diff --git a/mailpit/testing/pytest.py b/mailpit/testing/pytest.py index c13a632..525c2a3 100644 --- a/mailpit/testing/pytest.py +++ b/mailpit/testing/pytest.py @@ -1,4 +1,4 @@ -"""Module providing helpers for :py:module:`unittest` kind of testing against the +"""Module providing helpers for :py:mod:`unittest` kind of testing against the Mailpit-API""" try: @@ -7,20 +7,32 @@ _pytest = None if _pytest: + import pathlib as _pathlib + import os as _os import mailpit.client.api as _api - import mailpit.client.models as _models @_pytest.fixture(scope="session") def mailpit_api(request): - """fixture creating a connection to the mailpit API. This fixture is meant to be - called parametrized, in order to pass the url for which an - :py:class:`mailpit.client.api.API` instance is created and yielded""" - client_api = _api.API(request.param) + """:py:func:`pytest.fixture` creating a connection to the mailpit API. + This fixture has got a default of ``http://localhost:8025`` but it is possible + to be called `parametrized `_ with the parameter + ``indirect`` set to ``True``, in order to pass the url for which an + :py:class:`mailpit.client.api.API` instance is created and yielded. + The fixture has got a scope of ``session`` and it will call + :py:meth:`API.delete_messages() ` + with an empty list to delete all messages, when it goes out of scope.""" + try: + client_api = _api.API(request.param) + except AttributeError: + if _pathlib.Path(_os.environ["HOME"]).is_relative_to( + _pathlib.Path("/tmp/pytest-of-root") + ): + client_api = _api.API("http://mailpit:8025") + else: + client_api = _api.API("http://localhost:8025") yield client_api messages = client_api.get_messages() client_api.delete_messages([message.id for message in messages.messages]) - - def assert_message_equal(first: _models.Message, second: _models.Message): - assert first == second diff --git a/mailpit/testing/unittest.py b/mailpit/testing/unittest.py index 0dce9cf..17b4911 100644 --- a/mailpit/testing/unittest.py +++ b/mailpit/testing/unittest.py @@ -1,4 +1,4 @@ -"""Module providing helpers for :py:module:`unittest` kind of testing against the +"""Provides helpers for :py:mod:`unittest` kind of testing against the Mailpit-API""" from typing import Optional import unittest as _unittest @@ -8,7 +8,7 @@ class EMailTestCase(_unittest.TestCase): - """:py:class:`unittest.TestCase` derived class with added test-helper methods and + """:py:class:`unittest.TestCase`-derived class with added test-helper methods and attributes, in order to test against the Mailpit-API. Simply derive from this class, as you would from :py:class:`unittest.TestCase` and write your tests as you are used to. @@ -19,8 +19,8 @@ class EMailTestCase(_unittest.TestCase): class ExampleTestCase(EMailTestCase): def test_api_object(self): - messages: mailpit.client.models.Messages = self.api.get_messages() - self.assertEqual(0, len(messages.messages)) + messages: mailpit.client.models.Messages = self.api.get_messages() + self.assertEqual(0, len(messages.messages)) """ api_url: str = "http://localhost:8025" diff --git a/pyproject.toml b/pyproject.toml index 84c0381..73eaf40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,8 +22,6 @@ classifiers = [ "Topic :: Utilities", ] - - dependencies = [ "dataclasses_json", "httpx", @@ -32,7 +30,6 @@ dependencies = [ "logging518 >= 1.0.0", ] - [project.optional-dependencies] docs = [ "sphinx", diff --git a/tests/integration/test_testing_pytest.py b/tests/integration/test_testing_pytest.py index 05f15c9..33e1eb8 100644 --- a/tests/integration/test_testing_pytest.py +++ b/tests/integration/test_testing_pytest.py @@ -17,3 +17,20 @@ def test_api(mailpit_api): ) result = pytester.runpytest() result.assert_outcomes(passed=1) + + +def test_pytest_helpers_default_api_url(pytester): + pytester.makeconftest("""pytest_plugins = ["mailpit.testing.pytest"]""") + pytester.makepyfile( + """import os as _os +import pathlib as _pathlib + +def test_api(mailpit_api): + if _pathlib.Path(_os.environ["HOME"]).is_relative_to(_pathlib.Path("/tmp/pytest-of-root")): + assert mailpit_api.mailpit_url == "http://mailpit:8025" + else: + assert mailpit_api.mailpit_url == "http://localhost:8025" +""" + ) + result = pytester.runpytest() + result.assert_outcomes(passed=1)