bitreserve 1.1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8d1c7b27348dfa25433e60edf1be84f5cc89b49
4
- data.tar.gz: f294a82c9d166b9f56df06c668f578fa6410a0c5
3
+ metadata.gz: 3bbbbdb0761739cd6c5e1d66a3f0ac5dfa71c498
4
+ data.tar.gz: d12bcb0e633a3a04665b17d7b778838645d584d7
5
5
  SHA512:
6
- metadata.gz: 1d1ecd9e4f0c707ebff9f0be545b1a9ce58476f9f459b4f3f5abab0daedf58b16714bec53f21ae6f8227e8efe4a1e549d63d84c0f035f0ba51bcfbd38361a3c1
7
- data.tar.gz: 40a9eca15c48940afe36e845f73d6f65e8e24e1f8589aa0dcb4797367d991b0e27971c5178e7fe090277d7fbc89218dd2af162b3c4ace265a1f31b76cb214fe7
6
+ metadata.gz: 3e07529048a9d805f6b22460e26f89defe5f7da1b6fe71d3dc49b7b20c3018bac0df8cf0a0b834e59a0191d2c8ded7a7ea99438d4cdb033d3c992de2a4e43a38
7
+ data.tar.gz: dbd7039f5765587738de721d3dd48d67b3f942948abfa8fd63bea919baa380682c5eafcf98c997237a61131387a769a1236032a7722674978fb8d6889e303eec
data/README.md CHANGED
@@ -43,6 +43,7 @@ Or install it yourself as:
43
43
  * [Contacts](#contacts)
44
44
  * [Users](#users)
45
45
  * [Transparency](#transparency)
46
+ * [Pagination](#pagination)
46
47
  * [Contributing](#contributing)
47
48
 
48
49
  # Usage
@@ -63,6 +64,9 @@ client. Here's how you can do that.
63
64
 
64
65
  ## Personal Access Token
65
66
 
67
+ If you don't have a PAT, learn how to generate one
68
+ [here](#basic-authentication).
69
+
66
70
  If you already have a token, you can use it by setting an environment variable,
67
71
  or by passing it when instantiating the client.
68
72
 
@@ -99,11 +103,24 @@ Bitreserve's API.
99
103
 
100
104
  ### OAuth2
101
105
 
102
- **NOT SUPPORTED YET**
106
+ **NOT SUPPORTED BY BITRESERVE YET**
103
107
 
104
108
  ### Basic Authentication
105
109
 
106
- TODO
110
+ [*Bireserve documentation on basic authentication*](https://developer.bitreserve.org/api/v0/#basic-authentication)
111
+
112
+ The only thing you need, in order to use basic authentication is a Personal
113
+ Access Token, everything else is transparent to you. If you already have a
114
+ token, see how to use it [here](#personal-access-token).
115
+
116
+ ```ruby
117
+ client.generate_access_token(username: 'your-bitreserve-username', password:
118
+ 'your-bitreserve-password', otp: 'a-valid-bitreserve-otp')
119
+ ```
120
+
121
+ To generate a valid OTP you can install [Authy](https://www.authy.com/), follow
122
+ it's set up process and choose bitreserve. You should be prompted with a set of
123
+ numbers, which is your OTP (it only lasts 30 seconds, so you have to be quick).
107
124
 
108
125
  ## Tickers
109
126
 
@@ -151,13 +168,15 @@ You can interact with both the authenticated user's and public transactions.
151
168
 
152
169
  ### Public Transactions
153
170
 
154
- **Return the public view of all transactions in the reserve:**
171
+ **Return the public view of all transactions in the reserve (supports
172
+ [Pagination](#pagination)):**
155
173
 
156
174
  ```ruby
157
175
  client.all_public_transactions
158
176
  ```
159
177
 
160
- **Return the public view of a specific transaction:**
178
+ **Return the public view of a specific transaction (supports
179
+ [Pagination](#pagination)):**
161
180
 
162
181
  ```ruby
163
182
  client.find_public_transactions(id: 'a97bb994-6e24-4a89-b653-e0a6d0bcf634')
@@ -193,7 +212,8 @@ client.resend_transaction(card_id: 'a6d35fcd-xxxx-9c9d1dda6d57', transaction_id:
193
212
  'd51b4e4e-9827-40fb-8763-e0ea2880085b')
194
213
  ```
195
214
 
196
- **Return all transactions associated with the user:**
215
+ **Return all transactions associated with the user (supports
216
+ [Pagination](#pagination)):**
197
217
 
198
218
  ```ruby
199
219
  client.all_user_transactions
@@ -254,6 +274,24 @@ client.phones
254
274
  client.statistics
255
275
  ```
256
276
 
277
+ ## Pagination
278
+
279
+ [*Bitreserve documentation on pagination*](https://developer.bitreserve.org/api/v0/#pagination)
280
+
281
+ All endpoints that support pagination take a `range` attribute, in which you can
282
+ specify the first and last indexes for the items you wish to retrieve.
283
+
284
+ The response will look exactly like an `Array`, but with a method called
285
+ `total_items`, that returns the total number of items of that type that
286
+ Bitreserve knows of.
287
+
288
+ ```ruby
289
+ client = Bitreserve::Client.new token: 'XXX'
290
+ client.all_public_transactions.size # 5
291
+ client.all_public_transactions.total_size # 21110
292
+ client.all_public_transactions(range: (5..20)).size # 16
293
+ ```
294
+
257
295
  # Contributing
258
296
 
259
297
  1. Fork it ( https://github.com/groupbuddies/bitreserve/fork )
@@ -26,20 +26,20 @@ module Bitreserve
26
26
  Request.perform_with_object(:post, request_data)
27
27
  end
28
28
 
29
- def all_user_transactions
29
+ def all_user_transactions(range: (0..4))
30
30
  request_data = RequestData.new(
31
31
  Endpoints::USER_PRIVATE_TRANSACTIONS,
32
32
  Entities::Transaction,
33
- authorization_header
33
+ authorization_header.merge(pagination_header_for_range(range))
34
34
  )
35
35
  Request.perform_with_objects(:get, request_data)
36
36
  end
37
37
 
38
- def all_card_transactions(card_id: nil)
38
+ def all_card_transactions(card_id: nil, range: (0..4))
39
39
  request_data = RequestData.new(
40
40
  Endpoints.with_placeholders(Endpoints::CARD_PRIVATE_TRANSACTIONS, ':card' => card_id),
41
41
  Entities::Transaction,
42
- authorization_header
42
+ authorization_header.merge(pagination_header_for_range(range))
43
43
  )
44
44
  Request.perform_with_objects(:get, request_data)
45
45
  end
@@ -1,11 +1,11 @@
1
1
  module Bitreserve
2
2
  module API
3
3
  module PublicTransaction
4
- def all_public_transactions
4
+ def all_public_transactions(range: (0..4))
5
5
  request_data = RequestData.new(
6
6
  Endpoints::PUBLIC_TRANSACTIONS,
7
7
  Entities::Transaction,
8
- authorization_header
8
+ authorization_header.merge(pagination_header_for_range(range))
9
9
  )
10
10
  Request.perform_with_objects(:get, request_data)
11
11
  end
@@ -1,7 +1,9 @@
1
1
  require 'bitreserve/api'
2
+ require 'bitreserve/pagination'
2
3
 
3
4
  module Bitreserve
4
5
  class Client
6
+ include Pagination
5
7
  include API
6
8
  attr_reader :bearer_token
7
9
 
@@ -3,15 +3,25 @@ module Bitreserve
3
3
  class BaseEntity
4
4
  include Virtus.model
5
5
 
6
- def self.from_collection(entities)
7
- entities.map do |entity|
8
- new(entity)
9
- end
6
+ def self.from_collection(entities, content_range)
7
+ total_size = (content_range && content_range.split('/')[1]) || entities.size
8
+ items = entities.map { |entity| new(entity) }
9
+
10
+ PaginatedCollection.new(items, total_size)
10
11
  end
11
12
 
12
13
  def initialize(attributes = {})
13
14
  super(Bitreserve::Helpers.underscored_hash(attributes))
14
15
  end
16
+
17
+ class PaginatedCollection < Array
18
+ attr_reader :total_size
19
+
20
+ def initialize(items, total_size)
21
+ super(items)
22
+ @total_size = total_size.to_i
23
+ end
24
+ end
15
25
  end
16
26
  end
17
27
  end
@@ -0,0 +1,9 @@
1
+ module Bitreserve
2
+ module Pagination
3
+ def pagination_header_for_range(range)
4
+ return {} unless range
5
+
6
+ { 'Range' => "items=#{range.min}-#{range.max}" }
7
+ end
8
+ end
9
+ end
@@ -1,22 +1,24 @@
1
1
  module Bitreserve
2
2
  class Request
3
+ class APIError < StandardError; end
4
+
3
5
  include ::HTTParty
4
6
  base_uri "#{Bitreserve.api_base}/v#{Bitreserve.api_version}"
5
7
 
6
8
  def self.perform_with_objects(http_method, request_data)
7
9
  response = new(request_data).public_send(http_method)
8
- check_error(response) || request_data.entity.from_collection(response)
10
+
11
+ with_valid_response(response) do
12
+ request_data.entity.from_collection(response.parsed_response, response.headers['content-range'])
13
+ end
9
14
  end
10
15
 
11
16
  def self.perform_with_object(http_method, request_data)
12
17
  response = new(request_data).public_send(http_method)
13
- check_error(response) || request_data.entity.new(response)
14
- end
15
18
 
16
- def self.check_error(response)
17
- return unless response.is_a?(Hash) && response['error']
18
-
19
- Entities::Error.new(response)
19
+ with_valid_response(response) do
20
+ request_data.entity.new(response.parsed_response)
21
+ end
20
22
  end
21
23
 
22
24
  def initialize(request_data)
@@ -28,19 +30,27 @@ module Bitreserve
28
30
  def get
29
31
  response = self.class.get(path, options)
30
32
  log_request_info(:get, response)
31
- response.parsed_response
33
+ response
32
34
  end
33
35
 
34
36
  def post
35
37
  response = self.class.post(path, options)
36
38
  log_request_info(:post, response)
37
- response.parsed_response
39
+ response
38
40
  end
39
41
 
40
42
  private
41
43
 
42
44
  attr_reader :path, :data, :auth, :headers
43
45
 
46
+ def self.with_valid_response(response)
47
+ if response.is_a?(Hash) && response['error']
48
+ Entities::Error.new(response)
49
+ else
50
+ yield
51
+ end
52
+ end
53
+
44
54
  def options
45
55
  { body: data, headers: headers }.
46
56
  reject { |_k, v| v.nil? }
@@ -1,3 +1,3 @@
1
1
  module Bitreserve
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -11,6 +11,7 @@ module Bitreserve
11
11
  transactions = client.all_public_transactions
12
12
 
13
13
  expect(transactions).to be_a(Array)
14
+ expect(transactions.total_size).to eq 2
14
15
  expect(transactions.first).to be_a(Entities::Transaction)
15
16
  expect(transactions.first.id).to be_a(String)
16
17
  end
@@ -82,7 +82,7 @@ module Bitreserve
82
82
  request_data = RequestData.new(
83
83
  Endpoints::USER_PRIVATE_TRANSACTIONS,
84
84
  Entities::Transaction,
85
- client.authorization_header
85
+ client.authorization_header.merge(client.pagination_header_for_range(0..4))
86
86
  )
87
87
  allow(Request).to receive(:perform_with_objects)
88
88
 
@@ -99,7 +99,7 @@ module Bitreserve
99
99
  request_data = RequestData.new(
100
100
  Endpoints.with_placeholders(Endpoints::CARD_PRIVATE_TRANSACTIONS, ':card' => card_id),
101
101
  Entities::Transaction,
102
- client.authorization_header
102
+ client.authorization_header.merge(client.pagination_header_for_range(0..4))
103
103
  )
104
104
  allow(Request).to receive(:perform_with_objects)
105
105
 
@@ -7,7 +7,7 @@ module Bitreserve
7
7
 
8
8
  context '#all_public_transactions' do
9
9
  it 'gets all public transactions' do
10
- request_data = RequestData.new(Endpoints::PUBLIC_TRANSACTIONS, Entities::Transaction, client.authorization_header)
10
+ request_data = RequestData.new(Endpoints::PUBLIC_TRANSACTIONS, Entities::Transaction, client.authorization_header.merge(client.pagination_header_for_range(0..4)))
11
11
  allow(Request).to receive(:perform_with_objects)
12
12
 
13
13
  client.all_public_transactions
@@ -26,7 +26,7 @@ module Bitreserve
26
26
  entity = double('Entity')
27
27
  allow(MockEntity).to receive(:new)
28
28
 
29
- MockEntity.from_collection([entity])
29
+ MockEntity.from_collection([entity], '0-1/10')
30
30
 
31
31
  expect(MockEntity).to have_received(:new).with(entity)
32
32
  end
@@ -3,7 +3,8 @@ require 'spec_helper'
3
3
  module Bitreserve
4
4
  shared_examples 'perform request method' do |method_name|
5
5
  let(:object_class) { double('ObjectClass', new: nil, from_collection: nil) }
6
- let(:request) { spy('request') }
6
+ let(:response) { double('Response', code: 200, parsed_response: '', headers: {}) }
7
+ let(:request) { spy('request', get: response, post: response) }
7
8
  let(:client) { Client.new }
8
9
 
9
10
  context ".#{method_name}" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitreserve
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Group Buddies
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-11 00:00:00.000000000 Z
11
+ date: 2015-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -175,6 +175,7 @@ files:
175
175
  - lib/bitreserve/entities/transaction.rb
176
176
  - lib/bitreserve/entities/user.rb
177
177
  - lib/bitreserve/helpers.rb
178
+ - lib/bitreserve/pagination.rb
178
179
  - lib/bitreserve/request.rb
179
180
  - lib/bitreserve/request_data.rb
180
181
  - lib/bitreserve/version.rb
@@ -240,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
240
241
  version: '0'
241
242
  requirements: []
242
243
  rubyforge_project:
243
- rubygems_version: 2.4.6
244
+ rubygems_version: 2.4.5
244
245
  signing_key:
245
246
  specification_version: 4
246
247
  summary: A wrapper for the bitreserve API
@@ -287,4 +288,3 @@ test_files:
287
288
  - spec/unit/entities/base_entity_spec.rb
288
289
  - spec/unit/helper_spec.rb
289
290
  - spec/unit/request_spec.rb
290
- has_rdoc: