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 +7 -0
- data/.travis.yml +2 -1
- data/CHANGELOG +6 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +6 -5
- data/Gemfile_ar40threadsafe +5 -0
- data/README.rdoc +14 -0
- data/lib/shopify_api/resources/base.rb +20 -8
- data/lib/shopify_api/resources/carrier_service.rb +4 -0
- data/lib/shopify_api/resources/recurring_application_charge.rb +3 -3
- data/lib/shopify_api/session.rb +1 -0
- data/lib/shopify_api/version.rb +1 -1
- data/test/base_test.rb +55 -6
- data/test/carrier_service_test.rb +17 -0
- data/test/detailed_log_subscriber_test.rb +7 -7
- data/test/fixtures/carrier_service.json +9 -0
- data/test/fixtures/recurring_application_charge.json +20 -0
- data/test/fixtures/recurring_application_charges.json +100 -4
- data/test/fulfillment_test.rb +1 -1
- data/test/recurring_application_charge_test.rb +93 -7
- data/test/session_test.rb +11 -1
- data/test/test_helper.rb +2 -2
- metadata +26 -33
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
data/Gemfile.lock
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shopify_api (3.2.
|
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.
|
12
|
-
activesupport (= 4.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.
|
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.
|
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
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
superclass.headers
|
34
|
-
|
35
|
-
|
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
|
|
@@ -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
|
data/lib/shopify_api/session.rb
CHANGED
@@ -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
|
data/lib/shopify_api/version.rb
CHANGED
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.
|
53
|
-
ShopifyAPI::Base.connection.expects(:delete).with('/admin/bases/1.json',
|
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 = "
|
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
|
30
|
-
assert_match /\-\-\> 200/,
|
31
|
-
assert_equal "Headers: {\"Accept\"=>\"application/json\", #{@ua_header}}",
|
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
|
45
|
-
assert_match /\-\-\> 404/,
|
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:",
|
47
|
+
assert_equal "Response:", @logger.logged(:info)[3]
|
48
48
|
end
|
49
49
|
end
|
@@ -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
|
-
"
|
5
|
-
"
|
6
|
-
"
|
7
|
-
"
|
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
|
}
|
data/test/fulfillment_test.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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 = "
|
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
|
-
"
|
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.
|
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-
|
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:
|
249
|
+
rubygems_version: 2.2.0
|
257
250
|
signing_key:
|
258
|
-
specification_version:
|
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: []
|