aiaio-harvest 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +173 -146
- data/lib/harvest.rb +2 -2
- data/lib/harvest/base.rb +5 -0
- data/test/unit/resources/person_test.rb +150 -151
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -1,146 +1,173 @@
|
|
1
|
-
= harvest
|
2
|
-
|
3
|
-
A ruby library wrapping (most of) the Harvest Api.
|
4
|
-
|
5
|
-
== DESCRIPTION:
|
6
|
-
|
7
|
-
This library uses ActiveResource and activeresource_throttle to provide simple, reliable access to the Harvest Api. Good for building reporting scripts and simple apps.
|
8
|
-
|
9
|
-
Note that this library does not support the complete Harvest Api at this time. See Features/Issues below for details.
|
10
|
-
|
11
|
-
== USAGE:
|
12
|
-
|
13
|
-
=== Creating a new harvest object:
|
14
|
-
|
15
|
-
All calls to the Harvest API will originate from a Harvest object. Initialize it like so:
|
16
|
-
|
17
|
-
@harvest = Harvest(:email => "joe@example.com",
|
18
|
-
:password => "secret",
|
19
|
-
:sub_domain => "joeandcompany",
|
20
|
-
:headers => {"User-Agent" => "MyCompany"})
|
21
|
-
|
22
|
-
The _headers_ argument is optional. Use <b>:ssl => true</b> if your account requires HTTPS.
|
23
|
-
|
24
|
-
=== Clients
|
25
|
-
|
26
|
-
Index
|
27
|
-
@harvest.clients.find(:all)
|
28
|
-
Show
|
29
|
-
@harvest.clients.find(43235)
|
30
|
-
Create
|
31
|
-
@client = @harvest.clients.new
|
32
|
-
@client.attributes = {:name => "Company, LLC", :details => "New York, NY"}
|
33
|
-
@client.save
|
34
|
-
Update
|
35
|
-
@client.first_name = "Smith"
|
36
|
-
@client.save
|
37
|
-
Destroy
|
38
|
-
@client.destroy
|
39
|
-
|
40
|
-
Toggle (Active/Inactive)
|
41
|
-
@client.toggle
|
42
|
-
|
43
|
-
=== Tasks
|
44
|
-
|
45
|
-
Index
|
46
|
-
@harvest.tasks.find(:all)
|
47
|
-
Show
|
48
|
-
@harvest.tasks.find(123)
|
49
|
-
Create
|
50
|
-
@task = @harvest.tasks.new
|
51
|
-
@task.attributes = {:name => "Meeting", :billable_by_default => false,
|
52
|
-
:is_default => false, :default_hourly_rate => 100}
|
53
|
-
@task.save
|
54
|
-
Update
|
55
|
-
@task.name = "Client Meeting"
|
56
|
-
@task.save
|
57
|
-
Destroy
|
58
|
-
@task.destroy
|
59
|
-
|
60
|
-
=== People
|
61
|
-
|
62
|
-
Index
|
63
|
-
@harvest.people.find(:all)
|
64
|
-
Show
|
65
|
-
@harvest.people.find(123)
|
66
|
-
|
67
|
-
=== Projects
|
68
|
-
|
69
|
-
Index
|
70
|
-
@harvest.projects.find(:all)
|
71
|
-
Show
|
72
|
-
@harvest.projects.find(123)
|
73
|
-
Create
|
74
|
-
@project = @harvest.projects.new
|
75
|
-
@project.attributes = {:name => "Refactor", :active => true,
|
76
|
-
:bill_by => "None", :client_id => @client.id, }
|
77
|
-
@project.save
|
78
|
-
Update
|
79
|
-
@project.name = "Mega-Refactor"
|
80
|
-
@project.save
|
81
|
-
Destroy
|
82
|
-
@project.destroy
|
83
|
-
|
84
|
-
Toggle (Active/Inactive)
|
85
|
-
@project.toggle
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
@
|
91
|
-
|
92
|
-
|
93
|
-
@
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
@
|
101
|
-
@
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
1
|
+
= harvest
|
2
|
+
|
3
|
+
A ruby library wrapping (most of) the Harvest Api.
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
This library uses ActiveResource and activeresource_throttle to provide simple, reliable access to the Harvest Api. Good for building reporting scripts and simple apps.
|
8
|
+
|
9
|
+
Note that this library does not support the complete Harvest Api at this time. See Features/Issues below for details.
|
10
|
+
|
11
|
+
== USAGE:
|
12
|
+
|
13
|
+
=== Creating a new harvest object:
|
14
|
+
|
15
|
+
All calls to the Harvest API will originate from a Harvest object. Initialize it like so:
|
16
|
+
|
17
|
+
@harvest = Harvest(:email => "joe@example.com",
|
18
|
+
:password => "secret",
|
19
|
+
:sub_domain => "joeandcompany",
|
20
|
+
:headers => {"User-Agent" => "MyCompany"})
|
21
|
+
|
22
|
+
The _headers_ argument is optional. Use <b>:ssl => true</b> if your account requires HTTPS.
|
23
|
+
|
24
|
+
=== Clients
|
25
|
+
|
26
|
+
Index
|
27
|
+
@harvest.clients.find(:all)
|
28
|
+
Show
|
29
|
+
@harvest.clients.find(43235)
|
30
|
+
Create
|
31
|
+
@client = @harvest.clients.new
|
32
|
+
@client.attributes = {:name => "Company, LLC", :details => "New York, NY"}
|
33
|
+
@client.save
|
34
|
+
Update
|
35
|
+
@client.first_name = "Smith"
|
36
|
+
@client.save
|
37
|
+
Destroy
|
38
|
+
@client.destroy
|
39
|
+
|
40
|
+
Toggle (Active/Inactive)
|
41
|
+
@client.toggle
|
42
|
+
|
43
|
+
=== Tasks
|
44
|
+
|
45
|
+
Index
|
46
|
+
@harvest.tasks.find(:all)
|
47
|
+
Show
|
48
|
+
@harvest.tasks.find(123)
|
49
|
+
Create
|
50
|
+
@task = @harvest.tasks.new
|
51
|
+
@task.attributes = {:name => "Meeting", :billable_by_default => false,
|
52
|
+
:is_default => false, :default_hourly_rate => 100}
|
53
|
+
@task.save
|
54
|
+
Update
|
55
|
+
@task.name = "Client Meeting"
|
56
|
+
@task.save
|
57
|
+
Destroy
|
58
|
+
@task.destroy
|
59
|
+
|
60
|
+
=== People
|
61
|
+
|
62
|
+
Index
|
63
|
+
@harvest.people.find(:all)
|
64
|
+
Show
|
65
|
+
@harvest.people.find(123)
|
66
|
+
|
67
|
+
=== Projects
|
68
|
+
|
69
|
+
Index
|
70
|
+
@harvest.projects.find(:all)
|
71
|
+
Show
|
72
|
+
@harvest.projects.find(123)
|
73
|
+
Create
|
74
|
+
@project = @harvest.projects.new
|
75
|
+
@project.attributes = {:name => "Refactor", :active => true,
|
76
|
+
:bill_by => "None", :client_id => @client.id, }
|
77
|
+
@project.save
|
78
|
+
Update
|
79
|
+
@project.name = "Mega-Refactor"
|
80
|
+
@project.save
|
81
|
+
Destroy
|
82
|
+
@project.destroy
|
83
|
+
|
84
|
+
Toggle (Active/Inactive)
|
85
|
+
@project.toggle
|
86
|
+
|
87
|
+
=== Invoices
|
88
|
+
|
89
|
+
Index
|
90
|
+
@invoices = @harvest.invoices.find(:all)
|
91
|
+
|
92
|
+
Show
|
93
|
+
@invoice = @harvest.invoices.find(1)
|
94
|
+
|
95
|
+
Find By Invoice Number
|
96
|
+
@invoice = @harvest.invoices.find_by_number('200')
|
97
|
+
|
98
|
+
Create
|
99
|
+
@invoice = @harvest.invoices.new
|
100
|
+
@invoice.attributes = {:amount => '250.32', :client_id => @client.id}
|
101
|
+
@invoice.save
|
102
|
+
|
103
|
+
Update
|
104
|
+
@invoice.notes = "Pending payment"
|
105
|
+
@invoice.save
|
106
|
+
|
107
|
+
Destroy
|
108
|
+
@invoice.destroy
|
109
|
+
|
110
|
+
Return parsed csv line items
|
111
|
+
@invoice.parsed_csv_line_items
|
112
|
+
|
113
|
+
==== User and Task Assignments
|
114
|
+
|
115
|
+
@project.users.find(:all)
|
116
|
+
@project.users.find(:first)
|
117
|
+
|
118
|
+
@project.tasks.find(:all)
|
119
|
+
@project.tasks.find(:first)
|
120
|
+
|
121
|
+
=== Reports
|
122
|
+
|
123
|
+
@project.entries(:from => Time.now, :to => Time.now)
|
124
|
+
@project.entries(:from => Time.now, :to => Time.now, :user_id => @person.id)
|
125
|
+
|
126
|
+
@person.entries(:from => Time.now, :to => Time.now)
|
127
|
+
@person.expenses(:from => Time.now, :to => Time.now)
|
128
|
+
|
129
|
+
|
130
|
+
== FEATURES/PROBLEMS:
|
131
|
+
|
132
|
+
Supports most of the Harvest Api (http://www.getharvest.com/api).
|
133
|
+
|
134
|
+
Though RESTful, the Harvest Api does not entirely follow ActiveResource conventions. In order to support the complete API, certain customizations will be required. <b>We welcome any contributions/modifications to help complete this Api.</b>
|
135
|
+
|
136
|
+
The following Api features are incomplete due to incompatibilities with ActiveResource conventions (CRUD actions in parentheses):
|
137
|
+
|
138
|
+
1. People (CUD)
|
139
|
+
2. User & Task Assignments (CUD)
|
140
|
+
3. Expenses (CUD)
|
141
|
+
|
142
|
+
In addition, the following have not been implemented at all due to time constraints:
|
143
|
+
|
144
|
+
1. Time Tracking Api
|
145
|
+
2. Invoices, Invoice Payments, Invoice Categories, and Invoice Messages
|
146
|
+
|
147
|
+
Expect a more complete library in the near future. Again, contributions are welcome.
|
148
|
+
|
149
|
+
== TEST SUITE
|
150
|
+
|
151
|
+
This library includes a fairly thorough set of unit and integration tests. The unit tests can be run with the "rake" command.
|
152
|
+
|
153
|
+
The integration tests require a Harvest account. It is best to use a trial account when running these tests.
|
154
|
+
|
155
|
+
The credentials may be entered in test/test_helper.rb. To run the integration suite:
|
156
|
+
|
157
|
+
rake test:integration
|
158
|
+
|
159
|
+
Note that the integration test structure is somewhat unorthodox, as it requires tests to run in a particular order. The main test file is test/integration/harvest_integration_test.rb. Examine this to see how the integration suite works.
|
160
|
+
|
161
|
+
== REQUIREMENTS:
|
162
|
+
|
163
|
+
Requires active_resource >= 2.1 and activeresource_throttle >= 1.0.
|
164
|
+
|
165
|
+
active_resource_throttle should install automaticallt, but just in case you need to install manually:
|
166
|
+
|
167
|
+
gem sources -a http://gems.github.com
|
168
|
+
sudo gem install aiaio-active_resource_throttle
|
169
|
+
|
170
|
+
== INSTALL:
|
171
|
+
|
172
|
+
gem sources -a http://gems.github.com
|
173
|
+
gem install aiaio-harvest
|
data/lib/harvest.rb
CHANGED
@@ -5,7 +5,7 @@ module Harvest
|
|
5
5
|
# Class method to load all ruby files from a given path.
|
6
6
|
def self.load_all_ruby_files_from_path(path)
|
7
7
|
Dir.foreach(path) do |file|
|
8
|
-
require File.join(path, file) if file =~ /\.rb
|
8
|
+
require File.join(path, file) if file =~ /\.rb$/
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -33,4 +33,4 @@ require File.join(File.dirname(__FILE__), "harvest", "harvest_resource")
|
|
33
33
|
# :headers => {"User-Agent => "Harvest Rubygem"})
|
34
34
|
def Harvest(options={})
|
35
35
|
Harvest::Base.new(options)
|
36
|
-
end
|
36
|
+
end
|
data/lib/harvest/base.rb
CHANGED
@@ -1,151 +1,150 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
|
2
|
-
|
3
|
-
class PersonTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
def setup_resources
|
6
|
-
@person_xml = {:id => 1, :name => "Joe Coder"}.to_xml(:root => "person")
|
7
|
-
@people = [{:id => 1, :name => "Joe Coder"}].to_xml(:root => "people")
|
8
|
-
@entry = [{:id => 2, :project_id => 50}].to_xml(:root => "day-entries")
|
9
|
-
@entries = [{:id => 1, :project_id => "25"},
|
10
|
-
{:id => 2, :project_id => 50} ].to_xml(:root => "day-entries")
|
11
|
-
@expenses = [{:id => 1, :project_id => "25"},
|
12
|
-
{:id => 2, :project_id => 50} ].to_xml(:root => "expenses")
|
13
|
-
end
|
14
|
-
|
15
|
-
def mock_responses
|
16
|
-
ActiveResource::HttpMock.respond_to do |mock|
|
17
|
-
mock.get "/people.xml", {}, @people
|
18
|
-
mock.get "/people/1.xml", {}, @person_xml
|
19
|
-
mock.post "/people.xml", {}, @person_xml, 201, "Location" => "/people/5.xml"
|
20
|
-
mock.put "/people/1.xml", {}, nil, 200
|
21
|
-
mock.delete "/people/1.xml", {}, nil, 200
|
22
|
-
mock.put "/people/1/toggle.xml", {}, nil, 200
|
23
|
-
mock.get "/people/1/entries.xml?from=20080101&to=20080131", {}, @entries
|
24
|
-
mock.get "/people/1/entries.xml?from=20080101&project_id=3&to=20080131", {}, @entry
|
25
|
-
mock.get "/people/1/expenses.xml?from=20080101&to=20080131", {}, @expenses
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
context "People CRUD actions -- " do
|
30
|
-
setup do
|
31
|
-
setup_resources
|
32
|
-
mock_responses
|
33
|
-
end
|
34
|
-
|
35
|
-
should "get index" do
|
36
|
-
Harvest::Resources::Person.find(:all)
|
37
|
-
expected_request = ActiveResource::Request.new(:get, "/people.xml")
|
38
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
39
|
-
end
|
40
|
-
|
41
|
-
should "get a single project" do
|
42
|
-
Harvest::Resources::Person.find(1)
|
43
|
-
expected_request = ActiveResource::Request.new(:get, "/people/1.xml")
|
44
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
45
|
-
end
|
46
|
-
|
47
|
-
should "create a new project" do
|
48
|
-
project = Harvest::Resources::Person.new(:name => "Widgets&Co")
|
49
|
-
project.save
|
50
|
-
expected_request = ActiveResource::Request.new(:post, "/people.xml")
|
51
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
52
|
-
end
|
53
|
-
|
54
|
-
should "update an existing project" do
|
55
|
-
project = Harvest::Resources::Person.find(1)
|
56
|
-
project.name = "Joe Coder"
|
57
|
-
project.save
|
58
|
-
expected_request = ActiveResource::Request.new(:put, "/people/1.xml")
|
59
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
60
|
-
end
|
61
|
-
|
62
|
-
should "delete an existing project" do
|
63
|
-
Harvest::Resources::Person.delete(1)
|
64
|
-
expected_request = ActiveResource::Request.new(:delete, "/people/1.xml")
|
65
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
context "Toggling active/inactive status" do
|
72
|
-
setup do
|
73
|
-
setup_resources
|
74
|
-
mock_responses
|
75
|
-
end
|
76
|
-
|
77
|
-
should "hit the toggle method" do
|
78
|
-
person = Harvest::Resources::Person.find(1)
|
79
|
-
person.toggle
|
80
|
-
expected_request = ActiveResource::Request.new(:put, "/people/1/toggle.xml")
|
81
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
82
|
-
end
|
83
|
-
|
84
|
-
should "return 200 Success toggle method" do
|
85
|
-
person = Harvest::Resources::Person.find(1)
|
86
|
-
assert person.toggle.code == 200
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
context "Getting entries" do
|
92
|
-
setup do
|
93
|
-
setup_resources
|
94
|
-
mock_responses
|
95
|
-
@person = Harvest::Resources::Person.find(1)
|
96
|
-
end
|
97
|
-
|
98
|
-
should "raise an error if start and end are not included" do
|
99
|
-
assert_raises ArgumentError, "Must specify :start and :end as dates." do
|
100
|
-
@person.entries
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
should "raise an error if end date precedes start date" do
|
105
|
-
assert_raises ArgumentError, "Must specify :start and :end as dates." do
|
106
|
-
@person.entries(:from => Time.utc(2007, 1, 1), :to => Time.utc(2006, 1, 1))
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
should "return the project site prefix" do
|
111
|
-
entry_class = Harvest::Resources::Entry.clone
|
112
|
-
entry_class.person_id = @person.id
|
113
|
-
assert_equal "http://example.com/people/1", entry_class.site.to_s
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
context "Reports -- " do
|
119
|
-
setup do
|
120
|
-
setup_resources
|
121
|
-
mock_responses
|
122
|
-
@from = Time.utc(2008, 1, 1)
|
123
|
-
@to = Time.utc(2008, 1, 31)
|
124
|
-
@person = Harvest::Resources::Person.find(1)
|
125
|
-
@request_path = "/people/1/entries.xml?from=20080101&to=20080131"
|
126
|
-
@expense_path = "/people/1/expenses.xml?from=20080101&to=20080131"
|
127
|
-
end
|
128
|
-
|
129
|
-
should "get all entries for a given date range" do
|
130
|
-
@person.entries(:from => @from, :to => @to)
|
131
|
-
expected_request = ActiveResource::Request.new(:get, @request_path)
|
132
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
133
|
-
end
|
134
|
-
|
135
|
-
should "get all entries for the given date range and user" do
|
136
|
-
path = "/people/1/entries.xml?from=20080101&project_id=3&to=20080131"
|
137
|
-
@person.entries(:from => @from, :to => @to, :project_id => 3)
|
138
|
-
expected_request = ActiveResource::Request.new(:get, path)
|
139
|
-
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
140
|
-
end
|
141
|
-
|
142
|
-
should "return all expense entries logged by the given user" do
|
143
|
-
@person.expenses(:from => @from, :to => @to)
|
144
|
-
expected_request = ActiveResource::Request.new(:get, @expense_path)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
|
2
|
+
|
3
|
+
class PersonTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup_resources
|
6
|
+
@person_xml = {:id => 1, :name => "Joe Coder"}.to_xml(:root => "person")
|
7
|
+
@people = [{:id => 1, :name => "Joe Coder"}].to_xml(:root => "people")
|
8
|
+
@entry = [{:id => 2, :project_id => 50}].to_xml(:root => "day-entries")
|
9
|
+
@entries = [{:id => 1, :project_id => "25"},
|
10
|
+
{:id => 2, :project_id => 50} ].to_xml(:root => "day-entries")
|
11
|
+
@expenses = [{:id => 1, :project_id => "25"},
|
12
|
+
{:id => 2, :project_id => 50} ].to_xml(:root => "expenses")
|
13
|
+
end
|
14
|
+
|
15
|
+
def mock_responses
|
16
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
17
|
+
mock.get "/people.xml", {}, @people
|
18
|
+
mock.get "/people/1.xml", {}, @person_xml
|
19
|
+
mock.post "/people.xml", {}, @person_xml, 201, "Location" => "/people/5.xml"
|
20
|
+
mock.put "/people/1.xml", {}, nil, 200
|
21
|
+
mock.delete "/people/1.xml", {}, nil, 200
|
22
|
+
mock.put "/people/1/toggle.xml", {}, nil, 200
|
23
|
+
mock.get "/people/1/entries.xml?from=20080101&to=20080131", {}, @entries
|
24
|
+
mock.get "/people/1/entries.xml?from=20080101&project_id=3&to=20080131", {}, @entry
|
25
|
+
mock.get "/people/1/expenses.xml?from=20080101&to=20080131", {}, @expenses
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "People CRUD actions -- " do
|
30
|
+
setup do
|
31
|
+
setup_resources
|
32
|
+
mock_responses
|
33
|
+
end
|
34
|
+
|
35
|
+
should "get index" do
|
36
|
+
Harvest::Resources::Person.find(:all)
|
37
|
+
expected_request = ActiveResource::Request.new(:get, "/people.xml")
|
38
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
39
|
+
end
|
40
|
+
|
41
|
+
should "get a single project" do
|
42
|
+
Harvest::Resources::Person.find(1)
|
43
|
+
expected_request = ActiveResource::Request.new(:get, "/people/1.xml")
|
44
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "create a new project" do
|
48
|
+
project = Harvest::Resources::Person.new(:name => "Widgets&Co")
|
49
|
+
project.save
|
50
|
+
expected_request = ActiveResource::Request.new(:post, "/people.xml")
|
51
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "update an existing project" do
|
55
|
+
project = Harvest::Resources::Person.find(1)
|
56
|
+
project.name = "Joe Coder"
|
57
|
+
project.save
|
58
|
+
expected_request = ActiveResource::Request.new(:put, "/people/1.xml")
|
59
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
60
|
+
end
|
61
|
+
|
62
|
+
should "delete an existing project" do
|
63
|
+
Harvest::Resources::Person.delete(1)
|
64
|
+
expected_request = ActiveResource::Request.new(:delete, "/people/1.xml")
|
65
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
context "Toggling active/inactive status" do
|
72
|
+
setup do
|
73
|
+
setup_resources
|
74
|
+
mock_responses
|
75
|
+
end
|
76
|
+
|
77
|
+
should "hit the toggle method" do
|
78
|
+
person = Harvest::Resources::Person.find(1)
|
79
|
+
person.toggle
|
80
|
+
expected_request = ActiveResource::Request.new(:put, "/people/1/toggle.xml")
|
81
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
82
|
+
end
|
83
|
+
|
84
|
+
should "return 200 Success toggle method" do
|
85
|
+
person = Harvest::Resources::Person.find(1)
|
86
|
+
assert person.toggle.code == 200
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
context "Getting entries" do
|
92
|
+
setup do
|
93
|
+
setup_resources
|
94
|
+
mock_responses
|
95
|
+
@person = Harvest::Resources::Person.find(1)
|
96
|
+
end
|
97
|
+
|
98
|
+
should "raise an error if start and end are not included" do
|
99
|
+
assert_raises ArgumentError, "Must specify :start and :end as dates." do
|
100
|
+
@person.entries
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
should "raise an error if end date precedes start date" do
|
105
|
+
assert_raises ArgumentError, "Must specify :start and :end as dates." do
|
106
|
+
@person.entries(:from => Time.utc(2007, 1, 1), :to => Time.utc(2006, 1, 1))
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
should "return the project site prefix" do
|
111
|
+
entry_class = Harvest::Resources::Entry.clone
|
112
|
+
entry_class.person_id = @person.id
|
113
|
+
assert_equal "http://example.com/people/1", entry_class.site.to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
context "Reports -- " do
|
119
|
+
setup do
|
120
|
+
setup_resources
|
121
|
+
mock_responses
|
122
|
+
@from = Time.utc(2008, 1, 1)
|
123
|
+
@to = Time.utc(2008, 1, 31)
|
124
|
+
@person = Harvest::Resources::Person.find(1)
|
125
|
+
@request_path = "/people/1/entries.xml?from=20080101&to=20080131"
|
126
|
+
@expense_path = "/people/1/expenses.xml?from=20080101&to=20080131"
|
127
|
+
end
|
128
|
+
|
129
|
+
should "get all entries for a given date range" do
|
130
|
+
@person.entries(:from => @from, :to => @to)
|
131
|
+
expected_request = ActiveResource::Request.new(:get, @request_path)
|
132
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
133
|
+
end
|
134
|
+
|
135
|
+
should "get all entries for the given date range and user" do
|
136
|
+
path = "/people/1/entries.xml?from=20080101&project_id=3&to=20080131"
|
137
|
+
@person.entries(:from => @from, :to => @to, :project_id => 3)
|
138
|
+
expected_request = ActiveResource::Request.new(:get, path)
|
139
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
140
|
+
end
|
141
|
+
|
142
|
+
should "return all expense entries logged by the given user" do
|
143
|
+
@person.expenses(:from => @from, :to => @to)
|
144
|
+
expected_request = ActiveResource::Request.new(:get, @expense_path)
|
145
|
+
assert ActiveResource::HttpMock.requests.include?(expected_request)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|