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.
- data/README.rdoc +102 -19
- data/Rakefile +5 -5
- data/lib/etsy.rb +104 -26
- data/lib/etsy/basic_client.rb +26 -0
- data/lib/etsy/image.rb +19 -16
- data/lib/etsy/listing.rb +30 -27
- data/lib/etsy/model.rb +12 -49
- data/lib/etsy/request.rb +41 -18
- data/lib/etsy/response.rb +17 -11
- data/lib/etsy/secure_client.rb +79 -0
- data/lib/etsy/shop.rb +42 -18
- data/lib/etsy/user.rb +39 -34
- data/lib/etsy/verification_request.rb +17 -0
- data/lib/etsy/version.rb +4 -4
- data/test/fixtures/image/findAllListingImages.json +102 -0
- data/test/fixtures/listing/findAllShopListingsActive.json +69 -0
- data/test/fixtures/shop/findAllShop.json +1 -0
- data/test/fixtures/shop/findAllShop.single.json +1 -0
- data/test/fixtures/shop/getShop.multiple.json +1 -0
- data/test/fixtures/shop/getShop.single.json +32 -0
- data/test/fixtures/user/getUser.multiple.json +29 -0
- data/test/fixtures/user/getUser.single.json +13 -0
- data/test/fixtures/user/getUser.single.private.json +18 -0
- data/test/test_helper.rb +27 -42
- data/test/unit/etsy/basic_client_test.rb +28 -0
- data/test/unit/etsy/image_test.rb +36 -15
- data/test/unit/etsy/listing_test.rb +84 -66
- data/test/unit/etsy/request_test.rb +121 -39
- data/test/unit/etsy/response_test.rb +20 -20
- data/test/unit/etsy/secure_client_test.rb +110 -0
- data/test/unit/etsy/shop_test.rb +74 -40
- data/test/unit/etsy/user_test.rb +65 -61
- data/test/unit/etsy/verification_request_test.rb +26 -0
- data/test/unit/etsy_test.rb +91 -10
- metadata +61 -17
- data/test/fixtures/getShopDetails.json +0 -70
- data/test/fixtures/getShopListings.json +0 -135
- data/test/fixtures/getUserDetails.json +0 -34
@@ -1,92 +1,110 @@
|
|
1
|
-
require File.
|
1
|
+
require File.expand_path('../../../test_helper', __FILE__)
|
2
2
|
|
3
3
|
module Etsy
|
4
4
|
class ListingTest < Test::Unit::TestCase
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
91
|
+
|
92
|
+
should "have a collection of images" do
|
67
93
|
listing = Listing.new
|
68
|
-
listing.
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
100
|
+
|
101
|
+
should "have a default image" do
|
84
102
|
listing = Listing.new
|
85
|
-
listing.
|
86
|
-
|
87
|
-
listing.image.should == '
|
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.
|
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
|
-
|
9
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
56
|
-
end
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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.
|
64
|
-
|
65
|
-
|
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.
|
1
|
+
require File.expand_path('../../../test_helper', __FILE__)
|
2
2
|
|
3
3
|
module Etsy
|
4
4
|
class ResponseTest < Test::Unit::TestCase
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|