Skip to content

Commit 0baddb9

Browse files
add ! mixin for sync in admin
1 parent e10c853 commit 0baddb9

File tree

4 files changed

+27
-33
lines changed

4 files changed

+27
-33
lines changed

src/country_workspace/admin/base.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import TypedDict
12
from admin_extra_buttons.mixins import ExtraButtonsMixin
23
from adminfilters.mixin import AdminAutoCompleteSearchMixin, AdminFiltersMixin
34
from django.contrib import admin, messages
@@ -12,15 +13,19 @@ class BaseModelAdmin(ExtraButtonsMixin, AdminAutoCompleteSearchMixin, AdminFilte
1213
pass
1314

1415

16+
class SyncConfig(TypedDict):
17+
model: type[Model]
18+
step: SyncStep
19+
20+
1521
class SyncAdminMixin:
16-
sync_step: SyncStep = None
17-
sync_model: type[Model] = None
22+
sync_config: SyncConfig
1823

1924
@button()
2025
def sync(self, request: HttpRequest) -> None:
21-
totals = sync_context_programs(step=self.sync_step)
26+
totals = sync_context_programs(step=self.sync_config["step"])
2227
if errors := totals.get("errors"):
2328
self.message_user(request, "; ".join(errors), level=messages.ERROR)
2429
else:
25-
info = totals[self.sync_model._meta.model_name]
30+
info = totals[self.sync_config["model"]._meta.model_name]
2631
self.message_user(request, f"{info['add']} created - {info['upd']} updated", level=messages.SUCCESS)

src/country_workspace/admin/office.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from country_workspace.contrib.hope.sync.context_programs import SyncStep
66

77
from ..models import Office
8-
from .base import BaseModelAdmin, SyncAdminMixin
8+
from .base import BaseModelAdmin, SyncAdminMixin, SyncConfig
99

1010

1111
@admin.register(Office)
@@ -15,8 +15,7 @@ class OfficeAdmin(SyncAdminMixin, BaseModelAdmin):
1515
list_filter = ("active",)
1616
readonly_fields = ("hope_id", "slug")
1717
ordering = ("name",)
18-
sync_step = SyncStep.OFFICES
19-
sync_model = Office
18+
sync_config = SyncConfig(model=Office, step=SyncStep.OFFICES)
2019

2120
@link(change_list=False)
2221
def programmes(self, btn: LinkButton) -> None:

src/country_workspace/admin/program.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from ..cache.manager import cache_manager
1010
from ..compat.admin_extra_buttons import confirm_action
1111
from ..models import Program
12-
from .base import BaseModelAdmin, SyncAdminMixin
12+
from .base import BaseModelAdmin, SyncAdminMixin, SyncConfig
1313
from country_workspace.contrib.hope.sync.context_programs import SyncStep
1414

1515
if TYPE_CHECKING:
@@ -41,9 +41,7 @@ class ProgramAdmin(SyncAdminMixin, BaseModelAdmin):
4141
)
4242
ordering = ("name",)
4343
autocomplete_fields = ("country_office",)
44-
45-
sync_step = SyncStep.PROGRAMS
46-
sync_model = Program
44+
sync_config = SyncConfig(model=Program, step=SyncStep.PROGRAMS)
4745

4846
@button()
4947
def invalidate_cache(self, request: HttpRequest, pk: str) -> None:

tests/admin/test_admin_sync.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,58 +7,47 @@
77

88
from country_workspace.contrib.hope.sync.context_programs import SyncStep
99
from country_workspace.models import Office, Program
10+
from country_workspace.admin.base import SyncConfig
1011

1112
if TYPE_CHECKING:
1213
from django_webtest.pytest_plugin import MixinWithInstanceVariables
1314
from testutils.types import CWTestApp
14-
1515
from country_workspace.models import User
1616

1717

1818
@pytest.fixture
19-
def app(
20-
django_app_factory: "MixinWithInstanceVariables",
21-
admin_user: "User",
22-
) -> "CWTestApp":
19+
def app(django_app_factory: "MixinWithInstanceVariables", admin_user: "User") -> "CWTestApp":
2320
django_app = django_app_factory(csrf_checks=False)
2421
django_app.set_user(admin_user)
2522
return django_app
2623

2724

2825
@pytest.mark.parametrize(
29-
("admin_class", "model_name", "step", "url_name", "sync_result", "message", "level"),
26+
("sync_config", "url_name", "sync_result", "message", "level"),
3027
[
3128
(
32-
"admin.OfficeAdmin",
33-
Office._meta.model_name,
34-
SyncStep.OFFICES,
29+
SyncConfig(model=Office, step=SyncStep.OFFICES),
3530
"country_workspace_office_sync",
3631
{Office._meta.model_name: {"add": 1, "upd": 2}},
3732
"1 created - 2 updated",
3833
messages.SUCCESS,
3934
),
4035
(
41-
"admin.OfficeAdmin",
42-
Office._meta.model_name,
43-
SyncStep.OFFICES,
36+
SyncConfig(model=Office, step=SyncStep.OFFICES),
4437
"country_workspace_office_sync",
4538
{"errors": ["Error 1", "Error 2"], Office._meta.model_name: {"add": 0, "upd": 0}},
4639
"Error 1; Error 2",
4740
messages.ERROR,
4841
),
4942
(
50-
"admin.ProgramAdmin",
51-
Program._meta.model_name,
52-
SyncStep.PROGRAMS,
43+
SyncConfig(model=Program, step=SyncStep.PROGRAMS),
5344
"country_workspace_program_sync",
5445
{Program._meta.model_name: {"add": 1, "upd": 2}},
5546
"1 created - 2 updated",
5647
messages.SUCCESS,
5748
),
5849
(
59-
"admin.ProgramAdmin",
60-
Program._meta.model_name,
61-
SyncStep.PROGRAMS,
50+
SyncConfig(model=Program, step=SyncStep.PROGRAMS),
6251
"country_workspace_program_sync",
6352
{"errors": ["Error 3", "Error 4"], Program._meta.model_name: {"add": 0, "upd": 0}},
6453
"Error 3; Error 4",
@@ -68,11 +57,14 @@ def app(
6857
ids=["office_success", "office_errors", "program_success", "program_errors"],
6958
)
7059
@pytest.mark.xdist_group("remote")
71-
def test_admin_sync(app, mocker: MockerFixture, admin_class, model_name, step, url_name, sync_result, message, level):
72-
mocker.patch(
73-
"country_workspace.contrib.hope.sync.context_programs.sync_context_programs",
60+
def test_admin_sync(app, mocker: MockerFixture, sync_config, url_name, sync_result, message, level):
61+
mock_sync_context_programs = mocker.patch(
62+
"country_workspace.admin.base.sync_context_programs",
7463
return_value=sync_result,
7564
)
76-
mock_message_user = mocker.patch(f"country_workspace.{admin_class}.message_user")
65+
mock_message_user = mocker.patch("country_workspace.admin.base.BaseModelAdmin.message_user")
66+
7767
app.get(reverse(f"admin:{url_name}"))
68+
69+
mock_sync_context_programs.assert_called_once_with(step=sync_config["step"])
7870
mock_message_user.assert_called_once_with(mocker.ANY, message, level=level)

0 commit comments

Comments
 (0)