shopify_api 3.2.1 → 3.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc9fc203a46569db4cddb7ed4c82f9392dfdbb33
4
- data.tar.gz: ee232e9226eee62db4edd51db94ad38a66bb532b
3
+ metadata.gz: 4b7258c4c1368bc212523e4f8454567e21d46737
4
+ data.tar.gz: 3ab24e5dba88ffb8172b7b4b9f9b72029fefe208
5
5
  SHA512:
6
- metadata.gz: 5aaec38706d2c2226260f34ef597108fc68bb1a578f030553771e895e8b03b8dbb0d650ea88a6b3b6097b596e8f967f0315ca922dbfe13566a167e478b32f0ab
7
- data.tar.gz: d5bf632be11ffdf315c25616e26bfdd8c4e4fe89034ed98b182af5cd4b14dda035fd1dfe556ffc9a8119efbe5a188dd2e7b74399a1f6270027a24ef770e14990
6
+ metadata.gz: b3f0a8efebafd6e97a057c5e87de87a1fc81be1a587c4471c5c2129589d0ecbae0ba2b7398b5ecc6e6b4986e2cd1a2f9c85bbb090209e7438d7c31d42b885ab8
7
+ data.tar.gz: e38505ed41e9ae8bd00377483b57cf8a8b62dfff37eb218193cc620665309e978668193ede11b824cb2e7bf3bcbd820e85b4b5eb88a49539c6167eef7bb6e22e
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ == Version 3.2.2
2
+
3
+ * Temporary fix for the CLI
4
+ * Add a specific exception for signature validation failures
5
+
1
6
  == Version 3.2.1
2
7
 
3
8
  * Added CarrierService resource
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify_api (3.2.1)
4
+ shopify_api (3.2.2)
5
5
  activeresource (>= 3.0.0)
6
- thor (>= 0.14.4)
6
+ thor (~> 0.18.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -44,6 +44,7 @@ PLATFORMS
44
44
  DEPENDENCIES
45
45
  activeresource (~> 4.0.0)
46
46
  fakeweb
47
+ minitest (~> 4.0)
47
48
  mocha (>= 0.9.8)
48
49
  rake
49
50
  shopify_api!
@@ -1,10 +1,11 @@
1
1
  require 'thor'
2
2
  require 'abbrev'
3
+ require 'yaml'
3
4
 
4
5
  module ShopifyAPI
5
6
  class Cli < Thor
6
7
  include Thor::Actions
7
-
8
+
8
9
  class ConfigFileError < StandardError
9
10
  end
10
11
 
@@ -15,7 +16,7 @@ module ShopifyAPI
15
16
  puts prefix + c
16
17
  end
17
18
  end
18
-
19
+
19
20
  desc "add CONNECTION", "create a config file for a connection named CONNECTION"
20
21
  def add(connection)
21
22
  file = config_file(connection)
@@ -35,7 +36,7 @@ module ShopifyAPI
35
36
  default(connection)
36
37
  end
37
38
  end
38
-
39
+
39
40
  desc "remove CONNECTION", "remove the config file for CONNECTION"
40
41
  def remove(connection)
41
42
  file = config_file(connection)
@@ -46,7 +47,7 @@ module ShopifyAPI
46
47
  no_config_file_error(file)
47
48
  end
48
49
  end
49
-
50
+
50
51
  desc "edit [CONNECTION]", "open the config file for CONNECTION with your default editor"
51
52
  def edit(connection=nil)
52
53
  file = config_file(connection)
@@ -60,7 +61,7 @@ module ShopifyAPI
60
61
  no_config_file_error(file)
61
62
  end
62
63
  end
63
-
64
+
64
65
  desc "show [CONNECTION]", "output the location and contents of the CONNECTION's config file"
65
66
  def show(connection=nil)
66
67
  connection ||= default_connection
@@ -72,7 +73,7 @@ module ShopifyAPI
72
73
  no_config_file_error(file)
73
74
  end
74
75
  end
75
-
76
+
76
77
  desc "default [CONNECTION]", "show the default connection, or make CONNECTION the default"
77
78
  def default(connection=nil)
78
79
  if connection
@@ -90,15 +91,15 @@ module ShopifyAPI
90
91
  puts "There is no default connection set"
91
92
  end
92
93
  end
93
-
94
+
94
95
  desc "console [CONNECTION]", "start an API console for CONNECTION"
95
96
  def console(connection=nil)
96
97
  file = config_file(connection)
97
-
98
+
98
99
  config = YAML.load(File.read(file))
99
100
  puts "using #{config['domain']}"
100
101
  ShopifyAPI::Base.site = site_from_config(config)
101
-
102
+
102
103
  require 'irb'
103
104
  require 'irb/completion'
104
105
  ARGV.clear
@@ -110,15 +111,15 @@ module ShopifyAPI
110
111
  end
111
112
 
112
113
  private
113
-
114
+
114
115
  def shop_config_dir
115
116
  @shop_config_dir ||= File.join(ENV['HOME'], '.shopify', 'shops')
116
117
  end
117
-
118
+
118
119
  def default_symlink
119
120
  @default_symlink ||= File.join(shop_config_dir, 'default')
120
121
  end
121
-
122
+
122
123
  def config_file(connection)
123
124
  if connection
124
125
  File.join(shop_config_dir, "#{connection}.yml")
@@ -126,35 +127,35 @@ module ShopifyAPI
126
127
  default_symlink
127
128
  end
128
129
  end
129
-
130
+
130
131
  def site_from_config(config)
131
132
  protocol = config['protocol'] || 'https'
132
133
  api_key = config['api_key']
133
134
  password = config['password']
134
135
  domain = config['domain']
135
-
136
+
136
137
  ShopifyAPI::Base.site = "#{protocol}://#{api_key}:#{password}@#{domain}/admin"
137
138
  end
138
-
139
+
139
140
  def available_connections
140
141
  @available_connections ||= begin
141
142
  pattern = File.join(shop_config_dir, "*.yml")
142
143
  Dir.glob(pattern).map { |f| File.basename(f, ".yml") }
143
144
  end
144
145
  end
145
-
146
+
146
147
  def default_connection_target
147
148
  @default_connection_target ||= File.readlink(default_symlink)
148
149
  end
149
-
150
+
150
151
  def default_connection
151
152
  @default_connection ||= File.basename(default_connection_target, ".yml")
152
153
  end
153
-
154
+
154
155
  def default?(connection)
155
156
  default_connection == connection
156
157
  end
157
-
158
+
158
159
  def no_config_file_error(filename)
159
160
  raise ConfigFileError, "There is no config file at #{filename}"
160
161
  end
@@ -1,6 +1,9 @@
1
1
 
2
2
  module ShopifyAPI
3
3
 
4
+ class ValidationException < StandardError
5
+ end
6
+
4
7
  class Session
5
8
  cattr_accessor :api_key
6
9
  cattr_accessor :secret
@@ -74,7 +77,7 @@ module ShopifyAPI
74
77
  return token if token
75
78
 
76
79
  unless self.class.validate_signature(params) && params[:timestamp].to_i > 24.hours.ago.utc.to_i
77
- raise "Invalid Signature: Possible malicious login"
80
+ raise ShopifyAPI::ValidationException, "Invalid Signature: Possible malicious login"
78
81
  end
79
82
 
80
83
  code = params['code']
@@ -1,3 +1,3 @@
1
1
  module ShopifyAPI
2
- VERSION = "3.2.1"
2
+ VERSION = "3.2.2"
3
3
  end
@@ -25,15 +25,17 @@ Gem::Specification.new do |s|
25
25
  s.license = 'MIT'
26
26
 
27
27
  s.add_dependency("activeresource", [">= 3.0.0"])
28
- s.add_dependency("thor", [">= 0.14.4"])
29
-
28
+ s.add_dependency("thor", ["~> 0.18.1"])
29
+
30
30
  if s.respond_to?(:add_development_dependency)
31
31
  s.add_development_dependency("mocha", ">= 0.9.8")
32
32
  s.add_development_dependency("fakeweb")
33
+ s.add_development_dependency("minitest", "~> 4.0")
33
34
  s.add_development_dependency("rake")
34
35
  else
35
36
  s.add_dependency("mocha", ">= 0.9.8")
36
37
  s.add_dependency("fakeweb")
38
+ s.add_dependency("minitest", "~> 4.0")
37
39
  s.add_dependency("rake")
38
40
  end
39
41
  end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class CheckoutsTest < Test::Unit::TestCase
4
+ test "get all should get all orders" do
5
+ fake 'checkouts', :method => :get, :status => 200, :body => load_fixture('checkouts')
6
+ checkout = ShopifyAPI::Checkout.all
7
+ assert_equal 450789469, checkout.first.id
8
+ end
9
+ end
@@ -10,7 +10,7 @@ class CliTest < Test::Unit::TestCase
10
10
  `rm -rf #{@test_home}`
11
11
  ENV['HOME'] = @test_home
12
12
  @cli = ShopifyAPI::Cli.new
13
-
13
+
14
14
  FileUtils.mkdir_p(@shop_config_dir)
15
15
  File.open(config_file('foo'), 'w') do |file|
16
16
  file.puts valid_options.merge('domain' => 'foo.myshopify.com').to_yaml
@@ -20,11 +20,11 @@ class CliTest < Test::Unit::TestCase
20
20
  file.puts valid_options.merge('domain' => 'bar.myshopify.com').to_yaml
21
21
  end
22
22
  end
23
-
23
+
24
24
  def teardown
25
25
  `rm -rf #{@test_home}`
26
26
  end
27
-
27
+
28
28
  test "add with blank domain" do
29
29
  `rm -rf #{@shop_config_dir}/*`
30
30
  $stdout.expects(:print).with("Domain? (leave blank for foo.myshopify.com) ")
@@ -33,9 +33,9 @@ class CliTest < Test::Unit::TestCase
33
33
  $stdin.expects(:gets).times(3).returns("", "key", "pass")
34
34
  @cli.expects(:puts).with("\nopen https://foo.myshopify.com/admin/api in your browser to get API credentials\n")
35
35
  @cli.expects(:puts).with("Default connection is foo")
36
-
36
+
37
37
  @cli.add('foo')
38
-
38
+
39
39
  config = YAML.load(File.read(config_file('foo')))
40
40
  assert_equal 'foo.myshopify.com', config['domain']
41
41
  assert_equal 'key', config['api_key']
@@ -43,7 +43,7 @@ class CliTest < Test::Unit::TestCase
43
43
  assert_equal 'https', config['protocol']
44
44
  assert_equal config_file('foo'), File.readlink(@default_symlink)
45
45
  end
46
-
46
+
47
47
  test "add with explicit domain" do
48
48
  `rm -rf #{@shop_config_dir}/*`
49
49
  $stdout.expects(:print).with("Domain? (leave blank for foo.myshopify.com) ")
@@ -52,58 +52,58 @@ class CliTest < Test::Unit::TestCase
52
52
  $stdin.expects(:gets).times(3).returns("bar.myshopify.com", "key", "pass")
53
53
  @cli.expects(:puts).with("\nopen https://bar.myshopify.com/admin/api in your browser to get API credentials\n")
54
54
  @cli.expects(:puts).with("Default connection is foo")
55
-
55
+
56
56
  @cli.add('foo')
57
-
57
+
58
58
  config = YAML.load(File.read(config_file('foo')))
59
59
  assert_equal 'bar.myshopify.com', config['domain']
60
60
  end
61
-
61
+
62
62
  test "list" do
63
63
  @cli.expects(:puts).with(" bar")
64
64
  @cli.expects(:puts).with(" * foo")
65
-
65
+
66
66
  @cli.list
67
67
  end
68
-
68
+
69
69
  test "show default" do
70
70
  @cli.expects(:puts).with("Default connection is foo")
71
-
71
+
72
72
  @cli.default
73
73
  end
74
-
74
+
75
75
  test "set default" do
76
76
  @cli.expects(:puts).with("Default connection is bar")
77
-
77
+
78
78
  @cli.default('bar')
79
-
79
+
80
80
  assert_equal config_file('bar'), File.readlink(@default_symlink)
81
81
  end
82
-
82
+
83
83
  test "remove default connection" do
84
84
  @cli.remove('foo')
85
-
85
+
86
86
  assert !File.exist?(@default_symlink)
87
87
  assert !File.exist?(config_file('foo'))
88
88
  assert File.exist?(config_file('bar'))
89
89
  end
90
-
90
+
91
91
  test "remove non-default connection" do
92
92
  @cli.remove('bar')
93
-
93
+
94
94
  assert_equal config_file('foo'), File.readlink(@default_symlink)
95
95
  assert File.exist?(config_file('foo'))
96
96
  assert !File.exist?(config_file('bar'))
97
97
  end
98
-
98
+
99
99
  private
100
-
100
+
101
101
  def valid_options
102
102
  {'domain' => 'snowdevil.myshopify.com', 'api_key' => 'key', 'password' => 'pass', 'protocol' => 'https'}
103
103
  end
104
-
104
+
105
105
  def config_file(connection)
106
106
  File.join(@shop_config_dir, "#{connection}.yml")
107
107
  end
108
-
109
- end
108
+
109
+ end
@@ -0,0 +1,186 @@
1
+ {
2
+ "checkouts": [
3
+ {
4
+ "buyer_accepts_marketing": false,
5
+ "cart_token": "68778783ad298f1c80c3bafcddeea02f",
6
+ "closed_at": null,
7
+ "completed_at": null,
8
+ "created_at": "2012-10-12T07:05:27-04:00",
9
+ "currency": "USD",
10
+ "email": "bob.norman@hostmail.com",
11
+ "gateway": null,
12
+ "id": 450789469,
13
+ "landing_site": null,
14
+ "note": null,
15
+ "referring_site": null,
16
+ "shipping_lines": [
17
+ {
18
+ "title": "Free Shipping",
19
+ "price": "0.00",
20
+ "code": "Free Shipping",
21
+ "source": "shopify"
22
+ }
23
+ ],
24
+ "source": null,
25
+ "source_identifier": null,
26
+ "source_name": "web",
27
+ "source_url": null,
28
+ "subtotal_price": "398.00",
29
+ "taxes_included": false,
30
+ "token": "2a1ace52255252df566af0faaedfbfa7",
31
+ "total_discounts": "0.00",
32
+ "total_line_items_price": "398.00",
33
+ "total_price": "409.94",
34
+ "total_tax": "11.94",
35
+ "total_weight": 400,
36
+ "updated_at": "2012-10-12T07:05:27-04:00",
37
+ "line_items": [
38
+ {
39
+ "applied_discounts": [
40
+
41
+ ],
42
+ "compare_at_price": null,
43
+ "fulfillment_service": "manual",
44
+ "gift_card": false,
45
+ "grams": 200,
46
+ "id": 49148385,
47
+ "line_price": "199.00",
48
+ "price": "199.00",
49
+ "product_id": 632910392,
50
+ "properties": null,
51
+ "quantity": 1,
52
+ "requires_shipping": true,
53
+ "sku": "IPOD2008RED",
54
+ "tax_lines": [
55
+
56
+ ],
57
+ "taxable": true,
58
+ "title": "IPod Nano - 8GB",
59
+ "variant_id": 49148385,
60
+ "variant_title": "Red",
61
+ "vendor": "Apple"
62
+ },
63
+ {
64
+ "applied_discounts": [
65
+
66
+ ],
67
+ "compare_at_price": null,
68
+ "fulfillment_service": "manual",
69
+ "gift_card": false,
70
+ "grams": 200,
71
+ "id": 808950810,
72
+ "line_price": "199.00",
73
+ "price": "199.00",
74
+ "product_id": 632910392,
75
+ "properties": null,
76
+ "quantity": 1,
77
+ "requires_shipping": true,
78
+ "sku": "IPOD2008PINK",
79
+ "tax_lines": [
80
+
81
+ ],
82
+ "taxable": true,
83
+ "title": "IPod Nano - 8GB",
84
+ "variant_id": 808950810,
85
+ "variant_title": "Pink",
86
+ "vendor": "Apple"
87
+ }
88
+ ],
89
+ "name": "#450789469",
90
+ "note_attributes": [
91
+ {
92
+ "name": "custom engraving",
93
+ "value": "Happy Birthday"
94
+ },
95
+ {
96
+ "name": "colour",
97
+ "value": "green"
98
+ }
99
+ ],
100
+ "discount_codes": [
101
+ {
102
+ "code": "TENOFF",
103
+ "amount": "10.00"
104
+ }
105
+ ],
106
+ "abandoned_checkout_url": "https://checkout.local/orders/690933842/2a1ace52255252df566af0faaedfbfa7?recovered=1",
107
+ "tax_lines": [
108
+ {
109
+ "price": "11.94",
110
+ "rate": 0.06,
111
+ "title": "State Tax"
112
+ }
113
+ ],
114
+ "billing_address": {
115
+ "address1": "Chestnut Street 92",
116
+ "address2": "",
117
+ "city": "Louisville",
118
+ "company": null,
119
+ "country": "United States",
120
+ "first_name": "Bob",
121
+ "last_name": "Norman",
122
+ "latitude": "45.41634",
123
+ "longitude": "-75.6868",
124
+ "phone": "555-625-1199",
125
+ "province": "Kentucky",
126
+ "zip": "40202",
127
+ "name": "Bob Norman",
128
+ "country_code": "US",
129
+ "province_code": "KY"
130
+ },
131
+ "shipping_address": {
132
+ "address1": "Chestnut Street 92",
133
+ "address2": "",
134
+ "city": "Louisville",
135
+ "company": null,
136
+ "country": "United States",
137
+ "first_name": "Bob",
138
+ "last_name": "Norman",
139
+ "latitude": "45.41634",
140
+ "longitude": "-75.6868",
141
+ "phone": "555-625-1199",
142
+ "province": "Kentucky",
143
+ "zip": "40202",
144
+ "name": "Bob Norman",
145
+ "country_code": "US",
146
+ "province_code": "KY"
147
+ },
148
+ "customer": {
149
+ "accepts_marketing": false,
150
+ "created_at": "2014-03-07T16:12:37-05:00",
151
+ "email": "bob.norman@hostmail.com",
152
+ "first_name": "Bob",
153
+ "id": 207119551,
154
+ "last_name": "Norman",
155
+ "last_order_id": null,
156
+ "multipass_identifier": null,
157
+ "note": null,
158
+ "orders_count": 0,
159
+ "state": "disabled",
160
+ "total_spent": "0.00",
161
+ "updated_at": "2014-03-07T16:12:37-05:00",
162
+ "verified_email": true,
163
+ "tags": "",
164
+ "last_order_name": null,
165
+ "default_address": {
166
+ "address1": "Chestnut Street 92",
167
+ "address2": "",
168
+ "city": "Louisville",
169
+ "company": null,
170
+ "country": "United States",
171
+ "first_name": null,
172
+ "id": 207119551,
173
+ "last_name": null,
174
+ "phone": "555-625-1199",
175
+ "province": "Kentucky",
176
+ "zip": "40202",
177
+ "name": null,
178
+ "province_code": "KY",
179
+ "country_code": "US",
180
+ "country_name": "United States",
181
+ "default": true
182
+ }
183
+ }
184
+ }
185
+ ]
186
+ }