invoiced 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/invoiced.rb CHANGED
@@ -19,8 +19,10 @@ require 'invoiced/operations/update'
19
19
  require 'invoiced/object'
20
20
  require 'invoiced/attachment'
21
21
  require 'invoiced/contact'
22
+ require 'invoiced/credit_note'
22
23
  require 'invoiced/customer'
23
24
  require 'invoiced/email'
25
+ require 'invoiced/estimate'
24
26
  require 'invoiced/event'
25
27
  require 'invoiced/file'
26
28
  require 'invoiced/invoice'
@@ -29,114 +31,116 @@ require 'invoiced/subscription'
29
31
  require 'invoiced/transaction'
30
32
 
31
33
  module Invoiced
32
- class Client
33
- ApiBase = 'https://api.invoiced.com'
34
- ApiBaseSandbox = 'https://api.sandbox.invoiced.com'
35
-
36
- attr_reader :api_key, :api_url, :sandbox
37
- attr_reader :Customer, :Event, :File, :Invoice, :Subscription, :Transaction
38
-
39
- def initialize(api_key, sandbox=false)
40
- @api_key = api_key
41
- @sandbox = sandbox
42
- @api_url = sandbox ? ApiBaseSandbox : ApiBase
43
-
44
- # Object endpoints
45
- @Customer = Invoiced::Customer.new(self)
46
- @Event = Invoiced::Event.new(self)
47
- @File = Invoiced::File.new(self)
48
- @Invoice = Invoiced::Invoice.new(self)
49
- @Subscription = Invoiced::Subscription.new(self)
50
- @Transaction = Invoiced::Transaction.new(self)
51
- end
52
-
53
- def request(method, endpoint, params={})
54
- url = @api_url + endpoint
55
-
56
- case method.to_s.downcase.to_sym
57
- # These methods don't have a request body
58
- when :get, :head, :delete
59
- # Make params into GET parameters
60
- url += "#{URI.parse(url).query ? '&' : '?'}#{Util.uri_encode(params)}" if params && params.any?
61
- payload = nil
62
- # Otherwise, encode request body to JSON
63
- else
64
- payload = params.to_json
65
- end
66
-
67
- begin
68
- response = RestClient::Request.execute(
69
- :method => method,
70
- :url => url,
71
- :headers => {
72
- :authorization => Util.auth_header(@api_key),
73
- :content_type => "application/json",
74
- :user_agent => "Invoiced Ruby/#{Invoiced::VERSION}"
75
- },
76
- :payload => payload
77
- )
78
- rescue RestClient::Exception => e
79
- if e.response
80
- rescue_api_error(e.response)
81
- else
82
- rescue_rest_client_error(e)
83
- end
84
- end
85
-
86
- parse(response)
87
- end
88
-
89
- private
90
-
91
- def parse(response)
92
- unless response.code == 204
93
- parsed_response = JSON.parse(response.body, :symbolize_names => true)
94
- else
95
- parsed_response = nil
96
- end
97
-
98
- {
99
- :code => response.code,
100
- :headers => response.headers,
101
- :body => parsed_response
102
- }
103
- end
104
-
105
- def rescue_api_error(response)
106
- begin
107
- error = JSON.parse(response.body)
108
- rescue JSON::ParserError
109
- raise general_api_error(response.code, response.body)
110
- end
111
-
112
- case response.code
113
- when 400, 403, 404
114
- raise invalid_request_error(error, response)
115
- when 401
116
- raise authentication_error(error, response)
117
- else
118
- raise api_error(error, response)
119
- end
120
- end
121
-
122
- def rescue_rest_client_error(error)
123
- raise ApiConnectionError.new("There was an error connecting to Invoiced.")
124
- end
125
-
126
- def authentication_error(error, response)
127
- AuthenticationError.new(error["message"], response.code, error)
128
- end
129
-
130
- def invalid_request_error(error, response)
131
- InvalidRequestError.new(error["message"], response.code, error)
132
- end
133
-
134
- def api_error(error, response)
135
- ApiError.new(error["message"], response.code, error)
136
- end
137
-
138
- def general_api_error(code, body)
139
- ApiError.new("API Error #{code} - #{body}", code)
140
- end
141
- end
34
+ class Client
35
+ ApiBase = 'https://api.invoiced.com'
36
+ ApiBaseSandbox = 'https://api.sandbox.invoiced.com'
37
+
38
+ attr_reader :api_key, :api_url, :sandbox
39
+ attr_reader :CreditNote, :Customer, :Estimate, :Event, :File, :Invoice, :Subscription, :Transaction
40
+
41
+ def initialize(api_key, sandbox=false)
42
+ @api_key = api_key
43
+ @sandbox = sandbox
44
+ @api_url = sandbox ? ApiBaseSandbox : ApiBase
45
+
46
+ # Object endpoints
47
+ @CreditNote = Invoiced::CreditNote.new(self)
48
+ @Customer = Invoiced::Customer.new(self)
49
+ @Estimate = Invoiced::Estimate.new(self)
50
+ @Event = Invoiced::Event.new(self)
51
+ @File = Invoiced::File.new(self)
52
+ @Invoice = Invoiced::Invoice.new(self)
53
+ @Subscription = Invoiced::Subscription.new(self)
54
+ @Transaction = Invoiced::Transaction.new(self)
55
+ end
56
+
57
+ def request(method, endpoint, params={})
58
+ url = @api_url + endpoint
59
+
60
+ case method.to_s.downcase.to_sym
61
+ # These methods don't have a request body
62
+ when :get, :head, :delete
63
+ # Make params into GET parameters
64
+ url += "#{URI.parse(url).query ? '&' : '?'}#{Util.uri_encode(params)}" if params && params.any?
65
+ payload = nil
66
+ # Otherwise, encode request body to JSON
67
+ else
68
+ payload = params.to_json
69
+ end
70
+
71
+ begin
72
+ response = RestClient::Request.execute(
73
+ :method => method,
74
+ :url => url,
75
+ :headers => {
76
+ :authorization => Util.auth_header(@api_key),
77
+ :content_type => "application/json",
78
+ :user_agent => "Invoiced Ruby/#{Invoiced::VERSION}"
79
+ },
80
+ :payload => payload
81
+ )
82
+ rescue RestClient::Exception => e
83
+ if e.response
84
+ rescue_api_error(e.response)
85
+ else
86
+ rescue_rest_client_error(e)
87
+ end
88
+ end
89
+
90
+ parse(response)
91
+ end
92
+
93
+ private
94
+
95
+ def parse(response)
96
+ unless response.code == 204
97
+ parsed_response = JSON.parse(response.body, :symbolize_names => true)
98
+ else
99
+ parsed_response = nil
100
+ end
101
+
102
+ {
103
+ :code => response.code,
104
+ :headers => response.headers,
105
+ :body => parsed_response
106
+ }
107
+ end
108
+
109
+ def rescue_api_error(response)
110
+ begin
111
+ error = JSON.parse(response.body)
112
+ rescue JSON::ParserError
113
+ raise general_api_error(response.code, response.body)
114
+ end
115
+
116
+ case response.code
117
+ when 400, 403, 404
118
+ raise invalid_request_error(error, response)
119
+ when 401
120
+ raise authentication_error(error, response)
121
+ else
122
+ raise api_error(error, response)
123
+ end
124
+ end
125
+
126
+ def rescue_rest_client_error(error)
127
+ raise ApiConnectionError.new("There was an error connecting to Invoiced.")
128
+ end
129
+
130
+ def authentication_error(error, response)
131
+ AuthenticationError.new(error["message"], response.code, error)
132
+ end
133
+
134
+ def invalid_request_error(error, response)
135
+ InvalidRequestError.new(error["message"], response.code, error)
136
+ end
137
+
138
+ def api_error(error, response)
139
+ ApiError.new(error["message"], response.code, error)
140
+ end
141
+
142
+ def general_api_error(code, body)
143
+ ApiError.new("API Error #{code} - #{body}", code)
144
+ end
145
+ end
142
146
  end
@@ -0,0 +1,126 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Invoiced
4
+ class CreditNoteTest < Test::Unit::TestCase
5
+ should "return the api endpoint" do
6
+ creditNote = CreditNote.new(@client, 123)
7
+ assert_equal('/credit_notes/123', creditNote.endpoint())
8
+ end
9
+
10
+ should "create a credit note" do
11
+ mockResponse = mock('RestClient::Response')
12
+ mockResponse.stubs(:code).returns(201)
13
+ mockResponse.stubs(:body).returns('{"id":123,"number":"CN-0001"}')
14
+ mockResponse.stubs(:headers).returns({})
15
+
16
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
17
+
18
+ creditNote = @client.CreditNote.create({:number => "CN-0001"})
19
+
20
+ assert_instance_of(Invoiced::CreditNote, creditNote)
21
+ assert_equal(123, creditNote.id)
22
+ assert_equal('CN-0001', creditNote.number)
23
+ end
24
+
25
+ should "retrieve a credit note" do
26
+ mockResponse = mock('RestClient::Response')
27
+ mockResponse.stubs(:code).returns(200)
28
+ mockResponse.stubs(:body).returns('{"id":123,"number":"CN-0001"}')
29
+ mockResponse.stubs(:headers).returns({})
30
+
31
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
32
+
33
+ creditNote = @client.CreditNote.retrieve(123)
34
+
35
+ assert_instance_of(Invoiced::CreditNote, creditNote)
36
+ assert_equal(123, creditNote.id)
37
+ assert_equal('CN-0001', creditNote.number)
38
+ end
39
+
40
+ should "not update a credit note when no params" do
41
+ creditNote = CreditNote.new(@client, 123)
42
+ assert_false(creditNote.save)
43
+ end
44
+
45
+ should "update a credit note" do
46
+ mockResponse = mock('RestClient::Response')
47
+ mockResponse.stubs(:code).returns(200)
48
+ mockResponse.stubs(:body).returns('{"id":123,"closed":true}')
49
+ mockResponse.stubs(:headers).returns({})
50
+
51
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
52
+
53
+ creditNote = CreditNote.new(@client, 123)
54
+ creditNote.closed = true
55
+ assert_true(creditNote.save)
56
+
57
+ assert_true(creditNote.closed)
58
+ end
59
+
60
+ should "list all credit notes" do
61
+ mockResponse = mock('RestClient::Response')
62
+ mockResponse.stubs(:code).returns(200)
63
+ mockResponse.stubs(:body).returns('[{"id":123,"number":"CN-0001"}]')
64
+ mockResponse.stubs(:headers).returns(:x_total_count => 15, :link => '<https://api.invoiced.com/credit_notes?per_page=25&page=1>; rel="self", <https://api.invoiced.com/credit_notes?per_page=25&page=1>; rel="first", <https://api.invoiced.com/credit_notes?per_page=25&page=1>; rel="last"')
65
+
66
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
67
+
68
+ creditNotes, metadata = @client.CreditNote.list
69
+
70
+ assert_instance_of(Array, creditNotes)
71
+ assert_equal(1, creditNotes.length)
72
+ assert_equal(123, creditNotes[0].id)
73
+
74
+ assert_instance_of(Invoiced::List, metadata)
75
+ assert_equal(15, metadata.total_count)
76
+ end
77
+
78
+ should "delete a credit note" do
79
+ mockResponse = mock('RestClient::Response')
80
+ mockResponse.stubs(:code).returns(204)
81
+ mockResponse.stubs(:body).returns('')
82
+ mockResponse.stubs(:headers).returns({})
83
+
84
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
85
+
86
+ creditNote = CreditNote.new(@client, 123)
87
+ assert_true(creditNote.delete)
88
+ end
89
+
90
+ should "send a credit note" do
91
+ mockResponse = mock('RestClient::Response')
92
+ mockResponse.stubs(:code).returns(201)
93
+ mockResponse.stubs(:body).returns('[{"id":4567,"email":"test@example.com"}]')
94
+ mockResponse.stubs(:headers).returns({})
95
+
96
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
97
+
98
+ creditNote = CreditNote.new(@client, 1234)
99
+ emails = creditNote.send
100
+
101
+ assert_instance_of(Array, emails)
102
+ assert_equal(1, emails.length)
103
+ assert_instance_of(Invoiced::Email, emails[0])
104
+ assert_equal(4567, emails[0].id)
105
+ end
106
+
107
+ should "list all of the credit note's attachments" do
108
+ mockResponse = mock('RestClient::Response')
109
+ mockResponse.stubs(:code).returns(200)
110
+ mockResponse.stubs(:body).returns('[{"file":{"id":456}}]')
111
+ mockResponse.stubs(:headers).returns(:x_total_count => 10, :link => '<https://api.invoiced.com/credit_notes/123/attachments?per_page=25&page=1>; rel="self", <https://api.invoiced.com/credit_notes/123/attachments?per_page=25&page=1>; rel="first", <https://api.invoiced.com/credit_notes/123/attachments?per_page=25&page=1>; rel="last"')
112
+
113
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
114
+
115
+ creditNote = CreditNote.new(@client, 123)
116
+ attachments, metadata = creditNote.attachments
117
+
118
+ assert_instance_of(Array, attachments)
119
+ assert_equal(1, attachments.length)
120
+ assert_equal(456, attachments[0].id)
121
+
122
+ assert_instance_of(Invoiced::List, metadata)
123
+ assert_equal(10, metadata.total_count)
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,126 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Invoiced
4
+ class EstimateTest < Test::Unit::TestCase
5
+ should "return the api endpoint" do
6
+ estimate = Estimate.new(@client, 123)
7
+ assert_equal('/estimates/123', estimate.endpoint())
8
+ end
9
+
10
+ should "create an estimate" do
11
+ mockResponse = mock('RestClient::Response')
12
+ mockResponse.stubs(:code).returns(201)
13
+ mockResponse.stubs(:body).returns('{"id":123,"number":"EST-0001"}')
14
+ mockResponse.stubs(:headers).returns({})
15
+
16
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
17
+
18
+ estimate = @client.Estimate.create({:number => "EST-0001"})
19
+
20
+ assert_instance_of(Invoiced::Estimate, estimate)
21
+ assert_equal(123, estimate.id)
22
+ assert_equal('EST-0001', estimate.number)
23
+ end
24
+
25
+ should "retrieve an estimate" do
26
+ mockResponse = mock('RestClient::Response')
27
+ mockResponse.stubs(:code).returns(200)
28
+ mockResponse.stubs(:body).returns('{"id":123,"number":"EST-0001"}')
29
+ mockResponse.stubs(:headers).returns({})
30
+
31
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
32
+
33
+ estimate = @client.Estimate.retrieve(123)
34
+
35
+ assert_instance_of(Invoiced::Estimate, estimate)
36
+ assert_equal(123, estimate.id)
37
+ assert_equal('EST-0001', estimate.number)
38
+ end
39
+
40
+ should "not update an estimate when no params" do
41
+ estimate = Estimate.new(@client, 123)
42
+ assert_false(estimate.save)
43
+ end
44
+
45
+ should "update an estimate" do
46
+ mockResponse = mock('RestClient::Response')
47
+ mockResponse.stubs(:code).returns(200)
48
+ mockResponse.stubs(:body).returns('{"id":123,"closed":true}')
49
+ mockResponse.stubs(:headers).returns({})
50
+
51
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
52
+
53
+ estimate = Estimate.new(@client, 123)
54
+ estimate.closed = true
55
+ assert_true(estimate.save)
56
+
57
+ assert_true(estimate.closed)
58
+ end
59
+
60
+ should "list all estimates" do
61
+ mockResponse = mock('RestClient::Response')
62
+ mockResponse.stubs(:code).returns(200)
63
+ mockResponse.stubs(:body).returns('[{"id":123,"number":"EST-0001"}]')
64
+ mockResponse.stubs(:headers).returns(:x_total_count => 15, :link => '<https://api.invoiced.com/estimates?per_page=25&page=1>; rel="self", <https://api.invoiced.com/estimates?per_page=25&page=1>; rel="first", <https://api.invoiced.com/estimates?per_page=25&page=1>; rel="last"')
65
+
66
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
67
+
68
+ estimates, metadata = @client.Estimate.list
69
+
70
+ assert_instance_of(Array, estimates)
71
+ assert_equal(1, estimates.length)
72
+ assert_equal(123, estimates[0].id)
73
+
74
+ assert_instance_of(Invoiced::List, metadata)
75
+ assert_equal(15, metadata.total_count)
76
+ end
77
+
78
+ should "delete an estimate" do
79
+ mockResponse = mock('RestClient::Response')
80
+ mockResponse.stubs(:code).returns(204)
81
+ mockResponse.stubs(:body).returns('')
82
+ mockResponse.stubs(:headers).returns({})
83
+
84
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
85
+
86
+ estimate = Estimate.new(@client, 123)
87
+ assert_true(estimate.delete)
88
+ end
89
+
90
+ should "send an estimate" do
91
+ mockResponse = mock('RestClient::Response')
92
+ mockResponse.stubs(:code).returns(201)
93
+ mockResponse.stubs(:body).returns('[{"id":4567,"email":"test@example.com"}]')
94
+ mockResponse.stubs(:headers).returns({})
95
+
96
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
97
+
98
+ estimate = Estimate.new(@client, 1234)
99
+ emails = estimate.send
100
+
101
+ assert_instance_of(Array, emails)
102
+ assert_equal(1, emails.length)
103
+ assert_instance_of(Invoiced::Email, emails[0])
104
+ assert_equal(4567, emails[0].id)
105
+ end
106
+
107
+ should "list all of the estimate's attachments" do
108
+ mockResponse = mock('RestClient::Response')
109
+ mockResponse.stubs(:code).returns(200)
110
+ mockResponse.stubs(:body).returns('[{"file":{"id":456}}]')
111
+ mockResponse.stubs(:headers).returns(:x_total_count => 10, :link => '<https://api.invoiced.com/estimates/123/attachments?per_page=25&page=1>; rel="self", <https://api.invoiced.com/estimates/123/attachments?per_page=25&page=1>; rel="first", <https://api.invoiced.com/estimates/123/attachments?per_page=25&page=1>; rel="last"')
112
+
113
+ RestClient::Request.any_instance.expects(:execute).returns(mockResponse)
114
+
115
+ estimate = Estimate.new(@client, 123)
116
+ attachments, metadata = estimate.attachments
117
+
118
+ assert_instance_of(Array, attachments)
119
+ assert_equal(1, attachments.length)
120
+ assert_equal(456, attachments[0].id)
121
+
122
+ assert_instance_of(Invoiced::List, metadata)
123
+ assert_equal(10, metadata.total_count)
124
+ end
125
+ end
126
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invoiced
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared King
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-12 00:00:00.000000000 Z
11
+ date: 2017-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -124,6 +124,7 @@ files:
124
124
  - lib/invoiced.rb
125
125
  - lib/invoiced/attachment.rb
126
126
  - lib/invoiced/contact.rb
127
+ - lib/invoiced/credit_note.rb
127
128
  - lib/invoiced/customer.rb
128
129
  - lib/invoiced/email.rb
129
130
  - lib/invoiced/error/api_connection_error.rb
@@ -131,6 +132,7 @@ files:
131
132
  - lib/invoiced/error/authentication_error.rb
132
133
  - lib/invoiced/error/error_base.rb
133
134
  - lib/invoiced/error/invalid_request.rb
135
+ - lib/invoiced/estimate.rb
134
136
  - lib/invoiced/event.rb
135
137
  - lib/invoiced/file.rb
136
138
  - lib/invoiced/invoice.rb
@@ -146,8 +148,10 @@ files:
146
148
  - lib/invoiced/util.rb
147
149
  - lib/invoiced/version.rb
148
150
  - test/invoiced/contact_test.rb
151
+ - test/invoiced/credit_note_test.rb
149
152
  - test/invoiced/customer_test.rb
150
153
  - test/invoiced/error_test.rb
154
+ - test/invoiced/estimate_test.rb
151
155
  - test/invoiced/event_test.rb
152
156
  - test/invoiced/file_test.rb
153
157
  - test/invoiced/invoice_test.rb
@@ -184,8 +188,10 @@ specification_version: 4
184
188
  summary: Ruby client library for the Invoiced API
185
189
  test_files:
186
190
  - test/invoiced/contact_test.rb
191
+ - test/invoiced/credit_note_test.rb
187
192
  - test/invoiced/customer_test.rb
188
193
  - test/invoiced/error_test.rb
194
+ - test/invoiced/estimate_test.rb
189
195
  - test/invoiced/event_test.rb
190
196
  - test/invoiced/file_test.rb
191
197
  - test/invoiced/invoice_test.rb