ebay-api-ruby 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +35 -14
- data/lib/ebay/browse.rb +4 -0
- data/lib/ebay/client.rb +2 -1
- data/lib/ebay/configuration.rb +9 -1
- data/lib/ebay/finding.rb +18 -3
- data/lib/ebay/marketplace_insights.rb +9 -0
- data/lib/ebay/taxonomy.rb +4 -2
- data/lib/ebay/version.rb +1 -1
- data/lib/ebay.rb +3 -0
- metadata +2 -8
- data/spec/ebay/browse_spec.rb +0 -60
- data/spec/ebay/client_spec.rb +0 -125
- data/spec/ebay/configuration_spec.rb +0 -74
- data/spec/ebay/finding_spec.rb +0 -78
- data/spec/ebay/taxonomy_spec.rb +0 -49
- data/spec/examples.txt +0 -43
- data/spec/spec_helper.rb +0 -55
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca9bfb12653bedb4b382524b74f64351f54090af81c77aa904ddf56bd79e3622
|
|
4
|
+
data.tar.gz: 689b373e5c06a0eacc4c208abcce936c1bc4133beaf33604a19d674a17df0211
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 143f878b8ef05a3b51198a44aae4cc3a74b2457efbecca5fd36c97e19cc86cb06efa2f894f178675d32427ce69d513d827566de310bea150d95ae596a761f4e8
|
|
7
|
+
data.tar.gz: 556411ffe901a48604126121fa21c5dcf1f10797b3edc10833286c9fd3d0350308055821a2d3043a72d5c879a20ece5890b064ff356ae82a27534f275f41703a
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.0] - 2026-03-26
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Marketplace Insights API: `Ebay::MarketplaceInsights#search` for sold/completed item data
|
|
10
|
+
- Browse API: `Ebay::Browse#search_by_category` for category-only searches
|
|
11
|
+
|
|
12
|
+
### Deprecated
|
|
13
|
+
|
|
14
|
+
- Finding API: all methods deprecated — eBay has shut down the Finding Service
|
|
15
|
+
- `find_items_by_keywords` → use `Ebay::Browse#search`
|
|
16
|
+
- `find_completed_items` → use `Ebay::MarketplaceInsights#search`
|
|
17
|
+
- `find_items_by_category` → use `Ebay::Browse#search_by_category`
|
|
18
|
+
- `find_items_advanced` → use `Ebay::Browse#search`
|
|
19
|
+
- Configuration: `app_id` is deprecated (OAuth 2.0 only going forward)
|
|
20
|
+
|
|
5
21
|
## [0.1.0] - 2026-03-26
|
|
6
22
|
|
|
7
23
|
### Added
|
data/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# ebay-api-ruby
|
|
2
2
|
|
|
3
|
-
A modern Ruby gem for the eBay REST APIs. Supports the Browse API,
|
|
3
|
+
A modern Ruby gem for the eBay REST APIs. Supports the Browse API, Marketplace Insights API, and Taxonomy API with OAuth 2.0 authentication.
|
|
4
|
+
|
|
5
|
+
> **Deprecation Notice:** The eBay Finding API has been shut down. All `Ebay::Finding` methods now emit deprecation warnings and will be removed in v1.0.0. See [Migration Guide](#migrating-from-the-finding-api) below.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -30,7 +32,6 @@ require 'ebay'
|
|
|
30
32
|
Ebay.configure do |config|
|
|
31
33
|
config.client_id = ENV['EBAY_CLIENT_ID']
|
|
32
34
|
config.client_secret = ENV['EBAY_CLIENT_SECRET']
|
|
33
|
-
config.app_id = ENV['EBAY_APP_ID'] # Optional, defaults to client_id for Finding API
|
|
34
35
|
config.marketplace_id = 'EBAY_US' # Default
|
|
35
36
|
config.timeout = 30 # Default
|
|
36
37
|
end
|
|
@@ -67,29 +68,33 @@ item = browse.get_item("v1|123456789|0")
|
|
|
67
68
|
# Get items by group
|
|
68
69
|
items = browse.get_items_by_item_group("group123")
|
|
69
70
|
|
|
71
|
+
# Search by category (no keywords required)
|
|
72
|
+
results = browse.search_by_category("9355", limit: 10)
|
|
73
|
+
|
|
70
74
|
# Search by image
|
|
71
75
|
results = browse.search_by_image(Base64.encode64(File.read("watch.jpg")))
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
###
|
|
78
|
+
### Marketplace Insights API
|
|
75
79
|
|
|
76
|
-
Search
|
|
80
|
+
Search sold/completed items for price history and market data.
|
|
77
81
|
|
|
78
82
|
```ruby
|
|
79
|
-
|
|
83
|
+
insights = Ebay::MarketplaceInsights.new
|
|
80
84
|
|
|
81
|
-
# Search
|
|
82
|
-
|
|
85
|
+
# Search sold items
|
|
86
|
+
sold = insights.search(q: "pokemon base set charizard")
|
|
87
|
+
sold['itemSales'].each do |item|
|
|
88
|
+
puts "#{item['title']} - sold for #{item['lastSoldPrice']['value']}"
|
|
89
|
+
end
|
|
83
90
|
|
|
84
|
-
#
|
|
85
|
-
sold =
|
|
91
|
+
# With filters
|
|
92
|
+
sold = insights.search(q: "vintage rolex", category_ids: "31387", limit: 20)
|
|
93
|
+
```
|
|
86
94
|
|
|
87
|
-
|
|
88
|
-
results = finding.find_items_advanced(keywords: "nike jordan", categoryId: "93427")
|
|
95
|
+
### Finding API (Deprecated)
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
results = finding.find_items_by_category("9355")
|
|
92
|
-
```
|
|
97
|
+
> **The Finding API has been shut down by eBay.** All methods emit deprecation warnings. Use Browse and Marketplace Insights APIs instead. See [Migration Guide](#migrating-from-the-finding-api).
|
|
93
98
|
|
|
94
99
|
### Taxonomy API
|
|
95
100
|
|
|
@@ -144,6 +149,22 @@ rescue Ebay::ConfigurationError => e
|
|
|
144
149
|
end
|
|
145
150
|
```
|
|
146
151
|
|
|
152
|
+
## Migrating from the Finding API
|
|
153
|
+
|
|
154
|
+
The eBay Finding API has been shut down. Here's how to migrate to the replacement APIs:
|
|
155
|
+
|
|
156
|
+
| Finding (old) | Replacement (new) |
|
|
157
|
+
|---|---|
|
|
158
|
+
| `finding.find_items_by_keywords("query")` | `browse.search(q: "query")` |
|
|
159
|
+
| `finding.find_completed_items("query")` | `insights.search(q: "query")` |
|
|
160
|
+
| `finding.find_items_by_category("9355")` | `browse.search_by_category("9355")` |
|
|
161
|
+
| `finding.find_items_advanced(keywords: "q", categoryId: "9355")` | `browse.search(q: "q", category_ids: "9355")` |
|
|
162
|
+
|
|
163
|
+
**Key differences:**
|
|
164
|
+
- **Auth:** No more `app_id` — all APIs use OAuth 2.0 (`client_id` + `client_secret`)
|
|
165
|
+
- **Response format:** Clean REST JSON instead of the old nested XML-style format
|
|
166
|
+
- **Filters:** Browse API uses a `filter` parameter (e.g., `filter: "price:[10..50],priceCurrency:USD"`) instead of Finding's `itemFilter` syntax
|
|
167
|
+
|
|
147
168
|
## Development
|
|
148
169
|
|
|
149
170
|
```bash
|
data/lib/ebay/browse.rb
CHANGED
|
@@ -16,6 +16,10 @@ module Ebay
|
|
|
16
16
|
client.get("/buy/browse/v1/item/get_items_by_item_group", item_group_id: item_group_id)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
def search_by_category(category_ids, **params)
|
|
20
|
+
client.get("/buy/browse/v1/item_summary/search", { category_ids: category_ids }.merge(params))
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
def search_by_image(image_base64, **params)
|
|
20
24
|
client.post("/buy/browse/v1/item_summary/search_by_image", { image: image_base64 }.merge(params))
|
|
21
25
|
end
|
data/lib/ebay/client.rb
CHANGED
data/lib/ebay/configuration.rb
CHANGED
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
module Ebay
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :client_id, :client_secret,
|
|
5
|
+
attr_accessor :client_id, :client_secret,
|
|
6
6
|
:base_url, :sandbox, :timeout, :marketplace_id
|
|
7
|
+
attr_reader :app_id
|
|
8
|
+
|
|
9
|
+
def app_id=(value)
|
|
10
|
+
warn "[DEPRECATION] app_id is deprecated. The Finding API has been shut down by eBay. " \
|
|
11
|
+
"Use client_id and client_secret with OAuth 2.0 instead (Browse and Marketplace Insights APIs)."
|
|
12
|
+
@app_id = value
|
|
13
|
+
end
|
|
7
14
|
|
|
8
15
|
def initialize
|
|
9
16
|
@base_url = "https://api.ebay.com"
|
|
@@ -24,6 +31,7 @@ module Ebay
|
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
def finding_url
|
|
34
|
+
warn "[DEPRECATION] finding_url is deprecated. The Finding API has been shut down by eBay."
|
|
27
35
|
sandbox ? "https://svcs.sandbox.ebay.com/services/search/FindingService/v1" : "https://svcs.ebay.com/services/search/FindingService/v1"
|
|
28
36
|
end
|
|
29
37
|
end
|
data/lib/ebay/finding.rb
CHANGED
|
@@ -3,34 +3,49 @@
|
|
|
3
3
|
module Ebay
|
|
4
4
|
class Finding < Base
|
|
5
5
|
def find_items_by_keywords(keywords, **params)
|
|
6
|
+
warn "[DEPRECATION] Ebay::Finding#find_items_by_keywords is deprecated. " \
|
|
7
|
+
"Use Ebay::Browse#search(q: keywords) instead. " \
|
|
8
|
+
"The Finding API has been shut down by eBay."
|
|
6
9
|
finding_request("findItemsByKeywords", { keywords: keywords }.merge(params))
|
|
7
10
|
end
|
|
8
11
|
|
|
9
12
|
def find_completed_items(keywords, **params)
|
|
13
|
+
warn "[DEPRECATION] Ebay::Finding#find_completed_items is deprecated. " \
|
|
14
|
+
"Use Ebay::MarketplaceInsights#search(q: keywords) instead. " \
|
|
15
|
+
"The Finding API has been shut down by eBay."
|
|
10
16
|
finding_request("findCompletedItems", { keywords: keywords }.merge(params))
|
|
11
17
|
end
|
|
12
18
|
|
|
13
19
|
def find_items_advanced(**params)
|
|
20
|
+
warn "[DEPRECATION] Ebay::Finding#find_items_advanced is deprecated. " \
|
|
21
|
+
"Use Ebay::Browse#search(q:, category_ids:, ...) instead. " \
|
|
22
|
+
"The Finding API has been shut down by eBay."
|
|
14
23
|
finding_request("findItemsAdvanced", params)
|
|
15
24
|
end
|
|
16
25
|
|
|
17
26
|
def find_items_by_category(category_id, **params)
|
|
27
|
+
warn "[DEPRECATION] Ebay::Finding#find_items_by_category is deprecated. " \
|
|
28
|
+
"Use Ebay::Browse#search_by_category(category_ids) instead. " \
|
|
29
|
+
"The Finding API has been shut down by eBay."
|
|
18
30
|
finding_request("findItemsByCategory", { categoryId: category_id }.merge(params))
|
|
19
31
|
end
|
|
20
32
|
|
|
21
33
|
private
|
|
22
34
|
|
|
23
35
|
def finding_request(operation, params)
|
|
24
|
-
|
|
36
|
+
config = client.configuration
|
|
37
|
+
raise ConfigurationError, "app_id is required for the Finding API" if config.app_id.nil? || config.app_id.empty?
|
|
38
|
+
|
|
39
|
+
url = config.finding_url
|
|
25
40
|
query = {
|
|
26
41
|
"OPERATION-NAME" => operation,
|
|
27
42
|
"SERVICE-VERSION" => "1.0.0",
|
|
28
|
-
"SECURITY-APPNAME" =>
|
|
43
|
+
"SECURITY-APPNAME" => config.app_id,
|
|
29
44
|
"RESPONSE-DATA-FORMAT" => "JSON",
|
|
30
45
|
"REST-PAYLOAD" => ""
|
|
31
46
|
}.merge(params)
|
|
32
47
|
|
|
33
|
-
response = HTTParty.get(url, query: query, timeout:
|
|
48
|
+
response = HTTParty.get(url, query: query, timeout: config.timeout)
|
|
34
49
|
handle_finding_response(response, operation)
|
|
35
50
|
end
|
|
36
51
|
|
data/lib/ebay/taxonomy.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
3
5
|
module Ebay
|
|
4
6
|
class Taxonomy < Base
|
|
5
7
|
def get_default_category_tree_id(marketplace_id = nil)
|
|
@@ -8,11 +10,11 @@ module Ebay
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def get_category_tree(category_tree_id)
|
|
11
|
-
client.get("/commerce/taxonomy/v1/category_tree/#{category_tree_id}")
|
|
13
|
+
client.get("/commerce/taxonomy/v1/category_tree/#{URI.encode_www_form_component(category_tree_id)}")
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def get_category_subtree(category_tree_id, category_id)
|
|
15
|
-
client.get("/commerce/taxonomy/v1/category_tree/#{category_tree_id}/get_category_subtree", category_id: category_id)
|
|
17
|
+
client.get("/commerce/taxonomy/v1/category_tree/#{URI.encode_www_form_component(category_tree_id)}/get_category_subtree", category_id: category_id)
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
data/lib/ebay/version.rb
CHANGED
data/lib/ebay.rb
CHANGED
|
@@ -11,6 +11,7 @@ require_relative 'ebay/client'
|
|
|
11
11
|
require_relative 'ebay/base'
|
|
12
12
|
require_relative 'ebay/browse'
|
|
13
13
|
require_relative 'ebay/finding'
|
|
14
|
+
require_relative 'ebay/marketplace_insights'
|
|
14
15
|
require_relative 'ebay/taxonomy'
|
|
15
16
|
|
|
16
17
|
module Ebay
|
|
@@ -23,6 +24,8 @@ module Ebay
|
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def client
|
|
27
|
+
raise ConfigurationError, "Call Ebay.configure before using Ebay.client" unless configuration&.valid?
|
|
28
|
+
|
|
26
29
|
@client ||= Client.new(configuration)
|
|
27
30
|
end
|
|
28
31
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ebay-api-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eduardo Souza
|
|
@@ -154,15 +154,9 @@ files:
|
|
|
154
154
|
- lib/ebay/configuration.rb
|
|
155
155
|
- lib/ebay/errors.rb
|
|
156
156
|
- lib/ebay/finding.rb
|
|
157
|
+
- lib/ebay/marketplace_insights.rb
|
|
157
158
|
- lib/ebay/taxonomy.rb
|
|
158
159
|
- lib/ebay/version.rb
|
|
159
|
-
- spec/ebay/browse_spec.rb
|
|
160
|
-
- spec/ebay/client_spec.rb
|
|
161
|
-
- spec/ebay/configuration_spec.rb
|
|
162
|
-
- spec/ebay/finding_spec.rb
|
|
163
|
-
- spec/ebay/taxonomy_spec.rb
|
|
164
|
-
- spec/examples.txt
|
|
165
|
-
- spec/spec_helper.rb
|
|
166
160
|
homepage: https://github.com/esouza/ebay-api-ruby
|
|
167
161
|
licenses:
|
|
168
162
|
- MIT
|
data/spec/ebay/browse_spec.rb
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Ebay::Browse do
|
|
4
|
-
let(:client) { Ebay.client }
|
|
5
|
-
let(:browse) { described_class.new(client) }
|
|
6
|
-
|
|
7
|
-
before { stub_oauth_token }
|
|
8
|
-
|
|
9
|
-
describe "#search" do
|
|
10
|
-
it "searches items by keyword" do
|
|
11
|
-
stub_request(:get, "https://api.ebay.com/buy/browse/v1/item_summary/search")
|
|
12
|
-
.with(query: hash_including(q: "iphone"))
|
|
13
|
-
.to_return(status: 200, body: '{"itemSummaries": []}', headers: { 'Content-Type' => 'application/json' })
|
|
14
|
-
|
|
15
|
-
result = browse.search(q: "iphone")
|
|
16
|
-
expect(result).to eq("itemSummaries" => [])
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "passes additional params" do
|
|
20
|
-
stub_request(:get, "https://api.ebay.com/buy/browse/v1/item_summary/search")
|
|
21
|
-
.with(query: hash_including(q: "iphone", limit: "10"))
|
|
22
|
-
.to_return(status: 200, body: '{"itemSummaries": []}', headers: { 'Content-Type' => 'application/json' })
|
|
23
|
-
|
|
24
|
-
browse.search(q: "iphone", limit: "10")
|
|
25
|
-
expect(WebMock).to have_requested(:get, "https://api.ebay.com/buy/browse/v1/item_summary/search")
|
|
26
|
-
.with(query: hash_including(q: "iphone", limit: "10"))
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
describe "#get_item" do
|
|
31
|
-
it "retrieves a single item" do
|
|
32
|
-
stub_request(:get, "https://api.ebay.com/buy/browse/v1/item/v1%7C123%7C0")
|
|
33
|
-
.to_return(status: 200, body: '{"itemId": "v1|123|0"}', headers: { 'Content-Type' => 'application/json' })
|
|
34
|
-
|
|
35
|
-
result = browse.get_item("v1|123|0")
|
|
36
|
-
expect(result).to eq("itemId" => "v1|123|0")
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe "#get_items_by_item_group" do
|
|
41
|
-
it "retrieves items by group" do
|
|
42
|
-
stub_request(:get, "https://api.ebay.com/buy/browse/v1/item/get_items_by_item_group")
|
|
43
|
-
.with(query: { item_group_id: "group123" })
|
|
44
|
-
.to_return(status: 200, body: '{"items": []}', headers: { 'Content-Type' => 'application/json' })
|
|
45
|
-
|
|
46
|
-
result = browse.get_items_by_item_group("group123")
|
|
47
|
-
expect(result).to eq("items" => [])
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
describe "#search_by_image" do
|
|
52
|
-
it "searches by image" do
|
|
53
|
-
stub_request(:post, "https://api.ebay.com/buy/browse/v1/item_summary/search_by_image")
|
|
54
|
-
.to_return(status: 200, body: '{"itemSummaries": []}', headers: { 'Content-Type' => 'application/json' })
|
|
55
|
-
|
|
56
|
-
result = browse.search_by_image("base64data")
|
|
57
|
-
expect(result).to eq("itemSummaries" => [])
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
data/spec/ebay/client_spec.rb
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Ebay::Client do
|
|
4
|
-
let(:client) { Ebay.client }
|
|
5
|
-
|
|
6
|
-
describe "#initialize" do
|
|
7
|
-
it "raises ConfigurationError without valid config" do
|
|
8
|
-
Ebay.reset!
|
|
9
|
-
Ebay.configure { |c| c.client_id = nil }
|
|
10
|
-
expect { Ebay.client }.to raise_error(Ebay::ConfigurationError)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe "#authenticate!" do
|
|
15
|
-
it "obtains an access token" do
|
|
16
|
-
stub_oauth_token
|
|
17
|
-
token = client.authenticate!
|
|
18
|
-
expect(token).to eq("test_token")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "sends correct authorization header" do
|
|
22
|
-
stub_oauth_token
|
|
23
|
-
client.authenticate!
|
|
24
|
-
|
|
25
|
-
expected_credentials = Base64.strict_encode64("test_client_id:test_client_secret")
|
|
26
|
-
expect(WebMock).to have_requested(:post, "https://api.ebay.com/identity/v1/oauth2/token")
|
|
27
|
-
.with(headers: { 'Authorization' => "Basic #{expected_credentials}" })
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "raises AuthenticationError on failure" do
|
|
31
|
-
stub_request(:post, "https://api.ebay.com/identity/v1/oauth2/token")
|
|
32
|
-
.to_return(status: 401, body: "Unauthorized")
|
|
33
|
-
|
|
34
|
-
expect { client.authenticate! }.to raise_error(Ebay::AuthenticationError)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe "#get" do
|
|
39
|
-
before { stub_oauth_token }
|
|
40
|
-
|
|
41
|
-
it "makes authenticated GET requests" do
|
|
42
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
43
|
-
.to_return(status: 200, body: '{"result": "ok"}', headers: { 'Content-Type' => 'application/json' })
|
|
44
|
-
|
|
45
|
-
result = client.get("/test")
|
|
46
|
-
expect(result).to eq("result" => "ok")
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "passes query params" do
|
|
50
|
-
stub_request(:get, "https://api.ebay.com/test?q=shoes")
|
|
51
|
-
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
52
|
-
|
|
53
|
-
client.get("/test", q: "shoes")
|
|
54
|
-
expect(WebMock).to have_requested(:get, "https://api.ebay.com/test").with(query: { q: "shoes" })
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "auto-authenticates before request" do
|
|
58
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
59
|
-
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
60
|
-
|
|
61
|
-
client.get("/test")
|
|
62
|
-
expect(WebMock).to have_requested(:post, "https://api.ebay.com/identity/v1/oauth2/token").once
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
describe "#post" do
|
|
67
|
-
before { stub_oauth_token }
|
|
68
|
-
|
|
69
|
-
it "makes authenticated POST requests" do
|
|
70
|
-
stub_request(:post, "https://api.ebay.com/test")
|
|
71
|
-
.to_return(status: 200, body: '{"created": true}', headers: { 'Content-Type' => 'application/json' })
|
|
72
|
-
|
|
73
|
-
result = client.post("/test", { name: "item" })
|
|
74
|
-
expect(result).to eq("created" => true)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
describe "error handling" do
|
|
79
|
-
before { stub_oauth_token }
|
|
80
|
-
|
|
81
|
-
it "raises NotFoundError on 404" do
|
|
82
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
83
|
-
.to_return(status: 404, body: "Not Found")
|
|
84
|
-
|
|
85
|
-
expect { client.get("/test") }.to raise_error(Ebay::NotFoundError)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "raises RateLimitError on 429" do
|
|
89
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
90
|
-
.to_return(status: 429, body: "Too Many Requests", headers: { 'retry-after' => '60' })
|
|
91
|
-
|
|
92
|
-
expect { client.get("/test") }.to raise_error(Ebay::RateLimitError) do |error|
|
|
93
|
-
expect(error.retry_after).to eq('60')
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
it "raises ValidationError on 400" do
|
|
98
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
99
|
-
.to_return(status: 400, body: '{"message": "Bad Request"}', headers: { 'Content-Type' => 'application/json' })
|
|
100
|
-
|
|
101
|
-
expect { client.get("/test") }.to raise_error(Ebay::ValidationError)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
it "raises APIError on 500" do
|
|
105
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
106
|
-
.to_return(status: 500, body: "Internal Server Error")
|
|
107
|
-
|
|
108
|
-
expect { client.get("/test") }.to raise_error(Ebay::APIError)
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
describe "token caching" do
|
|
113
|
-
it "reuses token for multiple requests" do
|
|
114
|
-
stub_oauth_token
|
|
115
|
-
|
|
116
|
-
stub_request(:get, "https://api.ebay.com/test")
|
|
117
|
-
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
118
|
-
|
|
119
|
-
client.get("/test")
|
|
120
|
-
client.get("/test")
|
|
121
|
-
|
|
122
|
-
expect(WebMock).to have_requested(:post, "https://api.ebay.com/identity/v1/oauth2/token").once
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Ebay::Configuration do
|
|
4
|
-
subject(:config) { described_class.new }
|
|
5
|
-
|
|
6
|
-
describe "#initialize" do
|
|
7
|
-
it "sets default base_url" do
|
|
8
|
-
expect(config.base_url).to eq("https://api.ebay.com")
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it "sets default sandbox to false" do
|
|
12
|
-
expect(config.sandbox).to be false
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "sets default timeout to 30" do
|
|
16
|
-
expect(config.timeout).to eq(30)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "sets default marketplace_id" do
|
|
20
|
-
expect(config.marketplace_id).to eq("EBAY_US")
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe "#sandbox!" do
|
|
25
|
-
it "enables sandbox mode" do
|
|
26
|
-
config.sandbox!
|
|
27
|
-
expect(config.sandbox).to be true
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "changes base_url to sandbox" do
|
|
31
|
-
config.sandbox!
|
|
32
|
-
expect(config.base_url).to eq("https://api.sandbox.ebay.com")
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "returns self for chaining" do
|
|
36
|
-
expect(config.sandbox!).to eq(config)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe "#valid?" do
|
|
41
|
-
it "returns false when client_id is nil" do
|
|
42
|
-
config.client_secret = "secret"
|
|
43
|
-
expect(config.valid?).to be false
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "returns false when client_secret is nil" do
|
|
47
|
-
config.client_id = "id"
|
|
48
|
-
expect(config.valid?).to be false
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it "returns false when client_id is empty" do
|
|
52
|
-
config.client_id = ""
|
|
53
|
-
config.client_secret = "secret"
|
|
54
|
-
expect(config.valid?).to be false
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "returns true when both are set" do
|
|
58
|
-
config.client_id = "id"
|
|
59
|
-
config.client_secret = "secret"
|
|
60
|
-
expect(config.valid?).to be true
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
describe "#finding_url" do
|
|
65
|
-
it "returns production URL by default" do
|
|
66
|
-
expect(config.finding_url).to eq("https://svcs.ebay.com/services/search/FindingService/v1")
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it "returns sandbox URL when sandbox enabled" do
|
|
70
|
-
config.sandbox!
|
|
71
|
-
expect(config.finding_url).to eq("https://svcs.sandbox.ebay.com/services/search/FindingService/v1")
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
data/spec/ebay/finding_spec.rb
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Ebay::Finding do
|
|
4
|
-
let(:client) { Ebay.client }
|
|
5
|
-
let(:finding) { described_class.new(client) }
|
|
6
|
-
let(:finding_url) { "https://svcs.ebay.com/services/search/FindingService/v1" }
|
|
7
|
-
|
|
8
|
-
before do
|
|
9
|
-
stub_oauth_token
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
describe "#find_items_by_keywords" do
|
|
13
|
-
it "searches by keywords" do
|
|
14
|
-
stub_request(:get, finding_url)
|
|
15
|
-
.with(query: hash_including("OPERATION-NAME" => "findItemsByKeywords", "keywords" => "laptop"))
|
|
16
|
-
.to_return(status: 200, body: '{"findItemsByKeywordsResponse": []}', headers: { 'Content-Type' => 'application/json' })
|
|
17
|
-
|
|
18
|
-
result = finding.find_items_by_keywords("laptop")
|
|
19
|
-
expect(result).to eq("findItemsByKeywordsResponse" => [])
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it "includes correct service params" do
|
|
23
|
-
stub_request(:get, finding_url)
|
|
24
|
-
.with(query: hash_including(
|
|
25
|
-
"OPERATION-NAME" => "findItemsByKeywords",
|
|
26
|
-
"SERVICE-VERSION" => "1.0.0",
|
|
27
|
-
"SECURITY-APPNAME" => "test_app_id",
|
|
28
|
-
"RESPONSE-DATA-FORMAT" => "JSON"
|
|
29
|
-
))
|
|
30
|
-
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
31
|
-
|
|
32
|
-
finding.find_items_by_keywords("test")
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe "#find_completed_items" do
|
|
37
|
-
it "searches completed/sold items" do
|
|
38
|
-
stub_request(:get, finding_url)
|
|
39
|
-
.with(query: hash_including("OPERATION-NAME" => "findCompletedItems", "keywords" => "vintage watch"))
|
|
40
|
-
.to_return(status: 200, body: '{"findCompletedItemsResponse": []}', headers: { 'Content-Type' => 'application/json' })
|
|
41
|
-
|
|
42
|
-
result = finding.find_completed_items("vintage watch")
|
|
43
|
-
expect(result).to eq("findCompletedItemsResponse" => [])
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
describe "#find_items_advanced" do
|
|
48
|
-
it "performs advanced search" do
|
|
49
|
-
stub_request(:get, finding_url)
|
|
50
|
-
.with(query: hash_including("OPERATION-NAME" => "findItemsAdvanced"))
|
|
51
|
-
.to_return(status: 200, body: '{"findItemsAdvancedResponse": []}', headers: { 'Content-Type' => 'application/json' })
|
|
52
|
-
|
|
53
|
-
result = finding.find_items_advanced(keywords: "shoes", categoryId: "3034")
|
|
54
|
-
expect(result).to eq("findItemsAdvancedResponse" => [])
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
describe "#find_items_by_category" do
|
|
59
|
-
it "searches by category" do
|
|
60
|
-
stub_request(:get, finding_url)
|
|
61
|
-
.with(query: hash_including("OPERATION-NAME" => "findItemsByCategory", "categoryId" => "9355"))
|
|
62
|
-
.to_return(status: 200, body: '{"findItemsByCategoryResponse": []}', headers: { 'Content-Type' => 'application/json' })
|
|
63
|
-
|
|
64
|
-
result = finding.find_items_by_category("9355")
|
|
65
|
-
expect(result).to eq("findItemsByCategoryResponse" => [])
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
describe "error handling" do
|
|
70
|
-
it "raises APIError on failure" do
|
|
71
|
-
stub_request(:get, finding_url)
|
|
72
|
-
.with(query: hash_including("OPERATION-NAME" => "findItemsByKeywords"))
|
|
73
|
-
.to_return(status: 500, body: "Server Error")
|
|
74
|
-
|
|
75
|
-
expect { finding.find_items_by_keywords("test") }.to raise_error(Ebay::APIError)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
data/spec/ebay/taxonomy_spec.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Ebay::Taxonomy do
|
|
4
|
-
let(:client) { Ebay.client }
|
|
5
|
-
let(:taxonomy) { described_class.new(client) }
|
|
6
|
-
|
|
7
|
-
before { stub_oauth_token }
|
|
8
|
-
|
|
9
|
-
describe "#get_default_category_tree_id" do
|
|
10
|
-
it "returns default category tree id" do
|
|
11
|
-
stub_request(:get, "https://api.ebay.com/commerce/taxonomy/v1/get_default_category_tree_id")
|
|
12
|
-
.with(query: { marketplace_id: "EBAY_US" })
|
|
13
|
-
.to_return(status: 200, body: '{"categoryTreeId": "0", "categoryTreeVersion": "119"}', headers: { 'Content-Type' => 'application/json' })
|
|
14
|
-
|
|
15
|
-
result = taxonomy.get_default_category_tree_id
|
|
16
|
-
expect(result).to eq("categoryTreeId" => "0", "categoryTreeVersion" => "119")
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "accepts custom marketplace_id" do
|
|
20
|
-
stub_request(:get, "https://api.ebay.com/commerce/taxonomy/v1/get_default_category_tree_id")
|
|
21
|
-
.with(query: { marketplace_id: "EBAY_GB" })
|
|
22
|
-
.to_return(status: 200, body: '{"categoryTreeId": "3"}', headers: { 'Content-Type' => 'application/json' })
|
|
23
|
-
|
|
24
|
-
result = taxonomy.get_default_category_tree_id("EBAY_GB")
|
|
25
|
-
expect(result).to eq("categoryTreeId" => "3")
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe "#get_category_tree" do
|
|
30
|
-
it "returns category tree" do
|
|
31
|
-
stub_request(:get, "https://api.ebay.com/commerce/taxonomy/v1/category_tree/0")
|
|
32
|
-
.to_return(status: 200, body: '{"categoryTreeId": "0", "rootCategoryNode": {}}', headers: { 'Content-Type' => 'application/json' })
|
|
33
|
-
|
|
34
|
-
result = taxonomy.get_category_tree("0")
|
|
35
|
-
expect(result).to include("categoryTreeId" => "0")
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe "#get_category_subtree" do
|
|
40
|
-
it "returns category subtree" do
|
|
41
|
-
stub_request(:get, "https://api.ebay.com/commerce/taxonomy/v1/category_tree/0/get_category_subtree")
|
|
42
|
-
.with(query: { category_id: "9355" })
|
|
43
|
-
.to_return(status: 200, body: '{"categorySubtreeNode": {}}', headers: { 'Content-Type' => 'application/json' })
|
|
44
|
-
|
|
45
|
-
result = taxonomy.get_category_subtree("0", "9355")
|
|
46
|
-
expect(result).to eq("categorySubtreeNode" => {})
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
data/spec/examples.txt
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
example_id | status | run_time |
|
|
2
|
-
---------------------------------------- | ------ | --------------- |
|
|
3
|
-
./spec/ebay/browse_spec.rb[1:1:1] | passed | 0.00076 seconds |
|
|
4
|
-
./spec/ebay/browse_spec.rb[1:1:2] | passed | 0.00193 seconds |
|
|
5
|
-
./spec/ebay/browse_spec.rb[1:2:1] | passed | 0.00051 seconds |
|
|
6
|
-
./spec/ebay/browse_spec.rb[1:3:1] | passed | 0.00054 seconds |
|
|
7
|
-
./spec/ebay/browse_spec.rb[1:4:1] | passed | 0.00048 seconds |
|
|
8
|
-
./spec/ebay/client_spec.rb[1:1:1] | passed | 0.00004 seconds |
|
|
9
|
-
./spec/ebay/client_spec.rb[1:2:1] | passed | 0.00022 seconds |
|
|
10
|
-
./spec/ebay/client_spec.rb[1:2:2] | passed | 0.00031 seconds |
|
|
11
|
-
./spec/ebay/client_spec.rb[1:2:3] | passed | 0.00026 seconds |
|
|
12
|
-
./spec/ebay/client_spec.rb[1:3:1] | passed | 0.00041 seconds |
|
|
13
|
-
./spec/ebay/client_spec.rb[1:3:2] | passed | 0.00065 seconds |
|
|
14
|
-
./spec/ebay/client_spec.rb[1:3:3] | passed | 0.00039 seconds |
|
|
15
|
-
./spec/ebay/client_spec.rb[1:4:1] | passed | 0.00065 seconds |
|
|
16
|
-
./spec/ebay/client_spec.rb[1:5:1] | passed | 0.00044 seconds |
|
|
17
|
-
./spec/ebay/client_spec.rb[1:5:2] | passed | 0.00052 seconds |
|
|
18
|
-
./spec/ebay/client_spec.rb[1:5:3] | passed | 0.00059 seconds |
|
|
19
|
-
./spec/ebay/client_spec.rb[1:5:4] | passed | 0.00047 seconds |
|
|
20
|
-
./spec/ebay/client_spec.rb[1:6:1] | passed | 0.00057 seconds |
|
|
21
|
-
./spec/ebay/configuration_spec.rb[1:1:1] | passed | 0.00003 seconds |
|
|
22
|
-
./spec/ebay/configuration_spec.rb[1:1:2] | passed | 0.00004 seconds |
|
|
23
|
-
./spec/ebay/configuration_spec.rb[1:1:3] | passed | 0.00003 seconds |
|
|
24
|
-
./spec/ebay/configuration_spec.rb[1:1:4] | passed | 0.00003 seconds |
|
|
25
|
-
./spec/ebay/configuration_spec.rb[1:2:1] | passed | 0.00046 seconds |
|
|
26
|
-
./spec/ebay/configuration_spec.rb[1:2:2] | passed | 0.00005 seconds |
|
|
27
|
-
./spec/ebay/configuration_spec.rb[1:2:3] | passed | 0.00004 seconds |
|
|
28
|
-
./spec/ebay/configuration_spec.rb[1:3:1] | passed | 0.00004 seconds |
|
|
29
|
-
./spec/ebay/configuration_spec.rb[1:3:2] | passed | 0.00003 seconds |
|
|
30
|
-
./spec/ebay/configuration_spec.rb[1:3:3] | passed | 0.00005 seconds |
|
|
31
|
-
./spec/ebay/configuration_spec.rb[1:3:4] | passed | 0.00005 seconds |
|
|
32
|
-
./spec/ebay/configuration_spec.rb[1:4:1] | passed | 0.00003 seconds |
|
|
33
|
-
./spec/ebay/configuration_spec.rb[1:4:2] | passed | 0.00003 seconds |
|
|
34
|
-
./spec/ebay/finding_spec.rb[1:1:1] | passed | 0.00134 seconds |
|
|
35
|
-
./spec/ebay/finding_spec.rb[1:1:2] | passed | 0.02238 seconds |
|
|
36
|
-
./spec/ebay/finding_spec.rb[1:2:1] | passed | 0.00057 seconds |
|
|
37
|
-
./spec/ebay/finding_spec.rb[1:3:1] | passed | 0.00077 seconds |
|
|
38
|
-
./spec/ebay/finding_spec.rb[1:4:1] | passed | 0.00048 seconds |
|
|
39
|
-
./spec/ebay/finding_spec.rb[1:5:1] | passed | 0.00125 seconds |
|
|
40
|
-
./spec/ebay/taxonomy_spec.rb[1:1:1] | passed | 0.0007 seconds |
|
|
41
|
-
./spec/ebay/taxonomy_spec.rb[1:1:2] | passed | 0.00056 seconds |
|
|
42
|
-
./spec/ebay/taxonomy_spec.rb[1:2:1] | passed | 0.00212 seconds |
|
|
43
|
-
./spec/ebay/taxonomy_spec.rb[1:3:1] | passed | 0.0006 seconds |
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/setup"
|
|
4
|
-
require "ebay"
|
|
5
|
-
require "webmock/rspec"
|
|
6
|
-
|
|
7
|
-
RSpec.configure do |config|
|
|
8
|
-
config.expect_with :rspec do |expectations|
|
|
9
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
config.mock_with :rspec do |mocks|
|
|
13
|
-
mocks.verify_partial_doubles = true
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
config.shared_context_metadata_behavior = :apply_to_host_groups
|
|
17
|
-
config.filter_run_when_matching :focus
|
|
18
|
-
config.example_status_persistence_file_path = "spec/examples.txt"
|
|
19
|
-
config.disable_monkey_patching!
|
|
20
|
-
config.warnings = true
|
|
21
|
-
|
|
22
|
-
if config.files_to_run.one?
|
|
23
|
-
config.default_formatter = "doc"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
config.order = :random
|
|
27
|
-
Kernel.srand config.seed
|
|
28
|
-
|
|
29
|
-
config.before(:each) do
|
|
30
|
-
WebMock.disable_net_connect!
|
|
31
|
-
Ebay.reset!
|
|
32
|
-
Ebay.configure do |c|
|
|
33
|
-
c.client_id = "test_client_id"
|
|
34
|
-
c.client_secret = "test_client_secret"
|
|
35
|
-
c.app_id = "test_app_id"
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
config.after(:each) do
|
|
40
|
-
WebMock.reset!
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def stub_oauth_token
|
|
45
|
-
stub_request(:post, "https://api.ebay.com/identity/v1/oauth2/token")
|
|
46
|
-
.to_return(
|
|
47
|
-
status: 200,
|
|
48
|
-
headers: { 'Content-Type' => 'application/json' },
|
|
49
|
-
body: {
|
|
50
|
-
access_token: "test_token",
|
|
51
|
-
expires_in: 7200,
|
|
52
|
-
token_type: "Application Access Token"
|
|
53
|
-
}.to_json
|
|
54
|
-
)
|
|
55
|
-
end
|