shopify_api 3.2.0 → 3.2.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc9fc203a46569db4cddb7ed4c82f9392dfdbb33
4
+ data.tar.gz: ee232e9226eee62db4edd51db94ad38a66bb532b
5
+ SHA512:
6
+ metadata.gz: 5aaec38706d2c2226260f34ef597108fc68bb1a578f030553771e895e8b03b8dbb0d650ea88a6b3b6097b596e8f967f0315ca922dbfe13566a167e478b32f0ab
7
+ data.tar.gz: d5bf632be11ffdf315c25616e26bfdd8c4e4fe89034ed98b182af5cd4b14dda035fd1dfe556ffc9a8119efbe5a188dd2e7b74399a1f6270027a24ef770e14990
data/.travis.yml CHANGED
@@ -9,6 +9,7 @@ gemfile:
9
9
  - Gemfile_ar30
10
10
  - Gemfile_ar31
11
11
  - Gemfile_ar32
12
+ - Gemfile_ar40threadsafe
12
13
 
13
14
  install: bundle install
14
15
 
@@ -28,5 +29,5 @@ matrix:
28
29
 
29
30
 
30
31
  notifications:
31
- flowdock:
32
+ flowdock:
32
33
  secure: "RCgSxzMScnqK6bOwkv9sWSdieLBeJla8NcDtM/QmuFW8soTgV6qCTAPAGd4lpjg4vGTaM3DsdHU5GMDbgdWN5dE2Rf09ayFqiZg8OloPMQ63KIwLJyVcw3cVJO5i7smjIpsSjPjBkvAXHIOFcKdsnuYGS4YD8hjl+QrZ3ghi440="
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ == Version 3.2.1
2
+
3
+ * Added CarrierService resource
4
+ * Added optionally using threadsafe ActiveResource (see readme)
5
+ * Fixed bug in validate_signature
6
+
1
7
  == Version 3.2.0
2
8
 
3
9
  * in Session::request_token params is no longer optional, you must pass all the params and the method will now extract the code
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
+
5
+ gem "activeresource", "~> 4.0.0"
data/Gemfile.lock CHANGED
@@ -1,21 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify_api (3.2.0)
4
+ shopify_api (3.2.1)
5
5
  activeresource (>= 3.0.0)
6
6
  thor (>= 0.14.4)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (4.0.0)
12
- activesupport (= 4.0.0)
11
+ activemodel (4.0.3)
12
+ activesupport (= 4.0.3)
13
13
  builder (~> 3.1.0)
14
14
  activeresource (4.0.0)
15
15
  activemodel (~> 4.0)
16
16
  activesupport (~> 4.0)
17
17
  rails-observers (~> 0.1.1)
18
- activesupport (4.0.0)
18
+ activesupport (4.0.3)
19
19
  i18n (~> 0.6, >= 0.6.4)
20
20
  minitest (~> 4.2)
21
21
  multi_json (~> 1.3)
@@ -29,7 +29,7 @@ GEM
29
29
  minitest (4.7.5)
30
30
  mocha (0.14.0)
31
31
  metaclass (~> 0.0.1)
32
- multi_json (1.8.2)
32
+ multi_json (1.8.4)
33
33
  rails-observers (0.1.2)
34
34
  activemodel (~> 4.0)
35
35
  rake (10.1.0)
@@ -42,6 +42,7 @@ PLATFORMS
42
42
  ruby
43
43
 
44
44
  DEPENDENCIES
45
+ activeresource (~> 4.0.0)
45
46
  fakeweb
46
47
  mocha (>= 0.9.8)
47
48
  rake
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'activeresource', :git => 'git://github.com/Shopify/activeresource', :ref => 'e9dc76b4aa'
data/README.rdoc CHANGED
@@ -139,6 +139,20 @@ This package also includes the +shopify+ executable to make it easy to open up a
139
139
  shopify help
140
140
 
141
141
 
142
+ == Threadsafety
143
+
144
+ ActiveResource is inherently non-threadsafe, because class variables like ActiveResource::Base.site
145
+ and ActiveResource::Base.headers are shared between threads. This can cause conflicts when using
146
+ threaded libraries, like Sidekiq.
147
+
148
+ We have a forked version of ActiveResource that stores these class variables in threadlocal
149
+ variables. Using this forked version will allow ShopifyAPI to be used in a threaded environment.
150
+
151
+ To enable threadsafety with ShopifyAPI, add the following to your Gemfile:
152
+
153
+ gem 'activeresource', git: 'git://github.com/Shopify/activeresource', branch: 'threadsafe'
154
+ gem 'shopify_api', '>= 3.2.1'
155
+
142
156
  == Using Development Version
143
157
 
144
158
  Download the source code and run:
@@ -14,7 +14,7 @@ module ShopifyAPI
14
14
 
15
15
  same.send("to_#{self.class.format.extension}", options)
16
16
  end
17
-
17
+
18
18
  def as_json(options = nil)
19
19
  root = options[:root] if options.try(:key?, :root)
20
20
  if include_root_in_json
@@ -26,13 +26,25 @@ module ShopifyAPI
26
26
  end
27
27
 
28
28
  class << self
29
- def headers
30
- if defined?(@headers)
31
- @headers
32
- elsif superclass != Object && superclass.headers
33
- superclass.headers
34
- else
35
- @headers ||= {}
29
+ if ActiveResource::VERSION::MAJOR == 4 && ActiveResource::VERSION::PRE == 'threadsafe'
30
+ def headers
31
+ if _headers_defined?
32
+ _headers
33
+ elsif superclass != Object && superclass.headers
34
+ superclass.headers
35
+ else
36
+ _headers ||= {}
37
+ end
38
+ end
39
+ else
40
+ def headers
41
+ if defined?(@headers)
42
+ @headers
43
+ elsif superclass != Object && superclass.headers
44
+ superclass.headers
45
+ else
46
+ @headers ||= {}
47
+ end
36
48
  end
37
49
  end
38
50
 
@@ -0,0 +1,4 @@
1
+ module ShopifyAPI
2
+ class CarrierService < Base
3
+ end
4
+ end
@@ -1,7 +1,7 @@
1
1
  module ShopifyAPI
2
2
  class RecurringApplicationCharge < Base
3
3
  undef_method :test
4
-
4
+
5
5
  class << self
6
6
  def current
7
7
  all.find { |c| c.status == 'active' }
@@ -11,11 +11,11 @@ module ShopifyAPI
11
11
  define_method(status) { all.select { |c| c.status == status.to_s } }
12
12
  end
13
13
  end
14
-
14
+
15
15
  def cancel
16
16
  load_attributes_from_response(self.destroy)
17
17
  end
18
-
18
+
19
19
  def activate
20
20
  load_attributes_from_response(post(:activate))
21
21
  end
@@ -39,6 +39,7 @@ module ShopifyAPI
39
39
  end
40
40
 
41
41
  def validate_signature(params)
42
+ params = params.with_indifferent_access
42
43
  return false unless signature = params[:signature]
43
44
 
44
45
  sorted_params = params.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
@@ -1,3 +1,3 @@
1
1
  module ShopifyAPI
2
- VERSION = "3.2.0"
2
+ VERSION = "3.2.1"
3
3
  end
data/test/base_test.rb CHANGED
@@ -8,20 +8,24 @@ class BaseTest < Test::Unit::TestCase
8
8
  @session2 = ShopifyAPI::Session.new('shop2.myshopify.com', 'token2')
9
9
  end
10
10
 
11
+ def teardown
12
+ clear_header('X-Custom')
13
+ end
14
+
11
15
  test '#activate_session should set site and headers for given session' do
12
16
  ShopifyAPI::Base.activate_session @session1
13
17
 
14
18
  assert_nil ActiveResource::Base.site
15
19
  assert_equal 'https://shop1.myshopify.com/admin', ShopifyAPI::Base.site.to_s
16
20
  assert_equal 'https://shop1.myshopify.com/admin', ShopifyAPI::Shop.site.to_s
17
-
21
+
18
22
  assert_nil ActiveResource::Base.headers['X-Shopify-Access-Token']
19
23
  assert_equal 'token1', ShopifyAPI::Base.headers['X-Shopify-Access-Token']
20
24
  assert_equal 'token1', ShopifyAPI::Shop.headers['X-Shopify-Access-Token']
21
25
  end
22
26
 
23
27
  test '#clear_session should clear site and headers from Base' do
24
- ShopifyAPI::Base.activate_session @session1
28
+ ShopifyAPI::Base.activate_session @session1
25
29
  ShopifyAPI::Base.clear_session
26
30
 
27
31
  assert_nil ActiveResource::Base.site
@@ -34,8 +38,8 @@ class BaseTest < Test::Unit::TestCase
34
38
  end
35
39
 
36
40
  test '#activate_session with one session, then clearing and activating with another session should send request to correct shop' do
37
- ShopifyAPI::Base.activate_session @session1
38
- ShopifyAPI::Base.clear_session
41
+ ShopifyAPI::Base.activate_session @session1
42
+ ShopifyAPI::Base.clear_session
39
43
  ShopifyAPI::Base.activate_session @session2
40
44
 
41
45
  assert_nil ActiveResource::Base.site
@@ -49,9 +53,54 @@ class BaseTest < Test::Unit::TestCase
49
53
 
50
54
  test "#delete should send custom headers with request" do
51
55
  ShopifyAPI::Base.activate_session @session1
52
- ShopifyAPI::Base.expects(:headers).returns({'X-Custom' => 'abc'})
53
- ShopifyAPI::Base.connection.expects(:delete).with('/admin/bases/1.json', {'X-Custom' => 'abc'})
56
+ ShopifyAPI::Base.headers['X-Custom'] = 'abc'
57
+ ShopifyAPI::Base.connection.expects(:delete).with('/admin/bases/1.json', has_entry('X-Custom', 'abc'))
54
58
  ShopifyAPI::Base.delete "1"
55
59
  end
56
60
 
61
+ test "#headers includes the User-Agent" do
62
+ assert_not_includes ActiveResource::Base.headers.keys, 'User-Agent'
63
+ assert_includes ShopifyAPI::Base.headers.keys, 'User-Agent'
64
+ thread = Thread.new do
65
+ assert_includes ShopifyAPI::Base.headers.keys, 'User-Agent'
66
+ end
67
+ thread.join
68
+ end
69
+
70
+ if ActiveResource::VERSION::MAJOR >= 4
71
+ test "#headers propagates changes to subclasses" do
72
+ ShopifyAPI::Base.headers['X-Custom'] = "the value"
73
+ assert_equal "the value", ShopifyAPI::Base.headers['X-Custom']
74
+ assert_equal "the value", ShopifyAPI::Product.headers['X-Custom']
75
+ end
76
+
77
+ test "#headers clears changes to subclasses" do
78
+ ShopifyAPI::Base.headers['X-Custom'] = "the value"
79
+ assert_equal "the value", ShopifyAPI::Product.headers['X-Custom']
80
+ ShopifyAPI::Base.headers['X-Custom'] = nil
81
+ assert_nil ShopifyAPI::Product.headers['X-Custom']
82
+ end
83
+ end
84
+
85
+ if ActiveResource::VERSION::MAJOR >= 4 && ActiveResource::VERSION::PRE == "threadsafe"
86
+ test "#headers set in the main thread affect spawned threads" do
87
+ ShopifyAPI::Base.headers['X-Custom'] = "the value"
88
+ Thread.new do
89
+ assert_equal "the value", ShopifyAPI::Base.headers['X-Custom']
90
+ end.join
91
+ end
92
+
93
+ test "#headers set in spawned threads do not affect the main thread" do
94
+ Thread.new do
95
+ ShopifyAPI::Base.headers['X-Custom'] = "the value"
96
+ end.join
97
+ assert_nil ShopifyAPI::Base.headers['X-Custom']
98
+ end
99
+ end
100
+
101
+ def clear_header(header)
102
+ [ActiveResource::Base, ShopifyAPI::Base, ShopifyAPI::Product].each do |klass|
103
+ klass.headers.delete(header)
104
+ end
105
+ end
57
106
  end
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ class CarrierServiceTest < Test::Unit::TestCase
4
+ test 'new should create carrier service' do
5
+ fake "carrier_services", :method => :post, :body => load_fixture('carrier_service')
6
+ carrier_service = ShopifyAPI::CarrierService.new(:name => "Some Postal Service")
7
+ carrier_service.save
8
+ assert_equal "Some Postal Service" , carrier_service.name
9
+ end
10
+
11
+ test 'find should return the carrier service' do
12
+ fake "carrier_services/123456", :method => :get, :body => load_fixture('carrier_service')
13
+ carrier_service = ShopifyAPI::CarrierService.find(123456)
14
+ assert_equal 123456 , carrier_service.id
15
+ assert_equal "Some Postal Service", carrier_service.name
16
+ end
17
+ end
@@ -10,7 +10,7 @@ class LogSubscriberTest < Test::Unit::TestCase
10
10
  @ua_header = "\"User-Agent\"=>\"ShopifyAPI/#{ShopifyAPI::VERSION} ActiveResource/#{ActiveResource::VERSION::STRING} Ruby/#{RUBY_VERSION}\""
11
11
 
12
12
  ShopifyAPI::Base.clear_session
13
- ShopifyAPI::Base.site = "http://localhost/admin"
13
+ ShopifyAPI::Base.site = "https://this-is-my-test-shop.myshopify.com/admin"
14
14
 
15
15
  ActiveResource::LogSubscriber.attach_to :active_resource
16
16
  ActiveResource::DetailedLogSubscriber.attach_to :active_resource_detailed
@@ -26,9 +26,9 @@ class LogSubscriberTest < Test::Unit::TestCase
26
26
  ShopifyAPI::Page.find(1)
27
27
 
28
28
  assert_equal 4, @logger.logged(:info).size
29
- assert_equal "GET http://localhost:80/admin/pages/1.json", @logger.logged(:info)[0]
30
- assert_match /\-\-\> 200/, @logger.logged(:info)[1]
31
- assert_equal "Headers: {\"Accept\"=>\"application/json\", #{@ua_header}}", @logger.logged(:info)[2]
29
+ assert_equal "GET https://this-is-my-test-shop.myshopify.com:443/admin/pages/1.json", @logger.logged(:info)[0]
30
+ assert_match /\-\-\> 200/, @logger.logged(:info)[1]
31
+ assert_equal "Headers: {\"Accept\"=>\"application/json\", #{@ua_header}}", @logger.logged(:info)[2]
32
32
  assert_match /Response:\n\{\"page\"\:\{((\"id\"\:1)|(\"title\"\:\"Shopify API\")),((\"id\"\:1)|(\"title\"\:\"Shopify API\"))\}\}/, @logger.logged(:info)[3]
33
33
 
34
34
  end
@@ -41,9 +41,9 @@ class LogSubscriberTest < Test::Unit::TestCase
41
41
  end
42
42
 
43
43
  assert_equal 4, @logger.logged(:info).size
44
- assert_equal "GET http://localhost:80/admin/pages/2.json", @logger.logged(:info)[0]
45
- assert_match /\-\-\> 404/, @logger.logged(:info)[1]
44
+ assert_equal "GET https://this-is-my-test-shop.myshopify.com:443/admin/pages/2.json", @logger.logged(:info)[0]
45
+ assert_match /\-\-\> 404/, @logger.logged(:info)[1]
46
46
  assert_equal "Headers: {\"Accept\"=>\"application/json\", #{@ua_header}}", @logger.logged(:info)[2]
47
- assert_equal "Response:", @logger.logged(:info)[3]
47
+ assert_equal "Response:", @logger.logged(:info)[3]
48
48
  end
49
49
  end
@@ -0,0 +1,9 @@
1
+ {
2
+ "carrier_service": {
3
+ "name": "Some Postal Service",
4
+ "id": 123456,
5
+ "callback_url": "http://google.com",
6
+ "format": "json",
7
+ "service_discovery": true
8
+ }
9
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "recurring_application_charge": {
3
+ "activated_on": null,
4
+ "api_client_id": 755357713,
5
+ "billing_on": null,
6
+ "cancelled_on": null,
7
+ "created_at": "2014-01-20T13:42:19-05:00",
8
+ "id": 654381177,
9
+ "name": "Super Duper Plan",
10
+ "price": "10.00",
11
+ "return_url": "http://super-duper.shopifyapps.com",
12
+ "status": "pending",
13
+ "test": null,
14
+ "trial_days": 0,
15
+ "trial_ends_on": null,
16
+ "updated_at": "2014-01-20T13:42:19-05:00",
17
+ "decorated_return_url": "http://super-duper.shopifyapps.com?charge_id=654381177",
18
+ "confirmation_url": "http://apple.myshopify.com/admin/charges/654381177/confirm_recurring_application_charge?signature=BAhpBHkQASc%3D--419fc7424f8c290ac2b21b9004ed223e35b52164"
19
+ }
20
+ }
@@ -1,10 +1,106 @@
1
1
  {
2
2
  "recurring_application_charges": [
3
3
  {
4
- "name": "Super Duper Plan",
5
- "price": 10.0,
6
- "return_url": "http://super-duper.shopifyapps.com",
7
- "status": "active"
4
+ "activated_on": null,
5
+ "api_client_id": 755357713,
6
+ "billing_on": "2014-01-19T00:00:00+00:00",
7
+ "cancelled_on": null,
8
+ "created_at": "2014-01-20T13:41:37-05:00",
9
+ "id": 455696194,
10
+ "name": "Super Mega Plan2",
11
+ "price": "15.00",
12
+ "return_url": "http://yourapp.com",
13
+ "status": "active",
14
+ "test": null,
15
+ "trial_days": 0,
16
+ "trial_ends_on": null,
17
+ "updated_at": "2014-01-20T13:42:20-05:00",
18
+ "decorated_return_url": "http://yourapp.com?charge_id=455696195"
19
+ },
20
+ {
21
+ "activated_on": null,
22
+ "api_client_id": 755357713,
23
+ "billing_on": "2014-01-19T00:00:00+00:00",
24
+ "cancelled_on": null,
25
+ "created_at": "2014-01-20T13:41:37-05:00",
26
+ "id": 455696195,
27
+ "name": "Super Mega Plan2",
28
+ "price": "15.00",
29
+ "return_url": "http://yourapp.com",
30
+ "status": "pending",
31
+ "test": null,
32
+ "trial_days": 0,
33
+ "trial_ends_on": null,
34
+ "updated_at": "2014-01-20T13:42:20-05:00",
35
+ "decorated_return_url": "http://yourapp.com?charge_id=455696195"
36
+ },
37
+ {
38
+ "activated_on": null,
39
+ "api_client_id": 755357713,
40
+ "billing_on": "2014-01-19T00:00:00+00:00",
41
+ "cancelled_on": null,
42
+ "created_at": "2014-01-20T13:41:37-05:00",
43
+ "id": 455696196,
44
+ "name": "Super Mega Plan3",
45
+ "price": "15.00",
46
+ "return_url": "http://yourapp.com",
47
+ "status": "cancelled",
48
+ "test": null,
49
+ "trial_days": 0,
50
+ "trial_ends_on": null,
51
+ "updated_at": "2014-01-20T13:42:20-05:00",
52
+ "decorated_return_url": "http://yourapp.com?charge_id=455696195"
53
+ },
54
+ {
55
+ "activated_on": null,
56
+ "api_client_id": 755357713,
57
+ "billing_on": "2014-01-19T00:00:00+00:00",
58
+ "cancelled_on": null,
59
+ "created_at": "2014-01-20T13:41:37-05:00",
60
+ "id": 455696197,
61
+ "name": "Super Mega Plan4",
62
+ "price": "15.00",
63
+ "return_url": "http://yourapp.com",
64
+ "status": "accepted",
65
+ "test": null,
66
+ "trial_days": 0,
67
+ "trial_ends_on": null,
68
+ "updated_at": "2014-01-20T13:42:20-05:00",
69
+ "decorated_return_url": "http://yourapp.com?charge_id=455696195"
70
+ },
71
+ {
72
+ "activated_on": null,
73
+ "api_client_id": 755357713,
74
+ "billing_on": "2014-01-19T00:00:00+00:00",
75
+ "cancelled_on": null,
76
+ "created_at": "2014-01-20T13:41:37-05:00",
77
+ "id": 455696198,
78
+ "name": "Super Mega Plan5",
79
+ "price": "15.00",
80
+ "return_url": "http://yourapp.com",
81
+ "status": "declined",
82
+ "test": null,
83
+ "trial_days": 0,
84
+ "trial_ends_on": null,
85
+ "updated_at": "2014-01-20T13:42:20-05:00",
86
+ "decorated_return_url": "http://yourapp.com?charge_id=455696195"
87
+ },
88
+ {
89
+ "activated_on": null,
90
+ "api_client_id": 755357713,
91
+ "billing_on": "2014-01-19T00:00:00+00:00",
92
+ "cancelled_on": null,
93
+ "created_at": "2014-01-20T13:41:37-05:00",
94
+ "id": 455696199,
95
+ "name": "Super Mega Plan",
96
+ "price": "15.00",
97
+ "return_url": "http://yourapp.com",
98
+ "status": "accepted",
99
+ "test": null,
100
+ "trial_days": 0,
101
+ "trial_ends_on": null,
102
+ "updated_at": "2014-01-20T13:42:20-05:00",
103
+ "decorated_return_url": "http://yourapp.com?charge_id=455696195"
8
104
  }
9
105
  ]
10
106
  }
@@ -35,4 +35,4 @@ class FulFillmentTest < Test::Unit::TestCase
35
35
  end
36
36
  end
37
37
 
38
- end
38
+ end
@@ -1,21 +1,107 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class RecurringApplicationChargeTest < Test::Unit::TestCase
4
- context "#all" do
5
- should "get all charges" do
6
- fake "recurring_application_charges"
7
4
 
8
- charges = ShopifyAPI::RecurringApplicationCharge.all
9
- assert_equal "Super Duper Plan", charges.first.name
10
- end
5
+ def test_recurring_application_charges_create
6
+ fake "recurring_application_charges", :method => :post, :status => 201, :body => load_fixture('recurring_application_charge')
7
+
8
+ charge = ShopifyAPI::RecurringApplicationCharge.create(
9
+ name: "Default Plan",
10
+ price: 10.0,
11
+ return_url: "http://test.com/confirm"
12
+ )
13
+
14
+ assert_equal 'http://apple.myshopify.com/admin/charges/654381177/confirm_recurring_application_charge?signature=BAhpBHkQASc%3D--419fc7424f8c290ac2b21b9004ed223e35b52164', charge.confirmation_url
15
+ end
16
+
17
+ def test_get_recurring_application_charges
18
+ fake "recurring_application_charges/654381177", :method => :get, :status => 201, :body => load_fixture('recurring_application_charge')
19
+
20
+ charge = ShopifyAPI::RecurringApplicationCharge.find(654381177)
21
+
22
+ assert_equal "Super Duper Plan", charge.name
11
23
  end
12
24
 
25
+ def test_list_recurring_application_charges
26
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
27
+
28
+ charge = ShopifyAPI::RecurringApplicationCharge.find(:all)
29
+
30
+ assert_equal "Super Mega Plan", charge.last.name
31
+ end
32
+
33
+ def test_list_since_recurring_application_charges
34
+ fake "recurring_application_charges.json?since_id=64512345",:extension => false, :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
35
+
36
+ charge = ShopifyAPI::RecurringApplicationCharge.find(:all, :params => {:since_id => '64512345'})
37
+
38
+ assert_equal "Super Mega Plan", charge.last.name
39
+ end
40
+
41
+ def test_list_fields_recurring_application_charges
42
+ fake "recurring_application_charges.json?fields=name",:extension => false, :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
43
+
44
+ charge = ShopifyAPI::RecurringApplicationCharge.find(:all, :params => {:fields => 'name'})
45
+
46
+ assert_equal "Super Mega Plan", charge.last.name
47
+ end
48
+
49
+ def test_pending_recurring_application_charge
50
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
51
+
52
+ charge = ShopifyAPI::RecurringApplicationCharge.pending
53
+
54
+ assert_equal "Super Mega Plan2", charge.last.name
55
+ end
13
56
 
14
- should "not fail when there are no charges" do
57
+ def test_cancelled_recurring_application_charge
58
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
59
+
60
+ charge = ShopifyAPI::RecurringApplicationCharge.cancelled
61
+
62
+ assert_equal "Super Mega Plan3", charge.last.name
63
+ end
64
+
65
+ def test_accepted_recurring_application_charge
66
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
67
+
68
+ charge = ShopifyAPI::RecurringApplicationCharge.accepted
69
+
70
+ assert_equal "Super Mega Plan4", charge.first.name
71
+ assert_equal "Super Mega Plan", charge.last.name
72
+ end
73
+
74
+ def test_declined_recurring_application_charge
75
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
76
+
77
+ charge = ShopifyAPI::RecurringApplicationCharge.declined
78
+
79
+ assert_equal "Super Mega Plan5", charge.last.name
80
+ end
81
+
82
+ def test_activate_recurring_application_charge
83
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
84
+ fake "recurring_application_charges/455696199/activate", :method => :post, :status => 200, :body => "{}"
85
+
86
+ charge = ShopifyAPI::RecurringApplicationCharge.accepted
87
+
88
+ assert charge.last.activate
89
+ end
90
+
91
+ def test_cancel_recurring_application_charge
92
+ fake "recurring_application_charges", :method => :get, :status => 201, :body => load_fixture('recurring_application_charges')
93
+ fake "recurring_application_charges/455696194", :method => :delete, :status => 200, :body => "{}"
94
+
95
+ charge = ShopifyAPI::RecurringApplicationCharge.current
96
+ assert charge.cancel
97
+ end
98
+
99
+ def test_no_recurring_application_charge_found
15
100
  fake "recurring_application_charges", body: {recurring_application_charges: []}.to_json
16
101
 
17
102
  assert_equal 0, ShopifyAPI::RecurringApplicationCharge.all.count
18
103
  assert_equal nil, ShopifyAPI::RecurringApplicationCharge.current
19
104
  assert_equal [], ShopifyAPI::RecurringApplicationCharge.pending
20
105
  end
106
+
21
107
  end
data/test/session_test.rb CHANGED
@@ -148,10 +148,20 @@ class SessionTest < Test::Unit::TestCase
148
148
  end
149
149
  end
150
150
 
151
+ should "return true when the signature is valid and the keys of params are strings" do
152
+ now = Time.now
153
+ params = {"code" => "any-code", "timestamp" => now}
154
+ sorted_params = make_sorted_params(params)
155
+ signature = Digest::MD5.hexdigest(ShopifyAPI::Session.secret + sorted_params)
156
+ params = {"code" => "any-code", "timestamp" => now, "signature" => signature}
157
+
158
+ assert_equal true, ShopifyAPI::Session.validate_signature(params)
159
+ end
160
+
151
161
  private
152
162
 
153
163
  def make_sorted_params(params)
154
- sorted_params = params.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
164
+ sorted_params = params.with_indifferent_access.except(:signature, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join
155
165
  end
156
166
 
157
167
  end
data/test/test_helper.rb CHANGED
@@ -35,7 +35,7 @@ class Test::Unit::TestCase
35
35
  end
36
36
 
37
37
  ShopifyAPI::Base.clear_session
38
- ShopifyAPI::Base.site = "http://localhost/admin"
38
+ ShopifyAPI::Base.site = "https://this-is-my-test-shop.myshopify.com/admin"
39
39
  ShopifyAPI::Base.password = nil
40
40
  ShopifyAPI::Base.user = nil
41
41
  end
@@ -62,7 +62,7 @@ class Test::Unit::TestCase
62
62
  url = if options.has_key?(:url)
63
63
  options[:url]
64
64
  else
65
- "http://localhost/admin/#{endpoint}#{extension}"
65
+ "https://this-is-my-test-shop.myshopify.com/admin/#{endpoint}#{extension}"
66
66
  end
67
67
 
68
68
  FakeWeb.register_uri(method, url, {:body => body, :status => 200, :content_type => "text/#{format}", :content_length => 1}.merge(options))
metadata CHANGED
@@ -1,94 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
5
- prerelease:
4
+ version: 3.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Shopify
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-01-24 00:00:00.000000000 Z
11
+ date: 2014-02-25 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activeresource
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.0.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 3.0.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: thor
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: 0.14.4
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: 0.14.4
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: mocha
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: 0.9.8
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: 0.9.8
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: fakeweb
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rake
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  description: The Shopify API gem allows Ruby developers to programmatically access
@@ -103,9 +92,9 @@ extra_rdoc_files:
103
92
  - LICENSE
104
93
  - README.rdoc
105
94
  files:
106
- - .document
107
- - .gitignore
108
- - .travis.yml
95
+ - ".document"
96
+ - ".gitignore"
97
+ - ".travis.yml"
109
98
  - CHANGELOG
110
99
  - CONTRIBUTORS
111
100
  - Gemfile
@@ -113,6 +102,7 @@ files:
113
102
  - Gemfile_ar30
114
103
  - Gemfile_ar31
115
104
  - Gemfile_ar32
105
+ - Gemfile_ar40threadsafe
116
106
  - LICENSE
117
107
  - README.rdoc
118
108
  - RELEASING
@@ -140,6 +130,7 @@ files:
140
130
  - lib/shopify_api/resources/base.rb
141
131
  - lib/shopify_api/resources/billing_address.rb
142
132
  - lib/shopify_api/resources/blog.rb
133
+ - lib/shopify_api/resources/carrier_service.rb
143
134
  - lib/shopify_api/resources/cart.rb
144
135
  - lib/shopify_api/resources/checkout.rb
145
136
  - lib/shopify_api/resources/collect.rb
@@ -186,6 +177,7 @@ files:
186
177
  - test/asset_test.rb
187
178
  - test/base_test.rb
188
179
  - test/blog_test.rb
180
+ - test/carrier_service_test.rb
189
181
  - test/cart_test.rb
190
182
  - test/cli_test.rb
191
183
  - test/customer_saved_search_test.rb
@@ -198,6 +190,7 @@ files:
198
190
  - test/fixtures/authors.json
199
191
  - test/fixtures/blog.json
200
192
  - test/fixtures/blogs.json
193
+ - test/fixtures/carrier_service.json
201
194
  - test/fixtures/carts.json
202
195
  - test/fixtures/customer_saved_search.json
203
196
  - test/fixtures/customer_saved_search_customers.json
@@ -212,6 +205,7 @@ files:
212
205
  - test/fixtures/order_risk.json
213
206
  - test/fixtures/order_risks.json
214
207
  - test/fixtures/product.json
208
+ - test/fixtures/recurring_application_charge.json
215
209
  - test/fixtures/recurring_application_charges.json
216
210
  - test/fixtures/shop.json
217
211
  - test/fixtures/tags.json
@@ -234,28 +228,27 @@ files:
234
228
  homepage: http://www.shopify.com/partners/apps
235
229
  licenses:
236
230
  - MIT
231
+ metadata: {}
237
232
  post_install_message:
238
233
  rdoc_options:
239
- - --charset=UTF-8
234
+ - "--charset=UTF-8"
240
235
  require_paths:
241
236
  - lib
242
237
  required_ruby_version: !ruby/object:Gem::Requirement
243
- none: false
244
238
  requirements:
245
- - - ! '>='
239
+ - - ">="
246
240
  - !ruby/object:Gem::Version
247
241
  version: '0'
248
242
  required_rubygems_version: !ruby/object:Gem::Requirement
249
- none: false
250
243
  requirements:
251
- - - ! '>='
244
+ - - ">="
252
245
  - !ruby/object:Gem::Version
253
246
  version: '0'
254
247
  requirements: []
255
248
  rubyforge_project:
256
- rubygems_version: 1.8.23
249
+ rubygems_version: 2.2.0
257
250
  signing_key:
258
- specification_version: 3
251
+ specification_version: 4
259
252
  summary: ShopifyAPI is a lightweight gem for accessing the Shopify admin REST web
260
253
  services
261
254
  test_files: []