Skip to content

Commit d4623a5

Browse files
committed
Move email address related methods to GitHub
Add integration test for adding email addresses Remove integration tests for User#email_addresses
1 parent b751769 commit d4623a5

7 files changed

Lines changed: 53 additions & 93 deletions

File tree

github3/github.py

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from .search import (CodeSearchResult, IssueSearchResult,
2424
RepositorySearchResult, UserSearchResult)
2525
from .structs import SearchIterator
26-
from .users import User, Key
26+
from . import users
2727
from .notifications import Thread
2828
from .licenses import License
2929
from uritemplate import URITemplate
@@ -67,6 +67,20 @@ def _repr(self):
6767
return '<GitHub [{0[0]}]>'.format(self.session.auth)
6868
return '<GitHub at 0x{0:x}>'.format(id(self))
6969

70+
@requires_auth
71+
def add_email_addresses(self, addresses=[]):
72+
"""Add the email addresses in ``addresses`` to the authenticated
73+
user's account.
74+
75+
:param list addresses: (optional), email addresses to be added
76+
:returns: list of :class:`~github3.users.Email`
77+
"""
78+
json = []
79+
if addresses:
80+
url = self._build_url('user', 'emails')
81+
json = self._json(self._post(url, data=addresses), 201)
82+
return [users.Email(email) for email in json]
83+
7084
def all_events(self, number=-1, etag=None):
7185
"""Iterate over public events.
7286
@@ -134,7 +148,7 @@ def all_users(self, number=-1, etag=None, per_page=None, since=None):
134148
:returns: generator of :class:`User <github3.users.User>`
135149
"""
136150
url = self._build_url('users')
137-
return self._iter(int(number), url, User, etag=etag,
151+
return self._iter(int(number), url, users.User, etag=etag,
138152
params={'per_page': per_page, 'since': since})
139153

140154
@requires_basic_auth
@@ -298,7 +312,7 @@ def create_key(self, title, key):
298312
url = self._build_url('user', 'keys')
299313
req = self._post(url, data={'title': title, 'key': key})
300314
json = self._json(req, 201)
301-
return self._instance_or_null(Key, json)
315+
return self._instance_or_null(users.Key, json)
302316

303317
@requires_auth
304318
def create_repository(self, name, description='', homepage='',
@@ -331,6 +345,18 @@ def create_repository(self, name, description='', homepage='',
331345
json = self._json(self._post(url, data=data), 201)
332346
return self._instance_or_null(Repository, json)
333347

348+
@requires_auth
349+
def delete_email_addresses(self, addresses=[]):
350+
"""Delete the email addresses in ``addresses`` from the
351+
authenticated user's account.
352+
353+
:param list addresses: (optional), email addresses to be removed
354+
:returns: bool
355+
"""
356+
url = self._build_url('user', 'emails')
357+
return self._boolean(self._delete(url, data=json.dumps(addresses)),
358+
204, 404)
359+
334360
@requires_auth
335361
def emails(self, number=-1, etag=None):
336362
"""Iterate over email addresses for the authenticated user.
@@ -342,7 +368,7 @@ def emails(self, number=-1, etag=None):
342368
:returns: generator of dicts
343369
"""
344370
url = self._build_url('user', 'emails')
345-
return self._iter(int(number), url, dict, etag=etag)
371+
return self._iter(int(number), url, users.Email, etag=etag)
346372

347373
def emojis(self):
348374
"""Retrieves a dictionary of all of the emojis that GitHub supports.
@@ -440,7 +466,7 @@ def followed_by(self, username, number=-1, etag=None):
440466
:returns: generator of :class:`User <github3.users.User>`\ s
441467
"""
442468
url = self._build_url('users', username, 'following')
443-
return self._iter(int(number), url, User, etag=etag)
469+
return self._iter(int(number), url, users.User, etag=etag)
444470

445471
@requires_auth
446472
def followers(self, number=-1, etag=None):
@@ -457,7 +483,7 @@ def followers(self, number=-1, etag=None):
457483
:returns: generator of :class:`User <github3.users.User>`\ s
458484
"""
459485
url = self._build_url('user', 'followers')
460-
return self._iter(int(number), url, User, etag=etag)
486+
return self._iter(int(number), url, users.User, etag=etag)
461487

462488
def followers_of(self, username, number=-1, etag=None):
463489
"""Iterate over followers of ``username``.
@@ -474,7 +500,7 @@ def followers_of(self, username, number=-1, etag=None):
474500
:returns: generator of :class:`User <github3.users.User>`\ s
475501
"""
476502
url = self._build_url('users', username, 'followers')
477-
return self._iter(int(number), url, User, etag=etag)
503+
return self._iter(int(number), url, users.User, etag=etag)
478504

479505
@requires_auth
480506
def following(self, number=-1, etag=None):
@@ -491,7 +517,7 @@ def following(self, number=-1, etag=None):
491517
:returns: generator of :class:`User <github3.users.User>`\ s
492518
"""
493519
url = self._build_url('user', 'following')
494-
return self._iter(int(number), url, User, etag=etag)
520+
return self._iter(int(number), url, users.User, etag=etag)
495521

496522
def gist(self, id_num):
497523
"""Retrieve the gist using the specified id number.
@@ -685,7 +711,7 @@ def key(self, id_num):
685711
if int(id_num) > 0:
686712
url = self._build_url('user', 'keys', str(id_num))
687713
json = self._json(self._get(url), 200)
688-
return self._instance_or_null(Key, json)
714+
return self._instance_or_null(users.Key, json)
689715

690716
@requires_auth
691717
def keys(self, number=-1, etag=None):
@@ -698,7 +724,7 @@ def keys(self, number=-1, etag=None):
698724
:returns: generator of :class:`Key <github3.users.Key>`\ s
699725
"""
700726
url = self._build_url('user', 'keys')
701-
return self._iter(int(number), url, Key, etag=etag)
727+
return self._iter(int(number), url, users.Key, etag=etag)
702728

703729
def license(self, name):
704730
"""Retrieve the license specified by the name.
@@ -790,7 +816,7 @@ def me(self):
790816
"""
791817
url = self._build_url('user')
792818
json = self._json(self._get(url), 200)
793-
return self._instance_or_null(User, json)
819+
return self._instance_or_null(users.User, json)
794820

795821
@requires_auth
796822
def membership_in(self, organization):
@@ -1569,7 +1595,7 @@ def user(self, username):
15691595
"""
15701596
url = self._build_url('users', username)
15711597
json = self._json(self._get(url), 200)
1572-
return self._instance_or_null(User, json)
1598+
return self._instance_or_null(users.User, json)
15731599

15741600
@requires_auth
15751601
def user_issues(self, filter='', state='', labels='', sort='',
@@ -1638,7 +1664,7 @@ def user_with_id(self, number):
16381664
if number > 0:
16391665
url = self._build_url('user', str(number))
16401666
json = self._json(self._get(url), 200)
1641-
return self._instance_or_null(User, json)
1667+
return self._instance_or_null(users.User, json)
16421668

16431669
def zen(self):
16441670
"""Returns a quote from the Zen of GitHub. Yet another API Easter Egg
@@ -1684,7 +1710,7 @@ def create_user(self, login, email):
16841710
url = self._build_url('admin', 'users')
16851711
payload = {'login': login, 'email': email}
16861712
json_data = self._json(self._post(url, data=payload), 201)
1687-
return self._instance_or_null(User, json_data)
1713+
return self._instance_or_null(users.User, json_data)
16881714

16891715
@requires_auth
16901716
def admin_stats(self, option):

github3/users.py

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -217,62 +217,6 @@ def _update_attributes(self, user):
217217
def __str__(self):
218218
return self.login
219219

220-
@requires_auth
221-
def add_email_address(self, address):
222-
"""Add the single email address to the authenticated user's
223-
account.
224-
225-
:param str address: (required), email address to add
226-
:returns: list of email addresses
227-
"""
228-
return self.add_email_addresses([address])
229-
230-
@requires_auth
231-
def add_email_addresses(self, addresses=[]):
232-
"""Add the email addresses in ``addresses`` to the authenticated
233-
user's account.
234-
235-
:param list addresses: (optional), email addresses to be added
236-
:returns: list of email addresses
237-
"""
238-
json = []
239-
if addresses:
240-
url = self._build_url('user', 'emails')
241-
json = self._json(self._post(url, data=addresses), 201)
242-
return json
243-
244-
@requires_auth
245-
def delete_email_address(self, address):
246-
"""Delete the email address from the user's account.
247-
248-
:param str address: (required), email address to delete
249-
:returns: bool
250-
"""
251-
return self.delete_email_addresses([address])
252-
253-
@requires_auth
254-
def delete_email_addresses(self, addresses=[]):
255-
"""Delete the email addresses in ``addresses`` from the
256-
authenticated user's account.
257-
258-
:param list addresses: (optional), email addresses to be removed
259-
:returns: bool
260-
"""
261-
url = self._build_url('user', 'emails')
262-
return self._boolean(self._delete(url, data=dumps(addresses)),
263-
204, 404)
264-
265-
@requires_auth
266-
def email_addresses(self, number=-1):
267-
"""Iterate over each email address in the authenticated user's account.
268-
269-
:param int number: (optional), number of email addresses to return.
270-
Default: -1, returns all of them
271-
:returns: generator of :class:`Email <github3.users.Email>`
272-
"""
273-
url = self._build_url('user', 'emails')
274-
return self._iter(int(number), url, Email)
275-
276220
def is_assignee_on(self, username, repository):
277221
"""Check if this user can be assigned to issues on username/repository.
278222
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"recorded_with": "betamax/0.5.1", "http_interactions": [{"recorded_at": "2015-12-20T18:56:05", "response": {"url": "https://api.github.com/user/emails", "status": {"code": 201, "message": "Created"}, "headers": {"Server": "GitHub.com", "Date": "Sun, 20 Dec 2015 18:56:05 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "ETag": "\"b4fdbf10626c0cffe2eb8fe3ad230ec1\"", "X-Content-Type-Options": "nosniff", "X-RateLimit-Limit": "5000", "Content-Security-Policy": "default-src 'none'", "Content-Type": "application/json; charset=utf-8", "X-GitHub-Request-Id": "451DE1EB:14B57:380B98F:5676F9C5", "Content-Length": "206", "Access-Control-Allow-Credentials": "true", "X-RateLimit-Remaining": "4997", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Cache-Control": "private, max-age=60, s-maxage=60", "Access-Control-Allow-Origin": "*", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-RateLimit-Reset": "1450639603", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "2c18a09f3ac5e4dd1e004af7c5a94769", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "Status": "201 Created"}, "body": {"encoding": "utf-8", "string": "[{\"email\":\"gr.aff.at.colmingov@gmail.com\",\"primary\":true,\"verified\":true},{\"email\":\"example1@example.com\",\"primary\":false,\"verified\":false},{\"email\":\"example2@example.com\",\"primary\":false,\"verified\":false}]"}}, "request": {"method": "POST", "uri": "https://api.github.com/user/emails", "headers": {"Authorization": "Basic <BASIC_AUTH>", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json", "Content-Length": "48", "Accept-Charset": "utf-8", "Accept-Encoding": "gzip, deflate", "User-Agent": "github3.py/1.0.0a2", "Connection": "keep-alive"}, "body": {"encoding": "utf-8", "string": "[\"example1@example.com\", \"example2@example.com\"]"}}}]}

tests/cassettes/User_email_addresses.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/integration/test_github.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ def test_authorize(self):
3636

3737
assert isinstance(auth, github3.auths.Authorization)
3838

39+
def test_add_email_addresses(self):
40+
"""Add email addresses to the authorized user's account."""
41+
self.basic_login()
42+
cassette_name = self.cassette_name('add_email_addresses')
43+
with self.recorder.use_cassette(cassette_name):
44+
emails = self.gh.add_email_addresses(
45+
['example1@example.com', 'example2@example.com']
46+
)
47+
48+
for email in emails:
49+
assert isinstance(email, github3.users.Email)
50+
3951
def test_create_gist(self):
4052
"""Test the ability of a GitHub instance to create a new gist."""
4153
self.token_login()

tests/integration/test_users.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,6 @@ class TestUser(IntegrationHelper):
4040

4141
"""Integration tests for methods on the User class."""
4242

43-
def test_email_addresses(self):
44-
"""Test the ability to retrieve the email addresses of the
45-
authenticated user."""
46-
self.token_login()
47-
cassette_name = self.cassette_name('email_addresses')
48-
with self.recorder.use_cassette(cassette_name):
49-
user = self.gh.me()
50-
assert user is not None
51-
for address in user.email_addresses():
52-
assert isinstance(address, github3.users.Email)
53-
5443
def test_events(self):
5544
"""Show that a user can retrieve a events performed by a user."""
5645
cassette_name = self.cassette_name('events')

tests/unit/test_users.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,6 @@ class TestUserIterators(UnitIteratorHelper):
8686
described_class = github3.users.User
8787
example_data = example_data.copy()
8888

89-
def test_email_addresses(self):
90-
"""Verify the request to retrive a user's email addresses."""
91-
i = self.instance.email_addresses()
92-
self.get_next(i)
93-
94-
self.session.get.assert_called_once_with(
95-
url_for('user/emails'),
96-
params={'per_page': 100},
97-
headers={}
98-
)
99-
10089
def test_events(self):
10190
"""Test the request to retrieve a user's events."""
10291
i = self.instance.events()

0 commit comments

Comments
 (0)