cardmagic-etsy 0.3.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.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile +11 -0
  5. data/LICENSE +9 -0
  6. data/README.md +348 -0
  7. data/Rakefile +12 -0
  8. data/etsy.gemspec +34 -0
  9. data/lib/etsy.rb +223 -0
  10. data/lib/etsy/about.rb +15 -0
  11. data/lib/etsy/address.rb +47 -0
  12. data/lib/etsy/attribute_value.rb +46 -0
  13. data/lib/etsy/basic_client.rb +32 -0
  14. data/lib/etsy/category.rb +84 -0
  15. data/lib/etsy/country.rb +27 -0
  16. data/lib/etsy/favorite_listing.rb +26 -0
  17. data/lib/etsy/image.rb +44 -0
  18. data/lib/etsy/listing.rb +296 -0
  19. data/lib/etsy/model.rb +127 -0
  20. data/lib/etsy/payment_template.rb +33 -0
  21. data/lib/etsy/profile.rb +49 -0
  22. data/lib/etsy/receipt.rb +37 -0
  23. data/lib/etsy/request.rb +150 -0
  24. data/lib/etsy/response.rb +128 -0
  25. data/lib/etsy/section.rb +16 -0
  26. data/lib/etsy/secure_client.rb +131 -0
  27. data/lib/etsy/shipping_info.rb +27 -0
  28. data/lib/etsy/shipping_template.rb +41 -0
  29. data/lib/etsy/shop.rb +88 -0
  30. data/lib/etsy/transaction.rb +29 -0
  31. data/lib/etsy/user.rb +109 -0
  32. data/lib/etsy/variation/property_set.rb +71 -0
  33. data/lib/etsy/verification_request.rb +17 -0
  34. data/lib/etsy/version.rb +3 -0
  35. data/test/fixtures/about/getAbout.json +16 -0
  36. data/test/fixtures/address/getUserAddresses.json +12 -0
  37. data/test/fixtures/attribute_value/findAllListingPropertyValues.json +44 -0
  38. data/test/fixtures/category/findAllSubCategoryChildren.json +78 -0
  39. data/test/fixtures/category/findAllTopCategory.json +347 -0
  40. data/test/fixtures/category/findAllTopCategory.single.json +18 -0
  41. data/test/fixtures/category/findAllTopCategoryChildren.json +308 -0
  42. data/test/fixtures/category/getCategory.multiple.json +28 -0
  43. data/test/fixtures/category/getCategory.single.json +18 -0
  44. data/test/fixtures/country/getCountry.json +1 -0
  45. data/test/fixtures/favorite_listing/findAllFavoriteListings.json +1 -0
  46. data/test/fixtures/image/findAllListingImages.json +102 -0
  47. data/test/fixtures/listing/findAllListingActive.category.json +827 -0
  48. data/test/fixtures/listing/findAllShopListings.json +69 -0
  49. data/test/fixtures/listing/getListing.multiple.json +1 -0
  50. data/test/fixtures/listing/getListing.single.includeImages.json +1 -0
  51. data/test/fixtures/listing/getListing.single.json +1 -0
  52. data/test/fixtures/payment_template/getPaymentTemplate.json +1 -0
  53. data/test/fixtures/profile/new.json +28 -0
  54. data/test/fixtures/receipt/findAllShopReceipts.json +28 -0
  55. data/test/fixtures/section/getShopSection.json +18 -0
  56. data/test/fixtures/shipping_info/getShippingInfo.json +1 -0
  57. data/test/fixtures/shipping_template/getShippingTemplate.json +1 -0
  58. data/test/fixtures/shop/findAllShop.json +1 -0
  59. data/test/fixtures/shop/findAllShop.single.json +1 -0
  60. data/test/fixtures/shop/getShop.multiple.json +1 -0
  61. data/test/fixtures/shop/getShop.single.json +34 -0
  62. data/test/fixtures/transaction/findAllShopTransactions.json +1 -0
  63. data/test/fixtures/user/getUser.multiple.json +29 -0
  64. data/test/fixtures/user/getUser.single.json +13 -0
  65. data/test/fixtures/user/getUser.single.private.json +18 -0
  66. data/test/fixtures/user/getUser.single.withProfile.json +38 -0
  67. data/test/fixtures/user/getUser.single.withShops.json +41 -0
  68. data/test/test_helper.rb +45 -0
  69. data/test/unit/etsy/address_test.rb +61 -0
  70. data/test/unit/etsy/attribute_value_test.rb +67 -0
  71. data/test/unit/etsy/basic_client_test.rb +30 -0
  72. data/test/unit/etsy/category_test.rb +106 -0
  73. data/test/unit/etsy/country_test.rb +64 -0
  74. data/test/unit/etsy/favorite_listing_test.rb +44 -0
  75. data/test/unit/etsy/image_test.rb +51 -0
  76. data/test/unit/etsy/listing_test.rb +268 -0
  77. data/test/unit/etsy/model_test.rb +64 -0
  78. data/test/unit/etsy/payment_template_test.rb +68 -0
  79. data/test/unit/etsy/profile_test.rb +111 -0
  80. data/test/unit/etsy/receipt_test.rb +107 -0
  81. data/test/unit/etsy/request_test.rb +190 -0
  82. data/test/unit/etsy/response_test.rb +175 -0
  83. data/test/unit/etsy/section_test.rb +28 -0
  84. data/test/unit/etsy/secure_client_test.rb +132 -0
  85. data/test/unit/etsy/shipping_info_test.rb +24 -0
  86. data/test/unit/etsy/shipping_template_test.rb +24 -0
  87. data/test/unit/etsy/shop_about_test.rb +43 -0
  88. data/test/unit/etsy/shop_test.rb +116 -0
  89. data/test/unit/etsy/transaction_test.rb +61 -0
  90. data/test/unit/etsy/user_test.rb +250 -0
  91. data/test/unit/etsy/verification_request_test.rb +26 -0
  92. data/test/unit/etsy_test.rb +173 -0
  93. metadata +293 -0
@@ -0,0 +1,61 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class TransactionTest < Test::Unit::TestCase
5
+
6
+ context "The Transaction class" do
7
+
8
+ should "be able to find transactions for a shop" do
9
+ transactions = mock_request('/shops/1/transactions', {'key' => 'value'}, 'Transaction', 'findAllShopTransactions.json')
10
+ Transaction.find_all_by_shop_id(1, {'key' => 'value'}).should == transactions
11
+ end
12
+
13
+ should "be able to find transactions for a buyer" do
14
+ transactions = mock_request('/users/1/transactions', {'key' => 'value'}, 'Transaction', 'findAllShopTransactions.json')
15
+ Transaction.find_all_by_buyer_id(1, {'key' => 'value'}).should == transactions
16
+ end
17
+
18
+ should "be able to find transactions for a receipt" do
19
+ transactions = mock_request('/receipts/1/transactions', {'key' => 'value'}, 'Transaction', 'findAllShopTransactions.json')
20
+ Transaction.find_all_by_receipt_id(1, {'key' => 'value'}).should == transactions
21
+ end
22
+ end
23
+
24
+ context "An instance of the Transaction class" do
25
+
26
+ context "with response data" do
27
+ setup do
28
+ data = read_fixture('transaction/findAllShopTransactions.json')
29
+ @transaction = Transaction.new(data.first)
30
+ end
31
+
32
+ should "have a value for :id" do
33
+ @transaction.id.should == 27230877
34
+ end
35
+
36
+ should "have a value for :quantity" do
37
+ @transaction.quantity.should == 1
38
+ end
39
+
40
+ should "have a value for :buyer_id" do
41
+ @transaction.buyer_id.should == 9641557
42
+ end
43
+
44
+ should "have a value for :listing_id" do
45
+ @transaction.listing_id.should == 41680579
46
+ end
47
+ end
48
+
49
+ should "know the buyer" do
50
+ User.stubs(:find).with(1).returns('user')
51
+
52
+ transaction = Transaction.new
53
+ transaction.stubs(:buyer_id).with().returns(1)
54
+
55
+ transaction.buyer.should == 'user'
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,250 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class UserTest < Test::Unit::TestCase
5
+
6
+ context "The User class" do
7
+
8
+ should "be able to find a single user" do
9
+ users = mock_request('/users/littletjane', {}, 'User', 'getUser.single.json')
10
+ User.find('littletjane').should == users.first
11
+ end
12
+
13
+ should "be able to find multiple users" do
14
+ users = mock_request('/users/littletjane,reagent', {}, 'User', 'getUser.multiple.json')
15
+ User.find('littletjane', 'reagent').should == users
16
+ end
17
+
18
+ should "be able to pass options when finding a user" do
19
+ options = {:limit => 90, :offset => 90}
20
+ users = mock_request('/users/littletjane', options, 'User', 'getUser.single.json')
21
+ User.find('littletjane', options).should == users.first
22
+ end
23
+
24
+ should "be able to find the authenticated user" do
25
+ options = {:access_token => 'token', :access_secret => 'secret'}
26
+ users = mock_request('/users/__SELF__', options, 'User', 'getUser.single.json')
27
+ User.myself('token', 'secret', options).should == users.first
28
+ end
29
+ end
30
+
31
+ context "An instance of the User class" do
32
+
33
+ context "requested with oauth access token" do
34
+ setup do
35
+ options = {:access_token => 'token', :access_secret => 'secret'}
36
+
37
+ data = read_fixture('user/getUser.single.json')
38
+ response = 'response'
39
+ response.stubs(:result).with().returns [data]
40
+ Request.stubs(:get).with('/users/__SELF__', options).returns response
41
+
42
+ @user = User.find('__SELF__', options)
43
+ end
44
+
45
+ should "persist the token" do
46
+ @user.token.should == 'token'
47
+ end
48
+
49
+ should "persist the secret" do
50
+ @user.secret.should == 'secret'
51
+ end
52
+ end
53
+
54
+ context "with public response data" do
55
+ setup do
56
+ data = read_fixture('user/getUser.single.json')
57
+ @user = User.new(data.first)
58
+ end
59
+
60
+ should "have an ID" do
61
+ @user.id.should == 5327518
62
+ end
63
+
64
+ should "have a :username" do
65
+ @user.username.should == 'littletjane'
66
+ end
67
+
68
+ should "have a value for :created" do
69
+ @user.created.should == 1191381578
70
+ end
71
+
72
+ should "not have an email address" do
73
+ @user.email.should be_nil
74
+ end
75
+ end
76
+
77
+ context "with private response data" do
78
+ setup do
79
+ data = read_fixture('user/getUser.single.private.json')
80
+ @user = User.new(data.first, 'token', 'secret')
81
+ end
82
+
83
+ should "have an email address" do
84
+ @user.email.should == 'reaganpr@gmail.com'
85
+ end
86
+ end
87
+
88
+ context "requested with associated shops" do
89
+ setup do
90
+ data = read_fixture('user/getUser.single.withShops.json')
91
+ @user = User.new(data.first)
92
+ end
93
+
94
+ should "have shops" do
95
+ @user.shops.each do |shop|
96
+ shop.class.should == Shop
97
+ end
98
+ end
99
+
100
+ # This assumes for now that a user can have only one shop belonging to them
101
+ should "return the first shop belonging to the user" do
102
+ @user.shop.should == @user.shops.first
103
+ end
104
+ end
105
+
106
+ context "requested without associated shops" do
107
+ setup do
108
+ @data_without_shops = read_fixture('user/getUser.single.json')
109
+ @data_with_shops = read_fixture('user/getUser.single.withShops.json')
110
+ @options = {:fields => 'user_id', :includes => 'Shops'}
111
+
112
+ @user_without_shops = User.new(@data_without_shops.first)
113
+ @user_with_shops = User.new(@data_with_shops.first)
114
+ end
115
+
116
+ should "make a call to the API to retrieve it if requested" do
117
+ User.expects(:find).with('littletjane', @options).returns @user_with_shops
118
+ @user_without_shops.shops
119
+ end
120
+
121
+ should "not call the api twice" do
122
+ User.expects(:find).once.with('littletjane', @options).returns @user_with_shops
123
+ @user_without_shops.shops
124
+ @user_without_shops.shops
125
+ end
126
+
127
+ should "return a list of populated shop instances" do
128
+ User.stubs(:find).with('littletjane', @options).returns @user_with_shops
129
+ @user_without_shops.shops.first.name.should == 'LittleJane'
130
+ end
131
+
132
+ should "make the call with authentication if oauth is used" do
133
+ user = User.new(@data_without_shops.first, 'token', 'secret')
134
+ oauth = {:access_token => 'token', :access_secret => 'secret'}
135
+ User.expects(:find).with('littletjane', @options.merge(oauth)).returns @user_with_shops
136
+ user.shops
137
+ end
138
+ end
139
+
140
+ context "requested with an associated profile" do
141
+ setup do
142
+ data = read_fixture('user/getUser.single.withProfile.json')
143
+ @user = User.new(data.first)
144
+ end
145
+
146
+ should "have a profile" do
147
+ @user.profile.class.should == Profile
148
+ end
149
+ end
150
+
151
+ context "requested without an associated profile" do
152
+ setup do
153
+ @data_without_profile = read_fixture('user/getUser.single.json')
154
+ @data_with_profile = read_fixture('user/getUser.single.withProfile.json')
155
+ @options = {:fields => 'user_id', :includes => 'Profile'}
156
+
157
+ @user_without_profile = User.new(@data_without_profile.first)
158
+ @user_with_profile = User.new(@data_with_profile.first)
159
+ end
160
+
161
+ should "make a call to the API to retrieve it if requested" do
162
+ User.expects(:find).with('littletjane', @options).returns @user_with_profile
163
+ @user_without_profile.profile
164
+ end
165
+
166
+ should "not call the api twice" do
167
+ User.expects(:find).once.with('littletjane', @options).returns @user_with_profile
168
+ @user_without_profile.profile
169
+ @user_without_profile.profile
170
+ end
171
+
172
+ should "return a populated profile instance" do
173
+ User.stubs(:find).with('littletjane', @options).returns @user_with_profile
174
+ @user_without_profile.profile.bio.should == 'I make stuff'
175
+ end
176
+
177
+ should "make the call with authentication if oauth is used" do
178
+ user = User.new(@data_without_profile.first, 'token', 'secret')
179
+ oauth = {:access_token => 'token', :access_secret => 'secret'}
180
+ User.expects(:find).with('littletjane', @options.merge(oauth)).returns @user_with_profile
181
+ user.profile
182
+ end
183
+ end
184
+
185
+ context "instantiated with oauth token" do
186
+ setup do
187
+ @user = User.new(nil, 'token', 'secret')
188
+ end
189
+
190
+ should "have the token" do
191
+ @user.token.should == 'token'
192
+ end
193
+
194
+ should "have the secret" do
195
+ @user.secret.should == 'secret'
196
+ end
197
+
198
+ end
199
+
200
+ should "know when the user was created" do
201
+ user = User.new
202
+ user.stubs(:created).returns(1)
203
+
204
+ user.created_at.should == Time.at(1)
205
+ end
206
+
207
+ context "with favorite listings data" do
208
+ setup do
209
+ data = read_fixture('user/getUser.single.withProfile.json')
210
+ @user = User.new(data.first)
211
+ listing_1 = stub(:listing_id => 1, :user_id => @user.id)
212
+ listing_2 = stub(:listing_id => 2, :user_id => @user.id)
213
+ @favorite_listings = [listing_1, listing_2]
214
+ end
215
+
216
+ should "have all listings" do
217
+ FavoriteListing.stubs(:find_all_user_favorite_listings).with(@user.id, {:access_token => nil, :access_secret => nil}).returns(@favorite_listings)
218
+ Listing.stubs(:find).with([1, 2], {:access_token => nil, :access_secret => nil}).returns(['listings'])
219
+ @user.favorites.should == ['listings']
220
+ end
221
+ end
222
+
223
+ context "with bought listings data" do
224
+ setup do
225
+ data = read_fixture('user/getUser.single.withProfile.json')
226
+ @user = User.new(data.first)
227
+ listing_1 = stub(:listing_id => 1, :user_id => @user.id)
228
+ listing_2 = stub(:listing_id => 2, :user_id => @user.id)
229
+ @bought_listings = [listing_1, listing_2]
230
+ end
231
+
232
+ should "have all listings" do
233
+ Transaction.stubs(:find_all_by_buyer_id).with(@user.id, {:access_token => nil, :access_secret => nil}).returns(@bought_listings)
234
+ Listing.stubs(:find).with([1, 2], {:access_token => nil, :access_secret => nil}).returns(['listings'])
235
+ @user.bought_listings.should == ['listings']
236
+ end
237
+ end
238
+ end
239
+
240
+ should "know the addresses for a user" do
241
+ user = User.new
242
+ user.stubs(:username).with().returns('username')
243
+
244
+ Address.stubs(:find).with('username', {}).returns('addresses')
245
+
246
+ user.addresses.should == 'addresses'
247
+ end
248
+
249
+ end
250
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class VerificationRequestTest < Test::Unit::TestCase
5
+
6
+ context "An instance of the VerificationRequest class" do
7
+ setup { @request = VerificationRequest.new }
8
+
9
+ should "have a client" do
10
+ SecureClient.stubs(:new).returns('client')
11
+ @request.client.should == 'client'
12
+ end
13
+
14
+ should "know the url" do
15
+ client = stub()
16
+ client.stubs(:request_token).returns(stub(:params => {:login_url => 'http://www.etsy.com?foo=bar&baz=true'}, :secret => 'secret'))
17
+
18
+ @request.stubs(:client).returns(client)
19
+
20
+ @request.url.should == 'http://www.etsy.com?foo=bar&baz=true'
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,173 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class EtsyTest < Test::Unit::TestCase
4
+
5
+ context "The Etsy module" do
6
+ setup do
7
+ Etsy.instance_variable_set(:@protocol, nil)
8
+ Etsy.instance_variable_set(:@environment, nil)
9
+ Etsy.instance_variable_set(:@access_mode, nil)
10
+ Etsy.instance_variable_set(:@callback_url, nil)
11
+ Etsy.instance_variable_set(:@host, nil)
12
+ Etsy.instance_variable_set(:@api_key, nil)
13
+ Etsy.instance_variable_set(:@api_secret, nil)
14
+ Etsy.instance_variable_set(:@permission_scopes, nil)
15
+ Etsy.instance_variable_set(:@silent_errors, nil)
16
+ end
17
+
18
+ should "be able to set and retrieve the API key" do
19
+ Etsy.api_key = 'key'
20
+ Etsy.api_key.should == 'key'
21
+ end
22
+
23
+ should "be able to set and retrieve the API key across threads (global)" do
24
+ Etsy.api_key = 'key'
25
+ Thread.new do
26
+ Etsy.api_key.should == 'key'
27
+ end.join
28
+ end
29
+
30
+ should "be able to set and retrieve the API key inside a thread (thread local)" do
31
+ Etsy.api_key = 'key'
32
+ Thread.new do
33
+ Etsy.api_key = 'thread_local_key'
34
+ Etsy.api_key.should == 'thread_local_key'
35
+ end.join
36
+ end
37
+
38
+ should "be able to set and retrieve the API secret" do
39
+ Etsy.api_secret = 'secret'
40
+ Etsy.api_secret.should == 'secret'
41
+ end
42
+
43
+ should "be able to set and retrieve the API secret across threads (global)" do
44
+ Etsy.api_secret = 'secret'
45
+ Thread.new do
46
+ Etsy.api_secret.should == 'secret'
47
+ end.join
48
+ end
49
+
50
+ should "be able to set and retrieve the API secret inside a thread (thread local)" do
51
+ Etsy.api_secret = 'secret'
52
+ Thread.new do
53
+ Etsy.api_secret = 'thread_local_secret'
54
+ Etsy.api_secret.should == 'thread_local_secret'
55
+ end.join
56
+ end
57
+
58
+ should "be able to find a user by username" do
59
+ user = stub()
60
+
61
+ Etsy::User.expects(:find).with('littletjane').returns(user)
62
+ Etsy.user('littletjane').should == user
63
+ end
64
+
65
+ should "use the https protocol by default" do
66
+ Etsy.protocol.should == "https"
67
+ end
68
+
69
+ should "be able to set the protocol to a valid value" do
70
+ Etsy.protocol = 'http'
71
+ Etsy.protocol.should == 'http'
72
+ end
73
+
74
+ should "raise an exception when attempting to set an invalid protocol" do
75
+ lambda { Etsy.protocol = :invalid }.should raise_error(ArgumentError)
76
+ end
77
+
78
+ should "use silent errors by default" do
79
+ Etsy.silent_errors.should == true
80
+ end
81
+
82
+ should "be able to set silent errors to a valid value" do
83
+ Etsy.silent_errors = false
84
+ Etsy.silent_errors.should == false
85
+ end
86
+
87
+ should "raise an exception when attempting to set an invalid silent errors value" do
88
+ lambda { Etsy.silent_errors = :invalid }.should raise_error(ArgumentError)
89
+ end
90
+
91
+ should "use the production environment by default" do
92
+ Etsy.environment.should == :production
93
+ end
94
+
95
+ should "be able to set the environment to a valid value" do
96
+ Etsy.environment = :sandbox
97
+ Etsy.environment.should == :sandbox
98
+ end
99
+
100
+ should "raise an exception when attempting to set an invalid environment" do
101
+ lambda { Etsy.environment = :invalid }.should raise_error(ArgumentError)
102
+ end
103
+
104
+ should "know the host for the sandbox environment" do
105
+ Etsy.environment = :sandbox
106
+ Etsy.host.should == 'sandbox.openapi.etsy.com'
107
+ end
108
+
109
+ should "know the host for the production environment" do
110
+ Etsy.environment = :production
111
+ Etsy.host.should == 'openapi.etsy.com'
112
+ end
113
+
114
+ should "default to production host" do
115
+ Etsy.host.should == 'openapi.etsy.com'
116
+ end
117
+
118
+ should "be able to set the callback url" do
119
+ Etsy.callback_url = 'http://localhost'
120
+ Etsy.callback_url.should == 'http://localhost'
121
+ end
122
+
123
+ should "default callback to out-of-band" do
124
+ Etsy.callback_url.should == 'oob'
125
+ end
126
+
127
+ should "default permission scopes to an empty array" do
128
+ Etsy.permission_scopes.should == []
129
+ end
130
+
131
+ should "be able to set the scopes" do
132
+ Etsy.permission_scopes = %w(a_scope another_scope)
133
+ Etsy.permission_scopes.should == ['a_scope', 'another_scope']
134
+ end
135
+ end
136
+
137
+ context "The Etsy module when set up properly" do
138
+ setup do
139
+ Etsy.instance_variable_set(:@protocol, 'https')
140
+ Etsy.instance_variable_set(:@environment, :sandbox)
141
+ Etsy.instance_variable_set(:@access_mode, :read_write)
142
+ Etsy.instance_variable_set(:@api_key, 'key')
143
+ Etsy.instance_variable_set(:@api_secret, 'secret')
144
+ Etsy.instance_variable_set(:@verification_request, nil)
145
+ end
146
+
147
+ should "provide a request token" do
148
+ request = stub(:request_token => 'token')
149
+ Etsy::VerificationRequest.stubs(:new).returns(request)
150
+
151
+ Etsy.request_token.should == 'token'
152
+ end
153
+
154
+ should "be able to generate an access token" do
155
+ Etsy::SecureClient.stubs(:new).with({
156
+ :request_token => 'toke',
157
+ :request_secret => 'secret',
158
+ :verifier => 'verifier'
159
+ }).returns(stub(:client => 'token'))
160
+
161
+ Etsy.access_token('toke', 'secret', 'verifier').should == 'token'
162
+ end
163
+
164
+ should "provide a verification URL" do
165
+ request = stub(:url => 'url')
166
+ Etsy::VerificationRequest.stubs(:new).returns(request)
167
+
168
+ Etsy.verification_url.should == 'url'
169
+ end
170
+
171
+ end
172
+
173
+ end