@@ -23,19 +23,34 @@ def setup
2323 sid : "abc123" ,
2424 }
2525 @session_token = JWT . encode ( @jwt_payload , ShopifyAPI ::Context . api_secret_key , "HS256" )
26- @token_exchange_request = {
26+ base_offline_token_exchange_request = {
2727 client_id : ShopifyAPI ::Context . api_key ,
2828 client_secret : ShopifyAPI ::Context . api_secret_key ,
2929 grant_type : "urn:ietf:params:oauth:grant-type:token-exchange" ,
3030 subject_token_type : "urn:ietf:params:oauth:token-type:id_token" ,
3131 subject_token : @session_token ,
3232 requested_token_type : "urn:shopify:params:oauth:token-type:offline-access-token" ,
3333 }
34+ @non_expiring_offline_token_exchange_request = base_offline_token_exchange_request . merge ( { expiring : 0 } )
35+ @expiring_offline_token_exchange_request = base_offline_token_exchange_request . merge ( { expiring : 1 } )
36+
37+ @online_token_exchange_request = base_offline_token_exchange_request . merge (
38+ { requested_token_type : "urn:shopify:params:oauth:token-type:online-access-token" } ,
39+ )
40+
3441 @offline_token_response = {
3542 access_token : SecureRandom . alphanumeric ( 10 ) ,
3643 scope : "scope1,scope2" ,
3744 session : SecureRandom . alphanumeric ( 10 ) ,
3845 }
46+ @expiring_offline_token_response = @offline_token_response . merge (
47+ {
48+ expires_in : 2000 ,
49+ refresh_token : SecureRandom . alphanumeric ( 10 ) ,
50+ refresh_token_expires_in : 4000 ,
51+ } ,
52+ )
53+
3954 @online_token_response = {
4055 access_token : SecureRandom . alphanumeric ( 10 ) ,
4156 scope : "scope1,scope2" ,
@@ -117,7 +132,7 @@ def test_exchange_token_invalid_session_token
117132 def test_exchange_token_rejected_session_token
118133 modify_context ( is_embedded : true )
119134 stub_request ( :post , "https://#{ @shop } /admin/oauth/access_token" )
120- . with ( body : @token_exchange_request )
135+ . with ( body : @non_expiring_offline_token_exchange_request )
121136 . to_return (
122137 status : 400 ,
123138 body : { error : "invalid_subject_token" } . to_json ,
@@ -134,9 +149,9 @@ def test_exchange_token_rejected_session_token
134149 end
135150
136151 def test_exchange_token_offline_token
137- modify_context ( is_embedded : true )
152+ modify_context ( is_embedded : true , expiring_offline_access_tokens : false )
138153 stub_request ( :post , "https://#{ @shop } /admin/oauth/access_token" )
139- . with ( body : @token_exchange_request )
154+ . with ( body : @non_expiring_offline_token_exchange_request )
140155 . to_return ( body : @offline_token_response . to_json , headers : { content_type : "application/json" } )
141156 expected_session = ShopifyAPI ::Auth ::Session . new (
142157 id : "offline_#{ @shop } " ,
@@ -146,6 +161,8 @@ def test_exchange_token_offline_token
146161 is_online : false ,
147162 expires : nil ,
148163 shopify_session_id : @offline_token_response [ :session ] ,
164+ refresh_token : nil ,
165+ refresh_token_expires : nil ,
149166 )
150167
151168 session = ShopifyAPI ::Auth ::TokenExchange . exchange_token (
@@ -157,12 +174,38 @@ def test_exchange_token_offline_token
157174 assert_equal ( expected_session , session )
158175 end
159176
177+ def test_exchange_token_expiring_offline_token
178+ modify_context ( is_embedded : true , expiring_offline_access_tokens : true )
179+ stub_request ( :post , "https://#{ @shop } /admin/oauth/access_token" )
180+ . with ( body : @expiring_offline_token_exchange_request )
181+ . to_return ( body : @expiring_offline_token_response . to_json , headers : { content_type : "application/json" } )
182+ expected_session = ShopifyAPI ::Auth ::Session . new (
183+ id : "offline_#{ @shop } " ,
184+ shop : @shop ,
185+ access_token : @expiring_offline_token_response [ :access_token ] ,
186+ scope : @expiring_offline_token_response [ :scope ] ,
187+ is_online : false ,
188+ expires : @stubbed_time_now + @expiring_offline_token_response [ :expires_in ] . to_i ,
189+ shopify_session_id : @expiring_offline_token_response [ :session ] ,
190+ refresh_token : @expiring_offline_token_response [ :refresh_token ] ,
191+ refresh_token_expires : @stubbed_time_now + @expiring_offline_token_response [ :refresh_token_expires_in ] . to_i ,
192+ )
193+
194+ session = Time . stub ( :now , @stubbed_time_now ) do
195+ ShopifyAPI ::Auth ::TokenExchange . exchange_token (
196+ shop : @shop ,
197+ session_token : @session_token ,
198+ requested_token_type : ShopifyAPI ::Auth ::TokenExchange ::RequestedTokenType ::OFFLINE_ACCESS_TOKEN ,
199+ )
200+ end
201+
202+ assert_equal ( expected_session , session )
203+ end
204+
160205 def test_exchange_token_online_token
161206 modify_context ( is_embedded : true )
162207 stub_request ( :post , "https://#{ @shop } /admin/oauth/access_token" )
163- . with ( body : @token_exchange_request . dup . tap do |h |
164- h [ :requested_token_type ] = "urn:shopify:params:oauth:token-type:online-access-token"
165- end )
208+ . with ( body : @online_token_exchange_request )
166209 . to_return ( body : @online_token_response . to_json , headers : { content_type : "application/json" } )
167210 expected_session = ShopifyAPI ::Auth ::Session . new (
168211 id : "#{ @shop } _#{ @online_token_response [ :associated_user ] [ :id ] } " ,
0 commit comments