Django Rest Framework Test: Как обновить отношения? - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть разрешение в Django Rest Framework:

from annoying.functions import get_object_or_None
from django.utils.translation import ugettext_lazy as _
from rest_framework import permissions

from restaurants.models import Restaurant

class TableBelongsToRestaurantPermission(permissions.BasePermission):
    """
    Permission to check if the table belongs to the restaurant in the request. This ensures
    (together with the UserOwnsRestaurantPermission) that owner can change the QR code of a
    restaurant that he doesn't own.
    """
    message = TABLE_BELONGS_TO_RESTAURANT_PERMISSION_DENIED_MESSAGE

    def has_object_permission(self, request, view, obj):
        if not obj.table:
            return True

        slug = request.data.get("restaurant_slug", "")
        restaurant = get_object_or_None(Restaurant, slug=slug)
        if restaurant:
            return restaurant.table_set.filter(id=obj.table.id).exists()

        return False

А теперь я написал тесты для этого:

from unittest import mock

from allauth.account.models import EmailAddress
from django.contrib.auth import get_user_model
from django.test import TestCase

from addresses.models import (Address, City, Country, PostalCode, State,
                              StreetName)
from core.utils import QR_CODE_FUNCTIONS
from employments.models import Employment
from licenses.models import RestaurantLicense
from profiles.models import UserOwnerProfile
from qrcodeproperties.models import QRCodePropertyCheckinUser
from restaurants.models import Restaurant
from tables.models import Table

from ...models import QRCode, QRCodeFunction
from ..permissions import TableBelongsToRestaurantPermission

User = get_user_model()

USER_OWNER_EMAIL = "owner@burgergrill.de"
USER_OWNER_NAME = "Owner"
USER_PASSWORD = "test1234test"
ISO_ALPHA_2_CODE = "DE"
STATE_NAME = "NRW"
CITY_NAME = "Köln"
STREET_NAME = "Burgerstraße"
POSTAL_CODE = "32062"
STREET_NUMBER = "119"
RESTAURANT_NAME = "Burgergrill"
RESTAURANT_SLUG = "burgergrill"
TABLE_NUMBER = 1

OTHER_RESTAURANT_NAME = "Extrablatt"
OTHER_RESTAURANT_SLUG = "extrablatt"


class TableBelongsToRestaurantPermissionTestCase(TestCase):
    def setUp(self):
        self.permission = TableBelongsToRestaurantPermission()
        owner_user = User.objects.create_user(
            email=USER_OWNER_EMAIL,
            name=USER_OWNER_NAME,
            password=USER_PASSWORD
        )
        self.owner_user = owner_user
        owner = UserOwnerProfile.objects.create(user=owner_user)
        owner.save()
        self.owner = owner
        emailaddress = EmailAddress.objects.create(
            user=owner_user,
            email=owner_user.email,
            verified=True,
            primary=True
        )
        emailaddress.save()
        self.emailaddress = emailaddress
        country = Country.objects.create(
            country=ISO_ALPHA_2_CODE
        )
        country.save()
        self.country = country
        state = State.objects.create(
            name=STATE_NAME,
            country=self.country
        )
        state.save()
        self.state = state
        city = City.objects.create(
            name=CITY_NAME,
            country=self.country,
            state=self.state
        )
        city.save()
        self.city = city
        street_name = StreetName.objects.create(
            name=STREET_NAME,
            city=self.city
        )
        street_name.save()
        self.street_name = street_name
        postal_code = PostalCode.objects.create(
            code=POSTAL_CODE,
            city=self.city
        )
        postal_code.save()
        self.postal_code = postal_code
        address = Address.objects.create(
            country=self.country,
            state=self.state,
            city=self.city,
            postal_code=self.postal_code,
            street_name=self.street_name,
            street_number=STREET_NUMBER
        )
        address.save()
        self.address = address
        restaurant = Restaurant.objects.create(
            name=RESTAURANT_NAME,
            address=self.address
        )
        restaurant.save()
        self.restaurant = restaurant
        qr_code = QRCode.objects.create()
        qr_code.save()
        self.qr_code = qr_code

        self.request = mock.MagicMock(
            user=owner_user,
            kwargs={"slug": RESTAURANT_SLUG}
        )
        self.view = mock.MagicMock()

    def test_permissions_table_belongs_to_restaurant_denied_when_table_belongs_to_different_restaurant(self):
        """Test if a user gets permission denied if the qr code's table belongs to another restaurant."""
        restaurant = Restaurant.objects.create(name=OTHER_RESTAURANT_NAME, address=self.address)
        restaurant.save()
        table = Table.objects.create(table_number=TABLE_NUMBER, restaurant=restaurant)
        table.save()
        prev_count = Table.objects.all().count()
        qr_code_function = QRCodeFunction.objects.create(
            qr_code=self.qr_code,
            qr_code_function=QR_CODE_FUNCTIONS.checkin_user
        )
        qr_code_function.save()
        qr_code_property = QRCodePropertyCheckinUser(
            qr_code=self.qr_code,
            table=table,
        )
        qr_code_property.save()

        self.assertFalse(self.permission.has_object_permission(
            request=self.request, view=self.view, obj=self.qr_code
        ))

    def test_permissions_table_belongs_to_restaurant_granted_when_table_belongs_to_same_restaurant(self):
        """Test if a user gets permission granted if the qr code's table belongs to the same restaurant."""
        table = Table.objects.create(table_number=TABLE_NUMBER, restaurant=self.restaurant)
        table.save()
        prev_count = Table.objects.all().count()
        qr_code_function = QRCodeFunction.objects.create(
            qr_code=self.qr_code,
            qr_code_function=QR_CODE_FUNCTIONS.checkin_user
        )
        qr_code_function.save()
        qr_code_property = QRCodePropertyCheckinUser(
            qr_code=self.qr_code,
            table=table,
        )
        qr_code_property.save()
        self.restaurant.refresh_from_db()
        print(table.restaurant == self.restaurant)
        print(self.qr_code.table)
        print(self.restaurant.table_set)

        self.assertTrue(self.permission.has_object_permission(
            request=self.request, view=self.view, obj=self.qr_code
        ))

    def test_permissions_table_belongs_to_restaurant_granted_when_qr_code_without_table(self):
        """Test if a user gets permission granted if the qr code has no table."""
        self.assertTrue(self.permission.has_object_permission(
            request=self.request, view=self.view, obj=self.qr_code
        ))

Проблема в том, что второй тест (test_permissions_table_belongs_to_restaurant_granted_when_table_belongs_to_same_restaurant) не удаетсяОператоры печати выдают True, 1 Pontgrill и tables.Table.None соответственно.Это означает, что по какой-то причине, хотя я сделал .refresh_from_db(), данные для ресторана не обновляются, и тест не пройден, потому что Джанго считает, что нет никаких отношений от Table до Restaurant.

Как можноВы обновляете отношения и исправляете тест?

...