tailored-etsy 0.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.
Files changed (75) hide show
  1. data/.gitignore +8 -0
  2. data/.travis.yml +8 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +9 -0
  5. data/README.md +280 -0
  6. data/Rakefile +12 -0
  7. data/etsy.gemspec +28 -0
  8. data/lib/etsy.rb +172 -0
  9. data/lib/etsy/address.rb +47 -0
  10. data/lib/etsy/basic_client.rb +26 -0
  11. data/lib/etsy/category.rb +84 -0
  12. data/lib/etsy/country.rb +27 -0
  13. data/lib/etsy/image.rb +34 -0
  14. data/lib/etsy/listing.rb +178 -0
  15. data/lib/etsy/model.rb +123 -0
  16. data/lib/etsy/payment_template.rb +33 -0
  17. data/lib/etsy/profile.rb +49 -0
  18. data/lib/etsy/request.rb +148 -0
  19. data/lib/etsy/response.rb +112 -0
  20. data/lib/etsy/section.rb +16 -0
  21. data/lib/etsy/secure_client.rb +128 -0
  22. data/lib/etsy/shipping_template.rb +32 -0
  23. data/lib/etsy/shop.rb +83 -0
  24. data/lib/etsy/transaction.rb +18 -0
  25. data/lib/etsy/user.rb +91 -0
  26. data/lib/etsy/verification_request.rb +17 -0
  27. data/lib/etsy/version.rb +3 -0
  28. data/test/fixtures/address/getUserAddresses.json +12 -0
  29. data/test/fixtures/category/findAllSubCategoryChildren.json +78 -0
  30. data/test/fixtures/category/findAllTopCategory.json +347 -0
  31. data/test/fixtures/category/findAllTopCategory.single.json +18 -0
  32. data/test/fixtures/category/findAllTopCategoryChildren.json +308 -0
  33. data/test/fixtures/category/getCategory.multiple.json +28 -0
  34. data/test/fixtures/category/getCategory.single.json +18 -0
  35. data/test/fixtures/country/getCountry.json +1 -0
  36. data/test/fixtures/image/findAllListingImages.json +102 -0
  37. data/test/fixtures/listing/findAllListingActive.category.json +827 -0
  38. data/test/fixtures/listing/findAllShopListings.json +69 -0
  39. data/test/fixtures/listing/getListing.multiple.json +1 -0
  40. data/test/fixtures/listing/getListing.single.json +1 -0
  41. data/test/fixtures/payment_template/getPaymentTemplate.json +1 -0
  42. data/test/fixtures/profile/new.json +28 -0
  43. data/test/fixtures/section/getShopSection.json +18 -0
  44. data/test/fixtures/shipping_template/getShippingTemplate.json +1 -0
  45. data/test/fixtures/shop/findAllShop.json +1 -0
  46. data/test/fixtures/shop/findAllShop.single.json +1 -0
  47. data/test/fixtures/shop/getShop.multiple.json +1 -0
  48. data/test/fixtures/shop/getShop.single.json +33 -0
  49. data/test/fixtures/transaction/findAllShopTransactions.json +1 -0
  50. data/test/fixtures/user/getUser.multiple.json +29 -0
  51. data/test/fixtures/user/getUser.single.json +13 -0
  52. data/test/fixtures/user/getUser.single.private.json +18 -0
  53. data/test/fixtures/user/getUser.single.withProfile.json +38 -0
  54. data/test/fixtures/user/getUser.single.withShops.json +41 -0
  55. data/test/test_helper.rb +44 -0
  56. data/test/unit/etsy/address_test.rb +61 -0
  57. data/test/unit/etsy/basic_client_test.rb +28 -0
  58. data/test/unit/etsy/category_test.rb +106 -0
  59. data/test/unit/etsy/country_test.rb +64 -0
  60. data/test/unit/etsy/image_test.rb +43 -0
  61. data/test/unit/etsy/listing_test.rb +217 -0
  62. data/test/unit/etsy/model_test.rb +64 -0
  63. data/test/unit/etsy/payment_template_test.rb +68 -0
  64. data/test/unit/etsy/profile_test.rb +111 -0
  65. data/test/unit/etsy/request_test.rb +192 -0
  66. data/test/unit/etsy/response_test.rb +164 -0
  67. data/test/unit/etsy/section_test.rb +28 -0
  68. data/test/unit/etsy/secure_client_test.rb +132 -0
  69. data/test/unit/etsy/shipping_template_test.rb +24 -0
  70. data/test/unit/etsy/shop_test.rb +104 -0
  71. data/test/unit/etsy/transaction_test.rb +52 -0
  72. data/test/unit/etsy/user_test.rb +218 -0
  73. data/test/unit/etsy/verification_request_test.rb +26 -0
  74. data/test/unit/etsy_test.rb +114 -0
  75. metadata +269 -0
@@ -0,0 +1,106 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class CategoryTest < Test::Unit::TestCase
5
+
6
+ context "The Category class" do
7
+
8
+ should "be able to find a single top-level category" do
9
+ categories = mock_request('/categories/accessories', {}, 'Category', 'getCategory.single.json')
10
+ Category.find_top('accessories').should == categories.first
11
+ end
12
+
13
+ should "be able to find multiple categories" do
14
+ categories = mock_request('/categories/accessories,art', {}, 'Category', 'getCategory.multiple.json')
15
+ Category.find_top('accessories', 'art').should == categories
16
+ end
17
+
18
+ should "be able to find all top-level categories" do
19
+ categories = mock_request('/taxonomy/categories', {}, 'Category', 'findAllTopCategory.json')
20
+ Category.all_top.should == categories
21
+ end
22
+
23
+ should "return an array of categories if there is only 1 result returned" do
24
+ categories = mock_request('/taxonomy/categories', {}, 'Category', 'findAllTopCategory.single.json')
25
+ Category.all_top.should == categories
26
+ end
27
+
28
+ context "within the scope of a top-level category" do
29
+
30
+ should "be able to find all subcategories" do
31
+ categories = mock_request('/taxonomy/categories/accessories', {}, 'Category', 'findAllTopCategoryChildren.json')
32
+ Category.find_all_subcategories('accessories').should == categories
33
+ end
34
+
35
+ should "be able to find the subcategories of a subcategory" do
36
+ categories = mock_request('/taxonomy/categories/accessories/apron', {}, 'Category', 'findAllSubCategoryChildren.json')
37
+ Category.find_all_subcategories('accessories/apron').should == categories
38
+ end
39
+
40
+ should "return nil when trying to find the subcategories of a subcategory of a subcategory" do
41
+ Category.find_all_subcategories('accessories/apron/women').should be_nil
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ context "An instance of the Category class" do
49
+
50
+ context "with response data" do
51
+ setup do
52
+ data = read_fixture('category/getCategory.single.json')
53
+ @category = Category.new(data.first)
54
+ end
55
+
56
+ should "have a value for :id" do
57
+ @category.id.should == 69150467
58
+ end
59
+
60
+ should "have a value for :page_description" do
61
+ @category.page_description.should == "Shop for unique, handmade accessories from our artisan community"
62
+ end
63
+
64
+ should "have a value for :page_title" do
65
+ @category.page_title.should == "Handmade accessories"
66
+ end
67
+
68
+ should "have a value for :category_name" do
69
+ @category.category_name.should == "accessories"
70
+ end
71
+
72
+ should "have a value for :short_name" do
73
+ @category.short_name.should == "Accessories"
74
+ end
75
+
76
+ should "have a value for :long_name" do
77
+ @category.long_name.should == "Accessories"
78
+ end
79
+
80
+ should "have a value for :children_count" do
81
+ @category.children_count.should == 27
82
+ end
83
+ end
84
+
85
+ should "have a collection of active listings" do
86
+ category = Category.new
87
+ category.stubs(:category_name).with().returns('accessories')
88
+
89
+ Listing.stubs(:find_all_active_by_category).with('accessories').returns('listings')
90
+
91
+ category.active_listings.should == 'listings'
92
+ end
93
+
94
+ should "have a collection of subcategories" do
95
+ category = Category.new
96
+ category.stubs(:category_name).with().returns('accessories')
97
+
98
+ Category.stubs(:find_all_subcategories).with('accessories').returns('categories')
99
+
100
+ category.subcategories.should == 'categories'
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class CountryTest < Test::Unit::TestCase
5
+ context "The Country class" do
6
+ should "be findable by ISO3166-1 Alpha-2 codes" do
7
+ united_states = mock
8
+ united_states.stubs(:iso_country_code => "US")
9
+
10
+ great_britain = mock
11
+ great_britain.stubs(:iso_country_code => "GB")
12
+
13
+ Country.stubs(:find_all).returns([great_britain, united_states])
14
+ Country.find_by_alpha2("us").should == united_states
15
+ end
16
+
17
+ should "be findable by world bank country codes" do
18
+ united_states = mock
19
+ united_states.stubs(:world_bank_country_code => "USA")
20
+
21
+ great_britain = mock
22
+ great_britain.stubs(:world_bank_country_code => "GBR")
23
+
24
+ Country.stubs(:find_all).returns([great_britain, united_states])
25
+ Country.find_by_world_bank_country_code("gbr").should == great_britain
26
+ end
27
+ end
28
+
29
+ context "An instance of the Country class" do
30
+ setup do
31
+ data = read_fixture('country/getCountry.json')
32
+ @listing = Country.new(data.first)
33
+ end
34
+
35
+ should "have an id" do
36
+ @listing.id.should == 55
37
+ end
38
+
39
+ should "have an iso_country_code" do
40
+ @listing.iso_country_code.should == "AF"
41
+ end
42
+
43
+ should "have an world_bank_country_code" do
44
+ @listing.world_bank_country_code.should == "AFG"
45
+ end
46
+
47
+ should "have an name" do
48
+ @listing.name.should == "Afghanistan"
49
+ end
50
+
51
+ should "have an slug" do
52
+ @listing.slug.should == "afghanistan"
53
+ end
54
+
55
+ should "have an lat" do
56
+ @listing.lat.should == 33.78
57
+ end
58
+
59
+ should "have an lon" do
60
+ @listing.lon.should == 66.17
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class ImageTest < Test::Unit::TestCase
5
+
6
+ context "The Image class" do
7
+
8
+ should "be able to find all images for a listing" do
9
+ images = mock_request('/listings/1/images', {}, 'Image', 'findAllListingImages.json')
10
+ Image.find_all_by_listing_id(1).should == images
11
+ end
12
+
13
+ end
14
+
15
+ context "An instance of the Image class" do
16
+
17
+ context "with response data" do
18
+ setup do
19
+ data = read_fixture('image/findAllListingImages.json')
20
+ @image = Image.new(data.first)
21
+ end
22
+
23
+ should "have a value for :square" do
24
+ @image.square.should == "http://ny-image0.etsy.com/il_75x75.185073072.jpg"
25
+ end
26
+
27
+ should "have a value for :small" do
28
+ @image.small.should == "http://ny-image0.etsy.com/il_170x135.185073072.jpg"
29
+ end
30
+
31
+ should "have a value for :thumbnail" do
32
+ @image.thumbnail.should == "http://ny-image0.etsy.com/il_570xN.185073072.jpg"
33
+ end
34
+
35
+ should "have a value for :full" do
36
+ @image.full.should == "http://ny-image0.etsy.com/il_fullxfull.185073072.jpg"
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,217 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class ListingTest < Test::Unit::TestCase
5
+
6
+ context "The Listing class" do
7
+
8
+ should "be able to find a single listing" do
9
+ listings = mock_request('/listings/123', {}, 'Listing', 'getListing.single.json')
10
+ Listing.find(123).should == listings.first
11
+ end
12
+
13
+ should "be able to find multiple listings" do
14
+ listings = mock_request('/listings/123,456', {}, 'Listing', 'getListing.multiple.json')
15
+ Listing.find('123', '456').should == listings
16
+ end
17
+
18
+ context "within the scope of a shop" do
19
+
20
+ should "be able to find the first 25 active listings" do
21
+ listings = mock_request('/shops/1/listings/active', {}, 'Listing', 'findAllShopListings.json')
22
+ Listing.find_all_by_shop_id(1).should == listings
23
+ end
24
+
25
+ should "be able to find expired listings" do
26
+ listings = mock_request('/shops/1/listings/expired', {}, 'Listing', 'findAllShopListings.json')
27
+ Listing.find_all_by_shop_id(1, :state => :expired).should == listings
28
+ end
29
+
30
+ should "be able to find inactive listings" do
31
+ listings = mock_request('/shops/1/listings/inactive', {}, 'Listing', 'findAllShopListings.json')
32
+ Listing.find_all_by_shop_id(1, :state => :inactive).should == listings
33
+ end
34
+
35
+ should "be able to find featured listings" do
36
+ listings = mock_request('/shops/1/listings/featured', {}, 'Listing', 'findAllShopListings.json')
37
+ Listing.find_all_by_shop_id(1, :state => :featured).should == listings
38
+ end
39
+
40
+ should "be able to find sold listings" do
41
+ transaction_1 = stub(:listing_id => 1)
42
+ transaction_2 = stub(:listing_id => 2)
43
+ transaction_3 = stub(:listing_id => 1)
44
+
45
+ transactions = [transaction_1, transaction_2, transaction_3]
46
+
47
+ Transaction.stubs(:find_all_by_shop_id).with(1, {}).returns(transactions)
48
+ Listing.stubs(:find).with([1, 2], {}).returns(['listings'])
49
+
50
+ Listing.find_all_by_shop_id(1, :state => :sold).should == ['listings']
51
+ end
52
+
53
+ should "defer associations to listings from transaction (sold listings)" do
54
+ transaction_1 = stub(:listing_id => 1)
55
+ transaction_2 = stub(:listing_id => 2)
56
+
57
+ Transaction.stubs(:find_all_by_shop_id).with(1, {}).returns [transaction_1, transaction_2]
58
+ Listing.stubs(:find).with([1, 2], {:includes => :an_association}).returns(['listings'])
59
+
60
+ Listing.find_all_by_shop_id(1, :state => :sold, :includes => :an_association).should == ['listings']
61
+ end
62
+
63
+ should "pass options through to the listing call" do
64
+ transaction_1 = stub(:listing_id => 1)
65
+ transaction_2 = stub(:listing_id => 2)
66
+
67
+ Transaction.stubs(:find_all_by_shop_id).with(1, {:other => :params}).returns [transaction_1, transaction_2]
68
+ Listing.stubs(:find).with([1, 2], {:other => :params}).returns(['listings'])
69
+
70
+ Listing.find_all_by_shop_id(1, :state => :sold, :other => :params).should == ['listings']
71
+
72
+ end
73
+
74
+ should "not ask the API for listings if there are no transactions" do
75
+ Transaction.stubs(:find_all_by_shop_id).with(1, {}).returns([])
76
+ Listing.expects(:find).never
77
+ Listing.sold_listings(1, {})
78
+ end
79
+
80
+ should "be able to override limit and offset" do
81
+ options = {:limit => 100, :offset => 100}
82
+ listings = mock_request('/shops/1/listings/active', options, 'Listing', 'findAllShopListings.json')
83
+ Listing.find_all_by_shop_id(1, options).should == listings
84
+ end
85
+
86
+ should "raise an exception when calling with an invalid state" do
87
+ options = {:state => :awesome}
88
+ lambda { Listing.find_all_by_shop_id(1, options) }.should raise_error(ArgumentError)
89
+ end
90
+
91
+ end
92
+
93
+ context "within the scope of a category" do
94
+ should "be able to find active listings" do
95
+ active_listings = mock_request('/listings/active', {:category => 'accessories'}, 'Listing', 'findAllListingActive.category.json')
96
+ Listing.find_all_active_by_category('accessories').should == active_listings
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ context "An instance of the Listing class" do
103
+
104
+ context "with response data" do
105
+ setup do
106
+ data = read_fixture('listing/findAllShopListings.json')
107
+ @listing = Listing.new(data.first)
108
+ end
109
+
110
+ should "have a value for :id" do
111
+ @listing.id.should == 59495892
112
+ end
113
+
114
+ should "have a value for :state" do
115
+ @listing.state.should == 'active'
116
+ end
117
+
118
+ should "have a value for :title" do
119
+ @listing.title.should == "initials carved into tree love stamp"
120
+ end
121
+
122
+ should "have a value for :description" do
123
+ @listing.description.should == "there! our initials are now carved deeply into this rough tree bark of memory"
124
+ end
125
+
126
+ should "have a value for :url" do
127
+ @listing.url.should == "http://www.etsy.com/listing/59495892/initials-carved-into-tree-love-stamp"
128
+ end
129
+
130
+ should "have a value for :view_count" do
131
+ @listing.view_count.should == 37
132
+ end
133
+
134
+ should "have a value for :created_at" do
135
+ @listing.created_at.should == Time.at(1287602289)
136
+ end
137
+
138
+ should "have a value for :modified_at" do
139
+ @listing.modified_at.should == Time.at(1287602289)
140
+ end
141
+
142
+ should "have a value for :price" do
143
+ @listing.price.should == "15.00"
144
+ end
145
+
146
+ should "have a value for :quantity" do
147
+ @listing.quantity.should == 1
148
+ end
149
+
150
+ should "have a value for :currency" do
151
+ @listing.currency.should == "USD"
152
+ end
153
+
154
+ should "have a value for :ending_at" do
155
+ @listing.ending_at.should == Time.at(1298178000)
156
+ end
157
+
158
+ should "have a value for :tags" do
159
+ @listing.tags.should == %w(tag_1 tag_2)
160
+ end
161
+
162
+ should "have a value for :materials" do
163
+ @listing.materials.should == %w(material_1 material_2)
164
+ end
165
+
166
+ should "have a value for :hue" do
167
+ @listing.hue.should == 0
168
+ end
169
+
170
+ should "have a value for :saturation" do
171
+ @listing.saturation.should == 0
172
+ end
173
+
174
+ should "have a value for :brightness" do
175
+ @listing.brightness.should == 100
176
+ end
177
+
178
+ should "have a value for :black_and_white?" do
179
+ @listing.black_and_white?.should == false
180
+ end
181
+ end
182
+
183
+ %w(active removed sold_out expired alchemy).each do |state|
184
+ should "know that the listing is #{state}" do
185
+ listing = Listing.new
186
+ listing.expects(:state).with().returns(state.sub('_', ''))
187
+
188
+ listing.send("#{state}?".to_sym).should be(true)
189
+ end
190
+
191
+ should "know that the listing is not #{state}" do
192
+ listing = Listing.new
193
+ listing.expects(:state).with().returns(state.reverse)
194
+
195
+ listing.send("#{state}?".to_sym).should be(false)
196
+ end
197
+ end
198
+
199
+ should "have a collection of images" do
200
+ listing = Listing.new
201
+ listing.stubs(:id).with().returns(1)
202
+
203
+ Image.stubs(:find_all_by_listing_id).with(1).returns('images')
204
+
205
+ listing.images.should == 'images'
206
+ end
207
+
208
+ should "have a default image" do
209
+ listing = Listing.new
210
+ listing.stubs(:images).with().returns(%w(image_1 image_2))
211
+
212
+ listing.image.should == 'image_1'
213
+ end
214
+
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class TestModel
5
+ include Etsy::Model
6
+ end
7
+
8
+ class ModelTest < Test::Unit::TestCase
9
+
10
+ def mock_empty_request(options = {})
11
+ body = options.delete(:body) { '{}' }
12
+ Request.expects(:new).with('', options).returns(stub(:get => stub(:body => body, :code => 200)))
13
+ end
14
+
15
+ context 'An instance of a Model' do
16
+
17
+ should 'perform no requests if :limit is 0' do
18
+ Request.expects(:new).never
19
+ TestModel.get_all('', :limit => 0)
20
+ end
21
+
22
+ should 'perform only one request if :limit is less than 100' do
23
+ mock_empty_request(:limit => 10, :offset => 0).once
24
+ TestModel.get_all('', :limit => 10)
25
+ end
26
+
27
+ should 'perform only one request if :limit is equal to 100' do
28
+ mock_empty_request(:limit => 100, :offset => 0).once
29
+ TestModel.get_all('', :limit => 100)
30
+ end
31
+
32
+ should 'perform multiple requests if :limit is greater than 100' do
33
+ mock_empty_request(:limit => 100, :offset => 0).once
34
+ mock_empty_request(:limit => 50, :offset => 100).once
35
+
36
+ TestModel.get_all('', :limit => 150)
37
+ end
38
+
39
+ should 'perform only one request if :limit is :all and count is less than 100' do
40
+ mock_empty_request(:limit => 100, :offset => 0, :body => '{"count": 10}').once
41
+ TestModel.get_all('', :limit => :all)
42
+ end
43
+
44
+ should 'perform only one request if :limit is :all and count is equal to 100' do
45
+ mock_empty_request(:limit => 100, :offset => 0, :body => '{"count": 100}').once
46
+ TestModel.get_all('', :limit => :all)
47
+ end
48
+
49
+ should 'perform only one request if :limit is :all and :offset is greater than count' do
50
+ mock_empty_request(:limit => 100, :offset => 40, :body => '{"count": 25}').once
51
+ TestModel.get_all('', :limit => :all, :offset => 40)
52
+ end
53
+
54
+ should 'perform multiple requests if :limit is :all and count is greater than 100' do
55
+ body = '{"count": 210}'
56
+ mock_empty_request(:limit => 100, :offset => 0, :body => body).once
57
+ mock_empty_request(:limit => 100, :offset => 100, :body => body).once
58
+ mock_empty_request(:limit => 10, :offset => 200, :body => body).once
59
+
60
+ TestModel.get_all('', :limit => :all)
61
+ end
62
+ end
63
+ end
64
+ end