cashboard 1.0.1

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.
Files changed (62) hide show
  1. data/.autotest +26 -0
  2. data/.gitignore +2 -0
  3. data/LICENSE +19 -0
  4. data/README.textile +58 -0
  5. data/Rakefile +25 -0
  6. data/cashboard.gemspec +129 -0
  7. data/examples/create_account.rb +38 -0
  8. data/examples/list_stuff_in_account.rb +15 -0
  9. data/examples/simple_workflow.rb +35 -0
  10. data/examples/time_tracking.rb +30 -0
  11. data/examples/toggle_timer.rb +0 -0
  12. data/lib/cashboard/account.rb +21 -0
  13. data/lib/cashboard/base.rb +223 -0
  14. data/lib/cashboard/behaviors/base.rb +4 -0
  15. data/lib/cashboard/behaviors/lists_line_items.rb +32 -0
  16. data/lib/cashboard/behaviors/toggleable.rb +18 -0
  17. data/lib/cashboard/client_company.rb +25 -0
  18. data/lib/cashboard/client_contact.rb +32 -0
  19. data/lib/cashboard/company_membership.rb +6 -0
  20. data/lib/cashboard/document_template.rb +10 -0
  21. data/lib/cashboard/employee.rb +29 -0
  22. data/lib/cashboard/errors.rb +48 -0
  23. data/lib/cashboard/estimate.rb +43 -0
  24. data/lib/cashboard/expense.rb +14 -0
  25. data/lib/cashboard/invoice.rb +75 -0
  26. data/lib/cashboard/invoice_line_item.rb +15 -0
  27. data/lib/cashboard/invoice_payment.rb +7 -0
  28. data/lib/cashboard/line_item.rb +27 -0
  29. data/lib/cashboard/payment.rb +22 -0
  30. data/lib/cashboard/project.rb +38 -0
  31. data/lib/cashboard/project_assignment.rb +9 -0
  32. data/lib/cashboard/time_entry.rb +45 -0
  33. data/lib/cashboard/version.rb +3 -0
  34. data/lib/cashboard.rb +75 -0
  35. data/lib/typecasted_open_struct.rb +82 -0
  36. data/test/fixtures/account.xml +50 -0
  37. data/test/fixtures/cashboard_credentials.yml +3 -0
  38. data/test/fixtures/client_companies.xml +41 -0
  39. data/test/fixtures/client_contacts.xml +53 -0
  40. data/test/fixtures/company_memberships.xml +21 -0
  41. data/test/fixtures/document_templates.xml +53 -0
  42. data/test/fixtures/employees.xml +51 -0
  43. data/test/fixtures/estimates.xml +243 -0
  44. data/test/fixtures/expenses.xml +101 -0
  45. data/test/fixtures/invoice_line_items.xml +138 -0
  46. data/test/fixtures/invoice_payments.xml +10 -0
  47. data/test/fixtures/invoices.xml +231 -0
  48. data/test/fixtures/line_items.xml +243 -0
  49. data/test/fixtures/payments.xml +93 -0
  50. data/test/fixtures/project_assignments.xml +30 -0
  51. data/test/fixtures/projects.xml +129 -0
  52. data/test/fixtures/time_entries.xml +213 -0
  53. data/test/full.rb +3 -0
  54. data/test/test_helper.rb +112 -0
  55. data/test/unit/account_test.rb +85 -0
  56. data/test/unit/document_template_test.rb +18 -0
  57. data/test/unit/estimate_test.rb +166 -0
  58. data/test/unit/expense_test.rb +16 -0
  59. data/test/unit/invoice_test.rb +185 -0
  60. data/test/unit/project_test.rb +198 -0
  61. data/test/unit/time_entry_test.rb +225 -0
  62. metadata +220 -0
@@ -0,0 +1,93 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <payments type="array">
3
+ <payment>
4
+ <link rel="invoices" href="http://apicashboard.i/payments/783544818/invoices"/>
5
+ <link rel="self" href="http://apicashboard.i/payments/783544818"/>
6
+ <id>783544818</id>
7
+ <amount rel="financial">50.00</amount>
8
+ <assigned_id>0</assigned_id>
9
+ <client_id>760501033</client_id>
10
+ <client_type>Company</client_type>
11
+ <created_on>2010-07-14</created_on>
12
+ <document_template_id></document_template_id>
13
+ <estimate_id></estimate_id>
14
+ <notes></notes>
15
+ <person_id>121898072</person_id>
16
+ <transaction_id></transaction_id>
17
+ </payment>
18
+ <payment>
19
+ <link rel="invoices" href="http://apicashboard.i/payments/699647491/invoices"/>
20
+ <link rel="self" href="http://apicashboard.i/payments/699647491"/>
21
+ <id>699647491</id>
22
+ <amount rel="financial">30.00</amount>
23
+ <assigned_id>2</assigned_id>
24
+ <client_id>760501033</client_id>
25
+ <client_type>Company</client_type>
26
+ <created_on>2010-07-14</created_on>
27
+ <document_template_id></document_template_id>
28
+ <estimate_id></estimate_id>
29
+ <notes></notes>
30
+ <person_id>121898072</person_id>
31
+ <transaction_id></transaction_id>
32
+ </payment>
33
+ <payment>
34
+ <link rel="invoices" href="http://apicashboard.i/payments/757178126/invoices"/>
35
+ <link rel="self" href="http://apicashboard.i/payments/757178126"/>
36
+ <id>757178126</id>
37
+ <amount rel="financial">800.00</amount>
38
+ <assigned_id>200</assigned_id>
39
+ <client_id>225395361</client_id>
40
+ <client_type>Person</client_type>
41
+ <created_on>2010-06-28</created_on>
42
+ <document_template_id></document_template_id>
43
+ <estimate_id></estimate_id>
44
+ <notes></notes>
45
+ <person_id></person_id>
46
+ <transaction_id></transaction_id>
47
+ </payment>
48
+ <payment>
49
+ <link rel="invoices" href="http://apicashboard.i/payments/1063113957/invoices"/>
50
+ <link rel="self" href="http://apicashboard.i/payments/1063113957"/>
51
+ <id>1063113957</id>
52
+ <amount rel="financial">100.00</amount>
53
+ <assigned_id>3</assigned_id>
54
+ <client_id>760501033</client_id>
55
+ <client_type>Company</client_type>
56
+ <created_on>2010-06-16</created_on>
57
+ <document_template_id></document_template_id>
58
+ <estimate_id></estimate_id>
59
+ <notes></notes>
60
+ <person_id>121898072</person_id>
61
+ <transaction_id></transaction_id>
62
+ </payment>
63
+ <payment>
64
+ <link rel="invoices" href="http://apicashboard.i/payments/736105732/invoices"/>
65
+ <link rel="self" href="http://apicashboard.i/payments/736105732"/>
66
+ <id>736105732</id>
67
+ <amount rel="financial">750.00</amount>
68
+ <assigned_id>4</assigned_id>
69
+ <client_id>695681551</client_id>
70
+ <client_type>Company</client_type>
71
+ <created_on>2009-07-28</created_on>
72
+ <document_template_id></document_template_id>
73
+ <estimate_id></estimate_id>
74
+ <notes></notes>
75
+ <person_id></person_id>
76
+ <transaction_id></transaction_id>
77
+ </payment>
78
+ <payment>
79
+ <link rel="invoices" href="http://apicashboard.i/payments/1058390128/invoices"/>
80
+ <link rel="self" href="http://apicashboard.i/payments/1058390128"/>
81
+ <id>1058390128</id>
82
+ <amount rel="financial">500.00</amount>
83
+ <assigned_id>500</assigned_id>
84
+ <client_id>121898072</client_id>
85
+ <client_type>Person</client_type>
86
+ <created_on>2010-06-28</created_on>
87
+ <document_template_id></document_template_id>
88
+ <estimate_id></estimate_id>
89
+ <notes></notes>
90
+ <person_id></person_id>
91
+ <transaction_id></transaction_id>
92
+ </payment>
93
+ </payments>
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project_assignments type="array">
3
+ <project_assignment>
4
+ <link rel="self" href="http://apicashboard.i/project_assignments/345337579"/>
5
+ <id>345337579</id>
6
+ <bill_rate rel="financial">75.00</bill_rate>
7
+ <has_access>true</has_access>
8
+ <pay_rate rel="financial">55.00</pay_rate>
9
+ <person_id>496989602</person_id>
10
+ <project_id>317862090</project_id>
11
+ </project_assignment>
12
+ <project_assignment>
13
+ <link rel="self" href="http://apicashboard.i/project_assignments/708146559"/>
14
+ <id>708146559</id>
15
+ <bill_rate rel="financial">35.00</bill_rate>
16
+ <has_access>true</has_access>
17
+ <pay_rate rel="financial">20.00</pay_rate>
18
+ <person_id>496989602</person_id>
19
+ <project_id>708146559</project_id>
20
+ </project_assignment>
21
+ <project_assignment>
22
+ <link rel="self" href="http://apicashboard.i/project_assignments/1073069532"/>
23
+ <id>1073069532</id>
24
+ <bill_rate rel="financial">75.00</bill_rate>
25
+ <has_access>true</has_access>
26
+ <pay_rate rel="financial">75.00</pay_rate>
27
+ <person_id>215816037</person_id>
28
+ <project_id>708146559</project_id>
29
+ </project_assignment>
30
+ </project_assignments>
@@ -0,0 +1,129 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projects type="array">
3
+ <project>
4
+ <link rel="self" href="http://apicashboard.i/projects/107689257"/>
5
+ <link rel="toggle_status" href="http://apicashboard.i/projects/107689257/toggle_status"/>
6
+ <link rel="line_items" href="http://apicashboard.i/projects/107689257/line_items"/>
7
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/107689257/assigned_employees"/>
8
+ <id>107689257</id>
9
+ <billing_code>1</billing_code>
10
+ <client_name read_only="true">Widgets Unlimited</client_name>
11
+ <client_id>695681551</client_id>
12
+ <client_type>Company</client_type>
13
+ <client_view_time_code>0</client_view_time_code>
14
+ <completion_date></completion_date>
15
+ <created_on>2010-07-21 00:00:00</created_on>
16
+ <is_active read_only="true">false</is_active>
17
+ <name>Internal Estimate</name>
18
+ <rate>0.00</rate>
19
+ <start_date>2010-07-28</start_date>
20
+ </project>
21
+ <project>
22
+ <link rel="self" href="http://apicashboard.i/projects/317862090"/>
23
+ <link rel="toggle_status" href="http://apicashboard.i/projects/317862090/toggle_status"/>
24
+ <link rel="line_items" href="http://apicashboard.i/projects/317862090/line_items"/>
25
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/317862090/assigned_employees"/>
26
+ <id>317862090</id>
27
+ <billing_code>1</billing_code>
28
+ <client_name read_only="true">Bobs Manufacturing</client_name>
29
+ <client_id>760501033</client_id>
30
+ <client_type>Company</client_type>
31
+ <client_view_time_code>0</client_view_time_code>
32
+ <completion_date></completion_date>
33
+ <created_on>2010-07-21 00:00:00</created_on>
34
+ <is_active read_only="true">true</is_active>
35
+ <name>Auctions Redesign</name>
36
+ <rate>60.00</rate>
37
+ <start_date>2010-07-28</start_date>
38
+ </project>
39
+ <project>
40
+ <link rel="self" href="http://apicashboard.i/projects/708146559"/>
41
+ <link rel="toggle_status" href="http://apicashboard.i/projects/708146559/toggle_status"/>
42
+ <link rel="line_items" href="http://apicashboard.i/projects/708146559/line_items"/>
43
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/708146559/assigned_employees"/>
44
+ <id>708146559</id>
45
+ <billing_code>2</billing_code>
46
+ <client_name read_only="true">Survial LTD</client_name>
47
+ <client_id>438872084</client_id>
48
+ <client_type>Company</client_type>
49
+ <client_view_time_code>0</client_view_time_code>
50
+ <completion_date></completion_date>
51
+ <created_on>2010-07-21 00:00:00</created_on>
52
+ <is_active read_only="true">true</is_active>
53
+ <name>Fend for yourselves, employee rate!</name>
54
+ <rate>0.00</rate>
55
+ <start_date>2010-07-28</start_date>
56
+ </project>
57
+ <project>
58
+ <link rel="self" href="http://apicashboard.i/projects/39791954"/>
59
+ <link rel="toggle_status" href="http://apicashboard.i/projects/39791954/toggle_status"/>
60
+ <link rel="line_items" href="http://apicashboard.i/projects/39791954/line_items"/>
61
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/39791954/assigned_employees"/>
62
+ <id>39791954</id>
63
+ <billing_code>1</billing_code>
64
+ <client_name read_only="true">Bob Barker</client_name>
65
+ <client_id>121898072</client_id>
66
+ <client_type>Person</client_type>
67
+ <client_view_time_code>0</client_view_time_code>
68
+ <completion_date></completion_date>
69
+ <created_on>2010-07-21 00:00:00</created_on>
70
+ <is_active read_only="true">true</is_active>
71
+ <name>Personal Person Project</name>
72
+ <rate>60.00</rate>
73
+ <start_date>2010-07-28</start_date>
74
+ </project>
75
+ <project>
76
+ <link rel="self" href="http://apicashboard.i/projects/660985040"/>
77
+ <link rel="toggle_status" href="http://apicashboard.i/projects/660985040/toggle_status"/>
78
+ <link rel="line_items" href="http://apicashboard.i/projects/660985040/line_items"/>
79
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/660985040/assigned_employees"/>
80
+ <id>660985040</id>
81
+ <billing_code>1</billing_code>
82
+ <client_name read_only="true">Survial LTD</client_name>
83
+ <client_id>438872084</client_id>
84
+ <client_type>Company</client_type>
85
+ <client_view_time_code>0</client_view_time_code>
86
+ <completion_date></completion_date>
87
+ <created_on>2010-07-21 00:00:00</created_on>
88
+ <is_active read_only="true">true</is_active>
89
+ <name>Survivalist Tendencies</name>
90
+ <rate>0.00</rate>
91
+ <start_date>2010-07-28</start_date>
92
+ </project>
93
+ <project>
94
+ <link rel="self" href="http://apicashboard.i/projects/200482051"/>
95
+ <link rel="toggle_status" href="http://apicashboard.i/projects/200482051/toggle_status"/>
96
+ <link rel="line_items" href="http://apicashboard.i/projects/200482051/line_items"/>
97
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/200482051/assigned_employees"/>
98
+ <id>200482051</id>
99
+ <billing_code>0</billing_code>
100
+ <client_name read_only="true">Widgets Unlimited</client_name>
101
+ <client_id>695681551</client_id>
102
+ <client_type>Company</client_type>
103
+ <client_view_time_code>0</client_view_time_code>
104
+ <completion_date></completion_date>
105
+ <created_on>2010-07-21 00:00:00</created_on>
106
+ <is_active read_only="true">true</is_active>
107
+ <name>XYZ Internal Stuff</name>
108
+ <rate>0.00</rate>
109
+ <start_date>2010-07-28</start_date>
110
+ </project>
111
+ <project>
112
+ <link rel="self" href="http://apicashboard.i/projects/198381282"/>
113
+ <link rel="toggle_status" href="http://apicashboard.i/projects/198381282/toggle_status"/>
114
+ <link rel="line_items" href="http://apicashboard.i/projects/198381282/line_items"/>
115
+ <link rel="assigned_employees" href="http://apicashboard.i/projects/198381282/assigned_employees"/>
116
+ <id>198381282</id>
117
+ <billing_code>1</billing_code>
118
+ <client_name read_only="true">Bobs Manufacturing</client_name>
119
+ <client_id>760501033</client_id>
120
+ <client_type>Company</client_type>
121
+ <client_view_time_code>0</client_view_time_code>
122
+ <completion_date></completion_date>
123
+ <created_on>2010-07-14 00:00:00</created_on>
124
+ <is_active read_only="true">false</is_active>
125
+ <name>Inactive Project</name>
126
+ <rate>60.00</rate>
127
+ <start_date></start_date>
128
+ </project>
129
+ </projects>
@@ -0,0 +1,213 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <time_entries type="array">
3
+ <time_entry>
4
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/200482051/toggle_timer"/>
5
+ <link rel="self" href="http://apicashboard.i/time_entries/200482051"/>
6
+ <id>200482051</id>
7
+ <created_on>2001-01-01 23:35:00</created_on>
8
+ <description>60 minutes of admin time on internal project</description>
9
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
10
+ <is_billable>true</is_billable>
11
+ <is_running read_only="true">false</is_running>
12
+ <line_item_id>200482051</line_item_id>
13
+ <minutes>60</minutes>
14
+ <minutes_with_timer read_only="true">60</minutes_with_timer>
15
+ <person_id>215816037</person_id>
16
+ <timer_started_at read_only="true"></timer_started_at>
17
+ </time_entry>
18
+ <time_entry>
19
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/800720104/toggle_timer"/>
20
+ <link rel="self" href="http://apicashboard.i/time_entries/800720104"/>
21
+ <id>800720104</id>
22
+ <created_on>2007-04-05 01:26:43</created_on>
23
+ <description>Not billed yet.</description>
24
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
25
+ <is_billable>false</is_billable>
26
+ <is_running read_only="true">false</is_running>
27
+ <line_item_id>5568311</line_item_id>
28
+ <minutes>30</minutes>
29
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
30
+ <person_id>215816037</person_id>
31
+ <timer_started_at read_only="true"></timer_started_at>
32
+ </time_entry>
33
+ <time_entry>
34
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/917722452/toggle_timer"/>
35
+ <link rel="self" href="http://apicashboard.i/time_entries/917722452"/>
36
+ <id>917722452</id>
37
+ <created_on>2007-04-05 01:26:43</created_on>
38
+ <description>Also not billed yet.</description>
39
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
40
+ <is_billable>true</is_billable>
41
+ <is_running read_only="true">false</is_running>
42
+ <line_item_id>5568311</line_item_id>
43
+ <minutes>30</minutes>
44
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
45
+ <person_id>215816037</person_id>
46
+ <timer_started_at read_only="true"></timer_started_at>
47
+ </time_entry>
48
+ <time_entry>
49
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/28599751/toggle_timer"/>
50
+ <link rel="self" href="http://apicashboard.i/time_entries/28599751"/>
51
+ <id>28599751</id>
52
+ <created_on>2007-04-05 01:26:43</created_on>
53
+ <description>Also not billed yet.</description>
54
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
55
+ <is_billable>true</is_billable>
56
+ <is_running read_only="true">false</is_running>
57
+ <line_item_id>332946883</line_item_id>
58
+ <minutes>90</minutes>
59
+ <minutes_with_timer read_only="true">90</minutes_with_timer>
60
+ <person_id>215816037</person_id>
61
+ <timer_started_at read_only="true"></timer_started_at>
62
+ </time_entry>
63
+ <time_entry>
64
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/720402845/toggle_timer"/>
65
+ <link rel="self" href="http://apicashboard.i/time_entries/720402845"/>
66
+ <id>720402845</id>
67
+ <created_on>2007-05-01 08:00:00</created_on>
68
+ <description>Doing stuff for money.</description>
69
+ <invoice_line_item_id read_only="true">1002399820</invoice_line_item_id>
70
+ <is_billable>true</is_billable>
71
+ <is_running read_only="true">false</is_running>
72
+ <line_item_id>5568311</line_item_id>
73
+ <minutes>30</minutes>
74
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
75
+ <person_id>215816037</person_id>
76
+ <timer_started_at read_only="true"></timer_started_at>
77
+ </time_entry>
78
+ <time_entry>
79
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/871966761/toggle_timer"/>
80
+ <link rel="self" href="http://apicashboard.i/time_entries/871966761"/>
81
+ <id>871966761</id>
82
+ <created_on>2007-05-01 08:00:00</created_on>
83
+ <description>More stuff, more money.</description>
84
+ <invoice_line_item_id read_only="true">1002399820</invoice_line_item_id>
85
+ <is_billable>true</is_billable>
86
+ <is_running read_only="true">false</is_running>
87
+ <line_item_id>5568311</line_item_id>
88
+ <minutes>30</minutes>
89
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
90
+ <person_id>215816037</person_id>
91
+ <timer_started_at read_only="true"></timer_started_at>
92
+ </time_entry>
93
+ <time_entry>
94
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/593385312/toggle_timer"/>
95
+ <link rel="self" href="http://apicashboard.i/time_entries/593385312"/>
96
+ <id>593385312</id>
97
+ <created_on>2007-05-01 08:00:00</created_on>
98
+ <description>Employee time 2</description>
99
+ <invoice_line_item_id read_only="true">582367732</invoice_line_item_id>
100
+ <is_billable>true</is_billable>
101
+ <is_running read_only="true">false</is_running>
102
+ <line_item_id>332946883</line_item_id>
103
+ <minutes>30</minutes>
104
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
105
+ <person_id>496989602</person_id>
106
+ <timer_started_at read_only="true"></timer_started_at>
107
+ </time_entry>
108
+ <time_entry>
109
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/978781916/toggle_timer"/>
110
+ <link rel="self" href="http://apicashboard.i/time_entries/978781916"/>
111
+ <id>978781916</id>
112
+ <created_on>2007-05-01 08:00:00</created_on>
113
+ <description>Employee time 1</description>
114
+ <invoice_line_item_id read_only="true">582367732</invoice_line_item_id>
115
+ <is_billable>true</is_billable>
116
+ <is_running read_only="true">false</is_running>
117
+ <line_item_id>332946883</line_item_id>
118
+ <minutes>30</minutes>
119
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
120
+ <person_id>496989602</person_id>
121
+ <timer_started_at read_only="true"></timer_started_at>
122
+ </time_entry>
123
+ <time_entry>
124
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/350357096/toggle_timer"/>
125
+ <link rel="self" href="http://apicashboard.i/time_entries/350357096"/>
126
+ <id>350357096</id>
127
+ <created_on>2007-05-01 08:00:00</created_on>
128
+ <description>Time entry for inactive project</description>
129
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
130
+ <is_billable>true</is_billable>
131
+ <is_running read_only="true">false</is_running>
132
+ <line_item_id>495791875</line_item_id>
133
+ <minutes>100</minutes>
134
+ <minutes_with_timer read_only="true">100</minutes_with_timer>
135
+ <person_id>496989602</person_id>
136
+ <timer_started_at read_only="true"></timer_started_at>
137
+ </time_entry>
138
+ <time_entry>
139
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/83761332/toggle_timer"/>
140
+ <link rel="self" href="http://apicashboard.i/time_entries/83761332"/>
141
+ <id>83761332</id>
142
+ <created_on>2007-05-02 08:00:00</created_on>
143
+ <description>Creation of custom logger, incorporation into models, controllers, mailers</description>
144
+ <invoice_line_item_id read_only="true">1002399820</invoice_line_item_id>
145
+ <is_billable>true</is_billable>
146
+ <is_running read_only="true">false</is_running>
147
+ <line_item_id>5568311</line_item_id>
148
+ <minutes>30</minutes>
149
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
150
+ <person_id>215816037</person_id>
151
+ <timer_started_at read_only="true"></timer_started_at>
152
+ </time_entry>
153
+ <time_entry>
154
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/476397491/toggle_timer"/>
155
+ <link rel="self" href="http://apicashboard.i/time_entries/476397491"/>
156
+ <id>476397491</id>
157
+ <created_on>2008-05-22 23:35:00</created_on>
158
+ <description>30 minutes of nonbillable employee time</description>
159
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
160
+ <is_billable>false</is_billable>
161
+ <is_running read_only="true">false</is_running>
162
+ <line_item_id>630194006</line_item_id>
163
+ <minutes>30</minutes>
164
+ <minutes_with_timer read_only="true">30</minutes_with_timer>
165
+ <person_id>496989602</person_id>
166
+ <timer_started_at read_only="true"></timer_started_at>
167
+ </time_entry>
168
+ <time_entry>
169
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/10069123/toggle_timer"/>
170
+ <link rel="self" href="http://apicashboard.i/time_entries/10069123"/>
171
+ <id>10069123</id>
172
+ <created_on>2008-05-22 23:35:00</created_on>
173
+ <description>60 minutes of admin time</description>
174
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
175
+ <is_billable>true</is_billable>
176
+ <is_running read_only="true">false</is_running>
177
+ <line_item_id>630194006</line_item_id>
178
+ <minutes>60</minutes>
179
+ <minutes_with_timer read_only="true">60</minutes_with_timer>
180
+ <person_id>215816037</person_id>
181
+ <timer_started_at read_only="true"></timer_started_at>
182
+ </time_entry>
183
+ <time_entry>
184
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/800636155/toggle_timer"/>
185
+ <link rel="self" href="http://apicashboard.i/time_entries/800636155"/>
186
+ <id>800636155</id>
187
+ <created_on>2008-05-22 23:35:00</created_on>
188
+ <description>Testing end of day import bug</description>
189
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
190
+ <is_billable>true</is_billable>
191
+ <is_running read_only="true">false</is_running>
192
+ <line_item_id>495791875</line_item_id>
193
+ <minutes>60</minutes>
194
+ <minutes_with_timer read_only="true">60</minutes_with_timer>
195
+ <person_id>215816037</person_id>
196
+ <timer_started_at read_only="true"></timer_started_at>
197
+ </time_entry>
198
+ <time_entry>
199
+ <link rel="toggle_timer" href="http://apicashboard.i/time_entries/965291090/toggle_timer"/>
200
+ <link rel="self" href="http://apicashboard.i/time_entries/965291090"/>
201
+ <id>965291090</id>
202
+ <created_on>2008-05-22 23:35:00</created_on>
203
+ <description>60 minutes of employee time</description>
204
+ <invoice_line_item_id read_only="true"></invoice_line_item_id>
205
+ <is_billable>true</is_billable>
206
+ <is_running read_only="true">false</is_running>
207
+ <line_item_id>630194006</line_item_id>
208
+ <minutes>60</minutes>
209
+ <minutes_with_timer read_only="true">60</minutes_with_timer>
210
+ <person_id>496989602</person_id>
211
+ <timer_started_at read_only="true"></timer_started_at>
212
+ </time_entry>
213
+ </time_entries>
data/test/full.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Runs all unit tests for the library
2
+ require 'test/unit'
3
+ Dir[File.join(File.dirname(__FILE__), 'unit/*.rb')].each {|lib| require lib}
@@ -0,0 +1,112 @@
1
+ TEST_ENVIRONMENT = true
2
+
3
+ require File.dirname(__FILE__) + '/../lib/cashboard'
4
+ require 'test/unit'
5
+ require 'yaml'
6
+ require 'rubygems'
7
+ require 'mocha'
8
+ require 'fakeweb'
9
+
10
+ FIXTURE_PATH = File.join(File.dirname(__FILE__), 'fixtures')
11
+ GENERIC_ERROR_XML = %Q\
12
+ <errors><error field="name">Is required</error></errors>
13
+ \
14
+
15
+ # Useful for turning off mocks in test suites globally.
16
+ #
17
+ # If you set this to FALSE the requests will go over the wire
18
+ # and attempt to conenct to the account specified in
19
+ # fixtures/cashboard_credentials.yml.
20
+ MOCK_WEB_CONNECTIONS = true
21
+
22
+ class Test::Unit::TestCase
23
+
24
+ # Loads auth credentials from a fixture file.
25
+ # NOT included in the base distribution. You need to create one
26
+ # if you wish to test, using the example file.
27
+ def setup
28
+ @auth = YAML::load(File.open(File.join(
29
+ File.dirname(__FILE__),
30
+ 'fixtures/cashboard_credentials.yml'
31
+ ))
32
+ )
33
+
34
+ Cashboard::Base.authenticate(
35
+ @auth['test_account']['subdomain'],
36
+ @auth['test_account']['api_key']
37
+ )
38
+
39
+ if MOCK_WEB_CONNECTIONS
40
+ FakeWeb.allow_net_connect = false
41
+ mock_simple_list_requests
42
+ end
43
+ end
44
+
45
+ # Generates a random alphanumeric string
46
+ def generate_random_string(size=10)
47
+ chars = (('a'..'z').to_a + ('0'..'9').to_a)
48
+ (1..size).collect{|a| chars[rand(chars.size)] }.join
49
+ end
50
+
51
+ # Returns XML string to be used as body of HTTP request.
52
+ # Useful as a shortcut from mocking requests in other tests.
53
+ def get_xml_for_fixture(resource)
54
+ file_name = File.join(FIXTURE_PATH, "#{resource}.xml")
55
+ return File.open(file_name, 'rb') { |f| f.read }
56
+ end
57
+
58
+ # Returns a regular expression that matches multiple fakeweb requests
59
+ # for sub resource URLS...like http://apicashboard.i/projects/{project-id}/line_items
60
+ def get_sub_url_regexp(resource, sub_resource)
61
+ url_no_prefix = Cashboard::Base.api_url.gsub(%r|https*\://|, '')
62
+ %r|#{url_no_prefix}/#{resource}/.*/#{sub_resource}|
63
+ end
64
+
65
+ # Returns the base API url with authentication credentials applied.
66
+ # Useful for fakeweb, which will be passed the auth string
67
+ # by HTTParty automatically.
68
+ #
69
+ # If a URL is passed in, it will be deconstructed and auth credentials
70
+ # added in place. Useful for mocking fakeweb requests for delete/update/etc.
71
+ def url_with_auth(passed_url=nil)
72
+ prefix_pattern = %r|https*\://|
73
+ url_prefix = Cashboard::Base.api_url.match(prefix_pattern)[0]
74
+ url = url_prefix
75
+ url << "#{@auth['test_account']['subdomain']}:"
76
+ url << "#{@auth['test_account']['api_key']}@"
77
+ url << Cashboard::Base.api_url.gsub(prefix_pattern, '')
78
+ # Replace base url with our auth'd one.
79
+ if passed_url
80
+ url << passed_url.gsub(/.*#{Cashboard::Base.api_url}/, '')
81
+ end
82
+ return url
83
+ end
84
+
85
+ # MOCKS ---------------------------------------------------------------------
86
+
87
+ # Fakes all list requests and returns proper xml response based
88
+ # on fixtures in our test directory.
89
+ def mock_simple_list_requests
90
+ Dir[File.join(FIXTURE_PATH, '/*.xml')].each do |file_name|
91
+ resource_name = file_name.match(/.*\/(.*)\.xml/)[1]
92
+
93
+ FakeWeb.register_uri(
94
+ :get,
95
+ url_with_auth + "/#{resource_name}",
96
+ :body => File.open(file_name, 'rb') { |f| f.read },
97
+ :content_type => "application/xml"
98
+ )
99
+ end
100
+ end
101
+
102
+ # Fakes request for a sub resource.
103
+ def mock_sub_resource(resource, sub_resource, fixture_name, status=['200', 'OK'])
104
+ FakeWeb.register_uri(
105
+ :get,
106
+ get_sub_url_regexp(resource, sub_resource),
107
+ :body => get_xml_for_fixture(fixture_name),
108
+ :status => status
109
+ )
110
+ end
111
+
112
+ end