myfinance 0.2.0 → 0.3.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: 2a816590d9795f867bf791715ad87a56057513e6
4
- data.tar.gz: 9ae9263ed7af1f079ca7483bd95a2351055cd8ca
3
+ metadata.gz: 47ca29c0b8c050bba8b6fcc65b54cc8f592a2f33
4
+ data.tar.gz: 95ece995c6429e18820a00a81b8854d0d57aad85
5
5
  SHA512:
6
- metadata.gz: 42164b2bd9722065052b6199cdde3d29adf4cc6a1e40f993491e8f9a4689c2f844768d40466c1ecb0c926f54a7cda35ecfdef1dd56e8a764fbebe50dcb70dfb1
7
- data.tar.gz: 7cae9bd220cf606c5ba66bc48639ea58d35d5830c9d9803f3d604bdac957de9fd181d3b6738d8b283cc50606dc1bb19fed7cca91d32238cc51a69b7f1303ce0e
6
+ metadata.gz: 347563b3d92b6e1a97b0930e7365889aab4be10896545cd7a59b4c8760f9aec220e744493f87af26fcd47f857e6142084b0e17a071cb1e37a119a00988326363
7
+ data.tar.gz: 93a52bc881d017a0abb9587ddd2518d14b3eedc48a124e8082e41c13b3bd97665f3bb2319bc896ac137e497c15d1a76f628c643d64dbc3b0bd091539fc6b0bc1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- myfinance (0.2.0)
4
+ myfinance (0.3.0)
5
5
  multi_json (~> 1.9.0)
6
6
  typhoeus (~> 0.7.1)
7
7
  virtus (~> 1.0.5)
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Ruby client for the [Myfinance](http://www.myfinance.com.br) REST API
4
4
 
5
- [![Gem version](https://badge.fury.io/rb/myfinance-client.png)](https://rubygems.org/gems/myfinance-client)
5
+ [![Gem version](https://badge.fury.io/rb/myfinance.png)](https://rubygems.org/gems/myfinance)
6
6
  [![Build status](https://travis-ci.org/myfreecomm/myfinance-client-ruby.png?branch=master)](https://travis-ci.org/myfreecomm/myfinance-client-ruby)
7
7
  [![Test coverage](https://codeclimate.com/github/myfreecomm/myfinance-client-ruby/badges/coverage.svg)](https://codeclimate.com/github/myfreecomm/myfinance-client-ruby)
8
8
  [![Code Climate grade](https://codeclimate.com/github/myfreecomm/myfinance-client-ruby.png)](https://codeclimate.com/github/myfreecomm/myfinance-client-ruby)
@@ -214,6 +214,26 @@ Myfinance.configure do |m|
214
214
  end
215
215
  ```
216
216
 
217
+ ### Multiple accounts
218
+
219
+ When an account has multiple accounts, an `ACCOUNT_ID` header is required for the requests. To instantiate a new client with an `ACCOUNT_ID` header:
220
+
221
+ ```ruby
222
+ client = Myfinance.client("YOUR_TOKEN_HERE", ACCOUNT_ID) # where ACCOUNT_ID is the ID of the account
223
+ ```
224
+
225
+ If you instantiate a new client without an `account_id` and the user has more than one account, the lib will raise a [`Myfinance::RequestError`](https://github.com/myfreecomm/myfinance-client-ruby/blob/master/lib/myfinance/response.rb#L33) error. The list of available accounts will be in the body of the object.
226
+
227
+ ```ruby
228
+ begin
229
+ client.entities.find_all
230
+ rescue Myfinance::RequestError => e
231
+ e.body # { "error" => "O cabeçalho da requisição não possui o atributo ACCOUNT_ID.", "accounts" => [{"account" => { "id" => 3, .. } }, { ... }] }
232
+ e.message # O cabeçalho da requisição não possui o atributo ACCOUNT_ID.
233
+ e.code # 422
234
+ end
235
+ ```
236
+
217
237
  ## Development
218
238
 
219
239
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -5,8 +5,8 @@ module Myfinance
5
5
  class Client
6
6
  attr_reader :http
7
7
 
8
- def initialize(token)
9
- @http = Http.new(token)
8
+ def initialize(token, account_id = nil)
9
+ @http = Http.new(token, account_id)
10
10
  end
11
11
 
12
12
  def authenticated?
@@ -3,10 +3,11 @@ require "myfinance/response"
3
3
 
4
4
  module Myfinance
5
5
  class Http
6
- attr_reader :token
6
+ attr_reader :token, :account_id
7
7
 
8
- def initialize(token)
8
+ def initialize(token, account_id = nil)
9
9
  @token = token
10
+ @account_id = account_id
10
11
  end
11
12
 
12
13
  %w[get post delete put].each do |m|
@@ -22,7 +23,8 @@ module Myfinance
22
23
  method: method,
23
24
  token: token,
24
25
  url: "#{Myfinance.configuration.url}#{path}",
25
- user_agent: Myfinance.configuration.user_agent
26
+ user_agent: Myfinance.configuration.user_agent,
27
+ account_id: account_id
26
28
  }))
27
29
 
28
30
  response = Response.new(request.run)
@@ -35,8 +35,9 @@ module Myfinance
35
35
  "Accept" => "application/json",
36
36
  "Content-Type" => "application/json",
37
37
  "User-Agent" => args[:user_agent],
38
- "Authorization" => "Basic #{authorization_hash}"
39
- }.merge(headers)
38
+ "Authorization" => "Basic #{authorization_hash}",
39
+ "ACCOUNT_ID" => args[:account_id]
40
+ }.merge(headers).delete_if { |_,v| v.nil? || v.to_s.empty? }
40
41
  end
41
42
 
42
43
  def body
@@ -32,10 +32,14 @@ module Myfinance
32
32
  def error!
33
33
  raise RequestError.new(
34
34
  code: code,
35
- message: status_message,
36
- body: body
35
+ message: request_error_message,
36
+ body: parsed_body
37
37
  )
38
38
  end
39
39
 
40
+ def request_error_message
41
+ return status_message if !status_message.nil? && status_message != ""
42
+ parsed_body["error"] || ""
43
+ end
40
44
  end
41
45
  end
@@ -1,3 +1,3 @@
1
1
  module Myfinance
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -5,9 +5,16 @@ describe Myfinance::Client do
5
5
 
6
6
  describe "#initialize" do
7
7
  it "instantiates a new Myfinance::Http object" do
8
- expect(Myfinance::Http).to receive(:new).with("abc")
8
+ expect(Myfinance::Http).to receive(:new).with("abc", nil)
9
9
  Myfinance::Client.new("abc")
10
10
  end
11
+
12
+ context "when account_id is present" do
13
+ it "instantiates a new Myfinance::Http object" do
14
+ expect(Myfinance::Http).to receive(:new).with("abc", 123)
15
+ Myfinance::Client.new("abc", 123)
16
+ end
17
+ end
11
18
  end
12
19
 
13
20
  describe "#authenticated?" do
@@ -1,7 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Myfinance::Http do
4
- subject { Myfinance::Http.new('b552dd5a8598ca089b91c5e355a83b86e4696aefac9eaa05') }
4
+ let(:account_id) { 12 }
5
+ subject { Myfinance::Http.new('b552dd5a8598ca089b91c5e355a83b86e4696aefac9eaa05', account_id) }
5
6
 
6
7
  describe '#get' do
7
8
  let(:http_method) { :get }
@@ -20,10 +20,37 @@ describe Myfinance::Request do
20
20
  subject.run
21
21
  end
22
22
 
23
- it 'generates the base 64 of the user token' do
23
+ it "generates the base 64 of the user token" do
24
24
  allow_any_instance_of(Typhoeus::Request).to receive(:run)
25
25
  expect(Base64).to receive(:strict_encode64).with("my-auth-hash:X").and_call_original
26
26
  subject.run
27
27
  end
28
+
29
+ context "when account_id is empty" do
30
+ subject { described_class.new({ method: 'post', params: {}, url: Myfinance.configuration.url, user_agent: 'My Test User-Agent', token: 'my-auth-hash', account_id: "" }) }
31
+
32
+ it "does not add ACCOUNT_ID on headers" do
33
+ expect(Typhoeus::Request).to receive(:new).with("https://sandbox.myfinance.com.br", { method: "post", params: {}, headers: { "Accept" => "application/json", "Content-Type" => "application/json", "User-Agent" => "My Test User-Agent", "Authorization" => "Basic bXktYXV0aC1oYXNoOlg=" }, accept_encoding: "gzip" }).and_return(double(run: true, response: true))
34
+ subject.run
35
+ end
36
+ end
37
+
38
+ context "when account_id is nil" do
39
+ subject { described_class.new({ method: 'post', params: {}, url: Myfinance.configuration.url, user_agent: 'My Test User-Agent', token: 'my-auth-hash', account_id: nil }) }
40
+
41
+ it "does not add ACCOUNT_ID on headers" do
42
+ expect(Typhoeus::Request).to receive(:new).with("https://sandbox.myfinance.com.br", { method: "post", params: {}, headers: { "Accept" => "application/json", "Content-Type" => "application/json", "User-Agent" => "My Test User-Agent", "Authorization" => "Basic bXktYXV0aC1oYXNoOlg=" }, accept_encoding: "gzip" }).and_return(double(run: true, response: true))
43
+ subject.run
44
+ end
45
+ end
46
+
47
+ context "when account_id is present" do
48
+ subject { described_class.new({ method: 'post', params: {}, url: Myfinance.configuration.url, user_agent: 'My Test User-Agent', token: 'my-auth-hash', account_id: 12 }) }
49
+
50
+ it "does not add ACCOUNT_ID on headers" do
51
+ expect(Typhoeus::Request).to receive(:new).with("https://sandbox.myfinance.com.br", { method: "post", params: {}, headers: { "Accept" => "application/json", "Content-Type" => "application/json", "User-Agent" => "My Test User-Agent", "Authorization" => "Basic bXktYXV0aC1oYXNoOlg=", "ACCOUNT_ID" => 12 }, accept_encoding: "gzip" }).and_return(double(run: true, response: true))
52
+ subject.run
53
+ end
54
+ end
28
55
  end
29
56
  end
@@ -66,7 +66,7 @@ describe Myfinance::Resources::PayableAccount do
66
66
  end
67
67
 
68
68
  it "adds information on request error object" do
69
- expect(Myfinance::RequestError).to receive(:new).with(code: 422, message: "", body: "{\"competency_month\":[\"n\\u00e3o pode ser vazio\"],\"due_date\":[\"n\\u00e3o \\u00e9 uma data v\\u00e1lida\"]}").and_call_original
69
+ expect(Myfinance::RequestError).to receive(:new).with(code: 422, message: "", body: { "competency_month" => ["não pode ser vazio"], "due_date" => ["não é uma data válida"] }).and_call_original
70
70
  expect { subject }.to raise_error(Myfinance::RequestError)
71
71
  end
72
72
  end
@@ -79,7 +79,7 @@ describe Myfinance::Resources::PayableAccount do
79
79
  end
80
80
 
81
81
  it "adds information on request error object" do
82
- expect(Myfinance::RequestError).to receive(:new).with(code: 403, message: "Forbidden", body: "{\"error\":\"Voc\\u00ea n\\u00e3o tem permiss\\u00e3o para acessar este recurso.\"}").and_call_original
82
+ expect(Myfinance::RequestError).to receive(:new).with(code: 403, message: "Forbidden", body: {"error" => "Você não tem permissão para acessar este recurso." }).and_call_original
83
83
  expect { subject }.to raise_error(Myfinance::RequestError)
84
84
  end
85
85
  end
@@ -66,7 +66,7 @@ describe Myfinance::Resources::ReceivableAccount do
66
66
  end
67
67
 
68
68
  it "adds information on request error object" do
69
- expect(Myfinance::RequestError).to receive(:new).with(code: 422, message: "", body: "{\"competency_month\":[\"n\\u00e3o pode ser vazio\"],\"due_date\":[\"n\\u00e3o \\u00e9 uma data v\\u00e1lida\"]}").and_call_original
69
+ expect(Myfinance::RequestError).to receive(:new).with(code: 422, message: "", body: { "competency_month" => ["não pode ser vazio"], "due_date" => ["não é uma data válida"] }).and_call_original
70
70
  expect { subject }.to raise_error(Myfinance::RequestError)
71
71
  end
72
72
  end
@@ -79,7 +79,7 @@ describe Myfinance::Resources::ReceivableAccount do
79
79
  end
80
80
 
81
81
  it "adds information on request error object" do
82
- expect(Myfinance::RequestError).to receive(:new).with(code: 403, message: "Forbidden", body: "{\"error\":\"Voc\\u00ea n\\u00e3o tem permiss\\u00e3o para acessar este recurso.\"}").and_call_original
82
+ expect(Myfinance::RequestError).to receive(:new).with(code: 403, message: "Forbidden", body: { "error" => "Você não tem permissão para acessar este recurso." }).and_call_original
83
83
  expect { subject }.to raise_error(Myfinance::RequestError)
84
84
  end
85
85
  end
@@ -32,12 +32,45 @@ describe Myfinance::Response do
32
32
  let(:response) { double(success?: false, timed_out?: false, code: 301, status_message: 'Moved Permanently', body: '') }
33
33
 
34
34
  it 'raises RequestError' do
35
- expect { subject.resolve! }.to raise_error(Myfinance::RequestError)
35
+ expect { subject.resolve! }.to raise_error do |error|
36
+ expect(error).to be_a(Myfinance::RequestError)
37
+ expect(error.code).to eq(301)
38
+ expect(error.message).to eq("Moved Permanently")
39
+ expect(error.body).to eq({})
40
+ end
41
+ end
42
+
43
+ context "when status_message is empty" do
44
+ context "when body has an 'error' key" do
45
+ let(:response) { double(success?: false, timed_out?: false, code: 301, status_message: '', body: '{"error": "My custom error message"}') }
46
+
47
+ it "raises RequestError with custom message" do
48
+ expect { subject.resolve! }.to raise_error do |error|
49
+ expect(error).to be_a(Myfinance::RequestError)
50
+ expect(error.code).to eq(301)
51
+ expect(error.message).to eq("My custom error message")
52
+ expect(error.body).to eq({ "error" => "My custom error message" })
53
+ end
54
+ end
55
+ end
56
+
57
+ context "when body has an 'error' key" do
58
+ let(:response) { double(success?: false, timed_out?: false, code: 301, status_message: '', body: '') }
59
+
60
+ it "raises RequestError with empty message" do
61
+ expect { subject.resolve! }.to raise_error do |error|
62
+ expect(error).to be_a(Myfinance::RequestError)
63
+ expect(error.code).to eq(301)
64
+ expect(error.message).to eq("")
65
+ expect(error.body).to eq({})
66
+ end
67
+ end
68
+ end
36
69
  end
37
70
  end
38
71
  end
39
72
 
40
- describe "#parsed_body" do
73
+ describe "#body" do
41
74
  let(:response) { double(success?: true) }
42
75
 
43
76
  context "when JSON is invalid" do
@@ -1,7 +1,7 @@
1
1
  shared_examples 'available http request methods' do
2
2
  it "instantiates a new Request object" do
3
3
  VCR.use_cassette("client/#{http_method}/request") do
4
- expect(Myfinance::Request).to receive(:new).and_call_original
4
+ expect(Myfinance::Request).to receive(:new).with({ body: params, method: http_method, token: "b552dd5a8598ca089b91c5e355a83b86e4696aefac9eaa05", url: "#{Myfinance.configuration.url}#{url}", user_agent: "Myfinance Ruby Client v#{Myfinance::VERSION}", account_id: account_id }).and_call_original
5
5
  subject.send(http_method, url, body: params)
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: myfinance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo Hertz
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-08-17 00:00:00.000000000 Z
13
+ date: 2015-08-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: typhoeus