diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3e3e1df..946aa41 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,6 @@ version: 2 -updates: +updates: - package-ecosystem: github-actions directory: / schedule: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 74cf048..6f7ccf4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -14,13 +14,17 @@ jobs: - name: Check out uses: actions/checkout@v3 - - name: Install poetry - run: pipx install poetry + - uses: snok/install-poetry@v1 + with: + version: 1.3.2 + virtualenvs-create: true + virtualenvs-in-project: true - name: Set up Python 3.10 uses: actions/setup-python@v4 with: python-version: "3.10" + cache: poetry - name: Install requirements run: poetry install diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a4414c5..c3d0a0f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,21 +14,8 @@ jobs: - name: Check out uses: actions/checkout@v3 - - name: Set up Python 3.10 - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - - name: Install pre-commit - run: pip install pre-commit - - - name: Cache pre-commit tools - uses: actions/cache@v3 - with: - key: - pre-commit-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ - hashFiles('.pre-commit-config.yaml') }} - path: ~/.cache/pre-commit - - name: Run pre-commit - run: pre-commit run --all-files + uses: pre-commit/action@v3.0.0 + + - uses: pre-commit-ci/lite-action@v1.0.1 + if: always() diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d9e931a..0990cda 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,18 +13,17 @@ jobs: - name: Checkout code uses: actions/checkout@v3 + - uses: snok/install-poetry@v1 + with: + version: 1.3.2 + virtualenvs-create: true + virtualenvs-in-project: true + - name: Set up Python 3.10 uses: actions/setup-python@v4 with: python-version: "3.10" - - - name: Install Poetry - uses: snok/install-poetry@v1 - with: - version: 1.2.2 - virtualenvs-create: true - virtualenvs-in-project: true - installer-parallel: true + cache: poetry - name: Build project run: poetry build diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bdcde73..1bae02b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,17 +13,19 @@ jobs: strategy: fail-fast: false matrix: - # NOTE: https://github.com/jefftriplett/python-github-actions-matrix-demo/ python-version: ["3.8", "3.9", "3.10", "3.11"] django-version: ["3.2", "4.0", "4.1", "4.2a1"] - anymail-version: ["8.4", "8.5", "8.6", "9.0"] + anymail-version: ["8.6", "9.0"] steps: - name: Check out the repository uses: actions/checkout@v3 - - name: Install poetry - run: pipx install poetry + - uses: snok/install-poetry@v1 + with: + version: 1.3.2 + virtualenvs-create: true + virtualenvs-in-project: true - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 @@ -31,6 +33,11 @@ jobs: python-version: ${{ matrix.python-version }} cache: poetry + + - name: Ensure Python version ${{ matrix.python-version }} + # https://github.com/actions/setup-python/issues/425 + run: poetry env use ${{ matrix.python-version }} + - name: Install requirements run: poetry install diff --git a/.github/workflows/upgrade_precommit.yml b/.github/workflows/upgrade_precommit.yml new file mode 100644 index 0000000..679d747 --- /dev/null +++ b/.github/workflows/upgrade_precommit.yml @@ -0,0 +1,26 @@ +name: Pre-commit auto-update + +on: + # every month + schedule: + - cron: "0 0 1 * *" + # on demand + workflow_dispatch: + +jobs: + auto-update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-python@v2 + + - uses: browniebroke/pre-commit-autoupdate-action@main + + - uses: peter-evans/create-pull-request@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: update/pre-commit-hooks + title: Update pre-commit hooks + commit-message: "chore: update pre-commit hooks" + body: Update versions of pre-commit hooks to latest version. diff --git a/README.md b/README.md index b6cc36a..498484f 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,11 @@ -# anymail-history - Email History for Django Anymail +# anymail-history - Email History (database storage) for [Django Anymail](https://anymail.dev/) [![CI tests](https://github.com/pfouque/django-anymail-history/actions/workflows/test.yml/badge.svg)](https://github.com/pfouque/django-anymail-history/actions/workflows/test.yml) - [![codecov](https://codecov.io/github/pfouque/django-anymail-history/branch/master/graph/badge.svg?token=GWGDR6AR6D)](https://codecov.io/github/pfouque/django-anymail-history) - -[![Documentation](https://img.shields.io/static/v1?label=Docs&message=READ&color=informational&style=plastic)](https://anymail-history.github.io/anymail-history/) - +[![Documentation](https://img.shields.io/static/v1?label=Docs&message=READ&color=informational&style=plastic)](https://github.com/pfouque/django-anymail-history#settings) [![MIT License](https://img.shields.io/static/v1?label=License&message=MIT&color=informational&style=plastic)](https://github.com/pfouque/anymail-history/LICENSE) -Keep history of all emails sent by Django Anymail +Keep history of all emails sent by [Django Anymail](https://anymail.dev/) ## Introduction @@ -16,7 +13,6 @@ anymail-history implements database storage for Django Anymail. ## Resources -- Full documentation: SOON - Package on PyPI: [https://pypi.org/project/anymail-history/](https://pypi.org/project/anymail-history/) - Project on Github: [https://github.com/pfouque/django-anymail-history](https://github.com/pfouque/django-anymail-history) @@ -35,11 +31,14 @@ anymail-history implements database storage for Django Anymail. ## How to -1. Install +1. [Install Anymail](https://anymail.dev/en/stable/quickstart/) + +2. Install ``` - $ pip install "django-anymail[mailgun]" "django-anymail-history" + $ pip install "django-anymail-history" ``` -2. [Configure Anymail](https://github.com/anymail/django-anymail/#anymail-1-2-3) + +3. Register anymail_history in your list of Django applications: ``` INSTALLED_APPS = [ # ... @@ -48,11 +47,14 @@ anymail-history implements database storage for Django Anymail. # ... ] ``` -3. Enjoy! +4. Then migrate the app to create the database table + ```manage.py migrate``` + +5. 🎉 Voila! -## settings +## Settings -You can add settings to your project’s settings.py either as a single ANYMAIL dict, or by breaking out individual settings prefixed with ANYMAIL_. So this settings dict: +You can add settings to your project’s settings.py either as a single `ANYMAIL` dict, or by breaking out individual settings prefixed with ANYMAIL_. So this settings dict: ``` ANYMAIL = { @@ -69,7 +71,6 @@ ANYMAIL_STORE_HTML = True - `ANYMAIL_STORE_FAILED_SEND`: (default: False) Store message even if esp didn't returned a message-id. - `ANYMAIL_STORE_HTML`: (default: False) Store html alternatives. -- `ANYMAIL_RENDER_HTML`: (default: True) Generate html alternatives. ## Contribute @@ -133,6 +134,8 @@ $ poetry shell #### CI -There is a `.github/workflows/lint.yml` file that can be used as a baseline to define and ensure coding rules on Github. +- `.github/workflows/lint.yml`: defines and ensure coding rules on Github. + +- `.github/workflows/test.yml`: Runs tests on all compatible combinations of Django (3.2+) & Anymail(8.4+), Python (3.8+)in a Github matrix. -There is a `.github/workflows/test.yml` file that can be used as a baseline to run all of the tests on Github. This file runs the oldest LTS (3.2), newest (4.1), and head of the main Django branch. +- `.github/workflows/coverage.yml`: Calculates the coverage on an up to date version. diff --git a/anymail_history/admin.py b/anymail_history/admin.py index 3659106..de8dafb 100644 --- a/anymail_history/admin.py +++ b/anymail_history/admin.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import Any - from django.contrib import admin from django.http import HttpRequest @@ -9,7 +7,6 @@ class ReadonlyInline(admin.TabularInline): - can_delete = False show_change_link = False extra = 0 @@ -26,7 +23,8 @@ def has_change_permission( class MessageEventInline(ReadonlyInline): model = MessageEvent - readonly_fields = fields = ("event_name", "created_on") + fields = ("event_name", "created_on") + readonly_fields = fields ordering = ["-created_on"] @@ -47,14 +45,9 @@ def has_change_permission( ) -> bool: return False - def get_actions(self, request: HttpRequest) -> dict[str, Any]: - actions = super().get_actions(request) - if "delete_selected" in actions: - del actions["delete_selected"] - return actions - class SentMessageInline(ReadonlyInline): model = SentMessage - readonly_fields = fields = ("message_id", "subject", "status") + fields = ("message_id", "subject", "status") + readonly_fields = fields ordering = ["-created_on"] diff --git a/anymail_history/migrations/0001_initial.py b/anymail_history/migrations/0001_initial.py index b2e454c..75993f5 100644 --- a/anymail_history/migrations/0001_initial.py +++ b/anymail_history/migrations/0001_initial.py @@ -1,16 +1,17 @@ -# Generated by Django 3.2.16 on 2022-12-08 04:45 - -from __future__ import annotations +# Generated by Django 4.1.6 on 2023-02-12 16:46 import django.db.models.deletion import django.utils.timezone +from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] operations = [ migrations.CreateModel( @@ -41,6 +42,14 @@ class Migration(migrations.Migration): ("content_html", models.TextField(editable=False, null=True)), ("status", models.CharField(editable=False, max_length=256)), ("recipient_email", models.EmailField(editable=False, max_length=254)), + ( + "recipient", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.CreateModel( @@ -69,4 +78,34 @@ class Migration(migrations.Migration): ), ], ), + migrations.AddIndex( + model_name="sentmessage", + index=models.Index( + fields=["created_on"], name="anymail_his_created_22d036_idx" + ), + ), + migrations.AddIndex( + model_name="sentmessage", + index=models.Index( + fields=["message_id"], name="anymail_his_message_1731a8_idx" + ), + ), + migrations.AddIndex( + model_name="sentmessage", + index=models.Index( + fields=["recipient_email"], name="anymail_his_recipie_b46581_idx" + ), + ), + migrations.AddIndex( + model_name="messageevent", + index=models.Index( + fields=["created_on"], name="anymail_his_created_04c5bf_idx" + ), + ), + migrations.AddIndex( + model_name="messageevent", + index=models.Index( + fields=["event_name"], name="anymail_his_event_n_63f45f_idx" + ), + ), ] diff --git a/anymail_history/migrations/0002_initial.py b/anymail_history/migrations/0002_initial.py deleted file mode 100644 index c3736a6..0000000 --- a/anymail_history/migrations/0002_initial.py +++ /dev/null @@ -1,58 +0,0 @@ -# Generated by Django 3.2.16 on 2022-12-08 04:45 - -from __future__ import annotations - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - initial = True - - dependencies = [ - ("anymail_history", "0001_initial"), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.AddField( - model_name="sentmessage", - name="recipient", - field=models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to=settings.AUTH_USER_MODEL, - ), - ), - migrations.AddIndex( - model_name="MessageEvent", - index=models.Index( - fields=["created_on"], name="anymail_his_created_01395c_idx" - ), - ), - migrations.AddIndex( - model_name="MessageEvent", - index=models.Index( - fields=["event_name"], name="anymail_his_event_n_e3a465_idx" - ), - ), - migrations.AddIndex( - model_name="sentmessage", - index=models.Index( - fields=["created_on"], name="anymail_his_created_22d036_idx" - ), - ), - migrations.AddIndex( - model_name="sentmessage", - index=models.Index( - fields=["message_id"], name="anymail_his_message_1731a8_idx" - ), - ), - migrations.AddIndex( - model_name="sentmessage", - index=models.Index( - fields=["recipient_email"], name="anymail_his_recipie_b46581_idx" - ), - ), - ] diff --git a/anymail_history/migrations/0003_auto_20221207_2316.py b/anymail_history/migrations/0003_auto_20221207_2316.py deleted file mode 100644 index de4476f..0000000 --- a/anymail_history/migrations/0003_auto_20221207_2316.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.2.16 on 2022-12-08 05:16 - -from __future__ import annotations - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("anymail_history", "0002_initial"), - ] - - operations = [ - migrations.RemoveIndex( - model_name="messageevent", - name="anymail_his_created_01395c_idx", - ), - migrations.RemoveIndex( - model_name="messageevent", - name="anymail_his_event_n_e3a465_idx", - ), - migrations.AddIndex( - model_name="messageevent", - index=models.Index( - fields=["created_on"], name="anymail_his_created_04c5bf_idx" - ), - ), - migrations.AddIndex( - model_name="messageevent", - index=models.Index( - fields=["event_name"], name="anymail_his_event_n_63f45f_idx" - ), - ), - ] diff --git a/poetry.lock b/poetry.lock index 9fec3c2..587a0cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -34,35 +34,6 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope.interface"] tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "black" version = "23.1.0" @@ -343,21 +314,20 @@ files = [ [[package]] name = "django" -version = "4.1.6" -description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +version = "3.2.17" +description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" files = [ - {file = "Django-4.1.6-py3-none-any.whl", hash = "sha256:c6fe7ebe7c017fe59f1029821dae0acb5a2ddcd6c9a0138fd20a8bfefac914bc"}, - {file = "Django-4.1.6.tar.gz", hash = "sha256:bceb0fe1a386781af0788cae4108622756cd05e7775448deec04a71ddf87685d"}, + {file = "Django-3.2.17-py3-none-any.whl", hash = "sha256:59c39fc342b242fb42b6b040ad8b1b4c15df438706c1d970d416d63cdd73e7fd"}, + {file = "Django-3.2.17.tar.gz", hash = "sha256:644288341f06ebe4938eec6801b6bd59a6534a78e4aedde2a153075d11143894"}, ] [package.dependencies] -asgiref = ">=3.5.2,<4" -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} +asgiref = ">=3.3.2,<4" +pytz = "*" sqlparse = ">=0.2.2" -tzdata = {version = "*", markers = "sys_platform == \"win32\""} [package.extras] argon2 = ["argon2-cffi (>=19.1.0)"] @@ -638,14 +608,14 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.0.4" +version = "2.21.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "pre_commit-3.0.4-py2.py3-none-any.whl", hash = "sha256:9e3255edb0c9e7fe9b4f328cb3dc86069f8fdc38026f1bf521018a05eaf4d67b"}, - {file = "pre_commit-3.0.4.tar.gz", hash = "sha256:bc4687478d55578c4ac37272fe96df66f73d9b5cf81be6f28627d4e712e752d5"}, + {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, + {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, ] [package.dependencies] @@ -732,6 +702,18 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "pytz" +version = "2022.7.1" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, + {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, +] + [[package]] name = "pyyaml" version = "6.0" @@ -931,18 +913,6 @@ files = [ {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] -[[package]] -name = "tzdata" -version = "2022.7" -description = "Provider of IANA time zone data" -category = "main" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, - {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, -] - [[package]] name = "urllib3" version = "1.26.14" @@ -984,4 +954,4 @@ test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "9b25ac43f802f93c205e0b479c8afb3ed27897ecc6412e82592c0bd4176db446" +content-hash = "b5f8e46e769fbfcf30da8b3ff42724d5776ffcc7ad38f171c60a952a288bb36e" diff --git a/pyproject.toml b/pyproject.toml index e469e2c..5a1393a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ packages = [{ include = "anymail_history" }] [tool.poetry.dependencies] python = "^3.8" django = "^3.2 || ^4.0 || ^4.1 || ^4.2" -django-anymail = "^8.4 || ^8.5 || ^8.6 || ^9.0" +django-anymail = "^8.6 || ^9.0" [tool.poetry.group.dev.dependencies] black = "*" @@ -108,27 +108,26 @@ unfixable = [ "F401" # unused-import ] -fix = false +fix = true [tool.ruff.mccabe] # Unlike Flake8, default to a complexity level of 10. max-complexity = 10 [tool.mypy] -python_version = "3.8" - plugins = ["mypy_django_plugin.main"] +[[tool.mypy.overrides]] +module = "anymail.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "tests.*" -disallow_untyped_defs = false +allow_untyped_defs = true [tool.django-stubs] django_settings_module = "tests.settings" - [build-system] requires = ["poetry-core> = 1.2.0"] build-backend = "poetry.core.masonry.api" diff --git a/tests/test_admin.py b/tests/test_admin.py index 277a2b8..e813191 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -12,15 +12,14 @@ class TestSentMessageAdmin(TestCase): staff_client: Client - def setUp(self): - super().setUp() - - self.sent_message = SentMessage.objects.create( + @classmethod + def setUpTestData(cls): + cls.sent_message = SentMessage.objects.create( esp_name="ESP_NAME", message_id="12345", ) MessageEvent.objects.create( - sent_message=self.sent_message, + sent_message=cls.sent_message, created_on=timezone.now(), event_name=EventType.SENT, payload={}, @@ -35,8 +34,8 @@ def setUp(self): "is_active": True, }, ) - self.staff_client = Client() - self.staff_client.force_login(user) + cls.staff_client = Client() + cls.staff_client.force_login(user) def test_changelist(self): resp = self.staff_client.get(