diff --git a/CHANGES/plugin_api/domain-get-create-serializer-mixin.bugfix b/CHANGES/plugin_api/domain-get-create-serializer-mixin.bugfix new file mode 100644 index 0000000000..43a8c62c84 --- /dev/null +++ b/CHANGES/plugin_api/domain-get-create-serializer-mixin.bugfix @@ -0,0 +1 @@ +Fixed `GetOrCreateSerializerMixin` not accepting pulp_domain for the natural key creation. diff --git a/pulpcore/app/serializers/base.py b/pulpcore/app/serializers/base.py index 446576afbb..fc47468e6d 100644 --- a/pulpcore/app/serializers/base.py +++ b/pulpcore/app/serializers/base.py @@ -386,6 +386,8 @@ def get_or_create(cls, natural_key, default_values=None): if default_values: data.update(default_values) data.update(natural_key) + if "pulp_domain" in natural_key: + del data["pulp_domain"] serializer = cls(data=data) try: serializer.is_valid(raise_exception=True) @@ -402,6 +404,8 @@ def get_or_create(cls, natural_key, default_values=None): # validation failed with 400 'unique' error code only result = cls.Meta.model.objects.get(**natural_key) try: + if "pulp_domain" in natural_key: + serializer.validated_data["pulp_domain"] = natural_key["pulp_domain"] result = result or serializer.create(serializer.validated_data) except IntegrityError: # recover from a race condition, where another thread just created the object diff --git a/pulpcore/tests/unit/serializers/test_base.py b/pulpcore/tests/unit/serializers/test_base.py index f7ae0b8768..54fccf7095 100644 --- a/pulpcore/tests/unit/serializers/test_base.py +++ b/pulpcore/tests/unit/serializers/test_base.py @@ -1,8 +1,15 @@ import pytest +from django.test import TestCase from rest_framework import serializers -from pulpcore.app.serializers import validate_unknown_fields +from pulpcore.app.serializers import ( + validate_unknown_fields, + RBACContentGuardSerializer, + GetOrCreateSerializerMixin, +) +from pulpcore.app.models import RBACContentGuard +from pulpcore.app.util import get_domain def test_unknown_field(): @@ -108,3 +115,28 @@ def test_ignored_fields_no_side_effects(): initial_data = {"field1": 1, "csrfmiddlewaretoken": 2} defined_fields = {"field1": 1} validate_unknown_fields(initial_data, defined_fields) + + +@pytest.fixture +def guard_fixture(db): + return RBACContentGuard.objects.get_or_create(name="test")[0] + + +class GuardSerializer(GetOrCreateSerializerMixin, RBACContentGuardSerializer): + pass + + +def test_mixin_get(guard_fixture): + """Test GetOrCreateSerializerMixin's get functionality.""" + natural_key = {"name": "test", "pulp_domain": get_domain()} + guard = GuardSerializer.get_or_create(natural_key) + assert guard.pk == guard_fixture.pk + + +def test_mixin_create(guard_fixture): + """Test GetOrCreateSerializerMixin's create functionality.'""" + natural_key = {"name": "test2", "pulp_domain": get_domain()} + default_data = {"description": "hello"} + guard = GuardSerializer.get_or_create(natural_key, default_data) + assert guard.pk != guard_fixture.pk + assert guard.description == default_data["description"]