@@ -7,6 +7,7 @@ class TwitterAPIClientTests: XCTestCase {
77 }
88
99 override func tearDownWithError( ) throws {
10+ MockURLProtocol . cleanup ( )
1011 }
1112
1213 func testJSONDecoder( ) throws {
@@ -18,13 +19,116 @@ class TwitterAPIClientTests: XCTestCase {
1819 XCTAssertEqual ( dateV1, dateV2)
1920 }
2021
21- func testRefreshInvalidAuthMethod( ) throws {
22+ func testRefreshToken( ) throws {
23+ let config = URLSessionConfiguration . default
24+ config. protocolClasses = [ MockURLProtocol . self]
25+
26+ let client = TwitterAPIClient (
27+ . oauth20(
28+ . init( clientID: " c " , scope: [ ] , tokenType: " t " , expiresIn: 0 , accessToken: " a " , refreshToken: " r " ) ) ,
29+ configuration: config
30+ )
31+
32+ MockURLProtocol . requestHandler = { request in
33+ let data = Data (
34+ #"""
35+ {
36+ "scope" : "tweet.write",
37+ "token_type" : "bearer",
38+ "expires_in" : 7200,
39+ "access_token" : "<token>",
40+ "refresh_token" : "<refresh token>"
41+ }
42+ """# . utf8)
43+ return (
44+ HTTPURLResponse ( url: request. url!, statusCode: 200 , httpVersion: " 2.0 " , headerFields: nil ) !, data
45+ )
46+ }
47+
48+ if case let . oauth20( token) = client. apiAuth {
49+ XCTAssertEqual ( token. accessToken, " a " )
50+ XCTAssertEqual ( token. refreshToken, " r " )
51+ } else {
52+ XCTFail ( )
53+ }
54+
55+ let exp = expectation ( description: " " )
56+ client. refreshOAuth20Token ( type: . publicClient) { result in
57+ do {
58+ let newToken = try result. get ( )
59+ XCTAssertEqual ( newToken. accessToken, " <token> " )
60+ XCTAssertEqual ( newToken. refreshToken, " <refresh token> " )
61+ } catch {
62+ XCTFail ( " Error: \( error) " )
63+ }
64+ exp. fulfill ( )
65+ }
66+ wait ( for: [ exp] , timeout: 10 )
67+
68+ // check refresh
69+ if case let . oauth20( token) = client. apiAuth {
70+ XCTAssertEqual ( token. accessToken, " <token> " )
71+ XCTAssertEqual ( token. refreshToken, " <refresh token> " )
72+ } else {
73+ XCTFail ( )
74+ }
75+ }
76+
77+ func testRefreshTokenForceRefresh( ) throws {
78+ let config = URLSessionConfiguration . default
79+ config. protocolClasses = [ MockURLProtocol . self]
80+
81+ let client = TwitterAPIClient (
82+ . oauth20(
83+ . init( clientID: " c " , scope: [ ] , tokenType: " t " , expiresIn: 1000 , accessToken: " a " , refreshToken: " r " )
84+ ) ,
85+ configuration: config
86+ )
87+
88+ MockURLProtocol . requestHandler = { request in
89+ let data = Data (
90+ #"""
91+ {
92+ "scope" : "tweet.write",
93+ "token_type" : "bearer",
94+ "expires_in" : 7200,
95+ "access_token" : "<token>",
96+ "refresh_token" : "<refresh token>"
97+ }
98+ """# . utf8)
99+ return (
100+ HTTPURLResponse ( url: request. url!, statusCode: 200 , httpVersion: " 2.0 " , headerFields: nil ) !, data
101+ )
102+ }
103+
104+ let exp = expectation ( description: " " )
105+ client. refreshOAuth20Token ( type: . publicClient, forceRefresh: true ) { result in
106+ do {
107+ let newToken = try result. get ( )
108+ XCTAssertEqual ( newToken. accessToken, " <token> " )
109+ XCTAssertEqual ( newToken. refreshToken, " <refresh token> " )
110+ } catch {
111+ XCTFail ( " Error: \( error) " )
112+ }
113+ exp. fulfill ( )
114+ }
115+ wait ( for: [ exp] , timeout: 10 )
116+
117+ // check refresh
118+ if case let . oauth20( token) = client. apiAuth {
119+ XCTAssertEqual ( token. accessToken, " <token> " )
120+ XCTAssertEqual ( token. refreshToken, " <refresh token> " )
121+ } else {
122+ XCTFail ( )
123+ }
124+ }
125+ func testRefreshToken_invalidAuthenticationMethod( ) throws {
22126 let client = TwitterAPIClient ( . none)
23127 let exp = expectation ( description: " " )
24128 client. refreshOAuth20Token ( type: . publicClient) { result in
25129 switch result {
26- case . failure( let error ) :
27- XCTAssertTrue ( error . isRefreshOAuth20TokenFailed )
130+ case . failure( . refreshOAuth20TokenFailed ( reason : . invalidAuthenticationMethod ( . none ) ) ) :
131+ break
28132 default :
29133 XCTFail ( )
30134 }
@@ -33,14 +137,51 @@ class TwitterAPIClientTests: XCTestCase {
33137 wait ( for: [ exp] , timeout: 10 )
34138 }
35139
36- func testRefreshTokenMissingRefreshToken ( ) throws {
140+ func testRefreshToken_refreshTokenIsMissing ( ) throws {
37141 let client = TwitterAPIClient (
38- . oauth20( . init( clientID: " " , scope: [ ] , tokenType: " " , expiresIn: 0 , accessToken: " " , refreshToken: nil ) ) )
142+ . oauth20(
143+ . init(
144+ clientID: " " ,
145+ scope: [ ] ,
146+ tokenType: " " ,
147+ expiresIn: 0 ,
148+ accessToken: " " ,
149+ refreshToken: nil
150+ ) ) )
151+ let exp = expectation ( description: " " )
152+ client. refreshOAuth20Token ( type: . publicClient) { result in
153+ switch result {
154+ case . failure( . refreshOAuth20TokenFailed( reason: . refreshTokenIsMissing) ) :
155+ break
156+ default :
157+ XCTFail ( )
158+ }
159+ exp. fulfill ( )
160+ }
161+ wait ( for: [ exp] , timeout: 10 )
162+ }
163+
164+ func testRefreshTokenNotExpired( ) throws {
165+ let now = Date ( )
166+ let client = TwitterAPIClient (
167+ . oauth20(
168+ . init(
169+ clientID: " c " ,
170+ scope: [ ] ,
171+ tokenType: " t " ,
172+ expiresIn: 100 ,
173+ accessToken: " a " ,
174+ refreshToken: " r " ,
175+ createdAt: now
176+ ) ) )
177+
39178 let exp = expectation ( description: " " )
40179 client. refreshOAuth20Token ( type: . publicClient) { result in
41180 switch result {
42- case . failure( let error) :
43- XCTAssertTrue ( error. isRefreshOAuth20TokenFailed)
181+ case . success( let token) :
182+ XCTAssertEqual ( token. clientID, " c " )
183+ XCTAssertEqual ( token. refreshToken, " r " )
184+ XCTAssertEqual ( token. createdAt, now)
44185 default :
45186 XCTFail ( )
46187 }
0 commit comments