shopify_api 3.1.8 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +32 -0
  3. data/CHANGELOG +14 -2
  4. data/Gemfile.lock +2 -2
  5. data/Gemfile_ar30 +9 -0
  6. data/Gemfile_ar31 +9 -0
  7. data/Gemfile_ar32 +9 -0
  8. data/README.rdoc +18 -15
  9. data/lib/active_resource/base_ext.rb +14 -15
  10. data/lib/active_resource/disable_prefix_check.rb +14 -0
  11. data/lib/active_resource/json_errors.rb +14 -4
  12. data/lib/active_resource/to_query.rb +10 -0
  13. data/lib/shopify_api.rb +1 -0
  14. data/lib/shopify_api/resources.rb +1 -1
  15. data/lib/shopify_api/resources/base.rb +4 -0
  16. data/lib/shopify_api/resources/customer.rb +4 -1
  17. data/lib/shopify_api/resources/fulfillment_service.rb +4 -0
  18. data/lib/shopify_api/resources/order_risk.rb +8 -0
  19. data/lib/shopify_api/session.rb +18 -18
  20. data/lib/shopify_api/version.rb +1 -1
  21. data/test/active_resource/json_errors_test.rb +22 -0
  22. data/test/article_test.rb +11 -0
  23. data/test/asset_test.rb +0 -1
  24. data/test/base_test.rb +0 -7
  25. data/test/customer_test.rb +10 -0
  26. data/test/fixtures/customers_search.json +60 -0
  27. data/test/fixtures/fulfillment_service.json +10 -0
  28. data/test/fixtures/image.json +10 -0
  29. data/test/fixtures/images.json +20 -0
  30. data/test/fixtures/order_risk.json +14 -0
  31. data/test/fixtures/order_risks.json +28 -0
  32. data/test/fixtures/recurring_application_charges.json +10 -0
  33. data/test/fixtures/variant.json +2 -1
  34. data/test/fixtures/variants.json +8 -4
  35. data/test/fulfillment_service_test.rb +17 -0
  36. data/test/image_test.rb +26 -0
  37. data/test/limits_test.rb +0 -1
  38. data/test/order_risk_test.rb +46 -0
  39. data/test/recurring_application_charge_test.rb +21 -0
  40. data/test/session_test.rb +44 -17
  41. data/test/test_helper.rb +6 -6
  42. data/test/variant_test.rb +14 -0
  43. metadata +49 -18
  44. checksums.yaml +0 -7
  45. data/lib/shopify_api/resources/product_search_engine.rb +0 -4
@@ -1,3 +1,3 @@
1
1
  module ShopifyAPI
2
- VERSION = "3.1.8"
2
+ VERSION = "3.2.0"
3
3
  end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveResource
4
+ class JsonErrorsTest < Test::Unit::TestCase
5
+
6
+ def test_parsing_of_error_json_hash
7
+ errors = some_error.from_json({errors: {name: ['missing']}}.to_json)
8
+ assert_equal({"name"=>["missing"]}, errors)
9
+ end
10
+
11
+ def test_parsing_of_error_json_plain_string
12
+ errors = some_error.from_json({errors: 'some generic error'}.to_json)
13
+ assert_equal(["some generic error"], errors)
14
+ end
15
+
16
+ private
17
+
18
+ def some_error
19
+ ActiveResource::Errors.new(ShopifyAPI::Order.new)
20
+ end
21
+ end
22
+ end
@@ -2,28 +2,39 @@ require 'test_helper'
2
2
 
3
3
  class ArticleTest < Test::Unit::TestCase
4
4
 
5
+ def test_create_article
6
+ fake "blogs/1008414260/articles", :method => :post, :body => load_fixture('article')
7
+ article = ShopifyAPI::Article.new(:blog_id => 1008414260)
8
+ article.save
9
+ assert_equal "First Post", article.title
10
+ end
11
+
5
12
  def test_get_article
6
13
  fake "articles/6242736", :method => :get, :body => load_fixture('article')
7
14
  article = ShopifyAPI::Article.find(6242736)
8
15
  assert_equal "First Post", article.title
16
+ assert_equal 1008414260, article.blog_id
9
17
  end
10
18
 
11
19
  def test_get_articles
12
20
  fake "articles", :method => :get, :body => load_fixture('articles')
13
21
  articles = ShopifyAPI::Article.all
14
22
  assert_equal 3, articles.length
23
+ assert_equal 1008414260, articles.first.blog_id
15
24
  end
16
25
 
17
26
  def test_get_articles_namespaced
18
27
  fake "blogs/1008414260/articles", :method => :get, :body => load_fixture('articles')
19
28
  articles = ShopifyAPI::Article.find(:all, :params => {:blog_id => 1008414260})
20
29
  assert_equal 3, articles.length
30
+ assert_equal 1008414260, articles.first.blog_id
21
31
  end
22
32
 
23
33
  def test_get_article_namespaced
24
34
  fake "blogs/1008414260/articles/6242736", :method => :get, :body => load_fixture('article')
25
35
  article = ShopifyAPI::Article.find(6242736, :params => {:blog_id => 1008414260})
26
36
  assert_equal "First Post", article.title
37
+ assert_equal 1008414260, article.blog_id
27
38
  end
28
39
 
29
40
  def test_get_authors
@@ -1,5 +1,4 @@
1
1
  require 'test_helper'
2
- require 'uri'
3
2
 
4
3
  class AssetTest < Test::Unit::TestCase
5
4
  def test_get_assetss
@@ -54,11 +54,4 @@ class BaseTest < Test::Unit::TestCase
54
54
  ShopifyAPI::Base.delete "1"
55
55
  end
56
56
 
57
- test "#build should send custom headers with request" do
58
- ShopifyAPI::Base.activate_session @session1
59
- ShopifyAPI::Base.expects(:headers).returns({'X-Custom' => 'abc'})
60
- ShopifyAPI::Base.connection.expects(:delete).with('/admin/bases/1.json', {'X-Custom' => 'abc'})
61
- ShopifyAPI::Base.delete "1"
62
- end
63
-
64
57
  end
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ class CustomerTest < Test::Unit::TestCase
4
+ def test_search
5
+ fake "customers/search.json?query=Bob+country%3AUnited+States", extension: false, body: load_fixture('customers_search')
6
+
7
+ results = ShopifyAPI::Customer.search(query: 'Bob country:United States')
8
+ assert_equal 'Bob', results.first.first_name
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ {
2
+ "customers": [
3
+ {
4
+ "accepts_marketing": false,
5
+ "created_at": "2014-01-20T17:25:18-05:00",
6
+ "email": "bob.norman@hostmail.com",
7
+ "first_name": "Bob",
8
+ "id": 207119551,
9
+ "last_name": "Norman",
10
+ "last_order_id": null,
11
+ "multipass_identifier": null,
12
+ "note": null,
13
+ "orders_count": 0,
14
+ "state": "disabled",
15
+ "total_spent": "0.00",
16
+ "updated_at": "2014-01-20T17:25:18-05:00",
17
+ "verified_email": true,
18
+ "tags": "",
19
+ "last_order_name": null,
20
+ "default_address": {
21
+ "address1": "Chestnut Street 92",
22
+ "address2": "",
23
+ "city": "Louisville",
24
+ "company": null,
25
+ "country": "United States",
26
+ "first_name": null,
27
+ "id": 207119551,
28
+ "last_name": null,
29
+ "phone": "555-625-1199",
30
+ "province": "Kentucky",
31
+ "zip": "40202",
32
+ "name": null,
33
+ "province_code": "KY",
34
+ "country_code": "US",
35
+ "country_name": "United States",
36
+ "default": true
37
+ },
38
+ "addresses": [
39
+ {
40
+ "address1": "Chestnut Street 92",
41
+ "address2": "",
42
+ "city": "Louisville",
43
+ "company": null,
44
+ "country": "United States",
45
+ "first_name": null,
46
+ "id": 207119551,
47
+ "last_name": null,
48
+ "phone": "555-625-1199",
49
+ "province": "Kentucky",
50
+ "zip": "40202",
51
+ "name": null,
52
+ "province_code": "KY",
53
+ "country_code": "US",
54
+ "country_name": "United States",
55
+ "default": true
56
+ }
57
+ ]
58
+ }
59
+ ]
60
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "fulfillment_service": {
3
+ "name": "SomeService",
4
+ "id": 123456,
5
+ "inventory_management": false,
6
+ "tracking_support": true,
7
+ "requires_shipping_method": false,
8
+ "format": "json"
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "image": {
3
+ "created_at": "2014-01-10T16:15:40-05:00",
4
+ "id": 850703190,
5
+ "position": 1,
6
+ "product_id": 632910392,
7
+ "updated_at": "2014-01-10T16:15:40-05:00",
8
+ "src": "http://cdn.shopify.com/s/files/1/0006/9093/3842/products/ipod-nano.png?v=1389388540"
9
+ }
10
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "images": [
3
+ {
4
+ "created_at": "2014-01-17T16:11:52-05:00",
5
+ "id": 850703190,
6
+ "position": 1,
7
+ "product_id": 632910392,
8
+ "updated_at": "2014-01-17T16:11:52-05:00",
9
+ "src": "http://cdn.shopify.com/s/files/1/0006/9093/3842/products/ipod-nano.png?v=1389993112"
10
+ },
11
+ {
12
+ "created_at": "2014-01-17T16:11:52-05:00",
13
+ "id": 562641783,
14
+ "position": 2,
15
+ "product_id": 632910392,
16
+ "updated_at": "2014-01-17T16:11:52-05:00",
17
+ "src": "http://cdn.shopify.com/s/files/1/0006/9093/3842/products/ipod-nano-2.png?v=1389993112"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "risk": {
3
+ "cause_cancel": true,
4
+ "checkout_id": null,
5
+ "display": true,
6
+ "id": 284138680,
7
+ "message": "This order was placed from a proxy IP",
8
+ "order_id": 450789469,
9
+ "recommendation": "cancel",
10
+ "score": "1.0",
11
+ "source": "External",
12
+ "merchant_message": "This order was placed from a proxy IP"
13
+ }
14
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "risks": [
3
+ {
4
+ "cause_cancel": true,
5
+ "checkout_id": null,
6
+ "display": true,
7
+ "id": 284138680,
8
+ "message": "This order was placed from a proxy IP",
9
+ "order_id": 450789469,
10
+ "recommendation": "cancel",
11
+ "score": "1.0",
12
+ "source": "External",
13
+ "merchant_message": "This order was placed from a proxy IP"
14
+ },
15
+ {
16
+ "cause_cancel": true,
17
+ "checkout_id": null,
18
+ "display": true,
19
+ "id": 432527878,
20
+ "message": "This order came from an anonymous proxy",
21
+ "order_id": 450789469,
22
+ "recommendation": "cancel",
23
+ "score": "1.0",
24
+ "source": "External",
25
+ "merchant_message": "This order came from an anonymous proxy"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "recurring_application_charges": [
3
+ {
4
+ "name": "Super Duper Plan",
5
+ "price": 10.0,
6
+ "return_url": "http://super-duper.shopifyapps.com",
7
+ "status": "active"
8
+ }
9
+ ]
10
+ }
@@ -17,6 +17,7 @@
17
17
  "option1": "Pink",
18
18
  "option2": null,
19
19
  "fulfillment_service": "manual",
20
- "option3": null
20
+ "option3": null,
21
+ "product_id": 632910392
21
22
  }
22
23
  }
@@ -18,7 +18,8 @@
18
18
  "option1": "Pink",
19
19
  "option2": null,
20
20
  "fulfillment_service": "manual",
21
- "option3": null
21
+ "option3": null,
22
+ "product_id": 632910392
22
23
  },
23
24
  {
24
25
  "price": "199.00",
@@ -38,7 +39,8 @@
38
39
  "option1": "Red",
39
40
  "option2": null,
40
41
  "fulfillment_service": "manual",
41
- "option3": null
42
+ "option3": null,
43
+ "product_id": 632910392
42
44
  },
43
45
  {
44
46
  "price": "199.00",
@@ -58,7 +60,8 @@
58
60
  "option1": "Green",
59
61
  "option2": null,
60
62
  "fulfillment_service": "manual",
61
- "option3": null
63
+ "option3": null,
64
+ "product_id": 632910392
62
65
  },
63
66
  {
64
67
  "price": "199.00",
@@ -78,7 +81,8 @@
78
81
  "option1": "Black",
79
82
  "option2": null,
80
83
  "fulfillment_service": "manual",
81
- "option3": null
84
+ "option3": null,
85
+ "product_id": 632910392
82
86
  }
83
87
  ]
84
88
  }
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ class FulFillmentServiceTest < Test::Unit::TestCase
4
+ test 'new should create fulfillment service' do
5
+ fake "fulfillment_services", :method => :post, :body => load_fixture('fulfillment_service')
6
+ fulfillment_service = ShopifyAPI::FulfillmentService.new(:name => "SomeService")
7
+ fulfillment_service.save
8
+ assert_equal "SomeService" , fulfillment_service.name
9
+ end
10
+
11
+ test 'find should return the fulfillment service' do
12
+ fake "fulfillment_services/123456", :method => :get, :body => load_fixture('fulfillment_service')
13
+ fulfillment_service = ShopifyAPI::FulfillmentService.find(123456)
14
+ assert_equal 123456 , fulfillment_service.id
15
+ assert_equal "SomeService", fulfillment_service.name
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ class ImageTest < Test::Unit::TestCase
4
+ def test_create_image
5
+ fake "products/632910392/images", :method => :post, :body => load_fixture('image')
6
+ image = ShopifyAPI::Image.new(:product_id => 632910392)
7
+ image.position = 1
8
+ image.attachment = "R0lGODlhbgCMAPf/APbr48VySrxTO7IgKt2qmKQdJeK8lsFjROG5p/nz7Zg3MNmnd7Q1MLNVS9GId71hSJMZIuzTu4UtKbeEeakhKMl8U8WYjfr18YQaIbAf=="
9
+ image.save
10
+
11
+ assert_equal 'http://cdn.shopify.com/s/files/1/0006/9093/3842/products/ipod-nano.png?v=1389388540', image.src
12
+ assert_equal 850703190, image.id
13
+ end
14
+
15
+ def test_get_images
16
+ fake "products/632910392/images", :method => :get, :body => load_fixture('images')
17
+ image = ShopifyAPI::Image.find(:all, :params => {:product_id => 632910392})
18
+ assert_equal 2, image.size
19
+ end
20
+
21
+ def test_get_image
22
+ fake "products/632910392/images/850703190", :method => :get, :body => load_fixture('image')
23
+ image = ShopifyAPI::Image.find(850703190, :params => {:product_id => 632910392})
24
+ assert_equal 850703190, image.id
25
+ end
26
+ end
@@ -1,5 +1,4 @@
1
1
  require 'test_helper'
2
- require 'mocha'
3
2
 
4
3
  class LimitsTest < Test::Unit::TestCase
5
4
  def setup
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ class OrderRiskTest < Test::Unit::TestCase
4
+ def test_create_order_risk
5
+ fake "orders/450789469/risks", :method => :post, :body => load_fixture('order_risk')
6
+ v = ShopifyAPI::OrderRisk.new(:order_id => 450789469)
7
+ v.message = "This order was placed from a proxy IP"
8
+ v.recommendation = "cancel"
9
+ v.score = "1.0"
10
+ v.source = "External"
11
+ v.merchant_message = "This order was placed from a proxy IP"
12
+ v.display = true
13
+ v.cause_cancel = true
14
+ v.save
15
+
16
+ assert_equal 284138680, v.id
17
+ end
18
+
19
+ def test_get_order_risks
20
+ fake "orders/450789469/risks", :method => :get, :body => load_fixture('order_risks')
21
+ v = ShopifyAPI::OrderRisk.find(:all, :params => {:order_id => 450789469})
22
+ assert_equal 2, v.size
23
+ end
24
+
25
+ def test_get_order_risk
26
+ fake "orders/450789469/risks/284138680", :method => :get, :body => load_fixture('order_risk')
27
+ v = ShopifyAPI::OrderRisk.find(284138680, :params => {:order_id => 450789469})
28
+ assert_equal 284138680, v.id
29
+ end
30
+
31
+ def test_delete_order_risk
32
+ fake "orders/450789469/risks/284138680", :method => :get, :body => load_fixture('order_risk')
33
+ fake "orders/450789469/risks/284138680", :method => :delete, :body => "destroyed"
34
+ v = ShopifyAPI::OrderRisk.find(284138680, :params => {:order_id => 450789469})
35
+ assert v.destroy
36
+ end
37
+
38
+ def test_delete_order_risk
39
+ fake "orders/450789469/risks/284138680", :method => :get, :body => load_fixture('order_risk')
40
+ fake "orders/450789469/risks/284138680", :method => :put, :body => load_fixture('order_risk')
41
+
42
+ v = ShopifyAPI::OrderRisk.find(284138680, :params => {:order_id => 450789469})
43
+ v.position = 3
44
+ v.save
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class RecurringApplicationChargeTest < Test::Unit::TestCase
4
+ context "#all" do
5
+ should "get all charges" do
6
+ fake "recurring_application_charges"
7
+
8
+ charges = ShopifyAPI::RecurringApplicationCharge.all
9
+ assert_equal "Super Duper Plan", charges.first.name
10
+ end
11
+ end
12
+
13
+
14
+ should "not fail when there are no charges" do
15
+ fake "recurring_application_charges", body: {recurring_application_charges: []}.to_json
16
+
17
+ assert_equal 0, ShopifyAPI::RecurringApplicationCharge.all.count
18
+ assert_equal nil, ShopifyAPI::RecurringApplicationCharge.current
19
+ assert_equal [], ShopifyAPI::RecurringApplicationCharge.pending
20
+ end
21
+ end
@@ -1,13 +1,13 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class SessionTest < Test::Unit::TestCase
4
-
4
+
5
5
  context "Session" do
6
6
  should "not be valid without a url" do
7
7
  session = ShopifyAPI::Session.new(nil, "any-token")
8
8
  assert_not session.valid?
9
9
  end
10
-
10
+
11
11
  should "not be valid without token" do
12
12
  session = ShopifyAPI::Session.new("testshop.myshopify.com")
13
13
  assert_not session.valid?
@@ -17,7 +17,7 @@ class SessionTest < Test::Unit::TestCase
17
17
  session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
18
18
  assert session.valid?
19
19
  end
20
-
20
+
21
21
  should "not raise error without params" do
22
22
  assert_nothing_raised do
23
23
  session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
@@ -26,7 +26,8 @@ class SessionTest < Test::Unit::TestCase
26
26
 
27
27
  should "raise error if params passed but signature omitted" do
28
28
  assert_raises(RuntimeError) do
29
- session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token", {'foo' => 'bar'})
29
+ session = ShopifyAPI::Session.new("testshop.myshopify.com")
30
+ session.request_token({'code' => 'any-code'})
30
31
  end
31
32
  end
32
33
 
@@ -35,13 +36,13 @@ class SessionTest < Test::Unit::TestCase
35
36
  assert_equal "My test key", ShopifyAPI::Session.api_key
36
37
  assert_equal "My test secret", ShopifyAPI::Session.secret
37
38
  end
38
-
39
+
39
40
  should "use 'https' protocol by default for all sessions" do
40
41
  assert_equal 'https', ShopifyAPI::Session.protocol
41
42
  end
42
43
 
43
44
  should "#temp reset ShopifyAPI::Base.site to original value" do
44
-
45
+
45
46
  ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret")
46
47
  session1 = ShopifyAPI::Session.new('fakeshop.myshopify.com', 'token1')
47
48
  ShopifyAPI::Base.activate_session(session1)
@@ -85,19 +86,12 @@ class SessionTest < Test::Unit::TestCase
85
86
  assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=", permission_url
86
87
  end
87
88
 
88
- should "request token should get token" do
89
- ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
90
- session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
91
- fake nil, :url => 'https://localhost.myshopify.com/admin/oauth/access_token',:method => :post, :body => '{"access_token" : "token"}'
92
- assert_equal "token", session.request_token("code")
93
- end
94
-
95
89
  should "raise exception if code invalid in request token" do
96
90
  ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
97
91
  session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
98
92
  fake nil, :url => 'https://localhost.myshopify.com/admin/oauth/access_token',:method => :post, :status => 404, :body => '{"error" : "invalid_request"}'
99
93
  assert_raises(RuntimeError) do
100
- session.request_token("bad_code")
94
+ session.request_token(params={:code => "bad-code"})
101
95
  end
102
96
  assert_equal false, session.valid?
103
97
  end
@@ -119,13 +113,46 @@ class SessionTest < Test::Unit::TestCase
119
113
  assert_equal "https://testshop.myshopify.com/admin", session.site
120
114
  end
121
115
 
116
+ should "return_token_if_signature_is_valid" do
117
+ ShopifyAPI::Session.secret = 'secret'
118
+ params = {:code => 'any-code', :timestamp => Time.now}
119
+ sorted_params = make_sorted_params(params)
120
+ signature = Digest::MD5.hexdigest(ShopifyAPI::Session.secret + sorted_params)
121
+ fake nil, :url => 'https://testshop.myshopify.com/admin/oauth/access_token',:method => :post, :body => '{"access_token" : "any-token"}'
122
+ session = ShopifyAPI::Session.new("testshop.myshopify.com")
123
+ token = session.request_token(params.merge(:signature => signature))
124
+ assert_equal "any-token", token
125
+ end
126
+
122
127
  should "raise error if signature does not match expected" do
123
128
  ShopifyAPI::Session.secret = 'secret'
124
- params = {:foo => 'hello', :foo => 'world', :timestamp => Time.now}
125
- sorted_params = params.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
129
+ params = {:code => "any-code", :timestamp => Time.now}
130
+ sorted_params = make_sorted_params(params)
126
131
  signature = Digest::MD5.hexdigest(ShopifyAPI::Session.secret + sorted_params)
132
+ params[:foo] = 'world'
133
+ assert_raises(RuntimeError) do
134
+ session = ShopifyAPI::Session.new("testshop.myshopify.com")
135
+ session.request_token(params.merge(:signature => signature))
136
+ end
137
+ end
127
138
 
128
- session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token", params.merge(:signature => signature))
139
+ should "raise error if timestamp is too old" do
140
+ ShopifyAPI::Session.secret = 'secret'
141
+ params = {:code => "any-code", :timestamp => Time.now - 2.days}
142
+ sorted_params = make_sorted_params(params)
143
+ signature = Digest::MD5.hexdigest(ShopifyAPI::Session.secret + sorted_params)
144
+ params[:foo] = 'world'
145
+ assert_raises(RuntimeError) do
146
+ session = ShopifyAPI::Session.new("testshop.myshopify.com")
147
+ session.request_token(params.merge(:signature => signature))
148
+ end
149
+ end
150
+
151
+ private
152
+
153
+ def make_sorted_params(params)
154
+ sorted_params = params.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
129
155
  end
156
+
130
157
  end
131
158
  end