diff options
| -rw-r--r-- | pydis_site/apps/api/tests/test_github_utils.py | 7 | ||||
| -rw-r--r-- | pydis_site/apps/content/tests/test_utils.py | 132 | ||||
| -rw-r--r-- | pydis_site/apps/content/tests/test_views.py | 36 | ||||
| -rw-r--r-- | pydis_site/apps/content/utils.py | 2 | 
4 files changed, 148 insertions, 29 deletions
| diff --git a/pydis_site/apps/api/tests/test_github_utils.py b/pydis_site/apps/api/tests/test_github_utils.py index f642f689..6e25bc80 100644 --- a/pydis_site/apps/api/tests/test_github_utils.py +++ b/pydis_site/apps/api/tests/test_github_utils.py @@ -11,6 +11,7 @@ import rest_framework.response  import rest_framework.test  from django.urls import reverse +from pydis_site import settings  from .. import github_utils @@ -49,7 +50,7 @@ class CheckRunTests(unittest.TestCase):          "head_sha": "sha",          "status": "completed",          "conclusion": "success", -        "created_at": datetime.datetime.utcnow().strftime(github_utils.ISO_FORMAT_STRING), +        "created_at": datetime.datetime.utcnow().strftime(settings.GITHUB_TIMESTAMP_FORMAT),          "artifacts_url": "url",      } @@ -74,7 +75,7 @@ class CheckRunTests(unittest.TestCase):          # to guarantee the right conclusion          kwargs["created_at"] = (              datetime.datetime.utcnow() - github_utils.MAX_RUN_TIME - datetime.timedelta(minutes=10) -        ).strftime(github_utils.ISO_FORMAT_STRING) +        ).strftime(settings.GITHUB_TIMESTAMP_FORMAT)          with self.assertRaises(github_utils.RunTimeoutError):              github_utils.check_run_status(github_utils.WorkflowRun(**kwargs)) @@ -178,7 +179,7 @@ class ArtifactFetcherTests(unittest.TestCase):                  run = github_utils.WorkflowRun(                      name="action_name",                      head_sha="action_sha", -                    created_at=datetime.datetime.now().strftime(github_utils.ISO_FORMAT_STRING), +                    created_at=datetime.datetime.now().strftime(settings.GITHUB_TIMESTAMP_FORMAT),                      status="completed",                      conclusion="success",                      artifacts_url="artifacts_url" diff --git a/pydis_site/apps/content/tests/test_utils.py b/pydis_site/apps/content/tests/test_utils.py index 556f633c..2ef033e4 100644 --- a/pydis_site/apps/content/tests/test_utils.py +++ b/pydis_site/apps/content/tests/test_utils.py @@ -1,3 +1,5 @@ +import datetime +import json  import tarfile  import tempfile  import textwrap @@ -15,6 +17,18 @@ from pydis_site.apps.content.tests.helpers import (      BASE_PATH, MockPagesTestCase, PARSED_CATEGORY_INFO, PARSED_HTML, PARSED_METADATA  ) +_time = datetime.datetime(2022, 10, 10, 10, 10, 10, tzinfo=datetime.timezone.utc) +_time_str = _time.strftime(settings.GITHUB_TIMESTAMP_FORMAT) +TEST_COMMIT_KWARGS = { +    "sha": "123", +    "message": "Hello world\n\nThis is a commit message", +    "date": _time, +    "author": json.dumps([ +        {"name": "Author 1", "email": "[email protected]", "date": _time_str}, +        {"name": "Author 2", "email": "[email protected]", "date": _time_str}, +    ]), +} +  class GetCategoryTests(MockPagesTestCase):      """Tests for the get_category function.""" @@ -109,6 +123,10 @@ class GetPageTests(MockPagesTestCase):  class TagUtilsTests(TestCase):      """Tests for the tag-related utilities.""" +    def setUp(self) -> None: +        super().setUp() +        self.commit = models.Commit.objects.create(**TEST_COMMIT_KWARGS) +      @mock.patch.object(utils, "fetch_tags")      def test_static_fetch(self, fetch_mock: mock.Mock):          """Test that the static fetch function is only called at most once during static builds.""" @@ -121,9 +139,27 @@ class TagUtilsTests(TestCase):          self.assertEqual(tags, result)          self.assertEqual(tags, second_result) -    @mock.patch("httpx.get") +    @mock.patch("httpx.Client.get")      def test_mocked_fetch(self, get_mock: mock.Mock):          """Test that proper data is returned from fetch, but with a mocked API response.""" +        fake_request = httpx.Request("GET", "https://google.com") + +        # Metadata requests +        returns = [httpx.Response( +            request=fake_request, +            status_code=200, +            json=[ +                {"type": "file", "name": "first_tag.md", "sha": "123"}, +                {"type": "file", "name": "second_tag.md", "sha": "456"}, +                {"type": "dir", "name": "some_group", "sha": "789", "url": "/some_group"}, +            ] +        ), httpx.Response( +            request=fake_request, +            status_code=200, +            json=[{"type": "file", "name": "grouped_tag.md", "sha": "789123"}] +        )] + +        # Main content request          bodies = (              "This is the first tag!",              textwrap.dedent(""" @@ -156,33 +192,36 @@ class TagUtilsTests(TestCase):                  body = (tar_folder / "temp.tar").read_bytes() -        get_mock.return_value = httpx.Response( +        returns.append(httpx.Response(              status_code=200,              content=body, -            request=httpx.Request("GET", "https://google.com"), -        ) +            request=fake_request, +        )) +        get_mock.side_effect = returns          result = utils.fetch_tags()          def sort(_tag: models.Tag) -> str:              return _tag.name          self.assertEqual(sorted([ -            models.Tag(name="first_tag", body=bodies[0]), -            models.Tag(name="second_tag", body=bodies[1]), -            models.Tag(name="grouped_tag", body=bodies[2], group=group_folder.name), +            models.Tag(name="first_tag", body=bodies[0], sha="123"), +            models.Tag(name="second_tag", body=bodies[1], sha="245"), +            models.Tag(name="grouped_tag", body=bodies[2], group=group_folder.name, sha="789123"),          ], key=sort), sorted(result, key=sort))      def test_get_real_tag(self):          """Test that a single tag is returned if it exists.""" -        tag = models.Tag.objects.create(name="real-tag") +        tag = models.Tag.objects.create(name="real-tag", last_commit=self.commit)          result = utils.get_tag("real-tag")          self.assertEqual(tag, result)      def test_get_grouped_tag(self):          """Test fetching a tag from a group.""" -        tag = models.Tag.objects.create(name="real-tag", group="real-group") +        tag = models.Tag.objects.create( +            name="real-tag", group="real-group", last_commit=self.commit +        )          result = utils.get_tag("real-group/real-tag")          self.assertEqual(tag, result) @@ -269,3 +308,78 @@ class TagUtilsTests(TestCase):              tag = models.Tag(**options)              with self.subTest(tag=tag):                  self.assertEqual(url, tag.url) + +    @mock.patch("httpx.Client.get") +    def test_get_tag_commit(self, get_mock: mock.Mock): +        """Test the get commit function with a normal tag.""" +        tag = models.Tag.objects.create(name="example") + +        authors = json.loads(self.commit.author) + +        get_mock.return_value = httpx.Response( +            request=httpx.Request("GET", "https://google.com"), +            status_code=200, +            json=[{ +                "sha": self.commit.sha, +                "commit": { +                    "message": self.commit.message, +                    "author": authors[0], +                    "committer": authors[1], +                } +            }] +        ) + +        result = utils.get_tag(tag.name) +        self.assertEqual(tag, result) + +        get_mock.assert_called_once() +        call_params = get_mock.call_args[1]["params"] + +        self.assertEqual({"path": "/bot/resources/tags/example.md"}, call_params) +        self.assertEqual(self.commit, models.Tag.objects.get(name=tag.name).last_commit) + +    @mock.patch("httpx.Client.get") +    def test_get_group_tag_commit(self, get_mock: mock.Mock): +        """Test the get commit function with a group tag.""" +        tag = models.Tag.objects.create(name="example", group="group-name") + +        authors = json.loads(self.commit.author) +        authors.pop() +        self.commit.author = json.dumps(authors) +        self.commit.save() + +        get_mock.return_value = httpx.Response( +            request=httpx.Request("GET", "https://google.com"), +            status_code=200, +            json=[{ +                "sha": self.commit.sha, +                "commit": { +                    "message": self.commit.message, +                    "author": authors[0], +                    "committer": authors[0], +                } +            }] +        ) + +        utils.set_tag_commit(tag) + +        get_mock.assert_called_once() +        call_params = get_mock.call_args[1]["params"] + +        self.assertEqual({"path": "/bot/resources/tags/group-name/example.md"}, call_params) +        self.assertEqual(self.commit, models.Tag.objects.get(name=tag.name).last_commit) + +    @mock.patch.object(utils, "set_tag_commit") +    def test_exiting_commit(self, set_commit_mock: mock.Mock): +        """Test that a commit is saved when the data has not changed.""" +        tag = models.Tag.objects.create(name="tag-name", body="old body", last_commit=self.commit) + +        # This is only applied to the object, not to the database +        tag.last_commit = None + +        utils.record_tags([tag]) +        self.assertEqual(self.commit, tag.last_commit) + +        result = utils.get_tag("tag-name") +        self.assertEqual(tag, result) +        set_commit_mock.assert_not_called() diff --git a/pydis_site/apps/content/tests/test_views.py b/pydis_site/apps/content/tests/test_views.py index c5c25be4..658ac2cc 100644 --- a/pydis_site/apps/content/tests/test_views.py +++ b/pydis_site/apps/content/tests/test_views.py @@ -8,10 +8,11 @@ from django.http import Http404  from django.test import RequestFactory, SimpleTestCase, override_settings  from django.urls import reverse -from pydis_site.apps.content.models import Tag +from pydis_site.apps.content.models import Commit, Tag  from pydis_site.apps.content.tests.helpers import (      BASE_PATH, MockPagesTestCase, PARSED_CATEGORY_INFO, PARSED_HTML, PARSED_METADATA  ) +from pydis_site.apps.content.tests.test_utils import TEST_COMMIT_KWARGS  from pydis_site.apps.content.views import PageOrCategoryView @@ -193,11 +194,12 @@ class TagViewTests(django.test.TestCase):      def setUp(self):          """Set test helpers, then set up fake filesystem."""          super().setUp() +        self.commit = Commit.objects.create(**TEST_COMMIT_KWARGS)      def test_routing(self):          """Test that the correct template is returned for each route.""" -        Tag.objects.create(name="example") -        Tag.objects.create(name="grouped-tag", group="group-name") +        Tag.objects.create(name="example", last_commit=self.commit) +        Tag.objects.create(name="grouped-tag", group="group-name", last_commit=self.commit)          cases = [              ("/pages/tags/example/", "content/tag.html"), @@ -213,7 +215,7 @@ class TagViewTests(django.test.TestCase):      def test_valid_tag_returns_200(self):          """Test that a page is returned for a valid tag.""" -        Tag.objects.create(name="example", body="This is the tag body.") +        Tag.objects.create(name="example", body="This is the tag body.", last_commit=self.commit)          response = self.client.get("/pages/tags/example/")          self.assertEqual(200, response.status_code)          self.assertIn("This is the tag body", response.content.decode("utf-8")) @@ -233,7 +235,7 @@ class TagViewTests(django.test.TestCase):          Tag content here.          """) -        tag = Tag.objects.create(name="example", body=body) +        tag = Tag.objects.create(name="example", body=body, last_commit=self.commit)          response = self.client.get("/pages/tags/example/")          expected = {              "page_title": "example", @@ -256,7 +258,9 @@ class TagViewTests(django.test.TestCase):          The only difference between this and a regular tag are the breadcrumbs,          so only those are checked.          """ -        Tag.objects.create(name="example", body="Body text", group="group-name") +        Tag.objects.create( +            name="example", body="Body text", group="group-name", last_commit=self.commit +        )          response = self.client.get("/pages/tags/group-name/example/")          self.assertListEqual([              {"name": "Pages", "path": "."}, @@ -266,9 +270,9 @@ class TagViewTests(django.test.TestCase):      def test_group_page(self):          """Test rendering of a group's root page.""" -        Tag.objects.create(name="tag-1", body="Body 1", group="group-name") -        Tag.objects.create(name="tag-2", body="Body 2", group="group-name") -        Tag.objects.create(name="not-included") +        Tag.objects.create(name="tag-1", body="Body 1", group="group-name", last_commit=self.commit) +        Tag.objects.create(name="tag-2", body="Body 2", group="group-name", last_commit=self.commit) +        Tag.objects.create(name="not-included", last_commit=self.commit)          response = self.client.get("/pages/tags/group-name/")          content = response.content.decode("utf-8") @@ -298,7 +302,7 @@ class TagViewTests(django.test.TestCase):          **This text is in bold**          """) -        Tag.objects.create(name="example", body=body) +        Tag.objects.create(name="example", body=body, last_commit=self.commit)          response = self.client.get("/pages/tags/example/")          content = response.content.decode("utf-8") @@ -317,7 +321,7 @@ class TagViewTests(django.test.TestCase):          Tag body.          """) -        Tag.objects.create(name="example", body=body) +        Tag.objects.create(name="example", body=body, last_commit=self.commit)          response = self.client.get("/pages/tags/example/")          content = response.content.decode("utf-8") @@ -333,7 +337,7 @@ class TagViewTests(django.test.TestCase):          ---          """) -        Tag.objects.create(name="example", body=body) +        Tag.objects.create(name="example", body=body, last_commit=self.commit)          response = self.client.get("/pages/tags/example/")          self.assertEqual(              "Embed title", @@ -345,7 +349,7 @@ class TagViewTests(django.test.TestCase):          """Test hyperlinking of tags works as intended."""          filler_before, filler_after = "empty filler text\n\n", "more\nfiller"          body = filler_before + "`!tags return`" + filler_after -        Tag.objects.create(name="example", body=body) +        Tag.objects.create(name="example", body=body, last_commit=self.commit)          other_url = reverse("content:tag", kwargs={"location": "return"})          response = self.client.get("/pages/tags/example/") @@ -356,9 +360,9 @@ class TagViewTests(django.test.TestCase):      def test_tag_root_page(self):          """Test the root tag page which lists all tags.""" -        Tag.objects.create(name="tag-1") -        Tag.objects.create(name="tag-2") -        Tag.objects.create(name="tag-3") +        Tag.objects.create(name="tag-1", last_commit=self.commit) +        Tag.objects.create(name="tag-2", last_commit=self.commit) +        Tag.objects.create(name="tag-3", last_commit=self.commit)          response = self.client.get("/pages/tags/")          content = response.content.decode("utf-8") diff --git a/pydis_site/apps/content/utils.py b/pydis_site/apps/content/utils.py index e4a24a73..63f1c41c 100644 --- a/pydis_site/apps/content/utils.py +++ b/pydis_site/apps/content/utils.py @@ -130,7 +130,7 @@ def fetch_tags() -> list[Tag]:  def set_tag_commit(tag: Tag) -> None:      """Fetch commit information from the API, and save it for the tag.""" -    if settings.STATIC_BUILD: +    if settings.STATIC_BUILD:  # pragma: no cover          # Static builds request every page during build, which can ratelimit it.          # Instead, we return some fake data.          tag.last_commit = Commit( | 
