etsy 0.1.0 → 0.2.0

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 (38) hide show
  1. data/README.rdoc +102 -19
  2. data/Rakefile +5 -5
  3. data/lib/etsy.rb +104 -26
  4. data/lib/etsy/basic_client.rb +26 -0
  5. data/lib/etsy/image.rb +19 -16
  6. data/lib/etsy/listing.rb +30 -27
  7. data/lib/etsy/model.rb +12 -49
  8. data/lib/etsy/request.rb +41 -18
  9. data/lib/etsy/response.rb +17 -11
  10. data/lib/etsy/secure_client.rb +79 -0
  11. data/lib/etsy/shop.rb +42 -18
  12. data/lib/etsy/user.rb +39 -34
  13. data/lib/etsy/verification_request.rb +17 -0
  14. data/lib/etsy/version.rb +4 -4
  15. data/test/fixtures/image/findAllListingImages.json +102 -0
  16. data/test/fixtures/listing/findAllShopListingsActive.json +69 -0
  17. data/test/fixtures/shop/findAllShop.json +1 -0
  18. data/test/fixtures/shop/findAllShop.single.json +1 -0
  19. data/test/fixtures/shop/getShop.multiple.json +1 -0
  20. data/test/fixtures/shop/getShop.single.json +32 -0
  21. data/test/fixtures/user/getUser.multiple.json +29 -0
  22. data/test/fixtures/user/getUser.single.json +13 -0
  23. data/test/fixtures/user/getUser.single.private.json +18 -0
  24. data/test/test_helper.rb +27 -42
  25. data/test/unit/etsy/basic_client_test.rb +28 -0
  26. data/test/unit/etsy/image_test.rb +36 -15
  27. data/test/unit/etsy/listing_test.rb +84 -66
  28. data/test/unit/etsy/request_test.rb +121 -39
  29. data/test/unit/etsy/response_test.rb +20 -20
  30. data/test/unit/etsy/secure_client_test.rb +110 -0
  31. data/test/unit/etsy/shop_test.rb +74 -40
  32. data/test/unit/etsy/user_test.rb +65 -61
  33. data/test/unit/etsy/verification_request_test.rb +26 -0
  34. data/test/unit/etsy_test.rb +91 -10
  35. metadata +61 -17
  36. data/test/fixtures/getShopDetails.json +0 -70
  37. data/test/fixtures/getShopListings.json +0 -135
  38. data/test/fixtures/getUserDetails.json +0 -34
@@ -1,92 +1,110 @@
1
- require File.dirname(__FILE__) + '/../../test_helper'
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
2
 
3
3
  module Etsy
4
4
  class ListingTest < Test::Unit::TestCase
5
5
 
6
- describe "The Listing class" do
7
-
8
- it "should be able to find all listings by :user_id" do
9
- user_id = 122345
10
-
11
- response = mock_request_cycle :for => "/shops/#{user_id}/listings", :data => 'getShopListings'
12
-
13
- listing_1, listing_2 = response.result
14
-
15
- Listing.expects(:new).with(listing_1).returns('listing_1')
16
- Listing.expects(:new).with(listing_2).returns('listing_2')
17
-
18
- Listing.find_all_by_user_id(user_id).should == ['listing_1', 'listing_2']
6
+ context "The Listing class" do
7
+
8
+ should "be able to find all listings for a shop" do
9
+ listings = mock_request('/shops/1/listings/active', {}, 'Listing', 'findAllShopListingsActive.json')
10
+ Listing.find_all_by_shop_id(1).should == listings
19
11
  end
20
-
12
+
21
13
  end
22
-
23
- describe "An instance of the Listing class" do
24
-
25
- when_populating Listing, :from => 'getShopListings' do
26
-
27
- value_for :id, :is => 24165902
28
- value_for :state, :is => 'active'
29
- value_for :title, :is => 'hanging with the bad boys matchbox'
30
- value_for :description, :is => 'standard size matchbox ...'
31
- value_for :url, :is => 'http://www.etsy.com/view_listing.php?listing_id=24165902'
32
- value_for :view_count, :is => 18
33
- value_for :created, :is => 1240673494.49
34
- value_for :price, :is => 3
35
- value_for :quantity, :is => 1
36
- value_for :currency, :is => 'USD'
37
- value_for :ending, :is => 1251214294.49
38
- value_for :tags, :is => %w(accessories matchbox)
39
- value_for :materials, :is => %w(standard_matchbox notebook_paper)
40
-
14
+
15
+ context "An instance of the Listing class" do
16
+
17
+ context "with response data" do
18
+ setup do
19
+ data = read_fixture('listing/findAllShopListingsActive.json')
20
+ @listing = Listing.new(data.first)
21
+ end
22
+
23
+ should "have a value for :id" do
24
+ @listing.id.should == 59495892
25
+ end
26
+
27
+ should "have a value for :state" do
28
+ @listing.state.should == 'active'
29
+ end
30
+
31
+ should "have a value for :title" do
32
+ @listing.title.should == "initials carved into tree love stamp"
33
+ end
34
+
35
+ should "have a value for :description" do
36
+ @listing.description.should == "there! our initials are now carved deeply into this rough tree bark of memory"
37
+ end
38
+
39
+ should "have a value for :url" do
40
+ @listing.url.should == "http://www.etsy.com/listing/59495892/initials-carved-into-tree-love-stamp"
41
+ end
42
+
43
+ should "have a value for :view_count" do
44
+ @listing.view_count.should == 37
45
+ end
46
+
47
+ should "have a value for :created_at" do
48
+ @listing.created_at.should == Time.at(1287602289)
49
+ end
50
+
51
+ should "have a value for :price" do
52
+ @listing.price.should == "15.00"
53
+ end
54
+
55
+ should "have a value for :quantity" do
56
+ @listing.quantity.should == 1
57
+ end
58
+
59
+ should "have a value for :currency" do
60
+ @listing.currency.should == "USD"
61
+ end
62
+
63
+ should "have a value for :ending_at" do
64
+ @listing.ending_at.should == Time.at(1298178000)
65
+ end
66
+
67
+ should "have a value for :tags" do
68
+ @listing.tags.should == %w(tag_1 tag_2)
69
+ end
70
+
71
+ should "have a value for :materials" do
72
+ @listing.materials.should == %w(material_1 material_2)
73
+ end
41
74
  end
42
-
75
+
43
76
  %w(active removed sold_out expired alchemy).each do |state|
44
- it "should know that the listing is #{state}" do
77
+ should "know that the listing is #{state}" do
45
78
  listing = Listing.new
46
79
  listing.expects(:state).with().returns(state.sub('_', ''))
47
80
 
48
81
  listing.send("#{state}?".to_sym).should be(true)
49
82
  end
50
83
 
51
- it "should know that the listing is not #{state}" do
84
+ should "know that the listing is not #{state}" do
52
85
  listing = Listing.new
53
86
  listing.expects(:state).with().returns(state.reverse)
54
87
 
55
88
  listing.send("#{state}?".to_sym).should be(false)
56
- end
57
- end
58
-
59
- it "should know the create date" do
60
- listing = Listing.new
61
- listing.expects(:created).with().returns(1240673494.49)
62
-
63
- listing.created_at.should == Time.at(1240673494.49)
89
+ end
64
90
  end
65
-
66
- it "should know the ending date" do
91
+
92
+ should "have a collection of images" do
67
93
  listing = Listing.new
68
- listing.expects(:ending).with().returns(1240673494.49)
69
-
70
- listing.ending_at.should == Time.at(1240673494.49)
71
- end
72
-
73
- it "should have associated images" do
74
- data = read_fixture('getShopListings')[0]
75
- listing = Listing.new(data)
76
-
77
- Image.expects(:new).with(data['all_images'][0]).returns('image_1')
78
- Image.expects(:new).with(data['all_images'][1]).returns('image_2')
79
-
80
- listing.images.should == ['image_1', 'image_2']
94
+ listing.stubs(:id).with().returns(1)
95
+
96
+ Image.stubs(:find_all_by_listing_id).with(1).returns('images')
97
+
98
+ listing.images.should == 'images'
81
99
  end
82
-
83
- it "should have a primary image" do
100
+
101
+ should "have a default image" do
84
102
  listing = Listing.new
85
- listing.expects(:images).with().returns(%w(one two))
86
-
87
- listing.image.should == 'one'
103
+ listing.stubs(:images).with().returns(%w(image_1 image_2))
104
+
105
+ listing.image.should == 'image_1'
88
106
  end
89
-
107
+
90
108
  end
91
109
  end
92
110
  end
@@ -1,74 +1,156 @@
1
- require File.dirname(__FILE__) + '/../../test_helper'
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
2
 
3
3
  module Etsy
4
4
  class RequestTest < Test::Unit::TestCase
5
-
6
- describe "The Request class" do
7
5
 
8
- it "should know the base URL" do
9
- Request.base_url.should == 'http://beta-api.etsy.com/v1'
6
+ context "The Request class" do
7
+
8
+ should "know the host" do
9
+ Request.host.should == 'openapi.etsy.com'
10
10
  end
11
11
 
12
- it "should be able to retrieve a response" do
12
+ should "be able to retrieve a response" do
13
13
  http_response = stub()
14
14
  response = stub()
15
-
15
+
16
16
  Response.expects(:new).with(http_response).returns(response)
17
-
17
+
18
18
  request = mock {|m| m.expects(:get).with().returns(http_response) }
19
19
  Request.expects(:new).with('/user', :one => 'two').returns(request)
20
-
20
+
21
21
  Request.get('/user', :one => 'two').should == response
22
22
  end
23
23
  end
24
-
25
- describe "An instance of the Request class" do
26
24
 
27
- it "should append the api_key and detail_level to the parameters" do
25
+ context "An instance of the Request class" do
26
+
27
+ should "know the base path for the sandbox read-only environment" do
28
+ Etsy.stubs(:environment).returns(:sandbox)
29
+ Etsy.stubs(:access_mode).returns(:read_only)
30
+
31
+ Request.new('').base_path.should == '/v2/sandbox/public'
32
+ end
33
+
34
+ should "know the base path for the sandbox read/write environment when the access information is present" do
35
+ Etsy.stubs(:environment).returns(:sandbox)
36
+ Etsy.stubs(:access_mode).returns(:read_write)
37
+
38
+ r = Request.new('', :access_token => 'toke', :access_secret => 'secret')
39
+ r.base_path.should == '/v2/sandbox/private'
40
+ end
41
+
42
+ should "know the base path for the sandbox read/write environment when the access information is not present" do
43
+ Etsy.stubs(:environment).returns(:sandbox)
44
+ Etsy.stubs(:access_mode).returns(:read_write)
45
+
46
+ Request.new('').base_path.should == '/v2/sandbox/public'
47
+ end
48
+
49
+ should "know the base path for the production read-only environment" do
50
+ Etsy.stubs(:environment).returns(:production)
51
+ Etsy.stubs(:access_mode).returns(:read_only)
52
+
53
+ Request.new('').base_path.should == '/v2/public'
54
+ end
55
+
56
+ should "know the base path for the production read-write environment when access information is present" do
57
+ Etsy.stubs(:environment).returns(:production)
58
+ Etsy.stubs(:access_mode).returns(:read_write)
59
+
60
+ r = Request.new('', :access_token => 'toke', :access_secret => 'secret')
61
+ r.base_path.should == '/v2/private'
62
+ end
63
+
64
+ should "know the base path for the production read-write environment when access information is not present" do
65
+ Etsy.stubs(:environment).returns(:production)
66
+ Etsy.stubs(:access_mode).returns(:read_write)
67
+
68
+ Request.new('').base_path.should == '/v2/public'
69
+ end
70
+
71
+ should "append the api_key and detail_level to the parameters" do
28
72
  Etsy.expects(:api_key).with().returns('key')
29
-
73
+
30
74
  r = Request.new('/user', :limit => '1')
31
75
  r.parameters.should == {:limit => '1', :api_key => 'key', :detail_level => 'high'}
32
76
  end
33
77
 
34
- it "should be able to generate query parameters" do
78
+ should "be able to generate query parameters" do
35
79
  r = Request.new('/user')
36
80
  r.expects(:parameters).with().returns(:api_key => 'foo')
37
81
  r.query.should == 'api_key=foo'
38
82
  end
39
-
40
- it "should be able to join multiple query parameters" do
83
+
84
+ should "be able to join multiple query parameters" do
41
85
  params = {:limit => '1', :other => 'yes'}
42
-
86
+
43
87
  r = Request.new('/user', params)
44
88
  r.stubs(:parameters).with().returns(params)
45
-
89
+
46
90
  r.query.split('&').sort.should == %w(limit=1 other=yes)
47
91
  end
48
-
49
- it "should be able to determine the endpoint URI" do
50
- Request.stubs(:base_url).with().returns('http://example.com')
51
-
92
+
93
+ should "be able to determine the endpoint URI when in read-only mode" do
52
94
  r = Request.new('/user')
95
+ r.stubs(:base_path).with().returns('/base')
53
96
  r.stubs(:query).with().returns('a=b')
54
-
55
- r.endpoint_uri.to_s.should == 'http://example.com/user?a=b'
56
- end
57
-
58
- it "should be able to make a successful request" do
59
- uri = URI.parse('http://example.com')
60
- response = stub()
61
-
97
+
98
+ r.endpoint_url.should == '/base/user?a=b'
99
+ end
100
+
101
+ should "be able to determine the endpoint URI when in read-write mode" do
102
+ Etsy.stubs(:access_mode).returns(:read_write)
103
+
104
+ r = Request.new('/user', :access_token => 'toke', :access_secret => 'secret')
105
+ r.stubs(:base_path).with().returns('/base')
106
+ r.stubs(:query).with().returns('a=b')
107
+
108
+ r.endpoint_url.should == '/base/user?a=b'
109
+ end
110
+
111
+ should "know the client for read-only mode" do
112
+ Etsy.stubs(:access_mode).returns(:read_only)
113
+ Request.stubs(:host).returns('example.com')
114
+
115
+ BasicClient.stubs(:new).with('example.com').returns('client')
116
+
117
+ r = Request.new('')
118
+
119
+ r.client.should == 'client'
120
+ end
121
+
122
+ should "know the client for read-write mode when there is no access token information" do
123
+ Etsy.stubs(:access_mode).returns(:read_write)
124
+ Request.stubs(:host).returns('example.com')
125
+
126
+ BasicClient.stubs(:new).with('example.com').returns('client')
127
+
128
+ r = Request.new('')
129
+
130
+ r.client.should == 'client'
131
+ end
132
+
133
+ should "know the client for read-write mode when there is access token information" do
134
+ Etsy.stubs(:access_mode).returns(:read_write)
135
+ SecureClient.stubs(:new).with(:access_token => 'toke', :access_secret => 'secret').returns('client')
136
+
137
+ r = Request.new('', :access_token => 'toke', :access_secret => 'secret')
138
+ r.client.should == 'client'
139
+ end
140
+
141
+ should "be able to make a successful request" do
142
+ client = stub()
143
+ client.stubs(:get).with('endpoint_url').returns('response')
144
+
62
145
  r = Request.new('/user')
63
- r.expects(:endpoint_uri).with().returns(uri)
64
-
65
- Net::HTTP.expects(:get).with(uri).returns(response)
66
-
67
- r.get.should == response
146
+ r.stubs(:endpoint_url).with().returns('endpoint_url')
147
+ r.stubs(:client).returns(client)
148
+
149
+ r.get.should == 'response'
68
150
  end
69
-
151
+
70
152
  end
71
-
72
-
153
+
154
+
73
155
  end
74
- end
156
+ end
@@ -1,47 +1,47 @@
1
- require File.dirname(__FILE__) + '/../../test_helper'
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
2
 
3
3
  module Etsy
4
4
  class ResponseTest < Test::Unit::TestCase
5
5
 
6
- describe "An instance of the Response class" do
7
-
8
- it "should be able to decode the JSON data to a hash" do
6
+ context "An instance of the Response class" do
7
+
8
+ should "be able to decode the JSON data to a hash" do
9
9
  data = '{ "foo":"bar" }'
10
-
11
- r = Response.new(data)
10
+
11
+ r = Response.new(stub(:body => data))
12
12
  r.to_hash.should == {'foo' => 'bar'}
13
13
  end
14
-
15
- it "should only decode the JSON data once" do
14
+
15
+ should "only decode the JSON data once" do
16
16
  JSON.expects(:parse).once.returns({})
17
-
18
- r = Response.new('{ "foo":"bar" }')
17
+
18
+ r = Response.new(stub(:body => '{ "foo":"bar" }'))
19
19
  2.times { r.to_hash }
20
20
  end
21
-
22
- it "should have a record count" do
21
+
22
+ should "have a record count" do
23
23
  r = Response.new('')
24
24
  r.expects(:to_hash).with().returns('count' => 1)
25
-
25
+
26
26
  r.count.should == 1
27
27
  end
28
-
29
- it "should return an array if there are multiple results entries" do
28
+
29
+ should "return an array if there are multiple results entries" do
30
30
  r = Response.new('')
31
31
  r.expects(:count).with().returns(2)
32
32
  r.expects(:to_hash).with().returns('results' => %w(one two))
33
-
33
+
34
34
  r.result.should == %w(one two)
35
35
  end
36
-
37
- it "should return a single value for results if there is only 1 result" do
36
+
37
+ should "return a single value for results if there is only 1 result" do
38
38
  r = Response.new('')
39
39
  r.expects(:count).with().returns(1)
40
40
  r.expects(:to_hash).with().returns('results' => ['foo'])
41
-
41
+
42
42
  r.result.should == 'foo'
43
43
  end
44
-
44
+
45
45
  end
46
46
 
47
47
 
@@ -0,0 +1,110 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ module Etsy
4
+ class SecureClientTest < Test::Unit::TestCase
5
+
6
+ context "An instance of the SecureClient class" do
7
+
8
+ should "be able to generate an OAuth consumer" do
9
+ Etsy.stubs(:api_key).returns('key')
10
+ Etsy.stubs(:api_secret).returns('secret')
11
+
12
+ OAuth::Consumer.stubs(:new).with('key', 'secret', {
13
+ :site => 'http://openapi.etsy.com',
14
+ :request_token_path => '/v2/sandbox/oauth/request_token',
15
+ :access_token_path => '/v2/sandbox/oauth/access_token',
16
+ :authorize_url => 'https://www.etsy.com/oauth/signin'
17
+ }).returns('consumer')
18
+
19
+ client = SecureClient.new
20
+
21
+ client.consumer.should == 'consumer'
22
+ end
23
+
24
+ should "be able to generate a request token" do
25
+ Etsy.stubs(:callback_url).with().returns('callback_url')
26
+ consumer = stub() {|c| c.stubs(:get_request_token).with(:oauth_callback => 'callback_url').returns('toke') }
27
+
28
+ client = SecureClient.new
29
+ client.stubs(:consumer).returns(consumer)
30
+
31
+ client.request_token.should == 'toke'
32
+ end
33
+
34
+ context "with request data" do
35
+ setup do
36
+ @client = SecureClient.new(:request_token => 'toke', :request_secret => 'secret', :verifier => 'verify')
37
+ @client.stubs(:consumer).returns('consumer')
38
+ end
39
+
40
+ should "be able to generate an oauth client" do
41
+ request_token = stub()
42
+ request_token.stubs(:get_access_token).with(:oauth_verifier => 'verify').returns('client')
43
+
44
+ OAuth::RequestToken.stubs(:new).with('consumer', 'toke', 'secret').returns(request_token)
45
+
46
+ @client.client_from_request_data.should == 'client'
47
+ end
48
+
49
+ should "know to generate a client from request data" do
50
+ @client.stubs(:client_from_request_data).returns('client')
51
+ @client.client.should == 'client'
52
+ end
53
+ end
54
+
55
+ context "with access data" do
56
+ setup do
57
+ @client = SecureClient.new(:access_token => 'toke', :access_secret => 'secret')
58
+ @client.stubs(:consumer).returns('consumer')
59
+ end
60
+
61
+ should "know the :access_token" do
62
+ @client.access_token.should == 'toke'
63
+ end
64
+
65
+ should "know the access secret" do
66
+ @client.access_secret.should == 'secret'
67
+ end
68
+
69
+ should "be able to generate an oauth client" do
70
+ OAuth::AccessToken.stubs(:new).with('consumer', 'toke', 'secret').returns('client')
71
+ @client.client_from_access_data.should == 'client'
72
+ end
73
+
74
+ should "be able to generate a client" do
75
+ @client.stubs(:client_from_access_data).returns('client')
76
+ @client.client.should == 'client'
77
+ end
78
+ end
79
+
80
+ context "with a client" do
81
+ setup do
82
+ @client = SecureClient.new
83
+ @client.stubs(:client).returns(stub(:token => 'toke', :secret => 'secret'))
84
+ end
85
+
86
+ should "know the access token" do
87
+ @client.access_token.should == 'toke'
88
+ end
89
+
90
+ should "know the access_secret" do
91
+ @client.access_secret.should == 'secret'
92
+ end
93
+ end
94
+
95
+ should "delegate :get to :client" do
96
+ url = 'http://etsy.com/'
97
+
98
+ oauth_client = stub()
99
+ oauth_client.stubs(:get).with(url).returns('something')
100
+
101
+ client = SecureClient.new
102
+ client.stubs(:client).returns(oauth_client)
103
+
104
+ client.get(url).should == 'something'
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+ end