agent_cooper 0.0.5 → 0.0.6

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 (56) hide show
  1. data/.gitignore +1 -1
  2. data/README.md +13 -4
  3. data/Rakefile +0 -3
  4. data/agent_cooper.gemspec +12 -13
  5. data/features/finder.feature +4 -6
  6. data/features/merchandiser.feature +1 -2
  7. data/features/shopper.feature +2 -2
  8. data/features/support/env.rb +5 -5
  9. data/features/support/vcr.rb +10 -0
  10. data/lib/agent_cooper.rb +17 -4
  11. data/lib/agent_cooper/config.rb +3 -9
  12. data/lib/agent_cooper/nokogiri_decorator.rb +47 -0
  13. data/lib/agent_cooper/request.rb +36 -13
  14. data/lib/agent_cooper/requests/finder.rb +25 -0
  15. data/lib/agent_cooper/requests/merchandiser.rb +25 -0
  16. data/lib/agent_cooper/requests/shopper.rb +23 -0
  17. data/lib/agent_cooper/response.rb +3 -4
  18. data/lib/agent_cooper/synchrony.rb +34 -0
  19. data/lib/agent_cooper/version.rb +1 -1
  20. data/spec/agent_cooper/request_spec.rb +91 -6
  21. data/spec/agent_cooper/requests/finder_spec.rb +13 -0
  22. data/spec/agent_cooper/requests/merchandiser_spec.rb +13 -0
  23. data/spec/agent_cooper/requests/shopper_spec.rb +13 -0
  24. data/spec/agent_cooper/response_spec.rb +51 -1
  25. data/spec/agent_cooper_spec.rb +12 -0
  26. data/spec/fixtures/cassettes/finder/find_items_advanced/d49218a9522a4a055e31fc6b88c3a2b5.yml +528 -0
  27. data/spec/fixtures/cassettes/finder/find_items_by_category/85e07de9993e68d09e895f1b01234c5a.yml +463 -0
  28. data/spec/fixtures/cassettes/finder/find_items_by_keywords/91d7d9b4b62b82877604465a20f9ffa9.yml +668 -0
  29. data/spec/fixtures/cassettes/finder/find_items_by_product/59ee1391b6dfc2a93e30c8911942fc71.yml +744 -0
  30. data/spec/fixtures/cassettes/finder/find_items_in_ebay_stores/c7d658804b6353fda03809c21b183af2.yml +472 -0
  31. data/spec/fixtures/cassettes/finder/get_histograms/80bd04d96cd529af4148866a2d28f079.yml +46 -0
  32. data/spec/fixtures/cassettes/finder/get_search_keywords_recommendation/ec96bf3af091373de08550ff46f86c87.yml +41 -0
  33. data/spec/fixtures/cassettes/merchandiser/get_most_watched_items/3c0cb6fb7bb94b384cae15be175e9640.yml +51 -0
  34. data/spec/fixtures/cassettes/merchandiser/get_related_category_items/c949e90fb2bd975020df657a4348328d.yml +41 -0
  35. data/spec/fixtures/cassettes/merchandiser/get_similar_items/56c2c41a60135db83d359053778a065f.yml +41 -0
  36. data/spec/fixtures/cassettes/merchandiser/get_top_selling_products/a82dcb1f094754e54f2a5de191818c3f.yml +53 -0
  37. data/spec/fixtures/cassettes/shopper/find_half_products/77ad8a2ade8e4efadef07346677e43a9.yml +55 -0
  38. data/spec/fixtures/cassettes/shopper/find_popular_items/532fcb32fee187bdc6cc5fb7e4336992.yml +258 -0
  39. data/spec/fixtures/cassettes/shopper/find_popular_searches/6db9b375ea610e870e7a4ca4e20974ec.yml +45 -0
  40. data/spec/fixtures/cassettes/shopper/find_products/3fd6d6000037cd409ab1ef18a6075257.yml +52 -0
  41. data/spec/fixtures/cassettes/shopper/find_reviews_and_guides/8586a984e122cb84136d3cc0bb8bec77.yml +174 -0
  42. data/spec/fixtures/cassettes/shopper/get_item_status/f34cf10c602f9fec7a388297888b4299.yml +45 -0
  43. data/spec/fixtures/cassettes/shopper/get_multiple_items/c1183c23add6cad9afbb73f986c2692e.yml +46 -0
  44. data/spec/fixtures/cassettes/shopper/get_shipping_costs/e7de18031f266637414155639797c097.yml +45 -0
  45. data/spec/fixtures/cassettes/shopper/get_single_item/d4a895de6b214907c47a0b32ab630b9a.yml +44 -0
  46. data/spec/fixtures/cassettes/shopper/get_user_profile/dccabbf426bfeba4d898ca546e17dd4b.yml +47 -0
  47. data/spec/{support → fixtures}/ebay.yml.sample +0 -0
  48. data/spec/spec_helper.rb +4 -0
  49. metadata +141 -177
  50. data/lib/agent_cooper/finder.rb +0 -21
  51. data/lib/agent_cooper/merchandiser.rb +0 -24
  52. data/lib/agent_cooper/shopper.rb +0 -22
  53. data/spec/agent_cooper/config_spec.rb +0 -21
  54. data/spec/agent_cooper/finder_spec.rb +0 -19
  55. data/spec/agent_cooper/merchandiser_spec.rb +0 -18
  56. data/spec/agent_cooper/shopper_spec.rb +0 -18
data/.gitignore CHANGED
@@ -2,4 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
- *.yml
5
+ ebay.yml
data/README.md CHANGED
@@ -12,42 +12,51 @@ Usage
12
12
  -----
13
13
  Set up.
14
14
 
15
- AgentCooper::Config.set do |config|
15
+ ```ruby
16
+ AgentCooper.configure do |config|
16
17
  config.app_id = "SOME_OBSCURE_APP_ID"
17
18
  end
19
+ ```
18
20
 
19
21
  Initialize a request
20
22
 
23
+ ```ruby
21
24
  request = AgentCooper::Finder.new
22
25
  request = AgentCooper::Shopper.new
23
26
  request = AgentCooper::Merchandiser.new
24
-
27
+ ```
25
28
  Build request params.
26
29
 
30
+ ```ruby
27
31
  request << {
28
32
  'OPERATION-NAME' => 'getSearchKeywordsRecommendation',
29
33
  'KEYWORDS' => 'arry potter'
30
34
  }
35
+ ```
31
36
 
32
37
  Get a response.
33
38
 
39
+ ```ruby
34
40
  response = request.get
41
+ ```
35
42
 
36
43
  Return a hash:
37
44
 
45
+ ```ruby
38
46
  response.to_hash
39
47
 
40
48
  returns: {'getSearchKeywordsRecommendationResponse' => {'xmnls' => 'http://www.ebay.com/marketplace/search/v1/services', 'ack' => 'Success', 'version' => '1.9.0', 'keywords' => 'harry potter'}}
41
-
49
+ ```
42
50
 
43
51
  Or parse a response with Nokogiri:
44
52
 
53
+ ```ruby
45
54
  response.xml.css("Item > Title").each do |title|
46
55
  some business value
47
56
  end
48
57
 
49
58
  response.xml.xpath("//Item")
50
-
59
+ ```
51
60
  ----
52
61
 
53
62
  Based on papercavalier's [sucker](http://github.com/papercavalier/sucker).
data/Rakefile CHANGED
@@ -13,6 +13,3 @@ end
13
13
  Cucumber::Rake::Task.new(:features) do |t|
14
14
  t.cucumber_opts = "features --format pretty"
15
15
  end
16
-
17
- task :default => [:spec, :features]
18
-
data/agent_cooper.gemspec CHANGED
@@ -15,22 +15,21 @@ Gem::Specification.new do |s|
15
15
  s.rubyforge_project = "agent_cooper"
16
16
 
17
17
  {
18
- 'httparty' => '~> 0.7.7',
19
- 'nokogiri' => '~> 1.4.4'
18
+ 'httpclient' => '~> 2.2',
19
+ 'nokogiri' => '~> 1.4'
20
20
  }.each {|lib, version| s.add_runtime_dependency lib, version }
21
-
22
-
21
+
22
+
23
23
  {
24
- 'bundler' => '~> 1.0.0',
25
- 'addressable' => '2.2.4',
26
- 'cucumber' => '~> 0.10.0',
27
- 'rake' => '~> 0.8.7',
28
- 'relish' => '~> 0.3.0.pre',
29
- 'rspec' => '~> 2.5.0',
30
- 'vcr' => '~> 1.9.0',
31
- 'webmock' => '~> 1.6.0'
24
+ 'cucumber' => '~> 1.0',
25
+ 'em-http-request' => '~> 1.0.0.beta.4',
26
+ 'em-synchrony' => '~> 0.3.0.beta.1',
27
+ 'rake' => '~> 0.9',
28
+ 'rspec' => '~> 2.6',
29
+ 'vcr' => '~> 1.10',
30
+ 'webmock' => '~> 1.6'
32
31
  }.each {|lib, version| s.add_development_dependency lib, version }
33
-
32
+
34
33
  s.files = `git ls-files`.split("\n")
35
34
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
36
35
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -1,9 +1,9 @@
1
1
  Feature: Ebay Finder
2
2
  As an API consumer
3
3
 
4
- Background:
4
+ Background:
5
5
  Given a new finder request
6
-
6
+
7
7
  Scenario: getSearchKeywordsRecommendation
8
8
  Given the following parameters:
9
9
  | OPERATION-NAME | keywords |
@@ -11,7 +11,7 @@ Feature: Ebay Finder
11
11
  When I tape the "finder" request as: "get_search_keywords_recommendation"
12
12
  Then the response code should be "200"
13
13
  And the response should have 1 "keywords" nodes
14
-
14
+
15
15
  Scenario: findItemsByKeywords
16
16
  Given the following parameters:
17
17
  | OPERATION-NAME | keywords |
@@ -27,7 +27,7 @@ Feature: Ebay Finder
27
27
  When I tape the "finder" request as: "find_items_by_category"
28
28
  Then the response code should be "200"
29
29
  And the response should have 100 "item" nodes
30
-
30
+
31
31
  Scenario: findItemsAdvanced
32
32
  Given the following parameters:
33
33
  | OPERATION-NAME | keywords |
@@ -60,5 +60,3 @@ Feature: Ebay Finder
60
60
  When I tape the "finder" request as: "get_histograms"
61
61
  Then the response code should be "200"
62
62
  And the response should have 6 "childCategoryHistogram" nodes
63
-
64
-
@@ -1,7 +1,7 @@
1
1
  Feature: Ebay Merchandiser
2
2
  As an API consumer
3
3
 
4
- Background:
4
+ Background:
5
5
  Given a new merchandiser request
6
6
 
7
7
  Scenario: getMostWatchedItems
@@ -31,4 +31,3 @@ Feature: Ebay Merchandiser
31
31
  | getTopSellingProducts | 3 |
32
32
  When I tape the "merchandiser" request as: "get_top_selling_products"
33
33
  Then the response code should be "200"
34
-
@@ -1,9 +1,9 @@
1
1
  Feature: Ebay Shopper
2
2
  As an API consumer
3
3
 
4
- Background:
4
+ Background:
5
5
  Given a new shopper request
6
-
6
+
7
7
  Scenario: FindProducts
8
8
  Given the following parameters:
9
9
  | CALLNAME | QueryKeywords |
@@ -4,9 +4,9 @@ require 'digest/md5'
4
4
  require 'agent_cooper'
5
5
 
6
6
 
7
- module AgentCooperMethods
7
+ module AgentCooperMethods
8
8
  def ebay
9
- @ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/support/ebay.yml")
9
+ @ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/fixtures/ebay.yml")
10
10
  end
11
11
 
12
12
  def ebay_app_id
@@ -14,14 +14,14 @@ module AgentCooperMethods
14
14
  end
15
15
 
16
16
  def cassette_name
17
- Digest::MD5.hexdigest(@request.options.to_json)
17
+ Digest::MD5.hexdigest(@request.parameters.to_json)
18
18
  end
19
19
  end
20
20
 
21
21
  World(AgentCooperMethods)
22
22
 
23
23
  Before do
24
- AgentCooper::Config.set do |config|
25
- config.app_id = 'SOME_OBSCURE_APP_ID'
24
+ AgentCooper.configure do |config|
25
+ config.app_id = ebay_app_id
26
26
  end
27
27
  end
@@ -1,9 +1,19 @@
1
1
  require 'vcr'
2
2
 
3
+ def ebay
4
+ @ebay ||= YAML::load_file(File.dirname(__FILE__) + "/../../spec/fixtures/ebay.yml")
5
+ end
6
+
7
+ def ebay_app_id
8
+ ebay['app_id']
9
+ end
10
+
11
+
3
12
  VCR.config do |c|
4
13
  c.cassette_library_dir = File.dirname(__FILE__) + '/../../spec/fixtures/cassettes'
5
14
  c.default_cassette_options = {
6
15
  :record => :none,
7
16
  :match_requests_on => [:host] }
8
17
  c.stub_with :webmock
18
+ c.filter_sensitive_data('YOUR-APP-ID') { ebay_app_id }
9
19
  end
data/lib/agent_cooper.rb CHANGED
@@ -1,9 +1,22 @@
1
+ # Utilities
1
2
  require 'agent_cooper/config'
2
- require 'agent_cooper/request'
3
3
  require 'agent_cooper/response'
4
- require 'agent_cooper/finder'
5
- require 'agent_cooper/shopper'
6
- require 'agent_cooper/merchandiser'
4
+ require 'agent_cooper/request'
5
+
6
+ require 'agent_cooper/nokogiri_decorator'
7
+
8
+ # Requests
9
+ require 'agent_cooper/requests/finder'
10
+ require 'agent_cooper/requests/shopper'
11
+ require 'agent_cooper/requests/merchandiser'
12
+
13
+ #Version
14
+ require "agent_cooper/version"
7
15
 
8
16
  module AgentCooper
17
+ class << self
18
+ def configure(&block)
19
+ Config.configure(&block)
20
+ end
21
+ end
9
22
  end
@@ -1,16 +1,10 @@
1
1
  module AgentCooper
2
2
  class Config
3
3
  class << self
4
- def set(&block)
5
- yield self
6
- end
4
+ attr_accessor :app_id
7
5
 
8
- def app_id=(app_id)
9
- @@app_id = app_id
10
- end
11
-
12
- def app_id
13
- @@app_id ||= nil
6
+ def configure(&block)
7
+ yield self
14
8
  end
15
9
  end
16
10
  end
@@ -0,0 +1,47 @@
1
+ module AgentCooper
2
+
3
+ # Based on https://gist.github.com/335286
4
+
5
+ class Nokogiri::XML::Document
6
+ def to_hash
7
+ root.to_hash
8
+ end
9
+ end
10
+
11
+ class Nokogiri::XML::Element
12
+ def to_hash
13
+ ({}).tap do |hash|
14
+
15
+ attributes.each_pair do |key, attribute|
16
+ hash[key] = attribute.value
17
+ end
18
+
19
+ children.each do |child|
20
+ result = child.to_hash
21
+
22
+ if child.name == 'text'
23
+ if hash.empty?
24
+ return result
25
+ else
26
+ hash['__content__'] = result
27
+ end
28
+ elsif hash[child.name]
29
+ if hash[child.name].is_a?(Array)
30
+ hash[child.name] << result
31
+ else
32
+ hash[child.name] = [hash[child.name]] << result
33
+ end
34
+ else
35
+ hash[child.name] = result
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ class Nokogiri::XML::Text
43
+ def to_hash
44
+ content.to_s
45
+ end
46
+ end
47
+ end
@@ -1,30 +1,53 @@
1
- require 'httparty'
1
+ require 'forwardable'
2
+ require 'httpclient'
3
+ require 'cgi'
2
4
 
3
5
  module AgentCooper
4
6
  class Request
5
7
 
8
+ extend Forwardable
9
+
10
+ def_delegators :@config, :app_id
11
+
6
12
  ENCODING = 'XML'
7
13
 
8
- include HTTParty
9
- format :xml
14
+ def initialize
15
+ @config = Config
16
+ end
10
17
 
11
- attr_accessor :locale
18
+ def adapter
19
+ @adapter ||= HTTPClient.new
20
+ end
12
21
 
13
- def options
14
- @options ||= {}
22
+ def get
23
+ response = adapter.get(url)
24
+ Response.new(response)
15
25
  end
16
26
 
17
- def <<(hash)
18
- options.merge!(hash)
27
+ def url
28
+ URI::HTTP.build(
29
+ :host => host,
30
+ :path => path,
31
+ :query => query
32
+ )
19
33
  end
20
34
 
21
- def reset!
22
- @options = {}
35
+ def query
36
+ query = default_parameters.merge(parameters)
37
+
38
+ query.collect {|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"} * '&'
23
39
  end
24
40
 
25
- def get
26
- r = self.class.get(path, :query => options.merge(credentials))
27
- Response.new(r)
41
+ def parameters
42
+ @parameters ||= {}
43
+ end
44
+
45
+ def <<(hash)
46
+ parameters.merge!(hash)
47
+ end
48
+
49
+ def reset!
50
+ @parameters = {}
28
51
  end
29
52
  end
30
53
  end
@@ -0,0 +1,25 @@
1
+ module AgentCooper
2
+ class Finder < Request
3
+
4
+ VERSION = '1.9.0'
5
+
6
+ def host
7
+ 'svcs.ebay.com'
8
+ end
9
+
10
+
11
+ def path
12
+ '/services/search/FindingService/v1'
13
+ end
14
+
15
+ def default_parameters
16
+ {
17
+ 'SECURITY-APPNAME' => app_id,
18
+ 'SECURITY-VERSION' => VERSION,
19
+ 'RESPONSE-DATA-FORMAT' => ENCODING,
20
+ 'REST-PAYLOAD' => ''
21
+ }
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module AgentCooper
2
+ class Merchandiser < Request
3
+
4
+ SERVICE_NAME = 'MerchandisingService'
5
+ VERSION = '1.4.0'
6
+
7
+ def host
8
+ 'svcs.ebay.com'
9
+ end
10
+
11
+ def path
12
+ '/MerchandisingService'
13
+ end
14
+
15
+ def default_parameters
16
+ {
17
+ 'CONSUMER-ID' => app_id,
18
+ 'SERVICE-NAME' => SERVICE_NAME,
19
+ 'SERVICE-VERSION' => VERSION,
20
+ 'RESPONSE-DATA-FORMAT' => ENCODING,
21
+ 'REST-PAYLOAD' => ''
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module AgentCooper
2
+ class Shopper < Request
3
+
4
+ VERSION = '717'
5
+
6
+ def host
7
+ 'open.api.ebay.com'
8
+ end
9
+
10
+ def path
11
+ '/shopping'
12
+ end
13
+
14
+ def default_parameters
15
+ {
16
+ 'APPID' => app_id,
17
+ 'RESPONSEENCODING' => ENCODING,
18
+ 'VERSION' => VERSION,
19
+ 'SITEID' => 0
20
+ }
21
+ end
22
+ end
23
+ end