Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-labels for openSUSE:Factory checked in at 2022-09-30 17:57:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-labels (Old) and /work/SRC/openSUSE:Factory/.python-labels.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-labels" Fri Sep 30 17:57:54 2022 rev:3 rq:1007075 version:20.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-labels/python-labels.changes 2020-05-26 17:23:38.404532009 +0200 +++ /work/SRC/openSUSE:Factory/.python-labels.new.2275/python-labels.changes 2022-09-30 17:58:13.241303280 +0200 @@ -1,0 +2,7 @@ +Thu Sep 29 14:41:43 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to Version 20.1.0 + * This labels release adds support for paginated responses from the GitHub API on requesting a repository's labels. + This enables users to manage labels for projects that use more than 30 labels. rocket + +------------------------------------------------------------------- Old: ---- labels-0.2.0.tar.gz New: ---- labels-20.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-labels.spec ++++++ --- /var/tmp/diff_new_pack.A8PqX5/_old 2022-09-30 17:58:13.617304084 +0200 +++ /var/tmp/diff_new_pack.A8PqX5/_new 2022-09-30 17:58:13.625304102 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-labels # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-labels -Version: 0.2.0 +Version: 20.1.0 Release: 0 Summary: CLI app for managing GitHub labels License: MIT @@ -34,7 +34,7 @@ Requires: python-pytoml Requires: python-requests Requires(post): update-alternatives -Requires(postun): update-alternatives +Requires(postun):update-alternatives BuildArch: noarch # SECTION test requirements BuildRequires: %{python_module attrs} ++++++ labels-0.2.0.tar.gz -> labels-20.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/CODE_OF_CONDUCT.md new/labels-20.1.0/.github/CODE_OF_CONDUCT.md --- old/labels-0.2.0/.github/CODE_OF_CONDUCT.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/.github/CODE_OF_CONDUCT.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,75 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project -and our community a harassment-free experience for everyone, regardless of -age, body size, disability, ethnicity, gender identity and expression, level -of experience, nationality, personal appearance, race, religion, or sexual -identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of -acceptable behavior and are expected to take appropriate and fair corrective -action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an -appointed representative at an online or offline event. Representation of a -project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at raph...@hackebrot.de. The project -team will review and investigate all complaints, and will respond in a way -that it deems appropriate to the circumstances. The project team is obligated -to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 1.4, available at -[http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/COMMUNITY.md new/labels-20.1.0/.github/COMMUNITY.md --- old/labels-0.2.0/.github/COMMUNITY.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/.github/COMMUNITY.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,13 +0,0 @@ -# Community - -- [@Mariatta] -- [@hackebrot] -- [@mfonism] -- [@michaeljoseph] -- [@tprasadtp] - -[@Mariatta]: https://github.com/Mariatta -[@hackebrot]: https://github.com/hackebrot -[@mfonism]: https://github.com/mfonism -[@michaeljoseph]: https://github.com/michaeljoseph -[@tprasadtp]: https://github.com/tprasadtp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/CONTRIBUTING.md new/labels-20.1.0/.github/CONTRIBUTING.md --- old/labels-0.2.0/.github/CONTRIBUTING.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/.github/CONTRIBUTING.md 2020-05-04 16:55:36.000000000 +0200 @@ -21,5 +21,5 @@ [new issue]: https://github.com/hackebrot/labels/issues/new/choose [new pull request]: https://github.com/hackebrot/labels/compare [pull requests]: https://github.com/hackebrot/labels/pulls -[code of conduct]: /.github/CODE_OF_CONDUCT.md -[community]: /.github/COMMUNITY.md +[code of conduct]: /CODE_OF_CONDUCT.md +[community]: /COMMUNITY.md diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/ISSUE_TEMPLATE/BUG_REPORT.md new/labels-20.1.0/.github/ISSUE_TEMPLATE/BUG_REPORT.md --- old/labels-0.2.0/.github/ISSUE_TEMPLATE/BUG_REPORT.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/.github/ISSUE_TEMPLATE/BUG_REPORT.md 2020-05-04 16:55:36.000000000 +0200 @@ -6,7 +6,7 @@ Please note that **labels** is released with a [Contributor Code of Conduct][code of conduct]. By participating in this project you agree to abide by its terms. -[code of conduct]: /.github/CODE_OF_CONDUCT.md +[code of conduct]: /CODE_OF_CONDUCT.md ## Bug Report diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/ISSUE_TEMPLATE/OTHER.md new/labels-20.1.0/.github/ISSUE_TEMPLATE/OTHER.md --- old/labels-0.2.0/.github/ISSUE_TEMPLATE/OTHER.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/.github/ISSUE_TEMPLATE/OTHER.md 2020-05-04 16:55:36.000000000 +0200 @@ -6,7 +6,7 @@ Please note that **labels** is released with a [Contributor Code of Conduct][code of conduct]. By participating in this project you agree to abide by its terms. -[code of conduct]: /.github/CODE_OF_CONDUCT.md +[code of conduct]: /CODE_OF_CONDUCT.md ## Other diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/PULL_REQUEST_TEMPLATE.md new/labels-20.1.0/.github/PULL_REQUEST_TEMPLATE.md --- old/labels-0.2.0/.github/PULL_REQUEST_TEMPLATE.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/.github/PULL_REQUEST_TEMPLATE.md 2020-05-04 16:55:36.000000000 +0200 @@ -2,5 +2,5 @@ Please note that **labels** is released with a [Contributor Code of Conduct][code of conduct]. By participating in this project you agree to abide by its terms. -[code of conduct]: /.github/CODE_OF_CONDUCT.md +[code of conduct]: /CODE_OF_CONDUCT.md [contributing]: /.github/CONTRIBUTING.md diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/.github/labels.toml new/labels-20.1.0/.github/labels.toml --- old/labels-0.2.0/.github/labels.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/labels-20.1.0/.github/labels.toml 2020-05-04 16:55:36.000000000 +0200 @@ -0,0 +1,49 @@ +[bug] +color = "ffeb95" +name = "bug" +description = "Bugs and problems with labels" + +["code quality"] +color = "c792ea" +name = "code quality" +description = "Tasks related to linting, coding style, type checks" + +[dependencies] +color = "c792ea" +name = "dependencies" +description = "Tasks related to managing dependencies" + +[discussion] +color = "ffeb95" +name = "discussion" +description = "Issues for discussing ideas for features" + +["do not merge"] +color = "ef5350" +name = "do not merge" +description = "Pull requests which must not be merged" + +[docs] +color = "21c7a8" +name = "docs" +description = "Tasks to write and update documentation" + +[enhancement] +color = "82aaff" +name = "enhancement" +description = "New feature or enhancement for labels" + +["good first issue"] +color = "7fdbca" +name = "good first issue" +description = "Good tasks for newcomers to labels" + +[misc] +color = "ecc48d" +name = "misc" +description = "Tasks that don't fit any of the other categories" + +[project] +color = "d6deeb" +name = "project" +description = "Tasks related to managing this project" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/CODE_OF_CONDUCT.md new/labels-20.1.0/CODE_OF_CONDUCT.md --- old/labels-0.2.0/CODE_OF_CONDUCT.md 1970-01-01 01:00:00.000000000 +0100 +++ new/labels-20.1.0/CODE_OF_CONDUCT.md 2020-05-04 16:55:36.000000000 +0200 @@ -0,0 +1,75 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project +and our community a harassment-free experience for everyone, regardless of +age, body size, disability, ethnicity, gender identity and expression, level +of experience, nationality, personal appearance, race, religion, or sexual +identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of +acceptable behavior and are expected to take appropriate and fair corrective +action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an +appointed representative at an online or offline event. Representation of a +project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at raph...@hackebrot.de. The project +team will review and investigate all complaints, and will respond in a way +that it deems appropriate to the circumstances. The project team is obligated +to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +[http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/COMMUNITY.md new/labels-20.1.0/COMMUNITY.md --- old/labels-0.2.0/COMMUNITY.md 1970-01-01 01:00:00.000000000 +0100 +++ new/labels-20.1.0/COMMUNITY.md 2020-05-04 16:55:36.000000000 +0200 @@ -0,0 +1,15 @@ +# Community + +- [@Mariatta] +- [@hackebrot] +- [@jean] +- [@mfonism] +- [@michaeljoseph] +- [@tprasadtp] + +[@Mariatta]: https://github.com/Mariatta +[@hackebrot]: https://github.com/hackebrot +[@jean]: https://github.com/jean +[@mfonism]: https://github.com/mfonism +[@michaeljoseph]: https://github.com/michaeljoseph +[@tprasadtp]: https://github.com/tprasadtp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/MANIFEST.in new/labels-20.1.0/MANIFEST.in --- old/labels-0.2.0/MANIFEST.in 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/MANIFEST.in 2020-05-04 16:55:36.000000000 +0200 @@ -1,5 +1,7 @@ include LICENSE include README.md +include COMMUNITY.md +include CODE_OF_CONDUCT.md recursive-exclude * __pycache__ recursive-exclude * *.py[co] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/README.md new/labels-20.1.0/README.md --- old/labels-0.2.0/README.md 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/README.md 2020-05-04 16:55:36.000000000 +0200 @@ -10,6 +10,8 @@ pip install labels ``` +Versions follow [Calendar Versioning][calver] using a `YY.MINOR.MICRO` scheme. ???? + ## Authentication The labels CLI connects to the GitHub API to modify labels for a GitHub @@ -103,7 +105,6 @@ The section name (``[docs]`` in the example above) represents the name of the label for that repository and is identical to the ``name`` field when running ``labels fetch``. Do not edit the section name of existing labels yourself! -?????? The fields ``color``, ``description`` and ``name`` are parameters that you can edit with the **labels** CLI. @@ -173,7 +174,8 @@ source software. [PyPI]: https://pypi.org/project/labels/ -[code of conduct]: https://github.com/hackebrot/labels/blob/master/.github/CODE_OF_CONDUCT.md +[calver]: https://calver.org +[code of conduct]: https://github.com/hackebrot/labels/blob/master/CODE_OF_CONDUCT.md [contributing]: https://github.com/hackebrot/labels/blob/master/.github/CONTRIBUTING.md [create token]: https://blog.github.com/2013-05-16-personal-api-tokens/ [earth_repo]: https://github.com/hackebrot/earth diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/setup.py new/labels-20.1.0/setup.py --- old/labels-0.2.0/setup.py 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/setup.py 2020-05-04 16:55:36.000000000 +0200 @@ -9,7 +9,7 @@ setuptools.setup( name="labels", - version="0.2.0", + version="20.1.0", author="Raphael Pierzina", author_email="raph...@hackebrot.de", maintainer="Raphael Pierzina", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/src/labels/__init__.py new/labels-20.1.0/src/labels/__init__.py --- old/labels-0.2.0/src/labels/__init__.py 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/src/labels/__init__.py 2020-05-04 16:55:36.000000000 +0200 @@ -1,4 +1,4 @@ -__version__ = "0.2.0" +__version__ = "20.1.0" __title__ = "labels" __description__ = "CLI app for managing GitHub labels for Python 3.6 and newer. ????" __url__ = "https://github.com/hackebrot/labels" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/src/labels/github.py new/labels-20.1.0/src/labels/github.py --- old/labels-0.2.0/src/labels/github.py 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/src/labels/github.py 2020-05-04 16:55:36.000000000 +0200 @@ -1,5 +1,5 @@ -import typing import logging +from typing import Any, Dict, List, Optional, Tuple import attr import requests @@ -15,7 +15,7 @@ name: str -def not_read_only(attr: attr.Attribute, value: typing.Any) -> bool: +def not_read_only(attr: attr.Attribute, value: Any) -> bool: """Filter for attr that checks for a leading underscore.""" return not attr.name.startswith("_") @@ -35,12 +35,12 @@ _url: str = "" @property - def params_dict(self) -> typing.Dict[str, typing.Any]: + def params_dict(self) -> Dict[str, Any]: """Return label parameters as a dict.""" return attr.asdict(self, recurse=True, filter=not_read_only) @property - def params_tuple(self) -> typing.Tuple[typing.Any, ...]: + def params_tuple(self) -> Tuple[Any, ...]: """Return label parameters as a tuple.""" return attr.astuple(self, recurse=True, filter=not_read_only) @@ -56,7 +56,7 @@ self.session = requests.Session() self.session.auth = auth - def list_labels(self, repo: Repository) -> typing.List[Label]: + def list_labels(self, repo: Repository) -> List[Label]: """Return the list of Labels from the repository. GitHub API docs: @@ -65,9 +65,10 @@ logger = logging.getLogger("labels") logger.debug(f"Requesting labels for {repo.owner}/{repo.name}") + headers = {"Accept": "application/vnd.github.symmetra-preview+json"} + response = self.session.get( - f"{self.base_url}/repos/{repo.owner}/{repo.name}/labels", - headers={"Accept": "application/vnd.github.symmetra-preview+json"}, + f"{self.base_url}/repos/{repo.owner}/{repo.name}/labels", headers=headers ) if response.status_code != 200: @@ -77,7 +78,27 @@ f"{response.reason}" ) - return [Label(**data) for data in response.json()] + repo_labels: List[Dict] = response.json() + + next_page: Optional[Dict] = response.links.get("next", None) + + while next_page is not None: + + logger.debug(f"Requesting next page of labels") + response = self.session.get(next_page["url"], headers=headers) + + if response.status_code != 200: + raise GitHubException( + f"Error retrieving next page of labels: " + f"{response.status_code} - " + f"{response.reason}" + ) + + repo_labels.extend(response.json()) + + next_page = response.links.get("next", None) + + return [Label(**label) for label in repo_labels] def get_label(self, repo: Repository, *, name: str) -> Label: """Return a single Label from the repository. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/tests/conftest.py new/labels-20.1.0/tests/conftest.py --- old/labels-0.2.0/tests/conftest.py 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/tests/conftest.py 2020-05-04 16:55:36.000000000 +0200 @@ -1,4 +1,4 @@ -import typing +from typing import Any, Dict, Generator, List import attr import pytest @@ -6,8 +6,8 @@ from labels.github import Label -ResponseLabel = typing.Dict[str, typing.Any] -ResponseLabels = typing.List[ResponseLabel] +ResponseLabel = Dict[str, Any] +ResponseLabels = List[ResponseLabel] @pytest.fixture(name="username", scope="session") @@ -34,6 +34,12 @@ return "turtle" +@pytest.fixture(name="repo_id", scope="session") +def fixture_repo_id() -> int: + """Return a repository ID.""" + return 102909380 + + @attr.s(auto_attribs=True, frozen=True, kw_only=True) class FakeProc: """Fake for a CompletedProcess instance.""" @@ -43,7 +49,7 @@ @pytest.fixture(name="mock_repo_info") -def fixture_mock_repo_info(mocker: typing.Any, remote_url: str) -> typing.Any: +def fixture_mock_repo_info(mocker: Any, remote_url: str) -> Any: """Patch the subprocess call to git remote get-url.""" return mocker.patch( @@ -54,7 +60,7 @@ @pytest.fixture(name="mock_repo_info_error") -def fixture_mock_repo_info_error(mocker: typing.Any) -> typing.Any: +def fixture_mock_repo_info_error(mocker: Any) -> Any: """Patch the subprocess call to git remote get-url with an error.""" return mocker.patch( @@ -65,7 +71,7 @@ @pytest.fixture(name="mock_repo_info_bad_url") -def fixture_mock_repo_info_bad_url(mocker: typing.Any) -> typing.Any: +def fixture_mock_repo_info_bad_url(mocker: Any) -> Any: """Patch the subprocess call to git remote get-url with a bad URL.""" return mocker.patch( @@ -148,7 +154,7 @@ @pytest.fixture(name="mock_list_labels") def fixture_mock_list_labels( base_url: str, repo_owner: str, repo_name: str, response_list_labels: ResponseLabels -) -> None: +) -> Generator: """Mock requests for list labels.""" with responses.RequestsMock() as rsps: rsps.add( @@ -161,10 +167,55 @@ yield +@pytest.fixture(name="mock_list_labels_paginated") +def fixture_mock_list_labels_paginated( + base_url: str, + repo_owner: str, + repo_name: str, + repo_id: int, + response_get_infra: ResponseLabel, + response_get_docs: ResponseLabel, + response_get_bug: ResponseLabel, +) -> Generator: + """Mock requests for list labels with pagination.""" + + with responses.RequestsMock() as rsps: + + rsps.add( + responses.GET, + f"{base_url}/repos/{repo_owner}/{repo_name}/labels", + json=[response_get_bug, response_get_docs], + status=200, + content_type="application/json", + headers={ + "Link": ( + f'<{base_url}/repositories/{repo_id}/labels?page=2>; rel="next", ' + f'<{base_url}/repositories/{repo_id}/labels?page=2>; rel="last"' + ) + }, + ) + + rsps.add( + responses.GET, + f"{base_url}/repositories/{repo_id}/labels?page=2", + json=[response_get_infra], + status=200, + content_type="application/json", + headers={ + "Link": ( + f'<{base_url}/repositories/{repo_id}/labels?page=1>; rel="prev", ' + f'<{base_url}/repositories/{repo_id}/labels?page=1>; rel="first"' + ) + }, + ) + + yield + + @pytest.fixture(name="mock_get_label") def fixture_mock_get_label( base_url: str, repo_owner: str, repo_name: str, response_get_bug: ResponseLabel -) -> None: +) -> Generator: """Mock requests for get label.""" with responses.RequestsMock() as rsps: rsps.add( @@ -180,7 +231,7 @@ @pytest.fixture(name="mock_edit_label") def fixture_mock_edit_label( base_url: str, repo_owner: str, repo_name: str, response_get_bug: ResponseLabel -) -> None: +) -> Generator: """Mock requests for edit label.""" with responses.RequestsMock() as rsps: rsps.add( @@ -208,7 +259,7 @@ repo_name: str, label: Label, response_get_bug: ResponseLabel, -) -> None: +) -> Generator: """Mock requests for create label.""" with responses.RequestsMock() as rsps: rsps.add( @@ -222,7 +273,9 @@ @pytest.fixture(name="mock_delete_label") -def fixture_mock_delete_label(base_url: str, repo_owner: str, repo_name: str) -> None: +def fixture_mock_delete_label( + base_url: str, repo_owner: str, repo_name: str +) -> Generator: """Mock requests for delete label.""" with responses.RequestsMock() as rsps: rsps.add( @@ -236,7 +289,7 @@ @pytest.fixture(name="mock_sync") def fixture_mock_sync( base_url: str, repo_owner: str, repo_name: str, response_list_labels: ResponseLabels -) -> None: +) -> Generator: with responses.RequestsMock() as rsps: # Response mock for when sync requests the existing remote labels rsps.add( @@ -292,7 +345,7 @@ @pytest.fixture(name="labels") -def fixture_labels() -> typing.List[Label]: +def fixture_labels() -> List[Label]: """Return a list of Label instances.""" return [ Label( @@ -334,7 +387,7 @@ @pytest.fixture(name="labels_file_dict") -def fixture_labels_file_content() -> typing.Dict[str, typing.Any]: +def fixture_labels_file_content() -> Dict[str, Any]: """Return a mapping from label names to dicts representing Labels.""" return { "bug": { @@ -386,7 +439,7 @@ @pytest.fixture(name="labels_file_write") -def fixture_labels_file_write(tmpdir: typing.Any) -> str: +def fixture_labels_file_write(tmpdir: Any) -> str: """Return a filepath to a temporary file.""" labels_file = tmpdir.join("labels.toml") return str(labels_file) @@ -399,6 +452,6 @@ @pytest.fixture(name="labels_file_sync") -def fixture_labels_file_sync(tmpdir: typing.Any) -> str: +def fixture_labels_file_sync(tmpdir: Any) -> str: """Return a filepath to an existing labels file for the sync test.""" return "tests/sync.toml" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/labels-0.2.0/tests/test_github.py new/labels-20.1.0/tests/test_github.py --- old/labels-0.2.0/tests/test_github.py 2019-11-15 18:35:58.000000000 +0100 +++ new/labels-20.1.0/tests/test_github.py 2020-05-04 16:55:36.000000000 +0200 @@ -45,6 +45,32 @@ assert [l.params_dict for l in labels] == expected_params +@pytest.mark.usefixtures("mock_list_labels_paginated") +def test_list_labels_pagination(client: Client, repo: Repository) -> None: + """Test that list_labels() supports pagination.""" + labels = client.list_labels(repo) + + expected_params = [ + { + "name": "bug", + "description": "Bugs and problems with cookiecutter", + "color": "ea707a", + }, + { + "name": "docs", + "description": "Tasks to write and update documentation", + "color": "2abf88", + }, + { + "name": "infra", + "description": "Tasks related to Docker/CI etc.", + "color": "f9d03b", + }, + ] + + assert [l.params_dict for l in labels] == expected_params + + @pytest.mark.usefixtures("mock_get_label") def test_get_label(client: Client, repo: Repository) -> None: """Test that get_label() requests the specified label for the repo and