Метод формы clean_field не работает должным образом во время тестирования - PullRequest
1 голос
/ 25 января 2020

У меня есть небольшой проект, где пользователи могут создавать посты. Сообщения не публикуются по умолчанию (например, статус «премодерация»), но если пользователь входит в указанную группу c, его статус сообщения будет автоматически изменен на «опубликован» в приведенной ниже форме.

Это работает как очарование при фактическом использовании. Но когда я решил покрыть эту часть проекта тестами, я обнаружил, что он не работает во время тестов.

Мне нужна помощь. Я полагаю, что что-то упустил и неправильно выполнил тест.

models.py

STATUS_CHOICES = (
    ('pre-moderation', "Pre-moderation"),
    ('published', "Published"),
)


class NewsPost(models.Model):
    """
    Simple NewsPost model
    """

    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='pre-moderation', blank=True)
    body = models.TextField('Body', max_length=500)
    author = models.ForeignKey(
        Profile, on_delete=models.CASCADE, related_name='posts')

forms.py

class NewsPostCreateForm(ModelForm):
    """
    NewsPost form that adds a summernote widget
    """

    class Meta:
        model = NewsPost
        fields = ('body', 'status')
        widgets = {
            'body': SummernoteWidget(),
            'status': HiddenInput(),
        }

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')

        super(NewsPostCreateForm, self).__init__(*args, **kwargs)

    def clean_status(self):
        """
        Change status to published if the user has the required permission
        """
        if self.user.groups.filter(name__in=['editor', 'admin']).exists():
            print('---- this print will be visible in tests ----')
            return 'published'
        if self.instance:
            return self.instance.status
        return None

views.py

class ListAndCreateNewsPost(CreateView):

    template_name = 'newsfeed/templates/list.html'
    form_class = NewsPostCreateForm
    success_url = '/'

    queryset = NewsPost.objects.published

    def get_form_kwargs(self):
        kwargs = super(ListAndCreateNewsPost, self).get_form_kwargs()
        kwargs.update({'user': self.request.user})
        return kwargs

    def get_context_data(self, **kwargs):
        """
        Since you cant directly mix ListView and CreateView,
        doing that by overriding this method and passing it a queryset
        """
        context = super().get_context_data(**kwargs)
        context["objects"] = self.queryset
        return context

    def form_valid(self, form):
        """ Adding user as an author to posts"""
        form.instance.author = self.request.user
        return super().form_valid(form)

tests.py

@pytest.fixture
def user_with_permissions():
    group = Group.objects.get(name='admin') # this group is programmaticaly created in a migration
    user = mixer.blend('profiles.Profile')
    user.groups.set([group])

    return user

@pytest.mark.django_db
def test_newsposts_by_user_with_permissions_are_published(client, user_with_permissions):
    client.force_login(user_with_permissions)
    response = client.post(reverse('list_and_create_newspost'), {'body': 'testing body'}, follow=True)
    print(NewsPost.objects.first().status)

    assert response.status_code == 200
    assert NewsPost.objects.filter(status='published').count() == 1

Консольный вывод

============================================= FAILURES ==============================================
_______________________ test_newsposts_by_user_with_permissions_are_published _______________________

client = <django.test.client.Client object at 0x7fa7e5dbf630>
user_with_permissions = <Profile: johnsanchez>

    @pytest.mark.django_db
    def test_newsposts_by_user_with_permissions_are_published(client, user_with_permissions):
        client.force_login(user_with_permissions)
        response = client.post(reverse('list_and_create_newspost'), {'body': 'testing body'}, follow=True)
        print(NewsPost.objects.first().status)

        assert response.status_code == 200
>       assert NewsPost.objects.filter(status='published').count() == 1
E       AssertionError: assert 0 == 1
E        +  where 0 = <bound method QuerySet.count of <QuerySet []>>()
E        +    where <bound method QuerySet.count of <QuerySet []>> = <QuerySet []>.count
E        +      where <QuerySet []> = <bound method BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method of <newsfeed.models.NewsPostManager object at 0x7fa7e6d0b470>>(status='published')
E        +        where <bound method BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method of <newsfeed.models.NewsPostManager object at 0x7fa7e6d0b470>> = <newsfeed.models.NewsPostManager object at 0x7fa7e6d0b470>.filter
E        +          where <newsfeed.models.NewsPostManager object at 0x7fa7e6d0b470> = NewsPost.objects

newsfeed/tests/tests_newsfeed.py:56: AssertionError
--------------------------------------- Captured stdout call ----------------------------------------
---- this print will be visible in tests ----
pre-moderation

...