session_test.rb 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. # frozen_string_literal: true
  2. require 'test_helper'
  3. require 'timecop'
  4. class SessionTest < Test::Unit::TestCase
  5. SECONDS_IN_A_DAY = 24 * 60 * 60
  6. def setup
  7. super
  8. ShopifyAPI::Session.secret = 'secret'
  9. end
  10. test "not be valid without a url" do
  11. session = ShopifyAPI::Session.new(domain: nil, token: "any-token", api_version: any_api_version)
  12. assert_not(session.valid?)
  13. end
  14. test "not be valid without token" do
  15. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
  16. assert_not(session.valid?)
  17. end
  18. test "not be valid without an API version" do
  19. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: nil)
  20. assert_not(session.valid?)
  21. session = ShopifyAPI::Session.new(
  22. domain: "testshop.myshopify.com", token: "any-token", api_version: ShopifyAPI::ApiVersion::NullVersion
  23. )
  24. assert_not(session.valid?)
  25. end
  26. test "default to base API version" do
  27. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token")
  28. assert(session.valid?)
  29. assert_equal(session.api_version, ShopifyAPI::Base.api_version)
  30. end
  31. test "can override the base API version" do
  32. different_api_version = '2020-01'
  33. session = ShopifyAPI::Session.new(
  34. domain: "testshop.myshopify.com", token: "any-token", api_version: different_api_version
  35. )
  36. assert(session.valid?)
  37. assert_equal(session.api_version, ShopifyAPI::ApiVersion.find_version(different_api_version))
  38. end
  39. test "be valid with any token, any url and version" do
  40. session = ShopifyAPI::Session.new(
  41. domain: "testshop.myshopify.com",
  42. token: "any-token",
  43. api_version: any_api_version
  44. )
  45. assert(session.valid?)
  46. end
  47. test "be valid with nil access_scopes" do
  48. session = ShopifyAPI::Session.new(
  49. domain: "testshop.myshopify.com",
  50. token: "any-token",
  51. api_version: any_api_version,
  52. access_scopes: nil
  53. )
  54. assert(session.valid?)
  55. end
  56. test "be valid with string of access_scopes" do
  57. session = ShopifyAPI::Session.new(
  58. domain: "testshop.myshopify.com",
  59. token: "any-token",
  60. api_version: any_api_version,
  61. access_scopes: "read_products, write_orders"
  62. )
  63. assert(session.valid?)
  64. end
  65. test "be valid with a collection of access_scopes" do
  66. session = ShopifyAPI::Session.new(
  67. domain: "testshop.myshopify.com",
  68. token: "any-token",
  69. api_version: any_api_version,
  70. access_scopes: %w(read_products write_orders)
  71. )
  72. assert(session.valid?)
  73. end
  74. test "not raise error without params" do
  75. assert_nothing_raised do
  76. ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: any_api_version)
  77. end
  78. end
  79. test "ignore everything but the subdomain in the shop" do
  80. assert_equal_uri(
  81. "https://testshop.myshopify.com",
  82. ShopifyAPI::Session.new(
  83. domain: "http://user:pass@testshop.notshopify.net/path",
  84. token: "any-token",
  85. api_version: any_api_version
  86. ).site
  87. )
  88. end
  89. test "append the myshopify domain if not given" do
  90. assert_equal_uri(
  91. "https://testshop.myshopify.com",
  92. ShopifyAPI::Session.new(domain: "testshop", token: "any-token", api_version: any_api_version).site
  93. )
  94. end
  95. test "not raise error without params" do
  96. assert_nothing_raised do
  97. ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: any_api_version)
  98. end
  99. end
  100. test "provides default nil access_scopes attribute" do
  101. session = ShopifyAPI::Session.new(
  102. domain: "testshop.myshopify.com",
  103. token: "any-token",
  104. api_version: any_api_version
  105. )
  106. assert_nil session.access_scopes
  107. end
  108. test "provides specified nil access_scopes attribute" do
  109. session = ShopifyAPI::Session.new(
  110. domain: "testshop.myshopify.com",
  111. token: "any-token",
  112. access_scopes: "read_products",
  113. api_version: any_api_version
  114. )
  115. assert_equal "read_products", session.access_scopes.to_s
  116. end
  117. test "session instantiation raises error if bad access scopes are provided" do
  118. assert_raises NoMethodError do
  119. ShopifyAPI::Session.new(
  120. domain: "testshop.myshopify.com",
  121. token: "any-token",
  122. access_scopes: { bad_input: "bad_input" },
  123. api_version: any_api_version
  124. )
  125. end
  126. end
  127. test "raise error if params passed but signature omitted" do
  128. assert_raises(ShopifyAPI::ValidationException) do
  129. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
  130. session.request_token({ 'code' => 'any-code' })
  131. end
  132. end
  133. test "setup api_key and secret for all sessions" do
  134. ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
  135. assert_equal("My test key", ShopifyAPI::Session.api_key)
  136. assert_equal("My test secret", ShopifyAPI::Session.secret)
  137. end
  138. test "#temp reset ShopifyAPI::Base values to original value" do
  139. session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
  140. ShopifyAPI::Base.user = 'foo'
  141. ShopifyAPI::Base.password = 'bar'
  142. ShopifyAPI::Base.activate_session(session1)
  143. ShopifyAPI::Session.temp(domain: "testshop.myshopify.com", token: "any-token", api_version: :unstable) do
  144. @assigned_site = ShopifyAPI::Base.site
  145. @assigned_version = ShopifyAPI::Base.api_version
  146. @assigned_user = ShopifyAPI::Base.user
  147. @assigned_password = ShopifyAPI::Base.password
  148. end
  149. assert_equal('https://testshop.myshopify.com', @assigned_site.to_s)
  150. assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
  151. assert_equal(ShopifyAPI::ApiVersion.new(handle: :unstable), @assigned_version)
  152. assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
  153. assert_nil(@assigned_user)
  154. assert_equal('foo', ShopifyAPI::Base.user)
  155. assert_nil(@assigned_password)
  156. assert_equal('bar', ShopifyAPI::Base.password)
  157. end
  158. test "#temp does not use basic auth values from Base.site" do
  159. ShopifyAPI::Base.site = 'https://user:pass@fakeshop.myshopify.com'
  160. ShopifyAPI::Session.temp(domain: "testshop.myshopify.com", token: "any-token", api_version: :unstable) do
  161. @assigned_site = ShopifyAPI::Base.site
  162. @assigned_user = ShopifyAPI::Base.user
  163. @assigned_password = ShopifyAPI::Base.password
  164. end
  165. assert_equal('https://testshop.myshopify.com', @assigned_site.to_s)
  166. assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
  167. assert_nil(@assigned_user)
  168. assert_equal('user', ShopifyAPI::Base.user)
  169. assert_nil(@assigned_password)
  170. assert_equal('pass', ShopifyAPI::Base.password)
  171. end
  172. test "#with_session activates the session for the duration of the block" do
  173. session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
  174. ShopifyAPI::Base.activate_session(session1)
  175. other_session = ShopifyAPI::Session.new(
  176. domain: "testshop.myshopify.com",
  177. token: "any-token",
  178. api_version: :unstable
  179. )
  180. ShopifyAPI::Session.with_session(other_session) do
  181. @assigned_site = ShopifyAPI::Base.site
  182. @assigned_version = ShopifyAPI::Base.api_version
  183. end
  184. assert_equal('https://testshop.myshopify.com', @assigned_site.to_s)
  185. assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
  186. assert_equal(ShopifyAPI::ApiVersion.new(handle: :unstable), @assigned_version)
  187. assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
  188. end
  189. test "#with_session resets the activated session even if there an exception during the block" do
  190. session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
  191. ShopifyAPI::Base.activate_session(session1)
  192. other_session = ShopifyAPI::Session.new(
  193. domain: "testshop.myshopify.com",
  194. token: "any-token",
  195. api_version: :unstable
  196. )
  197. assert_raises(StandardError) do
  198. ShopifyAPI::Session.with_session(other_session) { raise StandardError, "" }
  199. end
  200. assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
  201. assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
  202. end
  203. test "#with_version will adjust the actvated api version for the duration of the block" do
  204. session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
  205. ShopifyAPI::Base.activate_session(session1)
  206. ShopifyAPI::Session.with_version(:unstable) do
  207. @assigned_site = ShopifyAPI::Base.site
  208. @assigned_version = ShopifyAPI::Base.api_version
  209. end
  210. assert_equal('https://fakeshop.myshopify.com', @assigned_site.to_s)
  211. assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
  212. assert_equal(ShopifyAPI::ApiVersion.new(handle: :unstable), @assigned_version)
  213. assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
  214. end
  215. test "create_permission_url requires redirect_uri" do
  216. ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
  217. session = ShopifyAPI::Session.new(
  218. domain: 'http://localhost.myshopify.com',
  219. token: 'any-token',
  220. api_version: any_api_version
  221. )
  222. scope = ["write_products"]
  223. assert_raises(ArgumentError) do
  224. session.create_permission_url(scope)
  225. end
  226. end
  227. test "create_permission_url returns correct url with single scope and redirect uri" do
  228. ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
  229. session = ShopifyAPI::Session.new(
  230. domain: 'http://localhost.myshopify.com',
  231. token: 'any-token',
  232. api_version: any_api_version
  233. )
  234. scope = ["write_products"]
  235. permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
  236. assert_equal_uri(
  237. "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
  238. "scope=write_products&redirect_uri=http://my_redirect_uri.com",
  239. permission_url
  240. )
  241. end
  242. test "create_permission_url returns correct url with dual scope" do
  243. ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
  244. session = ShopifyAPI::Session.new(
  245. domain: 'http://localhost.myshopify.com',
  246. token: 'any-token',
  247. api_version: any_api_version
  248. )
  249. scope = ["write_products", "write_customers"]
  250. permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
  251. assert_equal_uri(
  252. "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
  253. "scope=write_products,write_customers&redirect_uri=http://my_redirect_uri.com",
  254. permission_url
  255. )
  256. end
  257. test "create_permission_url returns correct url with no scope" do
  258. ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
  259. session = ShopifyAPI::Session.new(
  260. domain: 'http://localhost.myshopify.com',
  261. token: 'any-token',
  262. api_version: any_api_version
  263. )
  264. scope = []
  265. permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
  266. assert_equal_uri(
  267. "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
  268. "scope=&redirect_uri=http://my_redirect_uri.com",
  269. permission_url
  270. )
  271. end
  272. test "create_permission_url returns correct url with state" do
  273. ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
  274. session = ShopifyAPI::Session.new(
  275. domain: 'http://localhost.myshopify.com',
  276. token: 'any-token',
  277. api_version: any_api_version
  278. )
  279. scope = []
  280. permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", state: "My nonce")
  281. assert_equal_uri(
  282. "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
  283. "scope=&redirect_uri=http://my_redirect_uri.com&state=My+nonce",
  284. permission_url
  285. )
  286. end
  287. test "create_permission_url returns correct url with grant_options[]" do
  288. ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
  289. session = ShopifyAPI::Session.new(
  290. domain: 'http://localhost.myshopify.com',
  291. token: 'any-token',
  292. api_version: any_api_version
  293. )
  294. scope = []
  295. permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", grant_options: "per-user")
  296. assert_equal_uri(
  297. "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
  298. "scope=&redirect_uri=http://my_redirect_uri.com&grant_options[]=per-user",
  299. permission_url
  300. )
  301. end
  302. test "raise exception if code invalid in request token" do
  303. ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
  304. session = ShopifyAPI::Session.new(
  305. domain: 'http://localhost.myshopify.com',
  306. token: nil,
  307. api_version: any_api_version
  308. )
  309. fake(
  310. nil,
  311. url: 'https://localhost.myshopify.com/admin/oauth/access_token',
  312. method: :post,
  313. status: 404,
  314. body: '{"error" : "invalid_request"}'
  315. )
  316. assert_raises(ShopifyAPI::ValidationException) do
  317. session.request_token(code: "bad-code")
  318. end
  319. assert_equal(false, session.valid?)
  320. end
  321. test "return site for session" do
  322. session = ShopifyAPI::Session.new(
  323. domain: "testshop.myshopify.com",
  324. token: "any-token",
  325. api_version: any_api_version
  326. )
  327. assert_equal_uri("https://testshop.myshopify.com", session.site)
  328. end
  329. test "return_token_if_signature_is_valid" do
  330. api_version = any_api_version
  331. fake(
  332. nil,
  333. url: "https://testshop.myshopify.com/admin/oauth/access_token",
  334. method: :post,
  335. body: '{"access_token":"any-token"}'
  336. )
  337. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
  338. params = { code: 'any-code', timestamp: Time.now }
  339. token = session.request_token(params.merge(hmac: generate_signature(params)))
  340. assert_equal("any-token", token)
  341. assert_equal("any-token", session.token)
  342. end
  343. test "extra parameters are stored in session" do
  344. api_version = ShopifyAPI::ApiVersion.new(handle: :unstable)
  345. fake(
  346. nil,
  347. url: "https://testshop.myshopify.com/admin/oauth/access_token",
  348. method: :post,
  349. body: '{"access_token":"any-token","foo":"example"}'
  350. )
  351. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
  352. params = { code: 'any-code', timestamp: Time.now }
  353. assert(session.request_token(params.merge(hmac: generate_signature(params))))
  354. assert_equal({ "foo" => "example" }, session.extra)
  355. end
  356. test "expires_in is automatically converted in expires_at" do
  357. api_version = any_api_version
  358. fake(
  359. nil,
  360. url: "https://testshop.myshopify.com/admin/oauth/access_token",
  361. method: :post,
  362. body: '{"access_token":"any-token","expires_in":86393}'
  363. )
  364. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
  365. Timecop.freeze do
  366. params = { code: 'any-code', timestamp: Time.now }
  367. assert(session.request_token(params.merge(hmac: generate_signature(params))))
  368. expires_at = Time.now.utc + 86393
  369. assert_equal({ "expires_at" => expires_at.to_i }, session.extra)
  370. assert(session.expires_at.is_a?(Time))
  371. assert_equal(expires_at.to_i, session.expires_at.to_i)
  372. assert_equal(86393, session.expires_in)
  373. assert_equal(false, session.expired?)
  374. Timecop.travel(session.expires_at) do
  375. assert_equal(true, session.expired?)
  376. end
  377. end
  378. end
  379. test "raise error if signature does not match expected" do
  380. params = { code: "any-code", timestamp: Time.now }
  381. signature = generate_signature(params)
  382. params[:foo] = 'world'
  383. assert_raises(ShopifyAPI::ValidationException) do
  384. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
  385. session.request_token(params.merge(hmac: signature))
  386. end
  387. end
  388. test "raise error if timestamp is too old" do
  389. params = { code: "any-code", timestamp: Time.now - 2 * SECONDS_IN_A_DAY }
  390. signature = generate_signature(params)
  391. params[:foo] = 'world'
  392. assert_raises(ShopifyAPI::ValidationException) do
  393. session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
  394. session.request_token(params.merge(hmac: signature))
  395. end
  396. end
  397. test "return true when the signature is valid and the keys of params are strings" do
  398. params = { 'code' => 'any-code', 'timestamp' => Time.now }
  399. params[:hmac] = generate_signature(params)
  400. assert_equal(true, ShopifyAPI::Session.validate_signature(params))
  401. end
  402. test "return true when validating signature of params with ampersand and equal sign characters" do
  403. ShopifyAPI::Session.secret = 'secret'
  404. params = { 'a' => '1&b=2', 'c=3&d' => '4' }
  405. to_sign = 'a=1%26b=2&c%3D3%26d=4'
  406. params[:hmac] = generate_signature(to_sign)
  407. assert_equal(true, ShopifyAPI::Session.validate_signature(params))
  408. end
  409. test "return true when validating signature of params with percent sign characters" do
  410. ShopifyAPI::Session.secret = 'secret'
  411. params = { 'a%3D1%26b' => '2%26c%3D3' }
  412. to_sign = 'a%253D1%2526b=2%2526c%253D3'
  413. params[:hmac] = generate_signature(to_sign)
  414. assert_equal(true, ShopifyAPI::Session.validate_signature(params))
  415. end
  416. test "url is aliased to domain to minimize the upgrade changes" do
  417. session = ShopifyAPI::Session.new(
  418. domain: "http://testshop.myshopify.com",
  419. token: "any-token",
  420. api_version: any_api_version
  421. )
  422. assert_equal('testshop.myshopify.com', session.url)
  423. end
  424. test "#hash returns the same value for equal Sessions" do
  425. session = ShopifyAPI::Session.new(
  426. domain: "http://testshop.myshopify.com",
  427. token: "any-token",
  428. api_version: '2019-01',
  429. extra: { foo: "bar" }
  430. )
  431. other_session = ShopifyAPI::Session.new(
  432. domain: "http://testshop.myshopify.com",
  433. token: "any-token",
  434. api_version: '2019-01',
  435. extra: { foo: "bar" }
  436. )
  437. assert_equal(session.hash, other_session.hash)
  438. end
  439. test "equality verifies domain" do
  440. session = ShopifyAPI::Session.new(
  441. domain: "http://testshop.myshopify.com",
  442. token: "any-token",
  443. api_version: '2019-01',
  444. extra: { foo: "bar" }
  445. )
  446. other_session = ShopifyAPI::Session.new(
  447. domain: "http://testshop.myshopify.com",
  448. token: "any-token",
  449. api_version: '2019-01',
  450. extra: { foo: "bar" }
  451. )
  452. different_session = ShopifyAPI::Session.new(
  453. domain: "http://another_testshop.myshopify.com",
  454. token: "any-token",
  455. api_version: '2019-01',
  456. extra: { foo: "bar" }
  457. )
  458. assert_equal(session, other_session)
  459. refute_equal(session, different_session)
  460. end
  461. test "equality verifies token" do
  462. session = ShopifyAPI::Session.new(
  463. domain: "http://testshop.myshopify.com",
  464. token: "any-token",
  465. api_version: '2019-01',
  466. extra: { foo: "bar" }
  467. )
  468. different_session = ShopifyAPI::Session.new(
  469. domain: "http://testshop.myshopify.com",
  470. token: "very-different-token",
  471. api_version: '2019-01',
  472. extra: { foo: "bar" }
  473. )
  474. refute_equal(session, different_session)
  475. end
  476. test "equality verifies api_version" do
  477. session = ShopifyAPI::Session.new(
  478. domain: "http://testshop.myshopify.com",
  479. token: "any-token",
  480. api_version: '2019-01',
  481. extra: { foo: "bar" }
  482. )
  483. different_session = ShopifyAPI::Session.new(
  484. domain: "http://testshop.myshopify.com",
  485. token: "any-token",
  486. api_version: :unstable,
  487. extra: { foo: "bar" }
  488. )
  489. refute_equal(session, different_session)
  490. end
  491. test "equality verifies extra" do
  492. session = ShopifyAPI::Session.new(
  493. domain: "http://testshop.myshopify.com",
  494. token: "any-token",
  495. api_version: '2019-01',
  496. extra: { foo: "bar" }
  497. )
  498. different_session = ShopifyAPI::Session.new(
  499. domain: "http://testshop.myshopify.com",
  500. token: "any-token",
  501. api_version: '2019-01',
  502. extra: { bar: "other-bar" }
  503. )
  504. refute_equal(session, different_session)
  505. end
  506. test "equality verifies other is a Session" do
  507. session = ShopifyAPI::Session.new(
  508. domain: "http://testshop.myshopify.com",
  509. token: "any-token",
  510. api_version: '2019-01',
  511. extra: { foo: "bar" }
  512. )
  513. different_session = nil
  514. refute_equal(session, different_session)
  515. end
  516. test "#eql? and #hash are implemented" do
  517. session = ShopifyAPI::Session.new(
  518. domain: "http://testshop.myshopify.com",
  519. token: "any-token",
  520. api_version: '2019-01',
  521. extra: { foo: "bar" }
  522. )
  523. other_session = ShopifyAPI::Session.new(
  524. domain: "http://testshop.myshopify.com",
  525. token: "any-token",
  526. api_version: '2019-01',
  527. extra: { foo: "bar" }
  528. )
  529. different_session = ShopifyAPI::Session.new(
  530. domain: "http://another_testshop.myshopify.com",
  531. token: "any-token",
  532. api_version: '2019-01',
  533. extra: { foo: "bar" }
  534. )
  535. assert_equal([session, different_session], [session, other_session, different_session].uniq)
  536. end
  537. private
  538. def assert_equal_uri(expected, actual)
  539. assert_equal(Addressable::URI.parse(expected), Addressable::URI.parse(actual))
  540. end
  541. def make_sorted_params(params)
  542. params.with_indifferent_access.except(
  543. :signature, :hmac, :action, :controller
  544. ).collect { |k, v| "#{k}=#{v}" }.sort.join('&')
  545. end
  546. def generate_signature(params)
  547. params = make_sorted_params(params) if params.is_a?(Hash)
  548. OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA256'), ShopifyAPI::Session.secret, params)
  549. end
  550. def any_api_version
  551. version_name = ['2019-01', :unstable].sample(1).first
  552. ShopifyAPI::ApiVersion.find_version(version_name)
  553. end
  554. end