gun_broker 0.2.0 → 0.4.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 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: