2018-02-06 07:10:41 -06:00
import json
2018-02-26 13:14:33 -06:00
from collections import namedtuple
2018-02-05 16:36:27 -06:00
2018-02-06 11:36:42 -06:00
import pytest
import requests
from octokit import Octokit
2018-03-12 15:09:15 -05:00
from octokit import errors
2018-02-06 11:36:42 -06:00
2018-02-05 16:36:27 -06:00
class TestClientMethods ( object ) :
def test_client_methods_are_lower_case ( self ) :
for client in Octokit ( ) . __dict__ :
2018-02-27 08:41:58 -06:00
try :
cls = getattr ( Octokit ( ) , client ) . __dict__
2018-10-04 11:54:41 -05:00
assert all ( method . islower ( ) for method in cls )
2018-02-27 08:41:58 -06:00
except AttributeError :
pass # ignore non-class attributes
2018-02-05 16:36:27 -06:00
def test_method_has_doc_string ( self ) :
2020-01-16 16:31:40 -06:00
assert Octokit ( ) . activity . list_notifications . __doc__ == self . doc_string
2018-02-05 16:36:27 -06:00
def test_method_has_name_string ( self ) :
2020-01-17 11:49:05 -06:00
assert Octokit ( ) . oauth_authorizations . list_grants . __name__ == " list_grants "
2018-10-04 11:01:46 -05:00
def test_method_is_accessible_also_by_snake_case_name ( self ) :
2020-01-17 11:49:05 -06:00
assert (
Octokit ( ) . oauth_authorizations . list_your_grants . __name__
== " list_your_grants "
)
2018-02-05 16:36:27 -06:00
def test_method_calls_requests ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . get_authorization ( authorization_id = 1 )
2018-02-05 16:36:27 -06:00
assert requests . get . called
assert requests . get . call_count == 1
2018-02-06 14:09:18 -06:00
def test_has_required_method_parameters ( self ) :
2018-03-12 15:09:15 -05:00
with pytest . raises ( errors . OctokitParameterError ) as e1 :
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . get_authorization ( )
2020-01-17 11:49:05 -06:00
assert " authorization_id is a required parameter " == str ( e1 . value )
2018-03-12 15:09:15 -05:00
with pytest . raises ( errors . OctokitParameterError ) as e2 :
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . get_authorization ( authorization_id = None )
2020-01-17 11:49:05 -06:00
assert " authorization_id must have a value " == str ( e2 . value )
2018-02-05 16:36:27 -06:00
2018-02-06 14:09:18 -06:00
def test_only_allows_valid_method_parameters ( self ) :
2018-03-12 15:09:15 -05:00
with pytest . raises ( errors . OctokitParameterError ) as e :
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . list_grants ( notvalid = 1 )
2020-01-17 11:49:05 -06:00
assert " notvalid is not a valid parameter " == str ( e . value )
2018-02-05 16:36:27 -06:00
def test_validate_method_parameters ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . get_authorization ( authorization_id = 100 )
2018-02-07 11:50:01 -06:00
requests . get . assert_called_once_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/authorizations/100 " ,
params = { } ,
headers = Octokit ( ) . headers ,
2018-02-07 11:50:01 -06:00
)
2018-02-06 07:10:41 -06:00
def test_request_has_body_parameters ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.post " )
data = { " note " : " remind me " , " scopes " : [ " public_repo " ] }
2018-10-04 11:01:46 -05:00
create = Octokit ( ) . oauth_authorizations . create_authorization ( * * data )
2018-02-06 07:10:41 -06:00
requests . post . assert_called_once_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/authorizations " ,
data = json . dumps ( data , sort_keys = True ) ,
headers = create . headers ,
2018-02-06 07:10:41 -06:00
)
def test_must_include_required_body_parameters ( self ) :
2020-01-17 11:49:05 -06:00
data = { " gist_id " : " abc123 " , " note " : " remind me " }
2018-03-12 15:09:15 -05:00
with pytest . raises ( errors . OctokitParameterError ) as e :
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . create_authorization ( * * data )
2020-01-17 11:49:05 -06:00
assert " gist_id is not a valid parameter " == str ( e . value )
2018-02-06 07:10:41 -06:00
2019-01-24 08:55:40 -06:00
def test_must_include_required_dictionary_sub_parameters_when_used ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
data = { " owner " : " owner " , " repo " : " repo " , " name " : " name " }
2019-01-24 08:55:40 -06:00
with pytest . raises ( errors . OctokitParameterError ) as e :
Octokit ( ) . checks . create ( * * data )
2020-01-17 11:49:05 -06:00
assert " head_sha is a required parameter " == str ( e . value )
data . update ( { " head_sha " : " master " , " output " : { " title " : " blah " } } )
2019-01-24 08:55:40 -06:00
with pytest . raises ( errors . OctokitParameterError ) as e :
Octokit ( ) . checks . create ( * * data )
2020-01-17 11:49:05 -06:00
assert " summary is a required parameter " == str ( e . value )
data . update ( { " output " : { " title " : " blah " , " summary " : " that " } } )
2019-01-24 08:55:40 -06:00
Octokit ( ) . checks . create ( * * data )
2020-01-16 16:31:40 -06:00
def test_must_include_required_array_sub_parameters_when_used ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
data = {
" owner " : " owner " ,
" repo " : " repo " ,
" name " : " name " ,
" head_sha " : " master " ,
" actions " : [ ] ,
}
2019-01-24 08:55:40 -06:00
with pytest . raises ( errors . OctokitParameterError ) as e :
Octokit ( ) . checks . create ( * * data )
2020-01-17 11:49:05 -06:00
assert " property is missing required items " == str ( e . value )
data . update ( { " actions " : [ { " label " : " blah " } ] } )
2019-01-24 08:55:40 -06:00
with pytest . raises ( errors . OctokitParameterError ) as e :
Octokit ( ) . checks . create ( * * data )
2020-01-17 11:49:05 -06:00
assert " description is a required parameter " == str ( e . value )
data . update (
{ " actions " : [ { " label " : " blah " , " description " : " x " , " identifier " : " a " } ] }
)
2019-01-24 08:55:40 -06:00
Octokit ( ) . checks . create ( * * data )
2020-01-16 16:31:40 -06:00
def test_schema_types_must_match ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
2020-01-16 16:28:05 -06:00
data = {
2020-01-17 11:49:05 -06:00
" owner " : " owner " ,
" repo " : " repo " ,
" name " : " name " ,
" head_sha " : " master " ,
" actions " : { " desription " : " blah " } ,
2020-01-16 16:28:05 -06:00
}
2020-01-16 16:31:40 -06:00
with pytest . raises ( errors . OctokitParameterError ) as e :
Octokit ( ) . checks . create ( * * data )
2020-01-17 11:49:05 -06:00
assert (
f ' dict type does not match the schema type of array for the data of { data [ " actions " ] } '
== str ( e . value )
)
2020-01-16 16:31:40 -06:00
2018-02-06 07:10:41 -06:00
def test_use_default_parameter_values ( self , mocker ) :
2020-04-13 14:59:48 -05:00
mocker . patch ( " requests.get " )
headers = {
" Content-Type " : " application/json " ,
" accept " : " application/vnd.github.v3+json " ,
}
data = {
" visibility " : " all " ,
" affiliation " : " owner,collaborator,organization_member " ,
" type " : " all " ,
" sort " : " full_name " ,
" per_page " : 30 ,
" page " : 1 ,
}
Octokit ( ) . repos . list_for_authenticated_user ( )
requests . get . assert_called_once_with (
" https://api.github.com/user/repos " , params = data , headers = headers
)
def test_deprecated_methods_are_available ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
headers = {
" Content-Type " : " application/json " ,
" accept " : " application/vnd.github.v3+json " ,
}
2020-01-16 16:28:05 -06:00
data = {
2020-01-17 11:49:05 -06:00
" visibility " : " all " ,
" affiliation " : " owner,collaborator,organization_member " ,
" type " : " all " ,
" sort " : " full_name " ,
" per_page " : 30 ,
" page " : 1 ,
2020-01-16 16:28:05 -06:00
}
2020-01-16 16:31:40 -06:00
Octokit ( ) . repos . list ( )
2020-01-17 11:49:05 -06:00
requests . get . assert_called_once_with (
" https://api.github.com/user/repos " , params = data , headers = headers
)
2018-02-06 07:10:41 -06:00
def test_use_passed_value_instead_of_default_parameter_values ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
headers = {
" Content-Type " : " application/json " ,
" accept " : " application/vnd.github.v3+json " ,
}
2020-04-13 16:19:27 -05:00
data = { " sort " : " updated " , " per_page " : 30 , " page " : 1 }
2020-01-17 11:49:05 -06:00
Octokit ( ) . issues . list_comments_for_repo (
owner = " testUser " , repo = " testRepo " , * * data
)
2018-10-04 11:01:46 -05:00
requests . get . assert_called_once_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/repos/testUser/testRepo/issues/comments " ,
params = data ,
headers = headers ,
2018-02-06 07:10:41 -06:00
)
def test_validate_enum_values ( self ) :
2018-03-12 15:09:15 -05:00
with pytest . raises ( errors . OctokitParameterError ) as e :
2020-01-17 11:49:05 -06:00
Octokit ( ) . issues . update (
owner = " testUser " , repo = " testRepo " , issue_number = 1 , state = " closeddddd "
)
assert (
" closeddddd is not a valid option for state; must be one of [ ' open ' , ' closed ' ] "
== str ( e . value )
)
2018-02-07 12:04:38 -06:00
2018-06-01 15:28:53 -05:00
def test_validate_boolean_values ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.post " )
Octokit ( ) . repos . create_deployment (
owner = " testUser " , repo = " testRepo " , ref = " abc123 "
)
2020-01-16 16:31:40 -06:00
data = ' { " auto_merge " : true, " description " : " " , " environment " : " production " , " payload " : " " , " ref " : " abc123 " , " task " : " deploy " , " transient_environment " : false} ' # noqa E501
2020-01-17 11:49:05 -06:00
headers = {
" Content-Type " : " application/json " ,
" accept " : " application/vnd.github.v3+json " ,
}
2018-06-01 15:28:53 -05:00
requests . post . assert_called_once_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/repos/testUser/testRepo/deployments " ,
data = data ,
headers = headers ,
2018-06-01 15:28:53 -05:00
)
2020-01-17 11:49:05 -06:00
def test_non_default_params_not_in_the_url_for_get_requests_go_in_the_query_string (
self , mocker
) :
mocker . patch ( " requests.get " )
params = { " page " : 2 , " per_page " : 30 }
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . list_grants ( page = 2 )
2018-02-07 12:04:38 -06:00
requests . get . assert_called_once_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/applications/grants " ,
params = params ,
headers = Octokit ( ) . headers ,
2018-02-07 12:04:38 -06:00
)
2018-02-26 13:14:33 -06:00
2020-01-16 16:31:40 -06:00
def test_does_not_use_previous_values ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.patch " )
mocker . patch ( " requests.post " )
headers = {
" accept " : " application/vnd.github.v3+json " ,
" Content-Type " : " application/json " ,
}
data = { " state " : " closed " }
issue = Octokit ( ) . issues . update (
owner = " testUser " , repo = " testRepo " , issue_number = 1 , * * data
)
2018-02-27 08:41:58 -06:00
requests . patch . assert_called_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/repos/testUser/testRepo/issues/1 " ,
data = json . dumps ( data ) ,
headers = headers ,
)
issue . pulls . create (
owner = " user " , head = " branch " , base = " master " , title = " Title " , repo = " testRepo "
2018-02-27 08:41:58 -06:00
)
requests . post . assert_called_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/repos/user/testRepo/pulls " ,
data = json . dumps (
{ " base " : " master " , " head " : " branch " , " title " : " Title " } , sort_keys = True
) ,
2018-02-27 09:22:51 -06:00
headers = {
2020-01-17 11:49:05 -06:00
" Content-Type " : " application/json " ,
" accept " : " application/vnd.github.v3+json " ,
} ,
2018-02-27 08:41:58 -06:00
)
2018-03-12 15:10:10 -05:00
def test_returned_object_is_not_self_but_a_copy_of_self ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.patch " )
headers = {
" accept " : " application/vnd.github.v3+json " ,
" Content-Type " : " application/json " ,
}
2018-03-12 15:10:10 -05:00
octokit = Octokit ( )
2020-01-17 11:49:05 -06:00
sut = octokit . issues . update ( owner = " testUser " , repo = " testRepo " , issue_number = 1 )
2018-02-26 13:14:33 -06:00
requests . patch . assert_called_once_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/repos/testUser/testRepo/issues/1 " ,
data = " {} " ,
headers = headers ,
2018-02-26 13:14:33 -06:00
)
2020-01-17 11:49:05 -06:00
assert sut . __class__ . __name__ == " Octokit "
2018-03-12 15:10:10 -05:00
assert sut != octokit
2018-02-26 13:14:33 -06:00
def test_returned_object_has_requests_response_object ( self , mocker ) :
2020-01-17 11:49:05 -06:00
patch = mocker . patch ( " requests.patch " )
Response = namedtuple ( " Response " , [ " json " ] )
2018-02-26 13:14:33 -06:00
patch . return_value = Response ( json = lambda : { } )
2020-01-17 11:49:05 -06:00
sut = Octokit ( ) . issues . update ( owner = " testUser " , repo = " testRepo " , issue_number = 1 )
assert sut . _response . __class__ . __name__ == " Response "
2018-02-26 13:14:33 -06:00
def test_returned_object_has_json_attribute ( self , mocker ) :
2020-01-17 11:49:05 -06:00
patch = mocker . patch ( " requests.get " )
Request = namedtuple ( " Request " , [ " json " ] )
2018-02-26 13:14:33 -06:00
patch . return_value = Request ( json = lambda : data )
2019-04-16 20:56:41 -05:00
data = {
2020-01-17 11:49:05 -06:00
" documentation_url " : " https://developer.github.com/v3/issues/#get-a-single-issue " ,
" message " : " Not Found " ,
2019-04-16 20:56:41 -05:00
}
2020-01-17 11:49:05 -06:00
sut = Octokit ( ) . issues . get ( owner = " testUser " , repo = " testRepo " , issue_number = 1 )
2018-02-26 13:14:33 -06:00
assert sut . json == data
def test_returned_object_has_response_attributes ( self , mocker ) :
2020-01-17 11:49:05 -06:00
patch = mocker . patch ( " requests.patch " )
2018-02-26 13:14:33 -06:00
data = {
" id " : 1 ,
" number " : 1347 ,
" state " : " open " ,
" title " : " Found a bug " ,
2020-01-17 11:49:05 -06:00
" user " : { " login " : " octocat " , " site_admin " : False } ,
" labels " : [ { " id " : 208045946 } , { " id " : 208045947 } ] ,
2018-02-26 13:14:33 -06:00
}
2020-01-17 11:49:05 -06:00
Request = namedtuple ( " Request " , [ " json " ] )
2018-02-26 13:14:33 -06:00
patch . return_value = Request ( json = lambda : data )
2020-01-17 11:49:05 -06:00
sut = Octokit ( ) . issues . update ( owner = " testUser " , repo = " testRepo " , issue_number = 1 )
2018-02-26 13:14:33 -06:00
assert sut . response . id == 1
assert sut . response . number == 1347
2020-01-17 11:49:05 -06:00
assert sut . response . state == " open "
assert str ( sut . response . user ) == " <class ' octokit.ResponseData ' > "
assert sut . response . user . login == " octocat "
2018-02-26 13:14:33 -06:00
assert sut . response . user . site_admin is False
assert sut . response . labels [ 0 ] . id == 208045946
def test_returned_object_is_a_list ( self , mocker ) :
2020-01-17 11:49:05 -06:00
patch = mocker . patch ( " requests.patch " )
data = [ { " id " : 208045946 } , { " id " : 208045947 } ]
Request = namedtuple ( " Request " , [ " json " ] )
2018-02-26 13:14:33 -06:00
patch . return_value = Request ( json = lambda : data )
2020-01-17 11:49:05 -06:00
sut = Octokit ( ) . issues . update ( owner = " testUser " , repo = " testRepo " , issue_number = 1 )
2018-02-26 13:14:33 -06:00
assert sut . response [ 0 ] . id == 208045946
2018-03-01 15:03:33 -06:00
def test_an_exception_with_json_is_replaced_by_the_raw_text ( self , mocker ) :
2020-01-17 11:49:05 -06:00
patch = mocker . patch ( " requests.patch " )
Request = namedtuple ( " Request " , [ " json " ] )
patch . return_value = Request ( json = lambda : " test " )
sut = Octokit ( ) . issues . update ( owner = " testUser " , repo = " testRepo " , issue_number = 1 )
assert sut . json == " test "
2018-10-04 11:01:46 -05:00
def test_can_pass_in_optional_headers ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.get " )
headers = {
" accept " : " application/vnd.github.ant-man-preview+json " ,
" Content-Type " : " application/json " ,
}
2018-10-04 11:01:46 -05:00
Octokit ( ) . oauth_authorizations . get_authorization (
2020-01-17 11:49:05 -06:00
authorization_id = 100 ,
headers = { " accept " : " application/vnd.github.ant-man-preview+json " } ,
)
requests . get . assert_called_once_with (
" https://api.github.com/authorizations/100 " , params = { } , headers = headers
2018-10-04 11:01:46 -05:00
)
2018-10-05 09:59:44 -05:00
def test_dictionary_keys_are_validated ( self , mocker ) :
2020-01-17 11:49:05 -06:00
mocker . patch ( " requests.put " )
headers = {
" accept " : " application/vnd.github.v3+json " ,
" Content-Type " : " application/json " ,
}
2018-10-05 09:59:44 -05:00
data = {
2020-01-17 11:49:05 -06:00
" required_status_checks " : { " strict " : True , " contexts " : [ ] } ,
" required_pull_request_reviews " : { " dismiss_stale_reviews " : True } ,
2018-10-05 09:59:44 -05:00
" enforce_admins " : True ,
2020-01-17 11:49:05 -06:00
" restrictions " : { " users " : [ ] , " teams " : [ ] } ,
2018-10-05 09:59:44 -05:00
}
2020-01-17 11:49:05 -06:00
Octokit ( ) . repos . update_branch_protection (
owner = " user " , repo = " repo " , branch = " branch " , * * data
)
2018-10-05 09:59:44 -05:00
requests . put . assert_called_with (
2020-01-17 11:49:05 -06:00
" https://api.github.com/repos/user/repo/branches/branch/protection " ,
2018-10-05 09:59:44 -05:00
data = json . dumps ( data , sort_keys = True ) ,
2020-01-17 11:49:05 -06:00
headers = headers ,
2018-10-05 09:59:44 -05:00
)
2019-01-02 14:34:57 -06:00
@property
def doc_string ( self ) :
2020-01-16 16:31:40 -06:00
return """ List all notifications for the current user, sorted by most recently updated. \n \n The following example uses the `since` parameter to list notifications that have been updated after the specified time. """ # noqa E501