jpablobr-freshbooks 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +5 -0
  2. data/History.txt +8 -0
  3. data/LICENSE +10 -0
  4. data/Manifest.txt +44 -0
  5. data/README +65 -0
  6. data/Rakefile +19 -0
  7. data/lib/freshbooks.rb +94 -0
  8. data/lib/freshbooks/base.rb +168 -0
  9. data/lib/freshbooks/category.rb +11 -0
  10. data/lib/freshbooks/client.rb +20 -0
  11. data/lib/freshbooks/connection.rb +112 -0
  12. data/lib/freshbooks/estimate.rb +23 -0
  13. data/lib/freshbooks/expense.rb +12 -0
  14. data/lib/freshbooks/invoice.rb +25 -0
  15. data/lib/freshbooks/item.rb +11 -0
  16. data/lib/freshbooks/line.rb +10 -0
  17. data/lib/freshbooks/links.rb +7 -0
  18. data/lib/freshbooks/list_proxy.rb +70 -0
  19. data/lib/freshbooks/payment.rb +12 -0
  20. data/lib/freshbooks/project.rb +12 -0
  21. data/lib/freshbooks/recurring.rb +15 -0
  22. data/lib/freshbooks/response.rb +27 -0
  23. data/lib/freshbooks/schema/definition.rb +20 -0
  24. data/lib/freshbooks/schema/mixin.rb +40 -0
  25. data/lib/freshbooks/staff.rb +13 -0
  26. data/lib/freshbooks/task.rb +12 -0
  27. data/lib/freshbooks/time_entry.rb +12 -0
  28. data/lib/freshbooks/xml_serializer.rb +17 -0
  29. data/lib/freshbooks/xml_serializer/serializers.rb +107 -0
  30. data/script/console +10 -0
  31. data/script/destroy +14 -0
  32. data/script/generate +14 -0
  33. data/test/fixtures/invoice_create_response.xml +4 -0
  34. data/test/fixtures/invoice_get_response.xml +51 -0
  35. data/test/fixtures/invoice_list_response.xml +27 -0
  36. data/test/fixtures/success_response.xml +2 -0
  37. data/test/mock_connection.rb +13 -0
  38. data/test/schema/test_definition.rb +36 -0
  39. data/test/schema/test_mixin.rb +39 -0
  40. data/test/test_base.rb +97 -0
  41. data/test/test_connection.rb +83 -0
  42. data/test/test_helper.rb +32 -0
  43. data/test/test_invoice.rb +122 -0
  44. data/test/test_list_proxy.rb +41 -0
  45. data/test/test_page.rb +50 -0
  46. 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
@@ -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
@@ -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