diff --git a/tests/unit/packaging/test_models.py b/tests/unit/packaging/test_models.py index d3c12f3c67bd..7d41812d6f07 100644 --- a/tests/unit/packaging/test_models.py +++ b/tests/unit/packaging/test_models.py @@ -652,6 +652,47 @@ def test_urls(self, db_session, home_page, download_url, project_urls, expected) # TODO: It'd be nice to test for the actual ordering here. assert dict(release.urls) == dict(expected) + @pytest.mark.parametrize( + "release_urls", + [ + [ + ("Issues", "https://github.com/org/user/issues", True), + ("Source", "https://github.com/org/user", True), + ("Homepage", "https://example.com/", False), + ("Download", "https://example.com/", False), + ], + [ + ("Issues", "https://github.com/org/user/issues", True), + ("Source", "https://github.com/org/user", True), + ("Homepage", "https://homepage.com/", False), + ("Download", "https://download.com/", False), + ], + [ + ("Issues", "https://github.com/org/user/issues", True), + ("Source", "https://github.com/org/user", True), + ("Homepage", "https://homepage.com/", True), + ("Download", "https://download.com/", True), + ], + ], + ) + def test_urls_by_verify_status(self, db_session, release_urls): + release = DBReleaseFactory.create( + home_page="https://homepage.com", download_url="https://download.com" + ) + for label, url, verified in release_urls: + db_session.add( + ReleaseURL( + release=release, + name=label, + url=url, + verified=verified, + ) + ) + + for verified_status in [True, False]: + for label, url in release.urls_by_verify_status(verified_status).items(): + assert (label, url, verified_status) in release_urls + def test_acl(self, db_session): project = DBProjectFactory.create() owner1 = DBRoleFactory.create(project=project) diff --git a/warehouse/locale/messages.pot b/warehouse/locale/messages.pot index 8caab0d66b48..2fd5de005c91 100644 --- a/warehouse/locale/messages.pot +++ b/warehouse/locale/messages.pot @@ -2812,66 +2812,67 @@ msgstr "" msgid "Avatar for {username} from gravatar.com" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:49 -msgid "Unverified details" +#: warehouse/templates/includes/packaging/project-data.html:47 +#: warehouse/templates/includes/packaging/project-data.html:67 +msgid "Project links" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:52 -msgid "Project links" +#: warehouse/templates/includes/packaging/project-data.html:64 +msgid "Unverified details" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:67 +#: warehouse/templates/includes/packaging/project-data.html:82 msgid "GitHub Statistics" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:74 +#: warehouse/templates/includes/packaging/project-data.html:89 msgid "Stars:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:82 +#: warehouse/templates/includes/packaging/project-data.html:97 msgid "Forks:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:90 +#: warehouse/templates/includes/packaging/project-data.html:105 msgid "Open issues:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:98 +#: warehouse/templates/includes/packaging/project-data.html:113 msgid "Open PRs:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:108 +#: warehouse/templates/includes/packaging/project-data.html:123 msgid "Meta" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:110 +#: warehouse/templates/includes/packaging/project-data.html:125 msgid "License:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:113 -#: warehouse/templates/includes/packaging/project-data.html:115 +#: warehouse/templates/includes/packaging/project-data.html:128 +#: warehouse/templates/includes/packaging/project-data.html:130 msgid "Author:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:118 -#: warehouse/templates/includes/packaging/project-data.html:120 +#: warehouse/templates/includes/packaging/project-data.html:133 +#: warehouse/templates/includes/packaging/project-data.html:135 #: warehouse/templates/pages/help.html:612 msgid "Maintainer:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:125 +#: warehouse/templates/includes/packaging/project-data.html:140 msgid "Tags" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:135 +#: warehouse/templates/includes/packaging/project-data.html:150 msgid "Requires:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:140 +#: warehouse/templates/includes/packaging/project-data.html:155 msgid "Provides-Extra:" msgstr "" -#: warehouse/templates/includes/packaging/project-data.html:148 +#: warehouse/templates/includes/packaging/project-data.html:163 #: warehouse/templates/pages/classifiers.html:16 #: warehouse/templates/pages/classifiers.html:21 #: warehouse/templates/pages/sitemap.html:39 diff --git a/warehouse/packaging/models.py b/warehouse/packaging/models.py index b0226c293cd5..a33fbd0d09fe 100644 --- a/warehouse/packaging/models.py +++ b/warehouse/packaging/models.py @@ -689,6 +689,21 @@ def urls(self): return _urls + def urls_by_verify_status(self, verified: bool): + matching_urls = { + release_url.url + for release_url in self._project_urls.values() # type: ignore[attr-defined] + if release_url.verified == verified + } + + # Filter the output of `Release.urls`, since it has custom logic to de-duplicate + # release URLs + _urls = OrderedDict() + for name, url in self.urls.items(): + if url in matching_urls: + _urls[name] = url + return _urls + @staticmethod def get_user_name_and_repo_name(urls): for url in urls: diff --git a/warehouse/templates/includes/packaging/project-data.html b/warehouse/templates/includes/packaging/project-data.html index 567eca06a7e7..9986cb3b631b 100644 --- a/warehouse/templates/includes/packaging/project-data.html +++ b/warehouse/templates/includes/packaging/project-data.html @@ -42,16 +42,31 @@