Repository: django/django
File: tests/get_earliest_or_latest/tests.py (Python)

Code before:
            headline="Article 1",
            pub_date=datetime(2005, 7, 26),
            expire_date=datetime(2005, 9, 1),
        )
        check()

    def test_first_last_unordered_qs_aggregation_error(self):
        a1 = Article.objects.create(
            headline="Article 1",
            pub_date=datetime(2005, 7, 26),
            expire_date=datetime(2005, 9, 1),
        )
        Comment.objects.create(article=a1, likes_count=5)

        qs = Comment.objects.values("article").annotate(avg_likes=Avg("likes_count"))
        msg = (
            "Cannot use QuerySet.%s() on an unordered queryset performing aggregation. "
            "Add an ordering with order_by()."
        )
        with self.assertRaisesMessage(TypeError, msg % "first"):
            qs.first()
        with self.assertRaisesMessage(TypeError, msg % "last"):
            qs.last()

    def test_first_last_empty_order_by_deprecation(self):
        a1 = Article.objects.create(
            headline="Article 1",
            pub_date=datetime(2006, 9, 10),
            expire_date=datetime(2056, 9, 11),
        )

        # order_by() without arguments followed by first() triggers a
        # deprecation warning.
        msg_first = (
            "Calling first() after order_by() with no arguments will stop "
            "adding implicit 'pk' ordering in Django 7.0. Pass a field name "
            "to order_by() instead."
        )
        with self.assertWarnsMessage(RemovedInDjango70Warning, msg_first):
            result = Article.objects.order_by().first()
        self.assertEqual(result, a1)

        # order_by() without arguments followed by last() triggers a
        # deprecation warning.
        msg_last = (
            "Calling last() after order_by() with no arguments will stop "
            "adding implicit '-pk' ordering in Django 7.0. Pass a field name "
            "to order_by() instead."
        )
        with self.assertWarnsMessage(RemovedInDjango70Warning, msg_last):
            result = Article.objects.order_by().last()

Review comment (suggestion):
first() and last() returning the same object because only one object exists is a little non-intuitive for me when reading this test.

Code after:
            headline="Article 1",
            pub_date=datetime(2005, 7, 26),
            expire_date=datetime(2005, 9, 1),
        )
        check()

    def test_first_last_unordered_qs_aggregation_error(self):
        a1 = Article.objects.create(
            headline="Article 1",
            pub_date=datetime(2005, 7, 26),
            expire_date=datetime(2005, 9, 1),
        )
        Comment.objects.create(article=a1, likes_count=5)

        qs = Comment.objects.values("article").annotate(avg_likes=Avg("likes_count"))
        msg = (
            "Cannot use QuerySet.%s() on an unordered queryset performing aggregation. "
            "Add an ordering with order_by()."
        )
        with self.assertRaisesMessage(TypeError, msg % "first"):
            qs.first()
        with self.assertRaisesMessage(TypeError, msg % "last"):
            qs.last()

    def test_first_last_empty_order_by_has_no_pk_ordering(self):
        Article.objects.create(
            headline="Article 1",
            pub_date=datetime(2006, 9, 10),
            expire_date=datetime(2056, 9, 11),
        )

        qs = Article.objects.order_by()
        with patch.object(type(qs), "order_by") as mock_order_by:
            qs.first()
            mock_order_by.assert_not_called()
            qs.last()
            mock_order_by.assert_not_called()

    def test_first_last_empty_order_by_clears_default_ordering(self):
        OrderedArticle.objects.create(
            headline="Article 1",
            pub_date=datetime(2006, 9, 10),
        )

        qs = OrderedArticle.objects.order_by()
        with patch.object(type(qs), "order_by") as mock_order_by:
            qs.first()
            mock_order_by.assert_not_called()
            qs.last()
            mock_order_by.assert_not_called()