gun_broker 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 263f58913c30a8bc6cd92e93f7639764e36d5419
4
- data.tar.gz: b81f8988a611e475e3d0c2c5dba5ab27f2d77493
3
+ metadata.gz: ee763dfd6dc989b4a508ba5e8024dfc31a0a2451
4
+ data.tar.gz: 114c9fc33eb2b8ed81dd4a68abbea813379f1b93
5
5
  SHA512:
6
- metadata.gz: 75d66025a4a1678065a866fd879edb113b5662a4fe02f99dbfa7cc13d41b4149397ca8f0e56721497a4b7e2625a72c9b7f776e59e33d64e0d77b03c60d888ce6
7
- data.tar.gz: 7e3283d6755afd90d704bdbd502e495e9b00458875c4d4b2b6517de0197b43de23bcf02c62057a6ea243524452d11374bfa4591d8c78c94062cf421e0e8cecf1
6
+ metadata.gz: 2c3513dbaefad16934c3e9e96ac569ac8cc5fbd78f8ea1adbb16b910d2e9e46b204d96a58b90eefd5f40f18ab32e88cfecea9a966b2361bdf536b1cb28bd788b
7
+ data.tar.gz: f327aa604e32522f398582b516e0f37e48924a10849df6cda7b7d713757f357f75614691a5ec34a42fc37c77c277a48d9240cfc2821c0414f2f33be1bc700ec4
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --title "GunBroker API Documentation"
2
+ --readme README.md
3
+ --markup markdown
data/README.md CHANGED
@@ -20,6 +20,10 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
+ ### Documentation
24
+
25
+ The full documentation is located here: http://www.rubydoc.info/gems/gun_broker
26
+
23
27
  ### Developer Token
24
28
 
25
29
  You **must** set a developer key obtained from GunBroker.com in order to use this library.
@@ -49,9 +53,10 @@ Once the User has an access token, you can then grab all of their items (listing
49
53
  return an array of `GunBroker::Item` instances.
50
54
 
51
55
  ```ruby
52
- user.items # => [GunBroker::Item, ...]
53
- user.items_unsold # => [GunBroker::Item, ...]
54
- user.items_sold # => [GunBroker::Item, ...]
56
+ user.items.all # => [GunBroker::Item, ...]
57
+ user.items.unsold # => [GunBroker::Item, ...]
58
+ user.items.sold # => [GunBroker::Item, ...]
59
+ user.items.won # => [GunBroker::Item, ...]
55
60
  ```
56
61
 
57
62
  To revoke the access token, call `User#deauthenticate!`. This method is also aliased as `#revoke_access_token!`.
data/Rakefile CHANGED
@@ -1,7 +1,20 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
+ require 'yard'
3
4
 
4
5
  task :default => :spec
5
6
 
6
7
  desc 'Run the specs'
7
8
  RSpec::Core::RakeTask.new(:spec)
9
+
10
+ desc 'Generate API docs'
11
+ YARD::Rake::YardocTask.new(:docs) do |t|
12
+ t.files = ['lib/**/*.rb']
13
+ end
14
+
15
+ namespace :docs do
16
+ desc 'Run the docs server'
17
+ task :server do
18
+ $stdout.puts `yard server --reload --bind 0.0.0.0`
19
+ end
20
+ end
data/gun_broker.gemspec CHANGED
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec", "~> 3.1"
24
24
  spec.add_development_dependency "webmock", "~> 1.20"
25
+ spec.add_development_dependency "yard", "~> 0.8"
25
26
  end
data/lib/gun_broker.rb CHANGED
@@ -4,16 +4,22 @@ require 'gun_broker/api'
4
4
  require 'gun_broker/category'
5
5
  require 'gun_broker/error'
6
6
  require 'gun_broker/item'
7
+ require 'gun_broker/items_delegate'
7
8
  require 'gun_broker/user'
8
9
 
9
10
  module GunBroker
10
11
 
12
+ # Sets the developer key obtained from GunBroker.com.
13
+ # @param dev_key [String]
11
14
  def self.dev_key=(dev_key)
12
15
  @@dev_key = dev_key
13
16
  end
14
17
 
18
+ # Returns the set developer key, or raises GunBroker::Error if not set.
19
+ # @raise [GunBroker::Error] If the {.dev_key} has not been set.
20
+ # @return [String] The developer key.
15
21
  def self.dev_key
16
- raise 'GunBroker developer key not set.' unless dev_key_present?
22
+ raise GunBroker::Error.new('GunBroker developer key not set.') unless dev_key_present?
17
23
  @@dev_key
18
24
  end
19
25
 
@@ -2,10 +2,15 @@ require 'json'
2
2
  require 'net/https'
3
3
 
4
4
  module GunBroker
5
+ # Generic REST adapter for the GunBroker API.
5
6
  class API
6
7
 
8
+ # Root URL of the GunBroker API.
7
9
  GUNBROKER_API = 'https://api.gunbroker.com/v1'
8
10
 
11
+ # @param path [String] The requested API endpoint.
12
+ # @param params [Hash] (optional) URL params for GET requests; form params for POST request.
13
+ # @param headers [Hash] (optional) Additional headers sent with the request.
9
14
  def initialize(path, params = {}, headers = {})
10
15
  raise "Path must start with '/': #{path}" unless path.start_with?('/')
11
16
 
@@ -14,24 +19,32 @@ module GunBroker
14
19
  @headers = headers
15
20
  end
16
21
 
22
+ # Wrapper for {GunBroker::API#delete! `new(*args).delete!`}
23
+ # @param *args Splat arguments passed to {#initialize}.
17
24
  def self.delete(*args)
18
25
  new(*args).delete!
19
26
  end
20
27
 
28
+ # Wrapper for {GunBroker::API#get! `new(*args).get!`}
29
+ # @param *args Splat arguments passed to {#initialize}.
21
30
  def self.get(*args)
22
31
  new(*args).get!
23
32
  end
24
33
 
34
+ # Wrapper for {GunBroker::API#post! `new(*args).post!`}
35
+ # @param *args Splat arguments passed to {#initialize}.
25
36
  def self.post(*args)
26
37
  new(*args).post!
27
38
  end
28
39
 
40
+ # Sends a DELETE request to the given `path`.
29
41
  def delete!
30
42
  request = Net::HTTP::Delete.new(uri)
31
43
  response = get_response(request)
32
44
  handle_response(response)
33
45
  end
34
46
 
47
+ # Sends a GET request to the given `path`.
35
48
  def get!
36
49
  uri.query = URI.encode_www_form(@params)
37
50
 
@@ -40,6 +53,7 @@ module GunBroker
40
53
  handle_response(response)
41
54
  end
42
55
 
56
+ # Sends a POST request to the given `path`.
43
57
  def post!
44
58
  request = Net::HTTP::Post.new(uri)
45
59
  request.body = @params.to_json
@@ -1,25 +1,38 @@
1
1
  module GunBroker
2
+ # Represents a GunBroker category.
2
3
  class Category
3
4
 
4
5
  # The top-level category ID.
5
6
  ROOT_CATEGORY_ID = 0
6
7
 
8
+ # @param parent [Integer, String] (optional) Return all subcategories of the given parent Category ID; defaults to the root (top-level) categories.
9
+ # @return [Array<Category>] An array of GunBroker::Category instances.
7
10
  def self.all(parent = ROOT_CATEGORY_ID)
8
11
  response = GunBroker::API.get('/Categories', { 'ParentCategoryID' => parent })
9
12
  response['results'].map { |attrs| new(attrs) }
10
13
  end
11
14
 
15
+ # @param category_id [Integer, String] The ID of the Category to find.
16
+ # @return [Category] A Category instance.
12
17
  def self.find(category_id)
13
18
  new(GunBroker::API.get("/Categories/#{category_id}"))
14
19
  end
15
20
 
21
+ # @param attrs [Hash] The JSON attributes from the API response.
16
22
  def initialize(attrs = {})
17
23
  @attrs = attrs
18
24
  end
19
25
 
26
+ # @return [Integer] The Category ID.
20
27
  def id
21
28
  @attrs['categoryID']
22
29
  end
23
30
 
31
+ # @param key [String] A Category attribute name (from the JSON response).
32
+ # @return The value of the given `key` or `nil`.
33
+ def [](key)
34
+ @attrs[key]
35
+ end
36
+
24
37
  end
25
38
  end
@@ -2,6 +2,7 @@ module GunBroker
2
2
  class Error < StandardError
3
3
 
4
4
  class NotAuthorized < GunBroker::Error; end
5
+ class NotFound < GunBroker::Error; end
5
6
  class RequestError < GunBroker::Error; end
6
7
 
7
8
  end
@@ -1,14 +1,25 @@
1
1
  module GunBroker
2
+ # Represents a GunBroker item (listing).
2
3
  class Item
3
4
 
5
+ # @param item_id [Integer, String] The ID of the Item to find.
6
+ # @return [Item] An Item instance.
7
+ def self.find(item_id)
8
+ new(GunBroker::API.get("/Items/#{item_id}"))
9
+ end
10
+
11
+ # @param attrs [Hash] The JSON attributes from the API response.
4
12
  def initialize(attrs = {})
5
13
  @attrs = attrs
6
14
  end
7
15
 
16
+ # @return [Integer] The Item ID.
8
17
  def id
9
18
  @attrs['itemID']
10
19
  end
11
20
 
21
+ # @param key [String] An Item attribute name (from the JSON response).
22
+ # @return The value of the given `key` or `nil`.
12
23
  def [](key)
13
24
  @attrs[key]
14
25
  end
@@ -0,0 +1,98 @@
1
+ require 'gun_broker/token_header'
2
+
3
+ module GunBroker
4
+ # Used to scope {Item} lookup by {User}.
5
+ class ItemsDelegate
6
+
7
+ include GunBroker::TokenHeader
8
+
9
+ # @param user [User] A {User} instance to scope items by.
10
+ def initialize(user)
11
+ @user = user
12
+ end
13
+
14
+ # Returns all the User's items.
15
+ # @note {API#get! GET} /Items
16
+ # @raise [GunBroker::Error::NotAuthorized] If the {User#token} isn't valid.
17
+ # @raise [GunBroker::Error::RequestError] If there's an issue with the request (usually a `5xx` response).
18
+ # @return [Array<Item>]
19
+ def all
20
+ response = GunBroker::API.get('/Items', { 'SellerName' => @user.username }, token_header(@user.token))
21
+ items_from_results(response['results'])
22
+ end
23
+
24
+ # Returns all the items the User has bid on.
25
+ # @note {API#get! GET} /ItemsBidOn
26
+ # @raise (see #all)
27
+ # @return [Array<Item>]
28
+ def bid_on
29
+ response = GunBroker::API.get('/ItemsBidOn', {}, token_header(@user.token))
30
+ items_from_results(response['results'])
31
+ end
32
+
33
+ # Finds a specific User's Item by ID. Calls {Item.find} to get full Item details.
34
+ # @raise (see #all)
35
+ # @return [Item] Returns the Item or `nil` if no Item found.
36
+ def find(item_id)
37
+ # HACK: This has to filter through `#all`, since the GunBroker API currently has no way to scope the `/Items/{itemID}` endpoint by user.
38
+ if all.select { |item| item.id.to_s == item_id.to_s }.first
39
+ GunBroker::Item.find(item_id)
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ # Same as {#find} but raises GunBroker::Error::NotFound if no item is found.
46
+ # @raise (see #all)
47
+ # @raise [GunBroker::Error::NotFound] If the User has no Item with `item_id`.
48
+ # @return [Item] Returns the Item or `nil` if no Item found.
49
+ def find!(item_id)
50
+ item = find(item_id)
51
+ raise GunBroker::Error::NotFound.new("Couldn't find item with ID '#{item_id}'") if item.nil?
52
+ item
53
+ end
54
+
55
+ # Items the User has bid on, but not won.
56
+ # @note {API#get! GET} /ItemsNotWon
57
+ # @raise (see #all)
58
+ # @return [Array<Item>]
59
+ def not_won
60
+ response = GunBroker::API.get('/ItemsNotWon', {}, token_header(@user.token))
61
+ items_from_results(response['results'])
62
+ end
63
+
64
+ # Items the User has sold.
65
+ # @note {API#get! GET} /ItemsSold
66
+ # @raise (see #all)
67
+ # @return [Array<Item>]
68
+ def sold
69
+ response = GunBroker::API.get('/ItemsSold', {}, token_header(@user.token))
70
+ items_from_results(response['results'])
71
+ end
72
+
73
+ # Items that were listed, but not sold.
74
+ # @note {API#get! GET} /ItemsUnsold
75
+ # @raise (see #all)
76
+ # @return [Array<Item>]
77
+ def unsold
78
+ response = GunBroker::API.get('/ItemsUnsold', {}, token_header(@user.token))
79
+ items_from_results(response['results'])
80
+ end
81
+
82
+ # Items the User has won.
83
+ # @note {API#get! GET} /ItemsWon
84
+ # @raise (see #all)
85
+ # @return [Array<Item>]
86
+ def won
87
+ response = GunBroker::API.get('/ItemsWon', {}, token_header(@user.token))
88
+ items_from_results(response['results'])
89
+ end
90
+
91
+ private
92
+
93
+ def items_from_results(results)
94
+ results.map { |result| GunBroker::Item.new(result) }
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,13 @@
1
+ module GunBroker
2
+ # Holds helper methods dealing with a User's {User#token access token}.
3
+ module TokenHeader
4
+
5
+ protected
6
+
7
+ def token_header(token)
8
+ raise GunBroker::Error.new("No token given.") if token.nil?
9
+ { 'X-AccessToken' => token }
10
+ end
11
+
12
+ end
13
+ end
@@ -1,41 +1,61 @@
1
+ require 'gun_broker/token_header'
2
+
1
3
  module GunBroker
4
+ # Represents a GunBroker User.
2
5
  class User
3
6
 
7
+ include GunBroker::TokenHeader
8
+
9
+ # @return [String] The User's GunBroker.com username.
4
10
  attr_reader :username
11
+
12
+ # @return [String] The User's GunBroker access token obtained by calling {#authenticate!} or `nil` if not authenticated.
5
13
  attr_reader :token
6
14
 
15
+ # @param username [String]
16
+ # @param auth_options [Hash] Requires either a `:password` or `:token`.
17
+ # @option auth_options [String] :password The User's GunBroker.com password.
18
+ # @option auth_options [String] :token An existing access token previously obtained by calling {#authenticate!} with a username/password.
7
19
  def initialize(username, auth_options = {})
8
20
  @username = username
9
21
  @password = auth_options[:password] || auth_options['password']
10
22
  @token = auth_options[:token] || auth_options['token']
11
23
  end
12
24
 
25
+ # Authenticates with the GunBroker API server and saves the returned access {#token}.
26
+ # @note {API#post! POST} /Users/AccessToken
27
+ # @raise [GunBroker::Error::NotAuthorized] If the username/password is invalid.
28
+ # @raise [GunBroker::Error::RequestError] If there's an issue with the request (usually a `5xx` response).
29
+ # @return [String] The access {#token} used in subsequent requests.
13
30
  def authenticate!
14
31
  response = GunBroker::API.post('/Users/AccessToken', { username: @username, password: @password })
15
32
  @token = response['accessToken']
16
33
  end
17
34
 
18
- # Sends a DELETE request to deactivate the current access token.
35
+ # Sends a DELETE request to deactivate the current access {#token}.
36
+ # @note {API#delete! DELETE} /Users/AccessToken
37
+ # @raise [GunBroker::Error::RequestError] If there's an issue with the request (usually a `5xx` response).
38
+ # @return [true] Explicitly returns `true` unless an exception is raised.
19
39
  def deauthenticate!
20
- GunBroker::API.delete('/Users/AccessToken', {}, { 'X-AccessToken' => @token })
40
+ GunBroker::API.delete('/Users/AccessToken', {}, token_header(@token))
21
41
  @token = nil
22
42
  true # Explicit `true` so this method won't return the `nil` set above.
23
43
  end
24
44
  alias_method :revoke_access_token!, :deauthenticate!
25
45
 
26
- def items
27
- response = GunBroker::API.get('/Items', { 'SellerName' => @username }, { 'X-AccessToken' => @token })
28
- response['results'].map { |result| GunBroker::Item.new(result) }
46
+ # Returns the User's contact information.
47
+ # @note {API#get! GET} /Users/ContactInfo
48
+ # @raise [GunBroker::Error::RequestError] If there's an issue with the request (usually a `5xx` response).
49
+ # @return [Hash] From the JSON response.
50
+ def contact_info
51
+ GunBroker::API.get('/Users/ContactInfo', { 'UserName' => @username }, token_header(@token))
29
52
  end
30
53
 
31
- def items_unsold
32
- response = GunBroker::API.get('/ItemsUnsold', {}, { 'X-AccessToken' => @token })
33
- response['results'].map { |result| GunBroker::Item.new(result) }
34
- end
35
-
36
- def items_sold
37
- response = GunBroker::API.get('/ItemsSold', {}, { 'X-AccessToken' => @token })
38
- response['results'].map { |result| GunBroker::Item.new(result) }
54
+ # (see ItemsDelegate)
55
+ # See the {ItemsDelegate} docs.
56
+ # @return [ItemsDelegate]
57
+ def items
58
+ ItemsDelegate.new(self)
39
59
  end
40
60
 
41
61
  end
@@ -1,3 +1,3 @@
1
1
  module GunBroker
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -0,0 +1 @@
1
+ {"userID":12345,"userName":"test-user","firstName":"Test","lastName":"User","address1":"123 Main St.","address2":null,"city":"Sometown","state":"SC","postalCode":"12345","countryCode":"US","phone":"123-456-7890","alternatePhone":"","faxPhone":"","email":"test.user@example.com","companyName":"","isBusinessAddress":false,"links":[]}
@@ -17,6 +17,13 @@ describe GunBroker::Category do
17
17
  expect(category.id).to eq(attrs['categoryID'])
18
18
  end
19
19
 
20
+ context '#[]' do
21
+ it 'should return the value from @attrs' do
22
+ category = GunBroker::Category.new(attrs)
23
+ attrs.each { |k, v| expect(category[k]).to eq(v) }
24
+ end
25
+ end
26
+
20
27
  context '.all' do
21
28
  let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/Categories'].join }
22
29
 
@@ -16,4 +16,32 @@ describe GunBroker::Item do
16
16
  end
17
17
  end
18
18
 
19
+ context '.find' do
20
+ let(:attrs) { JSON.parse(response_fixture('item')) }
21
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, "/Items/#{attrs['itemID']}"].join }
22
+
23
+ context 'on success' do
24
+ it 'returns an Item' do
25
+ stub_request(:get, endpoint)
26
+ .with(headers: headers)
27
+ .to_return(body: response_fixture('item'))
28
+
29
+ id = attrs['itemID']
30
+ item = GunBroker::Item.find(id)
31
+ expect(item).to be_a(GunBroker::Item)
32
+ expect(item.id).to eq(id)
33
+ end
34
+ end
35
+
36
+ context 'on failure' do
37
+ it 'should raise an exception' do
38
+ stub_request(:get, endpoint)
39
+ .with(headers: headers)
40
+ .to_return(body: response_fixture('empty'), status: 404)
41
+
42
+ expect { GunBroker::Item.find(attrs['itemID']) }.to raise_error(GunBroker::Error::RequestError)
43
+ end
44
+ end
45
+ end
46
+
19
47
  end
@@ -0,0 +1,236 @@
1
+ require 'spec_helper'
2
+
3
+ describe GunBroker::ItemsDelegate do
4
+ let(:username) { 'test-user' }
5
+ let(:token) { 'test-user-access-token' }
6
+
7
+ let(:user) { GunBroker::User.new(username, token: token) }
8
+ let(:delegate) { GunBroker::ItemsDelegate.new(user) }
9
+
10
+ context '#all' do
11
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/Items'].join }
12
+
13
+ context 'on success' do
14
+ it 'returns the User items' do
15
+ stub_request(:get, endpoint)
16
+ .with(
17
+ headers: headers('X-AccessToken' => token),
18
+ query: { 'SellerName' => user.username }
19
+ )
20
+ .to_return(body: response_fixture('items'))
21
+
22
+ expect(delegate.all).not_to be_empty
23
+ expect(delegate.all.first).to be_a(GunBroker::Item)
24
+ end
25
+ end
26
+
27
+ context 'on failure' do
28
+ it 'should raise an exception' do
29
+ stub_request(:get, endpoint)
30
+ .with(
31
+ headers: headers('X-AccessToken' => token),
32
+ query: { 'SellerName' => user.username }
33
+ )
34
+ .to_return(body: response_fixture('not_authorized'), status: 401)
35
+
36
+ expect { delegate.all }.to raise_error(GunBroker::Error::NotAuthorized)
37
+ end
38
+ end
39
+ end
40
+
41
+ context '#bid_on' do
42
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsBidOn'].join }
43
+
44
+ context 'on success' do
45
+ it 'returns won Items' do
46
+ stub_request(:get, endpoint)
47
+ .with(headers: headers('X-AccessToken' => token))
48
+ .to_return(body: response_fixture('items'))
49
+
50
+ user = GunBroker::User.new(username, token: token)
51
+ expect(delegate.bid_on).not_to be_empty
52
+ expect(delegate.bid_on.first).to be_a(GunBroker::Item)
53
+ end
54
+ end
55
+
56
+ context 'on failure' do
57
+ it 'raises an exception' do
58
+ stub_request(:get, endpoint)
59
+ .with(headers: headers('X-AccessToken' => token))
60
+ .to_return(body: response_fixture('not_authorized'), status: 401)
61
+
62
+ user = GunBroker::User.new(username, token: token)
63
+ expect { delegate.bid_on }.to raise_error(GunBroker::Error::NotAuthorized)
64
+ end
65
+ end
66
+ end
67
+
68
+ context '#find' do
69
+ let(:attrs) { JSON.parse(response_fixture('item')) }
70
+ let(:all_endpoint) { [GunBroker::API::GUNBROKER_API, '/Items'].join }
71
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, "/Items/#{attrs['itemID']}"].join }
72
+
73
+ it 'returns a single Item' do
74
+ # First, stub the '/Items' request, since we have to use that to scope the Item find by user.
75
+ stub_request(:get, all_endpoint)
76
+ .with(
77
+ headers: headers('X-AccessToken' => token),
78
+ query: { 'SellerName' => user.username }
79
+ )
80
+ .to_return(body: response_fixture('items'))
81
+
82
+ # Now we stub the '/Items/:id' request.
83
+ stub_request(:get, endpoint)
84
+ .with(headers: headers)
85
+ .to_return(body: response_fixture('item'))
86
+
87
+ item = delegate.find(attrs['itemID'])
88
+ expect(item).to be_a(GunBroker::Item)
89
+ expect(item.id).to eq(attrs['itemID'])
90
+ end
91
+
92
+ it 'returns nil if no item found' do
93
+ stub_request(:get, all_endpoint)
94
+ .with(
95
+ headers: headers('X-AccessToken' => token),
96
+ query: { 'SellerName' => user.username }
97
+ )
98
+ .to_return(body: response_fixture('items'))
99
+
100
+ expect(delegate.find(666)).to be_nil
101
+ end
102
+ end
103
+
104
+ context '#find!' do
105
+ let(:all_endpoint) { [GunBroker::API::GUNBROKER_API, '/Items'].join }
106
+
107
+ it 'calls #find' do
108
+ item_id = 123
109
+ expect(delegate).to receive(:find).with(item_id).and_return(true)
110
+ delegate.find!(item_id)
111
+ end
112
+
113
+ it 'raises GunBroker::Error::NotFound if no item found' do
114
+ stub_request(:get, all_endpoint)
115
+ .with(
116
+ headers: headers('X-AccessToken' => token),
117
+ query: { 'SellerName' => user.username }
118
+ )
119
+ .to_return(body: response_fixture('items'))
120
+
121
+ item_id = 123
122
+ expect {
123
+ delegate.find!(item_id)
124
+ }.to raise_error(GunBroker::Error::NotFound)
125
+ end
126
+ end
127
+
128
+ context '#not_won' do
129
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsNotWon'].join }
130
+
131
+ context 'on success' do
132
+ it 'returns won Items' do
133
+ stub_request(:get, endpoint)
134
+ .with(headers: headers('X-AccessToken' => token))
135
+ .to_return(body: response_fixture('items'))
136
+
137
+ user = GunBroker::User.new(username, token: token)
138
+ expect(delegate.not_won).not_to be_empty
139
+ expect(delegate.not_won.first).to be_a(GunBroker::Item)
140
+ end
141
+ end
142
+
143
+ context 'on failure' do
144
+ it 'raises an exception' do
145
+ stub_request(:get, endpoint)
146
+ .with(headers: headers('X-AccessToken' => token))
147
+ .to_return(body: response_fixture('not_authorized'), status: 401)
148
+
149
+ user = GunBroker::User.new(username, token: token)
150
+ expect { delegate.not_won }.to raise_error(GunBroker::Error::NotAuthorized)
151
+ end
152
+ end
153
+ end
154
+
155
+ context '#sold' do
156
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsSold'].join }
157
+
158
+ context 'on success' do
159
+ it 'returns sold Items' do
160
+ stub_request(:get, endpoint)
161
+ .with(headers: headers('X-AccessToken' => token))
162
+ .to_return(body: response_fixture('items'))
163
+
164
+ user = GunBroker::User.new(username, token: token)
165
+ expect(delegate.sold).not_to be_empty
166
+ expect(delegate.sold.first).to be_a(GunBroker::Item)
167
+ end
168
+ end
169
+
170
+ context 'on failure' do
171
+ it 'raises an exception' do
172
+ stub_request(:get, endpoint)
173
+ .with(headers: headers('X-AccessToken' => token))
174
+ .to_return(body: response_fixture('not_authorized'), status: 401)
175
+
176
+ user = GunBroker::User.new(username, token: token)
177
+ expect { delegate.sold }.to raise_error(GunBroker::Error::NotAuthorized)
178
+ end
179
+ end
180
+ end
181
+
182
+ context '#unsold' do
183
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsUnsold'].join }
184
+
185
+ context 'on success' do
186
+ it 'returns unsold Items' do
187
+ stub_request(:get, endpoint)
188
+ .with(headers: headers('X-AccessToken' => token))
189
+ .to_return(body: response_fixture('items'))
190
+
191
+ user = GunBroker::User.new(username, token: token)
192
+ expect(delegate.unsold).not_to be_empty
193
+ expect(delegate.unsold.first).to be_a(GunBroker::Item)
194
+ end
195
+ end
196
+
197
+ context 'on failure' do
198
+ it 'raises an exception' do
199
+ stub_request(:get, endpoint)
200
+ .with(headers: headers('X-AccessToken' => token))
201
+ .to_return(body: response_fixture('not_authorized'), status: 401)
202
+
203
+ user = GunBroker::User.new(username, token: token)
204
+ expect { delegate.unsold }.to raise_error(GunBroker::Error::NotAuthorized)
205
+ end
206
+ end
207
+ end
208
+
209
+ context '#won' do
210
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsWon'].join }
211
+
212
+ context 'on success' do
213
+ it 'returns won Items' do
214
+ stub_request(:get, endpoint)
215
+ .with(headers: headers('X-AccessToken' => token))
216
+ .to_return(body: response_fixture('items'))
217
+
218
+ user = GunBroker::User.new(username, token: token)
219
+ expect(delegate.won).not_to be_empty
220
+ expect(delegate.won.first).to be_a(GunBroker::Item)
221
+ end
222
+ end
223
+
224
+ context 'on failure' do
225
+ it 'raises an exception' do
226
+ stub_request(:get, endpoint)
227
+ .with(headers: headers('X-AccessToken' => token))
228
+ .to_return(body: response_fixture('not_authorized'), status: 401)
229
+
230
+ user = GunBroker::User.new(username, token: token)
231
+ expect { delegate.won }.to raise_error(GunBroker::Error::NotAuthorized)
232
+ end
233
+ end
234
+ end
235
+
236
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe GunBroker::TokenHeader do
4
+
5
+ let(:mock_class) { (Class.new { include GunBroker::TokenHeader }).new }
6
+
7
+ context '#token_header' do
8
+ it 'returns the access token Hash' do
9
+ token = 'test-user-access-token'
10
+ header = { 'X-AccessToken' => token }
11
+ expect(mock_class.send(:token_header, token)).to eq(header)
12
+ end
13
+
14
+ it 'raises an exception if token is nil' do
15
+ expect {
16
+ mock_class.send(:token_header, nil)
17
+ }.to raise_error(GunBroker::Error)
18
+ end
19
+ end
20
+
21
+ end
@@ -23,6 +23,13 @@ describe GunBroker::User do
23
23
  end
24
24
  end
25
25
 
26
+ context '#token_header' do
27
+ it 'raises an error if @token nil' do
28
+ user = GunBroker::User.new(username, token: nil)
29
+ expect { user.items.all }.to raise_error(GunBroker::Error)
30
+ end
31
+ end
32
+
26
33
  context '#authenticate!' do
27
34
  let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/Users/AccessToken'].join }
28
35
 
@@ -96,90 +103,44 @@ describe GunBroker::User do
96
103
  end
97
104
  end
98
105
 
99
- context '#items' do
100
- let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/Items'].join }
106
+ context '#contact_info' do
107
+ let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/Users/ContactInfo'].join }
101
108
 
102
109
  context 'on success' do
103
- it 'returns the User items' do
104
- stub_request(:get, endpoint)
105
- .with(
106
- headers: headers('X-AccessToken' => token),
107
- query: { 'SellerName' => username }
108
- )
109
- .to_return(body: response_fixture('items'))
110
-
110
+ it 'returns a contact info hash' do
111
111
  user = GunBroker::User.new(username, token: token)
112
- expect(user.items).not_to be_empty
113
- expect(user.items.first).to be_a(GunBroker::Item)
114
- end
115
- end
116
112
 
117
- context 'on failure' do
118
- it 'should raise an exception' do
119
113
  stub_request(:get, endpoint)
120
114
  .with(
121
115
  headers: headers('X-AccessToken' => token),
122
- query: { 'SellerName' => username }
116
+ query: { 'UserName' => user.username }
123
117
  )
124
- .to_return(body: response_fixture('not_authorized'), status: 401)
125
-
126
- user = GunBroker::User.new(username, token: token)
127
- expect { user.items }.to raise_error(GunBroker::Error::NotAuthorized)
128
- end
129
- end
130
- end
131
-
132
- context '#items_unsold' do
133
- let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsUnsold'].join }
134
-
135
- context 'on success' do
136
- it 'returns unsold Items' do
137
- stub_request(:get, endpoint)
138
- .with(headers: headers('X-AccessToken' => token))
139
- .to_return(body: response_fixture('items'))
118
+ .to_return(body: response_fixture('contact_info'))
140
119
 
141
- user = GunBroker::User.new(username, token: token)
142
- expect(user.items_unsold).not_to be_empty
143
- expect(user.items_unsold.first).to be_a(GunBroker::Item)
120
+ expect(user.contact_info).to eq(JSON.parse(response_fixture('contact_info')))
144
121
  end
145
122
  end
146
123
 
147
124
  context 'on failure' do
148
125
  it 'raises an exception' do
149
- stub_request(:get, endpoint)
150
- .with(headers: headers('X-AccessToken' => token))
151
- .to_return(body: response_fixture('not_authorized'), status: 401)
152
-
153
126
  user = GunBroker::User.new(username, token: token)
154
- expect { user.items_unsold }.to raise_error(GunBroker::Error::NotAuthorized)
155
- end
156
- end
157
- end
158
-
159
- context '#items_sold' do
160
- let(:endpoint) { [GunBroker::API::GUNBROKER_API, '/ItemsSold'].join }
161
127
 
162
- context 'on success' do
163
- it 'returns sold Items' do
164
128
  stub_request(:get, endpoint)
165
- .with(headers: headers('X-AccessToken' => token))
166
- .to_return(body: response_fixture('items'))
129
+ .with(
130
+ headers: headers('X-AccessToken' => token),
131
+ query: { 'UserName' => user.username }
132
+ )
133
+ .to_return(body: response_fixture('empty'), status: 401)
167
134
 
168
- user = GunBroker::User.new(username, token: token)
169
- expect(user.items_sold).not_to be_empty
170
- expect(user.items_sold.first).to be_a(GunBroker::Item)
135
+ expect { user.contact_info }.to raise_error(GunBroker::Error::NotAuthorized)
171
136
  end
172
137
  end
138
+ end
173
139
 
174
- context 'on failure' do
175
- it 'raises an exception' do
176
- stub_request(:get, endpoint)
177
- .with(headers: headers('X-AccessToken' => token))
178
- .to_return(body: response_fixture('not_authorized'), status: 401)
179
-
180
- user = GunBroker::User.new(username, token: token)
181
- expect { user.items_sold }.to raise_error(GunBroker::Error::NotAuthorized)
182
- end
140
+ context '#items' do
141
+ it 'should return an ItemsDelegate instance' do
142
+ user = GunBroker::User.new(username, token: token)
143
+ expect(user.items).to be_a(GunBroker::ItemsDelegate)
183
144
  end
184
145
  end
185
146
 
@@ -18,6 +18,11 @@ describe GunBroker do
18
18
  GunBroker.dev_key = key
19
19
  expect(GunBroker.dev_key).to eq(key)
20
20
  end
21
+
22
+ it 'raises an exception if @@dev_key is nil' do
23
+ GunBroker.class_variable_set(:@@dev_key, nil)
24
+ expect { GunBroker.dev_key }.to raise_error(GunBroker::Error)
25
+ end
21
26
  end
22
27
 
23
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gun_broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Campbell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-31 00:00:00.000000000 Z
11
+ date: 2015-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.20'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.8'
69
83
  description: ''
70
84
  email:
71
85
  - oshuma@gmail.com
@@ -77,6 +91,7 @@ files:
77
91
  - .rspec
78
92
  - .ruby-gemset
79
93
  - .ruby-version
94
+ - .yardopts
80
95
  - Gemfile
81
96
  - LICENSE.txt
82
97
  - README.md
@@ -87,11 +102,14 @@ files:
87
102
  - lib/gun_broker/category.rb
88
103
  - lib/gun_broker/error.rb
89
104
  - lib/gun_broker/item.rb
105
+ - lib/gun_broker/items_delegate.rb
106
+ - lib/gun_broker/token_header.rb
90
107
  - lib/gun_broker/user.rb
91
108
  - lib/gun_broker/version.rb
92
109
  - spec/fixtures/authenticate.json
93
110
  - spec/fixtures/categories.json
94
111
  - spec/fixtures/category.json
112
+ - spec/fixtures/contact_info.json
95
113
  - spec/fixtures/deauthenticate.json
96
114
  - spec/fixtures/empty.json
97
115
  - spec/fixtures/item.json
@@ -100,6 +118,8 @@ files:
100
118
  - spec/gun_broker/api_spec.rb
101
119
  - spec/gun_broker/category_spec.rb
102
120
  - spec/gun_broker/item_spec.rb
121
+ - spec/gun_broker/items_delegate_spec.rb
122
+ - spec/gun_broker/token_header_spec.rb
103
123
  - spec/gun_broker/user_spec.rb
104
124
  - spec/gun_broker_spec.rb
105
125
  - spec/spec_helper.rb
@@ -133,6 +153,7 @@ test_files:
133
153
  - spec/fixtures/authenticate.json
134
154
  - spec/fixtures/categories.json
135
155
  - spec/fixtures/category.json
156
+ - spec/fixtures/contact_info.json
136
157
  - spec/fixtures/deauthenticate.json
137
158
  - spec/fixtures/empty.json
138
159
  - spec/fixtures/item.json
@@ -141,8 +162,11 @@ test_files:
141
162
  - spec/gun_broker/api_spec.rb
142
163
  - spec/gun_broker/category_spec.rb
143
164
  - spec/gun_broker/item_spec.rb
165
+ - spec/gun_broker/items_delegate_spec.rb
166
+ - spec/gun_broker/token_header_spec.rb
144
167
  - spec/gun_broker/user_spec.rb
145
168
  - spec/gun_broker_spec.rb
146
169
  - spec/spec_helper.rb
147
170
  - spec/support/fixtures.rb
148
171
  - spec/support/headers.rb
172
+ has_rdoc: