freshtrack 0.2.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/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +37 -0
- data/README.txt +30 -0
- data/Rakefile +4 -0
- data/bin/freshtrack +23 -0
- data/config/hoe.rb +74 -0
- data/config/requirements.rb +17 -0
- data/lib/freshbooks/extensions/base_object.rb +31 -0
- data/lib/freshbooks/extensions/project.rb +58 -0
- data/lib/freshbooks/extensions/task.rb +50 -0
- data/lib/freshbooks/extensions/time_entry.rb +53 -0
- data/lib/freshbooks/extensions.rb +5 -0
- data/lib/freshtrack/core_ext/array.rb +11 -0
- data/lib/freshtrack/core_ext/numeric.rb +5 -0
- data/lib/freshtrack/core_ext/time.rb +3 -0
- data/lib/freshtrack/core_ext.rb +3 -0
- data/lib/freshtrack/version.rb +9 -0
- data/lib/freshtrack.rb +107 -0
- data/log/debug.log +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/setup.rb +1585 -0
- data/spec/array_spec.rb +35 -0
- data/spec/base_object_spec.rb +51 -0
- data/spec/freshtrack_spec.rb +566 -0
- data/spec/numeric_spec.rb +21 -0
- data/spec/project_spec.rb +400 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/task_spec.rb +350 -0
- data/spec/time_entry_spec.rb +351 -0
- data/spec/time_spec.rb +37 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +9 -0
- metadata +110 -0
data/spec/task_spec.rb
ADDED
@@ -0,0 +1,350 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe FreshBooks::Task do
|
4
|
+
before :each do
|
5
|
+
@task = FreshBooks::Task.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'attributes' do
|
9
|
+
it 'should have a task_id' do
|
10
|
+
@task.should respond_to(:task_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should have a name' do
|
14
|
+
@task.should respond_to(:name)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should have billable' do
|
18
|
+
@task.should respond_to(:billable)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have a rate' do
|
22
|
+
@task.should respond_to(:rate)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have a description' do
|
26
|
+
@task.should respond_to(:description)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'type mappings' do
|
31
|
+
before :each do
|
32
|
+
@mapping = FreshBooks::Task::TYPE_MAPPINGS
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should map task_id to Fixnum' do
|
36
|
+
@mapping['task_id'].should == Fixnum
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should map rate to Float' do
|
40
|
+
@mapping['rate'].should == Float
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'creating an instance' do
|
45
|
+
before :each do
|
46
|
+
@response = stub('response', :success? => nil)
|
47
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should issue a request with the instance' do
|
51
|
+
FreshBooks.expects(:call_api).with('task.create', 'task' => @task).returns(@response)
|
52
|
+
@task.create
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'with a successful request' do
|
56
|
+
before :each do
|
57
|
+
@task_id = 5
|
58
|
+
@response.stubs(:elements).returns([stub('pre element'), stub('element', :text => @task_id.to_s), stub('post element')])
|
59
|
+
@response.stubs(:success?).returns(true)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should set the ID from the response' do
|
63
|
+
@task.expects(:task_id=).with(@task_id)
|
64
|
+
@task.create
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should return the ID' do
|
68
|
+
@task.create.should == @task_id
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'with an unsuccessful request' do
|
73
|
+
before :each do
|
74
|
+
@response.stubs(:success?).returns(false)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should not set the ID' do
|
78
|
+
@task.expects(:task_id=).never
|
79
|
+
@task.create
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should return nil' do
|
83
|
+
@task.create.should be_nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'updating an instance' do
|
89
|
+
before :each do
|
90
|
+
@response = stub('response', :success? => nil)
|
91
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should issue a request with the instance' do
|
95
|
+
FreshBooks.expects(:call_api).with('task.update', 'task' => @task).returns(@response)
|
96
|
+
@task.update
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'with a successful request' do
|
100
|
+
before :each do
|
101
|
+
@response.stubs(:success?).returns(true)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should return true' do
|
105
|
+
@task.update.should be(true)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'with an unsuccessful request' do
|
110
|
+
before :each do
|
111
|
+
@response.stubs(:success?).returns(false)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should return false' do
|
115
|
+
@task.update.should be(false)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'deleting an instance' do
|
121
|
+
before :each do
|
122
|
+
@task_id = '5'
|
123
|
+
@response = stub('response', :success? => nil)
|
124
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'from the class' do
|
128
|
+
it 'should require an argument' do
|
129
|
+
lambda { FreshBooks::Task.delete }.should raise_error(ArgumentError)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should accept an argument' do
|
133
|
+
lambda { FreshBooks::Task.delete('arg') }.should_not raise_error(ArgumentError)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should issue a request with the supplied ID' do
|
137
|
+
FreshBooks.expects(:call_api).with('task.delete', 'task_id' => @task_id).returns(@response)
|
138
|
+
FreshBooks::Task.delete(@task_id)
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'with a successful request' do
|
142
|
+
before :each do
|
143
|
+
@response.stubs(:success?).returns(true)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should return true' do
|
147
|
+
FreshBooks::Task.delete(@task_id).should be(true)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'with an unsuccessful request' do
|
152
|
+
before :each do
|
153
|
+
@response.stubs(:success?).returns(false)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should return false' do
|
157
|
+
FreshBooks::Task.delete(@task_id).should be(false)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe 'from the instance' do
|
163
|
+
before :each do
|
164
|
+
@task.stubs(:task_id).returns(@task_id)
|
165
|
+
FreshBooks::Task.stubs(:delete)
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'should delegate to the class' do
|
169
|
+
FreshBooks::Task.expects(:delete)
|
170
|
+
@task.delete
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should pass its ID to the class method' do
|
174
|
+
FreshBooks::Task.expects(:delete).with(@task_id)
|
175
|
+
@task.delete
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should return the result from the class method' do
|
179
|
+
val = stub('return val')
|
180
|
+
FreshBooks::Task.stubs(:delete).returns(val)
|
181
|
+
@task.delete.should == val
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe 'getting an instance' do
|
187
|
+
before :each do
|
188
|
+
@task_id = 1
|
189
|
+
@element = stub('element')
|
190
|
+
@response = stub('response', :elements => [stub('pre element'), @element, stub('post element')], :success? => nil)
|
191
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should require an argument' do
|
195
|
+
lambda { FreshBooks::Task.get }.should raise_error(ArgumentError)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should accept an argument' do
|
199
|
+
lambda { FreshBooks::Task.get(@task_id) }.should_not raise_error(ArgumentError)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'should issue a request for the supplied ID' do
|
203
|
+
FreshBooks.expects(:call_api).with('task.get', 'task_id' => @task_id).returns(@response)
|
204
|
+
FreshBooks::Task.get(@task_id)
|
205
|
+
end
|
206
|
+
|
207
|
+
describe 'with a successful request' do
|
208
|
+
before :each do
|
209
|
+
@response.stubs(:success?).returns(true)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should instantiate a new task instance from the request' do
|
213
|
+
FreshBooks::Task.expects(:new_from_xml).with(@element)
|
214
|
+
FreshBooks::Task.get(@task_id)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should return the task instance' do
|
218
|
+
val = stub('return val')
|
219
|
+
FreshBooks::Task.stubs(:new_from_xml).returns(val)
|
220
|
+
FreshBooks::Task.get(@task_id).should == val
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe 'with an unsuccessful request' do
|
225
|
+
before :each do
|
226
|
+
@response.stubs(:success?).returns(false)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should return nil' do
|
230
|
+
FreshBooks::Task.get(@task_id).should be_nil
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe 'getting a list' do
|
236
|
+
before :each do
|
237
|
+
@task_id = 1
|
238
|
+
@elements = Array.new(3) { stub('element') }
|
239
|
+
@response = stub('response', :elements => @elements, :success? => nil)
|
240
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should not require an argument' do
|
244
|
+
lambda { FreshBooks::Task.list }.should_not raise_error(ArgumentError)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should accept an argument' do
|
248
|
+
lambda { FreshBooks::Task.list('arg') }.should_not raise_error(ArgumentError)
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should issue a request for the task list' do
|
252
|
+
FreshBooks.expects(:call_api).with('task.list', {}).returns(@response)
|
253
|
+
FreshBooks::Task.list
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should pass the argument to the request' do
|
257
|
+
arg = stub('arg')
|
258
|
+
FreshBooks.expects(:call_api).with('task.list', arg).returns(@response)
|
259
|
+
FreshBooks::Task.list(arg)
|
260
|
+
end
|
261
|
+
|
262
|
+
describe 'with a successful request' do
|
263
|
+
before :each do
|
264
|
+
@response.stubs(:success?).returns(true)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should instantiate new task instances from the request' do
|
268
|
+
@elements.each do |element|
|
269
|
+
FreshBooks::Task.expects(:new_from_xml).with(element)
|
270
|
+
end
|
271
|
+
FreshBooks::Task.list
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should return the task instances' do
|
275
|
+
vals = Array.new(@elements.length) { stub('return val') }
|
276
|
+
@elements.each_with_index do |element, i|
|
277
|
+
FreshBooks::Task.stubs(:new_from_xml).with(element).returns(vals[i])
|
278
|
+
end
|
279
|
+
FreshBooks::Task.list.should == vals
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe 'with an unsuccessful request' do
|
284
|
+
before :each do
|
285
|
+
@response.stubs(:success?).returns(false)
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'should return nil' do
|
289
|
+
FreshBooks::Task.list.should be_nil
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe 'getting by name' do
|
295
|
+
before :each do
|
296
|
+
@name = 'taskname'
|
297
|
+
FreshBooks::Task.stubs(:list).returns([])
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'should require an argument' do
|
301
|
+
lambda { FreshBooks::Task.find_by_name }.should raise_error(ArgumentError)
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'should accept an argument' do
|
305
|
+
lambda { FreshBooks::Task.find_by_name(@name) }.should_not raise_error(ArgumentError)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'should return the task with a matching name' do
|
309
|
+
tasks = Array.new(3) { |i| stub('task', :name => "task #{i}" ) }
|
310
|
+
tasks[1,0] = expected = stub('task', :name => @name)
|
311
|
+
FreshBooks::Task.stubs(:list).returns(tasks)
|
312
|
+
FreshBooks::Task.find_by_name(@name).should == expected
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'should return the first task found whose name matches' do
|
316
|
+
tasks = Array.new(3) { |i| stub('task', :name => "task #{i}" ) }
|
317
|
+
tasks[1,0] = expected = stub('task', :name => @name)
|
318
|
+
tasks[3,0] = stub('task', :name => @name)
|
319
|
+
FreshBooks::Task.stubs(:list).returns(tasks)
|
320
|
+
FreshBooks::Task.find_by_name(@name).should == expected
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'should return nil if no task with matching name found' do
|
324
|
+
tasks = Array.new(3) { |i| stub('task', :name => "task #{i}" ) }
|
325
|
+
FreshBooks::Task.stubs(:list).returns(tasks)
|
326
|
+
FreshBooks::Task.find_by_name(@name).should be_nil
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should have time entries' do
|
331
|
+
@task.should respond_to(:time_entries)
|
332
|
+
end
|
333
|
+
|
334
|
+
describe 'time entries' do
|
335
|
+
it 'should list time entries based on task ID' do
|
336
|
+
task_id = stub('task ID')
|
337
|
+
@task.stubs(:task_id).returns(task_id)
|
338
|
+
FreshBooks::TimeEntry.expects(:list).with('task_id' => task_id)
|
339
|
+
@task.time_entries
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'should return found time entries' do
|
343
|
+
time_entries = stub('time entries')
|
344
|
+
task_id = stub('task ID')
|
345
|
+
@task.stubs(:task_id).returns(task_id)
|
346
|
+
FreshBooks::TimeEntry.stubs(:list).with('task_id' => task_id).returns(time_entries)
|
347
|
+
@task.time_entries.should == time_entries
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
@@ -0,0 +1,351 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe FreshBooks::TimeEntry do
|
4
|
+
before :each do
|
5
|
+
@time_entry = FreshBooks::TimeEntry.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'attributes' do
|
9
|
+
it 'should have a time_entry_id' do
|
10
|
+
@time_entry.should respond_to(:time_entry_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should have a project_id' do
|
14
|
+
@time_entry.should respond_to(:project_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should have a task_id' do
|
18
|
+
@time_entry.should respond_to(:task_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have hours' do
|
22
|
+
@time_entry.should respond_to(:hours)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have a date' do
|
26
|
+
@time_entry.should respond_to(:date)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should have notes' do
|
30
|
+
@time_entry.should respond_to(:notes)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'type mappings' do
|
35
|
+
before :each do
|
36
|
+
@mapping = FreshBooks::TimeEntry::TYPE_MAPPINGS
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should map time_entry_id to Fixnum' do
|
40
|
+
@mapping['time_entry_id'].should == Fixnum
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should map project_id to Fixnum' do
|
44
|
+
@mapping['project_id'].should == Fixnum
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should map task_id to Fixnum' do
|
48
|
+
@mapping['task_id'].should == Fixnum
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should map hours to Float' do
|
52
|
+
@mapping['hours'].should == Float
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should map date to Date' do
|
56
|
+
@mapping['date'].should == Date
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'creating an instance' do
|
61
|
+
before :each do
|
62
|
+
@response = stub('response', :success? => nil)
|
63
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should issue a request with the instance' do
|
67
|
+
FreshBooks.expects(:call_api).with('time_entry.create', 'time_entry' => @time_entry).returns(@response)
|
68
|
+
@time_entry.create
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'with a successful request' do
|
72
|
+
before :each do
|
73
|
+
@time_entry_id = 5
|
74
|
+
@response.stubs(:elements).returns([stub('pre element'), stub('element', :text => @time_entry_id.to_s), stub('post element')])
|
75
|
+
@response.stubs(:success?).returns(true)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should set the ID from the response' do
|
79
|
+
@time_entry.expects(:time_entry_id=).with(@time_entry_id)
|
80
|
+
@time_entry.create
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should return the ID' do
|
84
|
+
@time_entry.create.should == @time_entry_id
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'with an unsuccessful request' do
|
89
|
+
before :each do
|
90
|
+
@response.stubs(:success?).returns(false)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should not set the ID' do
|
94
|
+
@time_entry.expects(:time_entry_id=).never
|
95
|
+
@time_entry.create
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should return nil' do
|
99
|
+
@time_entry.create.should be_nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'updating an instance' do
|
105
|
+
before :each do
|
106
|
+
@response = stub('response', :success? => nil)
|
107
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should issue a request with the instance' do
|
111
|
+
FreshBooks.expects(:call_api).with('time_entry.update', 'time_entry' => @time_entry).returns(@response)
|
112
|
+
@time_entry.update
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'with a successful request' do
|
116
|
+
before :each do
|
117
|
+
@response.stubs(:success?).returns(true)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should return true' do
|
121
|
+
@time_entry.update.should be(true)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe 'with an unsuccessful request' do
|
126
|
+
before :each do
|
127
|
+
@response.stubs(:success?).returns(false)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should return false' do
|
131
|
+
@time_entry.update.should be(false)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'deleting an instance' do
|
137
|
+
before :each do
|
138
|
+
@time_entry_id = '5'
|
139
|
+
@response = stub('response', :success? => nil)
|
140
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'from the class' do
|
144
|
+
it 'should require an argument' do
|
145
|
+
lambda { FreshBooks::TimeEntry.delete }.should raise_error(ArgumentError)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should accept an argument' do
|
149
|
+
lambda { FreshBooks::TimeEntry.delete('arg') }.should_not raise_error(ArgumentError)
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should issue a request with the supplied ID' do
|
153
|
+
FreshBooks.expects(:call_api).with('time_entry.delete', 'time_entry_id' => @time_entry_id).returns(@response)
|
154
|
+
FreshBooks::TimeEntry.delete(@time_entry_id)
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'with a successful request' do
|
158
|
+
before :each do
|
159
|
+
@response.stubs(:success?).returns(true)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should return true' do
|
163
|
+
FreshBooks::TimeEntry.delete(@time_entry_id).should be(true)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe 'with an unsuccessful request' do
|
168
|
+
before :each do
|
169
|
+
@response.stubs(:success?).returns(false)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should return false' do
|
173
|
+
FreshBooks::TimeEntry.delete(@time_entry_id).should be(false)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe 'from the instance' do
|
179
|
+
before :each do
|
180
|
+
@time_entry.stubs(:time_entry_id).returns(@time_entry_id)
|
181
|
+
FreshBooks::TimeEntry.stubs(:delete)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should delegate to the class' do
|
185
|
+
FreshBooks::TimeEntry.expects(:delete)
|
186
|
+
@time_entry.delete
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'should pass its ID to the class method' do
|
190
|
+
FreshBooks::TimeEntry.expects(:delete).with(@time_entry_id)
|
191
|
+
@time_entry.delete
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should return the result from the class method' do
|
195
|
+
val = stub('return val')
|
196
|
+
FreshBooks::TimeEntry.stubs(:delete).returns(val)
|
197
|
+
@time_entry.delete.should == val
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe 'getting an instance' do
|
203
|
+
before :each do
|
204
|
+
@time_entry_id = 1
|
205
|
+
@element = stub('element')
|
206
|
+
@response = stub('response', :elements => [stub('pre element'), @element, stub('post element')], :success? => nil)
|
207
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should require an argument' do
|
211
|
+
lambda { FreshBooks::TimeEntry.get }.should raise_error(ArgumentError)
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should accept an argument' do
|
215
|
+
lambda { FreshBooks::TimeEntry.get(@time_entry_id) }.should_not raise_error(ArgumentError)
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should issue a request for the supplied ID' do
|
219
|
+
FreshBooks.expects(:call_api).with('time_entry.get', 'time_entry_id' => @time_entry_id).returns(@response)
|
220
|
+
FreshBooks::TimeEntry.get(@time_entry_id)
|
221
|
+
end
|
222
|
+
|
223
|
+
describe 'with a successful request' do
|
224
|
+
before :each do
|
225
|
+
@response.stubs(:success?).returns(true)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'should instantiate a new time_entry instance from the request' do
|
229
|
+
FreshBooks::TimeEntry.expects(:new_from_xml).with(@element)
|
230
|
+
FreshBooks::TimeEntry.get(@time_entry_id)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should return the time_entry instance' do
|
234
|
+
val = stub('return val')
|
235
|
+
FreshBooks::TimeEntry.stubs(:new_from_xml).returns(val)
|
236
|
+
FreshBooks::TimeEntry.get(@time_entry_id).should == val
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe 'with an unsuccessful request' do
|
241
|
+
before :each do
|
242
|
+
@response.stubs(:success?).returns(false)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should return nil' do
|
246
|
+
FreshBooks::TimeEntry.get(@time_entry_id).should be_nil
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe 'getting a list' do
|
252
|
+
before :each do
|
253
|
+
@time_entry_id = 1
|
254
|
+
@elements = Array.new(3) { stub('element') }
|
255
|
+
@response = stub('response', :elements => @elements, :success? => nil)
|
256
|
+
FreshBooks.stubs(:call_api).returns(@response)
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should not require an argument' do
|
260
|
+
lambda { FreshBooks::TimeEntry.list }.should_not raise_error(ArgumentError)
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'should accept an argument' do
|
264
|
+
lambda { FreshBooks::TimeEntry.list('arg') }.should_not raise_error(ArgumentError)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should issue a request for the time_entry list' do
|
268
|
+
FreshBooks.expects(:call_api).with('time_entry.list', {}).returns(@response)
|
269
|
+
FreshBooks::TimeEntry.list
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should pass the argument to the request' do
|
273
|
+
arg = stub('arg')
|
274
|
+
FreshBooks.expects(:call_api).with('time_entry.list', arg).returns(@response)
|
275
|
+
FreshBooks::TimeEntry.list(arg)
|
276
|
+
end
|
277
|
+
|
278
|
+
describe 'with a successful request' do
|
279
|
+
before :each do
|
280
|
+
@response.stubs(:success?).returns(true)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'should instantiate new time_entry instances from the request' do
|
284
|
+
@elements.each do |element|
|
285
|
+
FreshBooks::TimeEntry.expects(:new_from_xml).with(element)
|
286
|
+
end
|
287
|
+
FreshBooks::TimeEntry.list
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'should return the time_entry instances' do
|
291
|
+
vals = Array.new(@elements.length) { stub('return val') }
|
292
|
+
@elements.each_with_index do |element, i|
|
293
|
+
FreshBooks::TimeEntry.stubs(:new_from_xml).with(element).returns(vals[i])
|
294
|
+
end
|
295
|
+
FreshBooks::TimeEntry.list.should == vals
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
describe 'with an unsuccessful request' do
|
300
|
+
before :each do
|
301
|
+
@response.stubs(:success?).returns(false)
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'should return nil' do
|
305
|
+
FreshBooks::TimeEntry.list.should be_nil
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'should have a task' do
|
311
|
+
@time_entry.should respond_to(:task)
|
312
|
+
end
|
313
|
+
|
314
|
+
describe 'task' do
|
315
|
+
it 'should find task based on task_id' do
|
316
|
+
task_id = stub('task ID')
|
317
|
+
@time_entry.stubs(:task_id).returns(task_id)
|
318
|
+
FreshBooks::Task.expects(:get).with(task_id)
|
319
|
+
@time_entry.task
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'should return found task' do
|
323
|
+
task = stub('task')
|
324
|
+
task_id = stub('task ID')
|
325
|
+
@time_entry.stubs(:task_id).returns(task_id)
|
326
|
+
FreshBooks::Task.expects(:get).with(task_id).returns(task)
|
327
|
+
@time_entry.task.should == task
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'should have a project' do
|
332
|
+
@time_entry.should respond_to(:project)
|
333
|
+
end
|
334
|
+
|
335
|
+
describe 'project' do
|
336
|
+
it 'should find project based on project_id' do
|
337
|
+
project_id = stub('project ID')
|
338
|
+
@time_entry.stubs(:project_id).returns(project_id)
|
339
|
+
FreshBooks::Project.expects(:get).with(project_id)
|
340
|
+
@time_entry.project
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'should return found project' do
|
344
|
+
project = stub('project')
|
345
|
+
project_id = stub('project ID')
|
346
|
+
@time_entry.stubs(:project_id).returns(project_id)
|
347
|
+
FreshBooks::Project.expects(:get).with(project_id).returns(project)
|
348
|
+
@time_entry.project.should == project
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|