11using System ;
2+ using System . Collections . Generic ;
23using System . Net ;
34using System . Threading . Tasks ;
45using GitHub . Api ;
@@ -18,7 +19,7 @@ public class TheLoginMethod
1819 [ Fact ]
1920 public async Task LoginTokenIsSavedToCache ( )
2021 {
21- var client = Substitute . For < IGitHubClient > ( ) ;
22+ var client = CreateClient ( ) ;
2223 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
2324 . Returns ( new ApplicationAuthorization ( "123abc" ) ) ;
2425
@@ -35,11 +36,10 @@ public async Task LoginTokenIsSavedToCache()
3536 [ Fact ]
3637 public async Task LoggedInUserIsReturned ( )
3738 {
38- var client = Substitute . For < IGitHubClient > ( ) ;
3939 var user = new User ( ) ;
40+ var client = CreateClient ( user ) ;
4041 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
4142 . Returns ( new ApplicationAuthorization ( "123abc" ) ) ;
42- client . User . Current ( ) . Returns ( user ) ;
4343
4444 var keychain = Substitute . For < IKeychain > ( ) ;
4545 var tfa = Substitute . For < ITwoFactorChallengeHandler > ( ) ;
@@ -57,7 +57,7 @@ public async Task DeletesExistingAuthenticationIfNullTokenReturned()
5757 // If GetOrCreateApplicationAuthentication is called and a matching token already exists,
5858 // the returned token will be null because it is assumed that the token will be stored
5959 // locally. In this case, the existing token should be first deleted.
60- var client = Substitute . For < IGitHubClient > ( ) ;
60+ var client = CreateClient ( ) ;
6161 var user = new User ( ) ;
6262 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
6363 . Returns (
@@ -80,7 +80,7 @@ public async Task DeletesExistingAuthenticationIfNullTokenReturned()
8080 [ Fact ]
8181 public async Task TwoFactorExceptionIsPassedToHandler ( )
8282 {
83- var client = Substitute . For < IGitHubClient > ( ) ;
83+ var client = CreateClient ( ) ;
8484 var exception = new TwoFactorChallengeFailedException ( ) ;
8585
8686 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
@@ -106,7 +106,7 @@ await client.Authorization.Received().GetOrCreateApplicationAuthentication(
106106 [ Fact ]
107107 public async Task Failed2FACodeResultsInRetry ( )
108108 {
109- var client = Substitute . For < IGitHubClient > ( ) ;
109+ var client = CreateClient ( ) ;
110110 var exception = new TwoFactorChallengeFailedException ( ) ;
111111
112112 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
@@ -141,7 +141,7 @@ await client.Authorization.Received(1).GetOrCreateApplicationAuthentication(
141141 [ Fact ]
142142 public async Task HandlerNotifiedOfExceptionIn2FAChallengeResponse ( )
143143 {
144- var client = Substitute . For < IGitHubClient > ( ) ;
144+ var client = CreateClient ( ) ;
145145 var twoFaException = new TwoFactorChallengeFailedException ( ) ;
146146 var forbiddenResponse = Substitute . For < IResponse > ( ) ;
147147 forbiddenResponse . StatusCode . Returns ( HttpStatusCode . Forbidden ) ;
@@ -173,7 +173,7 @@ await client.Authorization.Received(1).GetOrCreateApplicationAuthentication(
173173 [ Fact ]
174174 public async Task RequestResendCodeResultsInRetryingLogin ( )
175175 {
176- var client = Substitute . For < IGitHubClient > ( ) ;
176+ var client = CreateClient ( ) ;
177177 var exception = new TwoFactorChallengeFailedException ( ) ;
178178 var user = new User ( ) ;
179179
@@ -199,11 +199,11 @@ public async Task RequestResendCodeResultsInRetryingLogin()
199199 [ Fact ]
200200 public async Task UsesUsernameAndPasswordInsteadOfAuthorizationTokenWhenEnterpriseAndAPIReturns404 ( )
201201 {
202- var client = Substitute . For < IGitHubClient > ( ) ;
202+ var client = CreateClient ( ) ;
203203 var user = new User ( ) ;
204204
205205 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
206- . Returns < ApplicationAuthorization > ( _ =>
206+ . Returns < ApplicationAuthorization > ( _ =>
207207 {
208208 throw new NotFoundException ( "Not there" , HttpStatusCode . NotFound ) ;
209209 } ) ;
@@ -222,7 +222,7 @@ public async Task UsesUsernameAndPasswordInsteadOfAuthorizationTokenWhenEnterpri
222222 [ Fact ]
223223 public async Task ErasesLoginWhenUnauthorized ( )
224224 {
225- var client = Substitute . For < IGitHubClient > ( ) ;
225+ var client = CreateClient ( ) ;
226226 var user = new User ( ) ;
227227
228228 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
@@ -241,7 +241,7 @@ public async Task ErasesLoginWhenUnauthorized()
241241 [ Fact ]
242242 public async Task ErasesLoginWhenNonOctokitExceptionThrown ( )
243243 {
244- var client = Substitute . For < IGitHubClient > ( ) ;
244+ var client = CreateClient ( ) ;
245245 var user = new User ( ) ;
246246
247247 client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
@@ -260,7 +260,7 @@ public async Task ErasesLoginWhenNonOctokitExceptionThrown()
260260 [ Fact ]
261261 public async Task ErasesLoginWhenNonOctokitExceptionThrownIn2FA ( )
262262 {
263- var client = Substitute . For < IGitHubClient > ( ) ;
263+ var client = CreateClient ( ) ;
264264 var user = new User ( ) ;
265265 var exception = new TwoFactorChallengeFailedException ( ) ;
266266
@@ -280,5 +280,34 @@ public async Task ErasesLoginWhenNonOctokitExceptionThrownIn2FA()
280280
281281 await keychain . Received ( ) . Delete ( host ) ;
282282 }
283+
284+ [ Fact ]
285+ public async Task InvalidResponseScopesCauseException ( )
286+ {
287+ var client = CreateClient ( responseScopes : new [ ] { "user" , "repo" } ) ;
288+ client . Authorization . GetOrCreateApplicationAuthentication ( "id" , "secret" , Arg . Any < NewAuthorization > ( ) )
289+ . Returns ( new ApplicationAuthorization ( "123abc" ) ) ;
290+
291+ var keychain = Substitute . For < IKeychain > ( ) ;
292+ var tfa = Substitute . For < ITwoFactorChallengeHandler > ( ) ;
293+ var oauthListener = Substitute . For < IOAuthCallbackListener > ( ) ;
294+
295+ var target = new LoginManager ( keychain , tfa , oauthListener , "id" , "secret" , scopes ) ;
296+
297+ await Assert . ThrowsAsync < IncorrectScopesException > ( ( ) => target . Login ( host , client , "foo" , "bar" ) ) ;
298+ }
299+
300+ IGitHubClient CreateClient ( User user = null , string [ ] responseScopes = null )
301+ {
302+ var result = Substitute . For < IGitHubClient > ( ) ;
303+ var userResponse = Substitute . For < IApiResponse < User > > ( ) ;
304+ userResponse . HttpResponse . Headers . Returns ( new Dictionary < string , string >
305+ {
306+ { "X-OAuth-Scopes" , string . Join ( "," , responseScopes ?? scopes ) }
307+ } ) ;
308+ userResponse . Body . Returns ( user ?? new User ( ) ) ;
309+ result . Connection . Get < User > ( new Uri ( "user" , UriKind . Relative ) , null , null ) . Returns ( userResponse ) ;
310+ return result ;
311+ }
283312 }
284- }
313+ }
0 commit comments