Skip to content

Commit bb40e7e

Browse files
authored
Merge pull request sigmavirus24#859 from jacquerie/add-support-for-repository-topics
Add support for repository topics
2 parents e9afdbf + 07a0b4a commit bb40e7e

6 files changed

Lines changed: 108 additions & 0 deletions

File tree

github3/repos/repo.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from . import stats
4141
from . import status
4242
from . import tag
43+
from . import topics
4344

4445
from ..decorators import requires_auth
4546

@@ -51,6 +52,10 @@ class _Repository(models.GitHubCore):
5152
method to ensure that all attributes are present on the object.
5253
"""
5354

55+
PREVIEW_HEADERS = {
56+
'Accept': 'application/vnd.github.mercy-preview+json'
57+
}
58+
5459
STAR_HEADERS = {
5560
'Accept': 'application/vnd.github.v3.star+json'
5661
}
@@ -2161,6 +2166,31 @@ def remove_collaborator(self, username):
21612166
base_url=self._api)
21622167
return self._boolean(self._delete(url), 204, 404)
21632168

2169+
@requires_auth
2170+
def replace_topics(self, new_topics):
2171+
"""Replace the repository topics with ``new_topics``.
2172+
2173+
:param topics:
2174+
(required), new topics of the repository
2175+
:type topics:
2176+
list
2177+
:returns:
2178+
new topics of the repository
2179+
:rtype:
2180+
:class:`~github3.repos.topics.Topics`
2181+
"""
2182+
url = self._build_url('topics', base_url=self._api)
2183+
data = {'names': new_topics}
2184+
json = self._json(
2185+
self._put(
2186+
url,
2187+
data=jsonlib.dumps(data),
2188+
headers=self.PREVIEW_HEADERS
2189+
),
2190+
200
2191+
)
2192+
return self._instance_or_null(topics.Topics, json)
2193+
21642194
def stargazers(self, number=-1, etag=None):
21652195
"""List users who have starred this repository.
21662196
@@ -2310,6 +2340,18 @@ def teams(self, number=-1, etag=None):
23102340
url = self._build_url('teams', base_url=self._api)
23112341
return self._iter(int(number), url, orgs.ShortTeam, etag=etag)
23122342

2343+
def topics(self):
2344+
"""Get the topics of this repository.
2345+
2346+
:returns:
2347+
this repository's topics
2348+
:rtype:
2349+
:class:`~github3.repos.topics.Topics`
2350+
"""
2351+
url = self._build_url('topics', base_url=self._api)
2352+
json = self._json(self._get(url, headers=self.PREVIEW_HEADERS), 200)
2353+
return self._instance_or_null(topics.Topics, json)
2354+
23132355
def tree(self, sha):
23142356
"""Get a tree.
23152357

github3/repos/topics.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
"""Topics related logic."""
3+
from __future__ import unicode_literals
4+
5+
from .. import models
6+
7+
8+
class Topics(models.GitHubCore):
9+
"""Representation of the repository topics.
10+
11+
.. attribute:: names
12+
13+
The names of the topics.
14+
"""
15+
16+
def _update_attributes(self, topics):
17+
self.names = topics['names']
18+
19+
def _repr(self):
20+
return '<Topics [{0}]>'.format(', '.join(self.names))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": ["gzip, deflate"], "Accept": ["application/vnd.github.v3.full+json"], "User-Agent": ["github3.py/1.1.0"], "Accept-Charset": ["utf-8"], "Connection": ["keep-alive"], "Content-Type": ["application/json"], "Authorization": ["token <AUTH_TOKEN>"]}, "method": "GET", "uri": "https://api.github.com/repos/jacquerie/flask-shell-bpython"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA62Yb3PiNhDGvwrD2wYM5D8zmWs7vblJp1zbG669yRtG2AIryJJPkqHEk+/eR5KNbSaXOInfJGC0Pz1e7653lfdZ1J9ejM8vJ9eTy5O+kBFd2Ev92W8fd3/y33n46fqBfPuyDcVmMpt/PZ3db/afdzc3fSwmCcXKFSd6M9Ax5XywTPcmlgI/rjLOF8WKexJ+z6hiNHh6rdwJqvrTvM/lmgkgDwYAWTWnV+PJ1agp7++Lf7595uH97Gw2vz2b/eIkkS0xRC0yxUGJjUn1NAj8RT0ZrpmJs2WmqQqlMFSYYSiTIAs8/sP25gyItSogzg24cARLWcHxxoDpoK43Ngk/EuD3devrK1eSc7mD/bHeZ7cIDmbWyw7BxPotCJjlgTQxhcNwG4/25pk2r5TjTPLA/kPkWIjGI1A0ep2kwgiCbDA85oGiqXS0bKlDxVLDpHiltIYpUFKtiWAP5A0omGoQrKhXinAmMKVbBNwrbb1NHqSKbUm4t+5QNKRsC+++hXdkDJzZpzaHv+L5W18zQxckSmwSrgjX9PGk7/Y2WOQunCCrWsX3D1I9ooeHiW2/0JSTkPYQg72IrkjGTc+ViJ4rJz1kTEJE1NshcXukp1nCOFE9KWhPZUIggHu//uUqzhDqV1JtDjKfzVr3TKpc/IFWy3vhgbUAIV+BgbwN3XdAs5Q8wN8i2UJUALKUihj5UiFpI7aBy4P6Vxt9hpKkg5twGOBiKbvwsMMAx7TOaKvEaOMKR9NBmYMiS5a+SLbJvDYbeA50E63ZWlDagWcPqDwoa/pSERHGXcBLUh74Ty4iyLoD2ZYC2JLLZQc0vG8Dh8oDHRP/XjOLbpRatiU10IquOpJtSQe0UZ3EhJNsUQcwXrYG4dGB5pIU5IWnORHrjKy7YB9QiAzbHqzJw4vNUpu8q1gA205QsWXWVfmsaFa1711QN7pwdQWr0K4ter7TauWSWpPlnJIk7KVmpQ23ADWSpTO4jevjDez3l/usttItKQ+qyu9fMMUe7/d68YYpNdd3KgaUDsKmJAX5Tykxsa2G2DAlir7/BgpQkC8JesXhcJjHlLgZIKGqkxrgOQASFcboe9+vOS9J6MsSYtyksbKSI0weXJKoA58fUMD6h/x+3Z5Tj5EUI3YHYh2mzkWTTbVBk90BvGLVdxDSsBUL2wxibVK1gcs/aCZCekI4P0GUGxYyxD1GBfuM0SrTLnzmObglHIH4qYxTpEAHDlPUk/LAD9MRRiS576im1WC2DCiKwS5aEINRbDIaXwxGF4PJaD6+no4m0/HZHdZkadRYczUYXQ7Gp3MsOL2YjtyaNMO0VmGw5HwwwpKr6eR0OrqyS1CqiwzAJxzJPHUi8tQUZo9aYK51XJn/XBlPnz1ZKoxDjlA+yr/X7r89fse2BUB8LBOaoiPyp0maPeDTeNxoaUKZCTyE05P+jhj06mgXqktlGwR7P+taJtELXxD6U6MyO5bjSqrkPQ2Nrl+rSlFt4Y5tWMPQNmyH0dnPvZWAhCkli0M1gWJxKMY4ICsOBWRKRSGoVD5BtrGQCo3bze3wC/1oKiC+OBWc3c57fxQr4I00+q84ebyd28BrHuE1j8QKsA4KYO3UMryYf+L3d/+eP9zNPz70cYDh52/r3JrK/hT6Smc7zxfnDws/2lixRBt3KpJSlcDZ9vzJ3kpxPuLdbmO/9KQtpP4zdkX5kbuF/p4RxK57i5XL/C/uEnxlG63mL4rat2nTRlCzwzFCLSrqrWXxqMaP/wPrRXVIzxUAAA==", "encoding": "utf-8"}, "headers": {"X-XSS-Protection": ["1; mode=block"], "Content-Security-Policy": ["default-src 'none'"], "Access-Control-Expose-Headers": ["ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"], "Transfer-Encoding": ["chunked"], "Last-Modified": ["Fri, 13 Jul 2018 02:36:04 GMT"], "Access-Control-Allow-Origin": ["*"], "X-Frame-Options": ["deny"], "Status": ["200 OK"], "X-GitHub-Request-Id": ["9A4E:7DB6:8AB0F67:11AD54DE:5B48110E"], "ETag": ["W/\"7107ffa6cfdb88d58106f3cb7649cbfb\""], "Date": ["Fri, 13 Jul 2018 02:40:15 GMT"], "X-RateLimit-Remaining": ["4992"], "Strict-Transport-Security": ["max-age=31536000; includeSubdomains; preload"], "Server": ["GitHub.com"], "X-OAuth-Scopes": ["public_repo"], "X-GitHub-Media-Type": ["github.v3; param=full; format=json"], "X-Content-Type-Options": ["nosniff"], "Content-Encoding": ["gzip"], "X-Runtime-rack": ["0.057600"], "Vary": ["Accept, Authorization, Cookie, X-GitHub-OTP"], "X-RateLimit-Limit": ["5000"], "Cache-Control": ["private, max-age=60, s-maxage=60"], "Referrer-Policy": ["origin-when-cross-origin, strict-origin-when-cross-origin"], "Content-Type": ["application/json; charset=utf-8"], "X-Accepted-OAuth-Scopes": ["repo"], "X-RateLimit-Reset": ["1531452513"]}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/jacquerie/flask-shell-bpython"}, "recorded_at": "2018-07-13T02:40:15"}, {"request": {"body": {"string": "{\"names\": [\"flask\", \"bpython\", \"python\"]}", "encoding": "utf-8"}, "headers": {"Content-Length": ["41"], "Accept-Encoding": ["gzip, deflate"], "Accept": ["application/vnd.github.mercy-preview+json"], "User-Agent": ["github3.py/1.1.0"], "Accept-Charset": ["utf-8"], "Connection": ["keep-alive"], "Content-Type": ["application/json"], "Authorization": ["token <AUTH_TOKEN>"]}, "method": "PUT", "uri": "https://api.github.com/repos/jacquerie/flask-shell-bpython/topics"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA6tWykvMTS1WsopWSstJLM5W0lFKKqgsycjPA7KgjNhaAGF4mvYmAAAA", "encoding": "utf-8"}, "headers": {"X-XSS-Protection": ["1; mode=block"], "Content-Security-Policy": ["default-src 'none'"], "Access-Control-Expose-Headers": ["ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"], "Transfer-Encoding": ["chunked"], "Access-Control-Allow-Origin": ["*"], "X-Frame-Options": ["deny"], "Status": ["200 OK"], "X-GitHub-Request-Id": ["9A4E:7DB6:8AB0F76:11AD54FF:5B48110F"], "ETag": ["W/\"8ae34e77215a659579641afb01a6a267\""], "Date": ["Fri, 13 Jul 2018 02:40:15 GMT"], "X-RateLimit-Remaining": ["4991"], "Strict-Transport-Security": ["max-age=31536000; includeSubdomains; preload"], "Server": ["GitHub.com"], "X-OAuth-Scopes": ["public_repo"], "X-GitHub-Media-Type": ["github.mercy-preview; format=json"], "X-Content-Type-Options": ["nosniff"], "Content-Encoding": ["gzip"], "X-Runtime-rack": ["0.105731"], "Vary": ["Accept, Authorization, Cookie, X-GitHub-OTP"], "X-RateLimit-Limit": ["5000"], "Cache-Control": ["private, max-age=60, s-maxage=60"], "Referrer-Policy": ["origin-when-cross-origin, strict-origin-when-cross-origin"], "Content-Type": ["application/json; charset=utf-8"], "X-Accepted-OAuth-Scopes": ["repo"], "X-RateLimit-Reset": ["1531452513"]}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/jacquerie/flask-shell-bpython/topics"}, "recorded_at": "2018-07-13T02:40:15"}], "recorded_with": "betamax/0.8.1"}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": ["gzip, deflate"], "Accept": ["application/vnd.github.v3.full+json"], "User-Agent": ["github3.py/1.1.0"], "Accept-Charset": ["utf-8"], "Connection": ["keep-alive"], "Content-Type": ["application/json"]}, "method": "GET", "uri": "https://api.github.com/repos/jacquerie/flask-shell-bpython"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA62Yb2/bNhDGv4qht7NN2/lvIOg2rCgyzO1WuFuRNwYt0RYTitRIyp4t5LvvISVbspEmcqI3TaLyfnx0vDvdMQ94FIwvhxdXo5vRVTeQKmIz9yiY/PZx/UX8LsJPN1v6/esqlI+jyfTb2eThcfN5fXsbYDFNGFYuBDWPPRMzIXrzdGNjJfGfi0yIWbnigYb/ZkxzRp5fq9aS6WCcB0ItuQRybwCQU3N2PRxdDw7l/XX59/fPInyYnE+md+eTX7wkuqKW6lmmBSixtakZE1I8NKP+kts4m2eG6VBJy6TthyohGSnwH1a350AsdQnxbsCDI1jKS05hDJghdb2xTcSRgGJfv76+cqGEUGvYH+t9cQuyN3Ne9ggul29BwCwnysYMDsNrPLmX58aeKMeb5MT9QOQ4iMERaBadJqk0giAXDE850SxVnpbNTah5armSJ0o7MAVK6SWVfEvfgIKpAcGJOlGEN4EpWyHgTrQtbHKSar6i4ca5Q7OQ8RW8+xbekTFwdpO6HP6G83e+5pbNaJS4JFxQYdhTN/B7WyzyD7rIqkbx/YNUj9j+MLHtV5YKGrIOYrATsQXNhO34EtHx5aSDjEmojDprJG6HdgxPuKC6oyTr6ExKBHDn1z99xelD/ULpx73MF7PWn0mViz/Q6nivHFgDEPIVGMh7ZJsWaI6SE/xbJluICkDnSlOrXiskTcQe4HJS/9NFn2U0aeElPAa4WKk2POwxwHFjMtYoMZq4wtMM2eWgzJJ5USSbZF6TDQoOdFNj+FIy1oJn96ic7Gr6XFMZxm3Ad6ScFL/5iKDLFmQ7CmBzoeYt0PC9JR6VExPT4rtmZ+0odWxHOkBrtmhJtiPt0Va3EhNeskPtwfjYWoRHC5p3JJKXnhZULjO6bIO9RyEyXHuwpNtXm6UmeVexAHadoObzrK3yWdGc6qJ3Qd1ow9UVrEL7tujlTquRS2pNlndKkvDXmpUm3BJ0kCytwV1cH2/g/n69z2oq3ZFyUlX+4gNT7vF+r5dfmJ3m+k7lgNJC2OxIJP8ppTZ21RAbplSz979ACSL5nKJX7Pf7ecyonwESplupAQUHQKrDGH3v+zXnOxL6soRaP2ksnOQIk4dQNGrB53sUsMUhv193wanHSIoRuwWxHlPnoslmxqLJbgFeseo7SGX5godNBrEmqXqAyz8YLkPWpUJ0EeWWhxxxj1HBnTFaZdaGzwoOXglXIMVUJhhSoAWHaVaQclIM0xFGJLVpqabVYK4MaIbBLppRi1FsNBhe9gaXvdFgOrwZD0bj4fk91mRpdLDmuje46g3PplhwPhgPL9yaNMO0VmGw5KI3wJLr8ehsPLh2S1CqywzAb7iSee5G5LkpzF21wNyYuDL/uTIev3izVBqHAqF8lH+n7r86/sY2BUB8rBKWoiMqbpMM3+K34fCgpQlVJnEIZ91gTS16dbQL1aNdGwT7YtZ1TGpmRUEIxlZnbizHk1SrBxZaU39WlaLawjV/5AeGrmHbj87F3FsJSLjWqrxUkygW+2KMC7LyUkClTJaCdspHyDYeMmnwurkbfqEfTQXEl7eCk7tp549yBbyRRv+VN493Uxd4h1d4h1diJdiQEli7tQwvp5/Ew/0/F9v76cdtgAuMYv52zq2pDMbQt3O293x5/zArRhsnlhrrb0Uks2vM8LUjqfd1pZ+GT/8D5BPhF0wVAAA=", "encoding": "utf-8"}, "headers": {"X-XSS-Protection": ["1; mode=block"], "Content-Security-Policy": ["default-src 'none'"], "Access-Control-Expose-Headers": ["ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"], "Transfer-Encoding": ["chunked"], "Last-Modified": ["Fri, 13 Jul 2018 02:40:15 GMT"], "Access-Control-Allow-Origin": ["*"], "X-Frame-Options": ["deny"], "Status": ["200 OK"], "X-GitHub-Request-Id": ["9AC2:7DB7:B5F3A84:1538CBC2:5B481450"], "ETag": ["W/\"d029658658da401bc28144b5257f64c6\""], "Date": ["Fri, 13 Jul 2018 02:54:09 GMT"], "X-RateLimit-Remaining": ["57"], "Strict-Transport-Security": ["max-age=31536000; includeSubdomains; preload"], "Server": ["GitHub.com"], "X-GitHub-Media-Type": ["github.v3; param=full; format=json"], "X-Content-Type-Options": ["nosniff"], "Content-Encoding": ["gzip"], "X-Runtime-rack": ["0.046247"], "Vary": ["Accept"], "X-RateLimit-Limit": ["60"], "Cache-Control": ["public, max-age=60, s-maxage=60"], "Referrer-Policy": ["origin-when-cross-origin, strict-origin-when-cross-origin"], "Content-Type": ["application/json; charset=utf-8"], "X-RateLimit-Reset": ["1531452470"]}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/jacquerie/flask-shell-bpython"}, "recorded_at": "2018-07-13T02:54:09"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": ["gzip, deflate"], "Accept": ["application/vnd.github.mercy-preview+json"], "User-Agent": ["github3.py/1.1.0"], "Accept-Charset": ["utf-8"], "Connection": ["keep-alive"], "Content-Type": ["application/json"]}, "method": "GET", "uri": "https://api.github.com/repos/jacquerie/flask-shell-bpython/topics"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA6tWykvMTS1WsopWSstJLM5W0lFKKqgsycjPA7KgjNhaAGF4mvYmAAAA", "encoding": "utf-8"}, "headers": {"X-XSS-Protection": ["1; mode=block"], "Content-Security-Policy": ["default-src 'none'"], "Access-Control-Expose-Headers": ["ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"], "Transfer-Encoding": ["chunked"], "Access-Control-Allow-Origin": ["*"], "X-Frame-Options": ["deny"], "Status": ["200 OK"], "X-GitHub-Request-Id": ["9AC2:7DB7:B5F3AD4:1538CC0C:5B481451"], "ETag": ["W/\"61a23bad4105517f68226fb33bebcb2d\""], "Date": ["Fri, 13 Jul 2018 02:54:09 GMT"], "X-RateLimit-Remaining": ["56"], "Strict-Transport-Security": ["max-age=31536000; includeSubdomains; preload"], "Server": ["GitHub.com"], "X-GitHub-Media-Type": ["github.mercy-preview; format=json"], "X-Content-Type-Options": ["nosniff"], "Content-Encoding": ["gzip"], "X-Runtime-rack": ["0.048572"], "Vary": ["Accept"], "X-RateLimit-Limit": ["60"], "Cache-Control": ["public, max-age=60, s-maxage=60"], "Referrer-Policy": ["origin-when-cross-origin, strict-origin-when-cross-origin"], "Content-Type": ["application/json; charset=utf-8"], "X-RateLimit-Reset": ["1531452470"]}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/jacquerie/flask-shell-bpython/topics"}, "recorded_at": "2018-07-13T02:54:09"}], "recorded_with": "betamax/0.8.1"}

tests/integration/test_repos_repo.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,17 @@ def test_remove_collaborator(self):
11551155

11561156
assert removed_collaborator is True
11571157

1158+
def test_replace_topics(self):
1159+
"""Test the ability to replace the topics of a repository."""
1160+
self.token_login()
1161+
cassette_name = self.cassette_name('replace_topics')
1162+
with self.recorder.use_cassette(cassette_name):
1163+
repository = self.gh.repository('jacquerie', 'flask-shell-bpython')
1164+
topics = repository.replace_topics(['flask', 'bpython', 'python'])
1165+
1166+
assert isinstance(topics, github3.repos.topics.Topics)
1167+
assert len(topics.names) == 3
1168+
11581169
def test_stargazers(self):
11591170
"""Test the ability to retrieve the stargazers on a repository."""
11601171
cassette_name = self.cassette_name('stargazers')
@@ -1251,6 +1262,16 @@ def test_teams(self):
12511262
for team in teams:
12521263
assert isinstance(team, github3.orgs.ShortTeam)
12531264

1265+
def test_topics(self):
1266+
"""Test the ability to retrieve topics from a repository."""
1267+
cassette_name = self.cassette_name('topics')
1268+
with self.recorder.use_cassette(cassette_name):
1269+
repository = self.gh.repository('jacquerie', 'flask-shell-bpython')
1270+
topics = repository.topics()
1271+
1272+
assert isinstance(topics, github3.repos.topics.Topics)
1273+
assert len(topics.names) == 3
1274+
12541275
def test_tree(self):
12551276
"""Test the ability to retrieve a tree from a repository."""
12561277
cassette_name = self.cassette_name('tree')

tests/unit/test_repos_repo.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,16 @@ def test_remove_collaborator_required_username(self):
972972

973973
assert self.session.delete.called is False
974974

975+
def test_replace_topics(self):
976+
"""Verify the request for replacing the topics."""
977+
self.instance.replace_topics(['flask', 'bpython', 'python'])
978+
979+
self.session.put.assert_called_once_with(
980+
url_for('topics'),
981+
data='{"names": ["flask", "bpython", "python"]}',
982+
headers=self.instance.PREVIEW_HEADERS
983+
)
984+
975985
def test_source(self):
976986
"""Verify that the source of the repository can be retrieved."""
977987
source = self.instance.source
@@ -1000,6 +1010,15 @@ def test_tag_required_sha(self):
10001010

10011011
assert self.session.get.called is False
10021012

1013+
def test_topics(self):
1014+
"""Verify the request for retrieving the topics."""
1015+
self.instance.topics()
1016+
1017+
self.session.get.assert_called_once_with(
1018+
url_for('topics'),
1019+
headers=self.instance.PREVIEW_HEADERS
1020+
)
1021+
10031022
def test_tree(self):
10041023
"""Verify the request for retrieving a tree."""
10051024
self.instance.tree('fake-sha')
@@ -1664,6 +1683,10 @@ def test_remove_collaborator(self):
16641683
"""Show that a user must be authenticated to remove a collaborator."""
16651684
self.assert_requires_auth(self.instance.remove_collaborator)
16661685

1686+
def test_replace_topics(self):
1687+
"""Show that a user must be authenticated to replace the topics."""
1688+
self.assert_requires_auth(self.instance.replace_topics)
1689+
16671690
def test_subscription(self):
16681691
"""
16691692
Show that a user must be authenticated to retrieve the

0 commit comments

Comments
 (0)