jpablobr-freshbooks 0.1.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.
- data/.gitignore +5 -0
- data/History.txt +8 -0
- data/LICENSE +10 -0
- data/Manifest.txt +44 -0
- data/README +65 -0
- data/Rakefile +19 -0
- data/lib/freshbooks.rb +94 -0
- data/lib/freshbooks/base.rb +168 -0
- data/lib/freshbooks/category.rb +11 -0
- data/lib/freshbooks/client.rb +20 -0
- data/lib/freshbooks/connection.rb +112 -0
- data/lib/freshbooks/estimate.rb +23 -0
- data/lib/freshbooks/expense.rb +12 -0
- data/lib/freshbooks/invoice.rb +25 -0
- data/lib/freshbooks/item.rb +11 -0
- data/lib/freshbooks/line.rb +10 -0
- data/lib/freshbooks/links.rb +7 -0
- data/lib/freshbooks/list_proxy.rb +70 -0
- data/lib/freshbooks/payment.rb +12 -0
- data/lib/freshbooks/project.rb +12 -0
- data/lib/freshbooks/recurring.rb +15 -0
- data/lib/freshbooks/response.rb +27 -0
- data/lib/freshbooks/schema/definition.rb +20 -0
- data/lib/freshbooks/schema/mixin.rb +40 -0
- data/lib/freshbooks/staff.rb +13 -0
- data/lib/freshbooks/task.rb +12 -0
- data/lib/freshbooks/time_entry.rb +12 -0
- data/lib/freshbooks/xml_serializer.rb +17 -0
- data/lib/freshbooks/xml_serializer/serializers.rb +107 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test/fixtures/invoice_create_response.xml +4 -0
- data/test/fixtures/invoice_get_response.xml +51 -0
- data/test/fixtures/invoice_list_response.xml +27 -0
- data/test/fixtures/success_response.xml +2 -0
- data/test/mock_connection.rb +13 -0
- data/test/schema/test_definition.rb +36 -0
- data/test/schema/test_mixin.rb +39 -0
- data/test/test_base.rb +97 -0
- data/test/test_connection.rb +83 -0
- data/test/test_helper.rb +32 -0
- data/test/test_invoice.rb +122 -0
- data/test/test_list_proxy.rb +41 -0
- data/test/test_page.rb +50 -0
- metadata +115 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestConnection < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@connection = FreshBooks::Connection.new("company.freshbooks.com", "auth_token")
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_connection_accessors
|
9
|
+
assert_equal "company.freshbooks.com", @connection.account_url
|
10
|
+
assert_equal "auth_token", @connection.auth_token
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_connection_request_headers
|
14
|
+
request_headers = { "key" => "value" }
|
15
|
+
connection = FreshBooks::Connection.new("company.freshbooks.com", "auth_token", request_headers)
|
16
|
+
assert_equal request_headers, connection.request_headers
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def test_create_request__array_of_elements
|
21
|
+
request = @connection.send(:create_request, 'mymethod', [['element1', 'value1'], [:element2, :value2]])
|
22
|
+
assert_equal "<?xml version='1.0' encoding='UTF-8'?><request method='mymethod'><element1>value1</element1><element2>value2</element2></request>", request
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_create_request__base_object_element
|
26
|
+
invoice = FreshBooks::Invoice.new
|
27
|
+
invoice.expects(:to_xml).with().returns("invoice")
|
28
|
+
|
29
|
+
request = @connection.send(:create_request, 'mymethod', 'invoice' => invoice)
|
30
|
+
assert_equal "<?xml version='1.0' encoding='UTF-8'?><request method='mymethod'><invoice/></request>", request
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def test_check_for_api_error__success
|
35
|
+
body = "body xml"
|
36
|
+
response = Net::HTTPSuccess.new("1.1", "200", "message")
|
37
|
+
response.expects(:body).with().returns(body)
|
38
|
+
assert_equal body, @connection.send(:check_for_api_error, response)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_check_for_api_error__unknown_system
|
42
|
+
response = Net::HTTPMovedPermanently.new("1.1", "301", "message")
|
43
|
+
response.stubs(:[]).with("location").returns("loginSearch")
|
44
|
+
assert_raise(FreshBooks::UnknownSystemError) do
|
45
|
+
@connection.send(:check_for_api_error, response)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_check_for_api_error__deactivated
|
50
|
+
response = Net::HTTPMovedPermanently.new("1.1", "301", "message")
|
51
|
+
response.stubs(:[]).with("location").returns("deactivated")
|
52
|
+
assert_raise(FreshBooks::AccountDeactivatedError) do
|
53
|
+
@connection.send(:check_for_api_error, response)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_check_for_api_error__unauthorized
|
58
|
+
response = Net::HTTPUnauthorized.new("1.1", "401", "message")
|
59
|
+
assert_raise(FreshBooks::AuthenticationError) do
|
60
|
+
@connection.send(:check_for_api_error, response)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_check_for_api_error__bad_request
|
65
|
+
response = Net::HTTPBadRequest.new("1.1", "401", "message")
|
66
|
+
assert_raise(FreshBooks::ApiAccessNotEnabledError) do
|
67
|
+
@connection.send(:check_for_api_error, response)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_check_for_api_error__internal_error
|
72
|
+
response = Net::HTTPBadGateway.new("1.1", "502", "message")
|
73
|
+
assert_raise(FreshBooks::InternalError) do
|
74
|
+
@connection.send(:check_for_api_error, response)
|
75
|
+
end
|
76
|
+
|
77
|
+
response = Net::HTTPMovedPermanently.new("1.1", "301", "message")
|
78
|
+
response.stubs(:[]).with("location").returns("somePage")
|
79
|
+
assert_raise(FreshBooks::InternalError) do
|
80
|
+
@connection.send(:check_for_api_error, response)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/freshbooks'
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require 'test/unit'
|
5
|
+
require File.dirname(__FILE__) + '/mock_connection'
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'mocha'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rubygems'
|
11
|
+
gem 'mocha'
|
12
|
+
require 'mocha'
|
13
|
+
end
|
14
|
+
|
15
|
+
class Test::Unit::TestCase
|
16
|
+
def mock_connection(file_name)
|
17
|
+
mock_connection = MockConnection.new(fixture_xml_content(file_name))
|
18
|
+
FreshBooks::Base.stubs(:connection).with().returns(mock_connection)
|
19
|
+
mock_connection
|
20
|
+
end
|
21
|
+
|
22
|
+
def fixture_xml_content(file_name)
|
23
|
+
# Quick way to remove white space and newlines from xml. Makes it easier to compare in tests
|
24
|
+
open(File.join(fixture_dir, "#{file_name}.xml"), "r").readlines.inject("") do |contents, line|
|
25
|
+
contents + line.strip
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def fixture_dir
|
30
|
+
File.join(File.dirname(__FILE__), "fixtures")
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestInvoice < Test::Unit::TestCase
|
4
|
+
def test_list
|
5
|
+
mock_call_api("invoice.list", { "page" => 1 }, "invoice_list_response")
|
6
|
+
|
7
|
+
invoices = FreshBooks::Invoice.list
|
8
|
+
assert_equal 3, invoices.size
|
9
|
+
assert_invoice invoices[0], 0
|
10
|
+
assert_invoice invoices[1], 1
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_get
|
14
|
+
invoice_id = 2
|
15
|
+
mock_call_api("invoice.get", { "invoice_id" => invoice_id }, "invoice_get_response")
|
16
|
+
|
17
|
+
invoice = FreshBooks::Invoice.get(invoice_id)
|
18
|
+
assert_invoice invoice, 0, true
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_create
|
22
|
+
invoice = FreshBooks::Invoice.new
|
23
|
+
assert_nil invoice.invoice_id
|
24
|
+
|
25
|
+
mock_call_api("invoice.create", { "invoice" => invoice }, "invoice_create_response")
|
26
|
+
assert invoice.create
|
27
|
+
assert_equal 1, invoice.invoice_id
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_update
|
31
|
+
invoice = FreshBooks::Invoice.new
|
32
|
+
invoice.invoice_id = 1
|
33
|
+
|
34
|
+
mock_call_api("invoice.update", { "invoice" => invoice }, "success_response")
|
35
|
+
assert invoice.update
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_delete
|
39
|
+
invoice = FreshBooks::Invoice.new
|
40
|
+
invoice.invoice_id = 2
|
41
|
+
mock_call_api("invoice.delete", { "invoice_id" => invoice.invoice_id }, "success_response")
|
42
|
+
|
43
|
+
assert invoice.delete
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_send_by_email
|
47
|
+
invoice = FreshBooks::Invoice.new
|
48
|
+
invoice.invoice_id = 2
|
49
|
+
mock_call_api("invoice.sendByEmail", { "invoice_id" => invoice.invoice_id }, "success_response")
|
50
|
+
|
51
|
+
assert invoice.send_by_email
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_send_by_snail_mail
|
55
|
+
invoice = FreshBooks::Invoice.new
|
56
|
+
invoice.invoice_id = 2
|
57
|
+
mock_call_api("invoice.sendBySnailMail", { "invoice_id" => invoice.invoice_id }, "success_response")
|
58
|
+
|
59
|
+
assert invoice.send_by_snail_mail
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def mock_call_api(method, options, response_fixture)
|
65
|
+
FreshBooks::Base.connection.
|
66
|
+
expects(:call_api).
|
67
|
+
with(method, options).
|
68
|
+
returns(FreshBooks::Response.new(fixture_xml_content(response_fixture)))
|
69
|
+
end
|
70
|
+
|
71
|
+
def assert_invoice(invoice, number, expanded_form = false)
|
72
|
+
number = number + 1
|
73
|
+
|
74
|
+
assert_equal number, invoice.invoice_id
|
75
|
+
assert_equal "number#{number}", invoice.number
|
76
|
+
assert_equal number, invoice.client_id
|
77
|
+
assert_equal number, invoice.recurring_id
|
78
|
+
assert_equal "draft", invoice.status
|
79
|
+
assert_equal (number * 100), invoice.amount
|
80
|
+
assert_equal (number * 100) / 2, invoice.amount_outstanding
|
81
|
+
assert_equal Date.parse("2009-02-0#{number}"), invoice.date
|
82
|
+
|
83
|
+
if expanded_form
|
84
|
+
assert_equal number, invoice.po_number
|
85
|
+
assert_equal number.to_f, invoice.discount
|
86
|
+
assert_equal "notes#{number}", invoice.notes
|
87
|
+
assert_equal "terms#{number}", invoice.terms
|
88
|
+
assert_equal "first_name#{number}", invoice.first_name
|
89
|
+
assert_equal "last_name#{number}", invoice.last_name
|
90
|
+
assert_equal "p_street1#{number}", invoice.p_street1
|
91
|
+
assert_equal "p_street2#{number}", invoice.p_street2
|
92
|
+
assert_equal "p_city#{number}", invoice.p_city
|
93
|
+
assert_equal "p_state#{number}", invoice.p_state
|
94
|
+
assert_equal "p_country#{number}", invoice.p_country
|
95
|
+
assert_equal "p_code#{number}", invoice.p_code
|
96
|
+
|
97
|
+
assert_equal "client_view1", invoice.links.client_view
|
98
|
+
assert_equal "view1", invoice.links.view
|
99
|
+
assert_equal "edit1", invoice.links.edit
|
100
|
+
|
101
|
+
lines = invoice.lines
|
102
|
+
assert_equal number, lines.size
|
103
|
+
lines.each_with_index do |line, index|
|
104
|
+
assert_line(line, index)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def assert_line(line, number)
|
110
|
+
number = number + 1
|
111
|
+
|
112
|
+
assert_equal number.to_f, line.amount
|
113
|
+
assert_equal "name#{number}", line.name
|
114
|
+
assert_equal "description#{number}", line.description
|
115
|
+
assert_equal number.to_f, line.unit_cost
|
116
|
+
assert_equal number, line.quantity
|
117
|
+
assert_equal "tax1_name#{number}", line.tax1_name
|
118
|
+
assert_equal "tax2_name#{number}", line.tax2_name
|
119
|
+
assert_equal number.to_f, line.tax1_percent
|
120
|
+
assert_equal number.to_f, line.tax2_percent
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestListProxy < Test::Unit::TestCase
|
4
|
+
def test_size__should_be_total_size_of_results
|
5
|
+
list_proxy = FreshBooks::ListProxy.new(create_proc(1, 2, 3))
|
6
|
+
assert_equal 3, list_proxy.size
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_reference_element
|
10
|
+
list_proxy = FreshBooks::ListProxy.new(create_proc(1, 2, 3))
|
11
|
+
assert_equal 0, list_proxy[0]
|
12
|
+
assert_equal 1, list_proxy[1]
|
13
|
+
assert_equal 2, list_proxy[2]
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_each
|
17
|
+
list_proxy = FreshBooks::ListProxy.new(create_proc(1, 2, 3))
|
18
|
+
count = 0
|
19
|
+
list_proxy.each_with_index do |item, i|
|
20
|
+
assert_equal i, item, "Incorrect item on iteration #{i}"
|
21
|
+
count += 1
|
22
|
+
end
|
23
|
+
assert_equal count, list_proxy.size
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Create a proc, the array generated will be sequential from 0 to total
|
29
|
+
def create_proc(page, per_page, total)
|
30
|
+
get_page_proc = proc do |page|
|
31
|
+
start_num = (page - 1) * per_page
|
32
|
+
end_num = start_num + per_page
|
33
|
+
if end_num >= total
|
34
|
+
end_num = total
|
35
|
+
end
|
36
|
+
|
37
|
+
array = Range.new(start_num, end_num, true).to_a
|
38
|
+
[array, FreshBooks::Page.new(page, per_page, total)]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/test/test_page.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestPage < Test::Unit::TestCase
|
4
|
+
def test_pages
|
5
|
+
page = FreshBooks::Page.new(1, 2, 1)
|
6
|
+
assert_equal 1, page.pages
|
7
|
+
|
8
|
+
page = FreshBooks::Page.new(1, 2, 2)
|
9
|
+
assert_equal 1, page.pages
|
10
|
+
|
11
|
+
page = FreshBooks::Page.new(1, 2, 3)
|
12
|
+
assert_equal 2, page.pages
|
13
|
+
|
14
|
+
page = FreshBooks::Page.new(1, 2, 4)
|
15
|
+
assert_equal 2, page.pages
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_next_page?
|
19
|
+
list_proxy = FreshBooks::Page.new(1, 2, 1)
|
20
|
+
assert !list_proxy.next_page?
|
21
|
+
|
22
|
+
list_proxy = FreshBooks::Page.new(1, 2, 3)
|
23
|
+
assert list_proxy.next_page?
|
24
|
+
|
25
|
+
list_proxy = FreshBooks::Page.new(2, 2, 3)
|
26
|
+
assert !list_proxy.next_page?
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_page_number
|
30
|
+
list_proxy = FreshBooks::Page.new(1, 2, 1)
|
31
|
+
assert_equal 1, list_proxy.page_number(0)
|
32
|
+
|
33
|
+
list_proxy = FreshBooks::Page.new(1, 2, 3)
|
34
|
+
assert_equal 1, list_proxy.page_number(1)
|
35
|
+
|
36
|
+
list_proxy = FreshBooks::Page.new(1, 2, 3)
|
37
|
+
assert_equal 2, list_proxy.page_number(2)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_position_number
|
41
|
+
list_proxy = FreshBooks::Page.new(1, 2, 1)
|
42
|
+
assert_equal 0, list_proxy.position_number(0)
|
43
|
+
|
44
|
+
list_proxy = FreshBooks::Page.new(1, 2, 3)
|
45
|
+
assert_equal 1, list_proxy.position_number(1)
|
46
|
+
|
47
|
+
list_proxy = FreshBooks::Page.new(2, 2, 3)
|
48
|
+
assert_equal 0, list_proxy.position_number(2)
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jpablobr-freshbooks
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jose Pablo Barrantes
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-22 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: jpablobr-freshBooks is a Ruby interface to the FreshBooks API. It exposes easy-to-use classes and methods for interacting with your FreshBooks account.
|
22
|
+
email: xjpablobrx@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- LICENSE
|
29
|
+
- README
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- History.txt
|
33
|
+
- LICENSE
|
34
|
+
- Manifest.txt
|
35
|
+
- README
|
36
|
+
- Rakefile
|
37
|
+
- lib/freshbooks.rb
|
38
|
+
- lib/freshbooks/base.rb
|
39
|
+
- lib/freshbooks/category.rb
|
40
|
+
- lib/freshbooks/client.rb
|
41
|
+
- lib/freshbooks/connection.rb
|
42
|
+
- lib/freshbooks/estimate.rb
|
43
|
+
- lib/freshbooks/expense.rb
|
44
|
+
- lib/freshbooks/invoice.rb
|
45
|
+
- lib/freshbooks/item.rb
|
46
|
+
- lib/freshbooks/line.rb
|
47
|
+
- lib/freshbooks/links.rb
|
48
|
+
- lib/freshbooks/list_proxy.rb
|
49
|
+
- lib/freshbooks/payment.rb
|
50
|
+
- lib/freshbooks/project.rb
|
51
|
+
- lib/freshbooks/recurring.rb
|
52
|
+
- lib/freshbooks/response.rb
|
53
|
+
- lib/freshbooks/schema/definition.rb
|
54
|
+
- lib/freshbooks/schema/mixin.rb
|
55
|
+
- lib/freshbooks/staff.rb
|
56
|
+
- lib/freshbooks/task.rb
|
57
|
+
- lib/freshbooks/time_entry.rb
|
58
|
+
- lib/freshbooks/xml_serializer.rb
|
59
|
+
- lib/freshbooks/xml_serializer/serializers.rb
|
60
|
+
- script/console
|
61
|
+
- script/destroy
|
62
|
+
- script/generate
|
63
|
+
- test/fixtures/invoice_create_response.xml
|
64
|
+
- test/fixtures/invoice_get_response.xml
|
65
|
+
- test/fixtures/invoice_list_response.xml
|
66
|
+
- test/fixtures/success_response.xml
|
67
|
+
- test/mock_connection.rb
|
68
|
+
- test/schema/test_definition.rb
|
69
|
+
- test/schema/test_mixin.rb
|
70
|
+
- test/test_base.rb
|
71
|
+
- test/test_connection.rb
|
72
|
+
- test/test_helper.rb
|
73
|
+
- test/test_invoice.rb
|
74
|
+
- test/test_list_proxy.rb
|
75
|
+
- test/test_page.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/jpablobr/freshbooks.rb
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options:
|
82
|
+
- --charset=UTF-8
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.3.6
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: jpablobr-freshBooks is a Ruby interface to the FreshBooks API.
|
106
|
+
test_files:
|
107
|
+
- test/mock_connection.rb
|
108
|
+
- test/schema/test_definition.rb
|
109
|
+
- test/schema/test_mixin.rb
|
110
|
+
- test/test_base.rb
|
111
|
+
- test/test_connection.rb
|
112
|
+
- test/test_helper.rb
|
113
|
+
- test/test_invoice.rb
|
114
|
+
- test/test_list_proxy.rb
|
115
|
+
- test/test_page.rb
|