harvested 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +15 -0
- data/HISTORY +11 -0
- data/README.md +14 -6
- data/Rakefile +13 -31
- data/TODO +2 -0
- data/VERSION +1 -1
- data/examples/user_assignments.rb +1 -1
- data/harvested.gemspec +114 -126
- data/lib/ext/array.rb +52 -0
- data/lib/ext/date.rb +9 -0
- data/lib/ext/hash.rb +17 -0
- data/lib/ext/time.rb +5 -0
- data/lib/harvest/api/account.rb +8 -1
- data/lib/harvest/api/base.rb +32 -10
- data/lib/harvest/api/contacts.rb +1 -1
- data/lib/harvest/api/expenses.rb +3 -4
- data/lib/harvest/api/invoice_categories.rb +26 -0
- data/lib/harvest/api/invoices.rb +16 -0
- data/lib/harvest/api/projects.rb +2 -10
- data/lib/harvest/api/reports.rb +13 -16
- data/lib/harvest/api/task_assignments.rb +8 -6
- data/lib/harvest/api/tasks.rb +1 -1
- data/lib/harvest/api/time.rb +13 -13
- data/lib/harvest/api/user_assignments.rb +7 -5
- data/lib/harvest/base.rb +9 -1
- data/lib/harvest/behavior/activatable.rb +2 -2
- data/lib/harvest/behavior/crud.rb +15 -13
- data/lib/harvest/client.rb +18 -13
- data/lib/harvest/contact.rb +13 -11
- data/lib/harvest/errors.rb +6 -4
- data/lib/harvest/expense.rb +40 -14
- data/lib/harvest/expense_category.rb +10 -9
- data/lib/harvest/hardy_client.rb +1 -1
- data/lib/harvest/invoice.rb +103 -0
- data/lib/harvest/invoice_category.rb +18 -0
- data/lib/harvest/line_item.rb +12 -0
- data/lib/harvest/model.rb +120 -0
- data/lib/harvest/project.rb +55 -26
- data/lib/harvest/rate_limit_status.rb +9 -8
- data/lib/harvest/task.rb +17 -14
- data/lib/harvest/task_assignment.rb +27 -22
- data/lib/harvest/time_entry.rb +32 -30
- data/lib/harvest/user.rb +46 -22
- data/lib/harvest/user_assignment.rb +24 -17
- data/lib/harvested.rb +12 -5
- data/spec/functional/account_spec.rb +17 -0
- data/spec/functional/clients_spec.rb +58 -0
- data/spec/functional/errors_spec.rb +22 -0
- data/spec/functional/expenses_spec.rb +84 -0
- data/spec/functional/hardy_client_spec.rb +33 -0
- data/spec/functional/invoice_spec.rb +67 -0
- data/spec/functional/project_spec.rb +50 -0
- data/spec/functional/reporting_spec.rb +80 -0
- data/spec/functional/tasks_spec.rb +88 -0
- data/spec/functional/time_tracking_spec.rb +53 -0
- data/spec/functional/users_spec.rb +102 -0
- data/spec/harvest/base_spec.rb +1 -1
- data/spec/harvest/credentials_spec.rb +1 -1
- data/spec/harvest/expense_category_spec.rb +5 -0
- data/spec/harvest/expense_spec.rb +8 -5
- data/spec/harvest/invoice_spec.rb +47 -0
- data/spec/harvest/project_spec.rb +11 -0
- data/spec/harvest/task_assignment_spec.rb +4 -4
- data/spec/harvest/task_spec.rb +7 -0
- data/spec/harvest/time_entry_spec.rb +11 -10
- data/spec/harvest/user_assignment_spec.rb +3 -3
- data/spec/harvest/user_spec.rb +3 -1
- data/spec/spec_helper.rb +37 -6
- data/{features → spec}/support/harvest_credentials.example.yml +0 -1
- data/spec/support/harvested_helpers.rb +44 -0
- data/spec/support/json_examples.rb +11 -0
- data/spec/test_rubies +5 -0
- metadata +109 -85
- data/.gitignore +0 -28
- data/features/account.feature +0 -7
- data/features/client_contacts.feature +0 -23
- data/features/clients.feature +0 -29
- data/features/errors.feature +0 -25
- data/features/expense_categories.feature +0 -21
- data/features/expenses.feature +0 -55
- data/features/hardy_client.feature +0 -40
- data/features/projects.feature +0 -39
- data/features/reporting.feature +0 -72
- data/features/step_definitions/account_steps.rb +0 -7
- data/features/step_definitions/assignment_steps.rb +0 -100
- data/features/step_definitions/contact_steps.rb +0 -11
- data/features/step_definitions/debug_steps.rb +0 -3
- data/features/step_definitions/error_steps.rb +0 -113
- data/features/step_definitions/expenses_steps.rb +0 -46
- data/features/step_definitions/harvest_steps.rb +0 -8
- data/features/step_definitions/model_steps.rb +0 -90
- data/features/step_definitions/people_steps.rb +0 -4
- data/features/step_definitions/report_steps.rb +0 -91
- data/features/step_definitions/time_entry_steps.rb +0 -40
- data/features/support/env.rb +0 -37
- data/features/support/error_helpers.rb +0 -18
- data/features/support/fixtures/empty_clients.xml +0 -2
- data/features/support/fixtures/over_limit.xml +0 -8
- data/features/support/fixtures/receipt.png +0 -0
- data/features/support/fixtures/under_limit.xml +0 -8
- data/features/support/harvest_helpers.rb +0 -11
- data/features/support/inflections.rb +0 -9
- data/features/task_assignment.feature +0 -69
- data/features/tasks.feature +0 -25
- data/features/time_tracking.feature +0 -29
- data/features/user_assignments.feature +0 -33
- data/features/users.feature +0 -55
- data/lib/harvest/base_model.rb +0 -73
- data/spec/spec.default.opts +0 -1
@@ -1,46 +0,0 @@
|
|
1
|
-
When 'I create an expense for the project "$1" with the category "$2" with the following:' do |project_name, category_name, table|
|
2
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
3
|
-
category = Then %Q{there should be an expense category "#{category_name}"}
|
4
|
-
|
5
|
-
expense = Harvest::Expense.new(table.rows_hash.merge("expense_category_id" => category.id, "project_id" => project.id))
|
6
|
-
harvest_api.expenses.create(expense)
|
7
|
-
end
|
8
|
-
|
9
|
-
Then 'there should be an expense "$1" on "$2"' do |notes, date|
|
10
|
-
expenses = harvest_api.expenses.all(date)
|
11
|
-
expense = expenses.detect {|e| e.notes == notes}
|
12
|
-
expense.should_not be_nil
|
13
|
-
expense
|
14
|
-
end
|
15
|
-
|
16
|
-
Then 'there should not be an expense "$1" on "$2"' do |notes, date|
|
17
|
-
expenses = harvest_api.expenses.all(date)
|
18
|
-
expense = expenses.detect {|e| e.notes == notes}
|
19
|
-
expense.should be_nil
|
20
|
-
end
|
21
|
-
|
22
|
-
When 'I delete the expense "$1" on "$2"' do |notes, date|
|
23
|
-
expense = Then %Q{there should be an expense "#{notes}" on "#{date}"}
|
24
|
-
id = harvest_api.expenses.delete(expense)
|
25
|
-
expense.id.should == id
|
26
|
-
end
|
27
|
-
|
28
|
-
Then 'the expense "$1" on "$2" should have the following attributes:' do |notes, date, table|
|
29
|
-
expense = Then %Q{there should be an expense "#{notes}" on "#{date}"}
|
30
|
-
table.rows_hash.each do |key, value|
|
31
|
-
expense.send(key).to_s.should == value
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
When 'I update the expense "$1" on "$2" with the following:' do |notes, date, table|
|
36
|
-
expense = Then %Q{there should be an expense "#{notes}" on "#{date}"}
|
37
|
-
expense.attributes = table.rows_hash
|
38
|
-
harvest_api.expenses.update(expense)
|
39
|
-
end
|
40
|
-
|
41
|
-
When 'I attach the receipt "$1" to the expense "$2" on "$3"' do |path, notes, date|
|
42
|
-
path = "#{File.dirname(__FILE__)}/../#{path}"
|
43
|
-
receipt = StringIO.new(File.read(path))
|
44
|
-
expense = Then %Q{there should be an expense "#{notes}" on "#{date}"}
|
45
|
-
harvest_api.expenses.attach(expense, "receipt.png", receipt)
|
46
|
-
end
|
@@ -1,8 +0,0 @@
|
|
1
|
-
Given 'I am using the credentials from "$1"' do |path|
|
2
|
-
raise "You need a credentials file in support/harvest_credentials.yml!!" unless File.exist?("#{File.dirname(__FILE__)}/../#{path}")
|
3
|
-
credentials = YAML.load_file("#{File.dirname(__FILE__)}/../#{path}")
|
4
|
-
@username = credentials["username"]
|
5
|
-
@password = credentials["password"]
|
6
|
-
@subdomain = credentials["subdomain"]
|
7
|
-
@ssl = credentials["ssl"]
|
8
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
When /^I create an? (client|task|user|expense category) with the following:$/ do |type, table|
|
2
|
-
case type
|
3
|
-
when "client"
|
4
|
-
client = Harvest::Client.new(table.rows_hash)
|
5
|
-
harvest_api.clients.create(client)
|
6
|
-
when "task"
|
7
|
-
task = Harvest::Task.new(table.rows_hash)
|
8
|
-
harvest_api.tasks.create(task)
|
9
|
-
when "user"
|
10
|
-
user = Harvest::User.new(table.rows_hash)
|
11
|
-
harvest_api.users.create(user)
|
12
|
-
when "expense category"
|
13
|
-
expense_cat = Harvest::ExpenseCategory.new(table.rows_hash)
|
14
|
-
harvest_api.expense_categories.create(expense_cat)
|
15
|
-
else pending end
|
16
|
-
end
|
17
|
-
|
18
|
-
When /^I create a (contact|project) for the client "([^\"]*)" with the following:$/ do |type, client_name, table|
|
19
|
-
client = Then %Q{there should be a client "#{client_name}"}
|
20
|
-
attributes = table.rows_hash.merge("client_id" => client.id)
|
21
|
-
|
22
|
-
case type
|
23
|
-
when "contact"
|
24
|
-
contact = Harvest::Contact.new(attributes)
|
25
|
-
harvest_api.contacts.create(contact)
|
26
|
-
when "project"
|
27
|
-
project = Harvest::Project.new(attributes)
|
28
|
-
harvest_api.projects.create(project)
|
29
|
-
else pending end
|
30
|
-
end
|
31
|
-
|
32
|
-
Then /^there should be an? (contact|project|client|task|user|expense category) "([^\"]*)"$/ do |type, identifier|
|
33
|
-
collection = harvest_api.send(pluralize(type)).all
|
34
|
-
attribute = case type
|
35
|
-
when 'contact', 'user' then 'email'
|
36
|
-
when 'project', 'client', 'task', 'expense category' then 'name'
|
37
|
-
else pending end
|
38
|
-
item = collection.detect {|c| c.send(attribute) == identifier}
|
39
|
-
item.should_not be_nil
|
40
|
-
item
|
41
|
-
end
|
42
|
-
|
43
|
-
Then /^there should not be an? (contact|project|client|task|user|expense category) "([^\"]*)"$/ do |type, identifier|
|
44
|
-
collection = harvest_api.send(pluralize(type)).all
|
45
|
-
attribute = case type
|
46
|
-
when 'contact', 'user' then 'email'
|
47
|
-
when 'project', 'client', 'task', 'expense category' then 'name'
|
48
|
-
else pending end
|
49
|
-
item = collection.detect {|c| c.send(attribute) == identifier}
|
50
|
-
item.should be_nil
|
51
|
-
end
|
52
|
-
|
53
|
-
When /^I update the (contact|project|client|task|user|expense category) "([^\"]*)" with the following:$/ do |type, name, table|
|
54
|
-
item = Then %Q{there should be a #{type} "#{name}"}
|
55
|
-
item.attributes = table.rows_hash
|
56
|
-
harvest_api.send(pluralize(type)).update(item)
|
57
|
-
end
|
58
|
-
|
59
|
-
Then /^the (contact|project|client|task|user|expense category) "([^\"]*)" should have the following attributes:$/ do |type, name, table|
|
60
|
-
item = Then %Q{there should be a #{type} "#{name}"}
|
61
|
-
table.rows_hash.each do |key, value|
|
62
|
-
item.send(key).to_s.should == value
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
When /^I delete the (contact|project|client|task|user|expense category) "([^\"]*)"$/ do |type, name|
|
67
|
-
item = Then %Q{there should be a #{type} "#{name}"}
|
68
|
-
id = harvest_api.send(pluralize(type)).delete(item)
|
69
|
-
id.should == item.id
|
70
|
-
end
|
71
|
-
|
72
|
-
Then /^the (client|project|user) "([^\"]*)" should be activated$/ do |type, identifier|
|
73
|
-
item = Then %Q{there should be a #{type} "#{identifier}"}
|
74
|
-
item.should be_active
|
75
|
-
end
|
76
|
-
|
77
|
-
Then /^the (client|project|user) "([^\"]*)" should be deactivated$/ do |type, identifier|
|
78
|
-
item = Then %Q{there should be a #{type} "#{identifier}"}
|
79
|
-
item.should_not be_active
|
80
|
-
end
|
81
|
-
|
82
|
-
When /^I deactivate the (client|project|user) "([^\"]*)"$/ do |type, identifier|
|
83
|
-
item = Then %Q{there should be a #{type} "#{identifier}"}
|
84
|
-
harvest_api.send(pluralize(type)).deactivate(item)
|
85
|
-
end
|
86
|
-
|
87
|
-
When /^I activate the (client|project|user) "([^\"]*)"$/ do |type, identifier|
|
88
|
-
item = Then %Q{there should be a #{type} "#{identifier}"}
|
89
|
-
harvest_api.send(pluralize(type)).activate(item)
|
90
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
When /^I run a project report for "([^\"]*)" for "([^\"]*)" and "([^\"]*)" the following entries should be returned:$/ do |project_name, start_date, end_date, table|
|
2
|
-
start_date = Time.parse(start_date)
|
3
|
-
end_date = Time.parse(end_date)
|
4
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
5
|
-
entries = harvest_api.reports.time_by_project(project, start_date, end_date)
|
6
|
-
table.raw.each do |row|
|
7
|
-
entry = entries.detect {|e| e.notes == row.first }
|
8
|
-
entry.should_not be_nil
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
When /^I run a project report for "([^\"]*)" for "([^\"]*)" and "([^\"]*)" the following entries should not be returned:$/ do |project_name, start_date, end_date, table|
|
13
|
-
start_date = Time.parse(start_date)
|
14
|
-
end_date = Time.parse(end_date)
|
15
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
16
|
-
entries = harvest_api.reports.time_by_project(project, start_date, end_date)
|
17
|
-
table.raw.each do |row|
|
18
|
-
entry = entries.detect {|e| e.notes == row.first }
|
19
|
-
entry.should be_nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
When /^I run a a project report for "([^\"]*)" for "([^\"]*)" and "([^\"]*)" filtered by my user the following entries should be returned:$/ do |project_name, start_date, end_date, table|
|
24
|
-
start_date = Time.parse(start_date)
|
25
|
-
end_date = Time.parse(end_date)
|
26
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
27
|
-
user = Then %Q{there should be a user "#{@username}"}
|
28
|
-
entries = harvest_api.reports.time_by_project(project, start_date, end_date, user)
|
29
|
-
table.raw.each do |row|
|
30
|
-
entry = entries.detect {|e| e.notes == row.first }
|
31
|
-
entry.should_not be_nil
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
When /^I run a a project report for "([^\"]*)" for "([^\"]*)" and "([^\"]*)" filtered by my user the following entries should not be returned:$/ do |project_name, start_date, end_date, table|
|
36
|
-
start_date = Time.parse(start_date)
|
37
|
-
end_date = Time.parse(end_date)
|
38
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
39
|
-
user = Then %Q{there should be a user "#{@username}"}
|
40
|
-
entries = harvest_api.reports.time_by_project(project, start_date, end_date, user)
|
41
|
-
table.raw.each do |row|
|
42
|
-
entry = entries.detect {|e| e.notes == row.first }
|
43
|
-
entry.should be_nil
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
When /^I run a people report for my user for "([^\"]*)" and "([^\"]*)" the following entries should be returned:$/ do |start_date, end_date, table|
|
48
|
-
start_date = Time.parse(start_date)
|
49
|
-
end_date = Time.parse(end_date)
|
50
|
-
user = Then %Q{there should be a user "#{@username}"}
|
51
|
-
entries = harvest_api.reports.time_by_user(user, start_date, end_date)
|
52
|
-
table.raw.each do |row|
|
53
|
-
entry = entries.detect {|e| e.notes == row.first }
|
54
|
-
entry.should_not be_nil
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
When /^I run a people report for my user for "([^\"]*)" and "([^\"]*)" filtered by the project "([^\"]*)" the following entries should be returned:$/ do |start_date, end_date, project_name, table|
|
59
|
-
start_date = Time.parse(start_date)
|
60
|
-
end_date = Time.parse(end_date)
|
61
|
-
user = Then %Q{there should be a user "#{@username}"}
|
62
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
63
|
-
entries = harvest_api.reports.time_by_user(user, start_date, end_date, project)
|
64
|
-
table.raw.each do |row|
|
65
|
-
entry = entries.detect {|e| e.notes == row.first }
|
66
|
-
entry.should_not be_nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
When /^I run a people report for my user for "([^\"]*)" and "([^\"]*)" filtered by the project "([^\"]*)" the following entries should not be returned:$/ do |start_date, end_date, project_name, table|
|
71
|
-
start_date = Time.parse(start_date)
|
72
|
-
end_date = Time.parse(end_date)
|
73
|
-
user = Then %Q{there should be a user "#{@username}"}
|
74
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
75
|
-
entries = harvest_api.reports.time_by_user(user, start_date, end_date, project)
|
76
|
-
table.raw.each do |row|
|
77
|
-
entry = entries.detect {|e| e.notes == row.first }
|
78
|
-
entry.should be_nil
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
When /^I run an expense report for my user for "([^\"]*)" and "([^\"]*)" the following entries should be returned:$/ do |start_date, end_date, table|
|
83
|
-
start_date = Time.parse(start_date)
|
84
|
-
end_date = Time.parse(end_date)
|
85
|
-
user = Then %Q{there should be a user "#{@username}"}
|
86
|
-
expenses = harvest_api.reports.expenses_by_user(user, start_date, end_date)
|
87
|
-
table.raw.each do |row|
|
88
|
-
expense = expenses.detect {|e| e.notes == row.first }
|
89
|
-
expense.should_not be_nil
|
90
|
-
end
|
91
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
When 'I create a time entry for the project "$1" and the task "$2" with the following:' do |project_name, task_name, table|
|
2
|
-
task = Then %Q{there should be a task "#{task_name}"}
|
3
|
-
project = Then %Q{there should be a project "#{project_name}"}
|
4
|
-
entry = Harvest::TimeEntry.new(table.rows_hash.merge('project_id' => project.id, 'task_id' => task.id))
|
5
|
-
created_entry = harvest_api.time.create(entry)
|
6
|
-
created_entry.project.should == project.name
|
7
|
-
created_entry.task.should == task.name
|
8
|
-
end
|
9
|
-
|
10
|
-
Then 'there should be a time entry "$1" on "$2"' do |notes, date|
|
11
|
-
entries = harvest_api.time.all(date)
|
12
|
-
entry = entries.detect {|e| e.notes == notes}
|
13
|
-
entry.should_not be_nil
|
14
|
-
entry
|
15
|
-
end
|
16
|
-
|
17
|
-
Then 'there should not be a time entry "$1" on "$2"' do |notes, date|
|
18
|
-
entries = harvest_api.time.all(date)
|
19
|
-
entry = entries.detect {|e| e.notes == notes}
|
20
|
-
entry.should be_nil
|
21
|
-
end
|
22
|
-
|
23
|
-
When 'I update the time entry "$1" on "$2" with the following:' do |note, date, table|
|
24
|
-
entry = Then %Q{there should be a time entry "#{note}" on "#{date}"}
|
25
|
-
entry.attributes = table.rows_hash
|
26
|
-
harvest_api.time.update(entry)
|
27
|
-
end
|
28
|
-
|
29
|
-
Then 'the time entry "$1" on "$2" should have the following attributes:' do |note, date, table|
|
30
|
-
entry = Then %Q{there should be a time entry "#{note}" on "#{date}"}
|
31
|
-
table.rows_hash.each do |key, value|
|
32
|
-
entry.send(key).to_s.should == value
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
When 'I delete the time entry "$1" on "$2"' do |note, date|
|
37
|
-
entry = Then %Q{there should be a time entry "#{note}" on "#{date}"}
|
38
|
-
id = harvest_api.time.delete(entry)
|
39
|
-
entry.id.should == id
|
40
|
-
end
|
data/features/support/env.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
|
2
|
-
require 'harvested'
|
3
|
-
require 'ruby-debug'
|
4
|
-
require 'fakeweb'
|
5
|
-
|
6
|
-
require 'spec/expectations'
|
7
|
-
|
8
|
-
Before do
|
9
|
-
FakeWeb.clean_registry
|
10
|
-
FakeWeb.allow_net_connect = true
|
11
|
-
end
|
12
|
-
|
13
|
-
Before('@disconnected') do
|
14
|
-
FakeWeb.allow_net_connect = false
|
15
|
-
end
|
16
|
-
|
17
|
-
Before('@clean') do
|
18
|
-
credentials = YAML.load_file("#{File.dirname(__FILE__)}/harvest_credentials.yml")
|
19
|
-
api = Harvest.hardy_client(credentials["subdomain"], credentials["username"], credentials["password"], :ssl => credentials["ssl"])
|
20
|
-
|
21
|
-
api.users.all.each do |u|
|
22
|
-
api.users.delete(u) if u.email != credentials["username"]
|
23
|
-
end
|
24
|
-
my_user = api.users.all.first
|
25
|
-
|
26
|
-
api.reports.time_by_user(my_user, Time.parse('01/01/2000'), Time.now).each do |time|
|
27
|
-
api.time.delete(time)
|
28
|
-
end
|
29
|
-
|
30
|
-
api.reports.expenses_by_user(my_user, Time.parse('01/01/2000'), Time.now).each do |time|
|
31
|
-
api.expenses.delete(time)
|
32
|
-
end
|
33
|
-
|
34
|
-
%w(expenses expense_categories projects contacts clients tasks).each do |collection|
|
35
|
-
api.send(collection).all.each {|m| api.send(collection).delete(m) }
|
36
|
-
end
|
37
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module ErrorHelpers
|
2
|
-
def set_time_and_return_and_error
|
3
|
-
@time = Time.now
|
4
|
-
@error = nil
|
5
|
-
begin
|
6
|
-
@clients = yield
|
7
|
-
rescue => e
|
8
|
-
case e
|
9
|
-
when Harvest::HTTPError, Net::HTTPError, Net::HTTPFatalError
|
10
|
-
@error = e
|
11
|
-
else
|
12
|
-
raise e
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
World(ErrorHelpers)
|
@@ -1,8 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<hash>
|
3
|
-
<last-access-at type="datetime">2010-04-02T01:34:59+00:00</last-access-at>
|
4
|
-
<count type="integer">41</count>
|
5
|
-
<timeframe-limit type="integer">15</timeframe-limit>
|
6
|
-
<max-calls type="integer">40</max-calls>
|
7
|
-
<lockout-seconds type="integer">5</lockout-seconds>
|
8
|
-
</hash>
|
Binary file
|
@@ -1,8 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<hash>
|
3
|
-
<last-access-at type="datetime">2010-04-02T01:34:59+00:00</last-access-at>
|
4
|
-
<count type="integer">2</count>
|
5
|
-
<timeframe-limit type="integer">15</timeframe-limit>
|
6
|
-
<max-calls type="integer">40</max-calls>
|
7
|
-
<lockout-seconds type="integer">5</lockout-seconds>
|
8
|
-
</hash>
|
@@ -1,69 +0,0 @@
|
|
1
|
-
@clean
|
2
|
-
Feature: Task Assignments
|
3
|
-
|
4
|
-
Scenario: Adding and Updating a Task on a Project
|
5
|
-
Given I am using the credentials from "./support/harvest_credentials.yml"
|
6
|
-
When I create a client with the following:
|
7
|
-
| name | Client Projects |
|
8
|
-
| details | Building API Widgets across the country |
|
9
|
-
When I create a project for the client "Client Projects" with the following:
|
10
|
-
| name | Test Project |
|
11
|
-
| active | true |
|
12
|
-
| notes | project to test the api |
|
13
|
-
Then there should be a project "Test Project"
|
14
|
-
When I create a task with the following:
|
15
|
-
| name | Test Task |
|
16
|
-
| billable | true |
|
17
|
-
| deactivated | false |
|
18
|
-
| hourly_rate | 120 |
|
19
|
-
Then there should be a task "Test Task"
|
20
|
-
When I assign the task "Test Task" to the project "Test Project"
|
21
|
-
Then the task "Test Task" should be assigned to the project "Test Project"
|
22
|
-
When I update the task "Test Task" for the project "Test Project" with the following:
|
23
|
-
| hourly_rate | 75 |
|
24
|
-
| billable | false |
|
25
|
-
Then the task "Test Task" for the project "Test Project" should have the following attributes:
|
26
|
-
| hourly_rate | 75.0 |
|
27
|
-
| billable? | false |
|
28
|
-
| active? | true |
|
29
|
-
|
30
|
-
Scenario: Removing Tasks on a project
|
31
|
-
Given I am using the credentials from "./support/harvest_credentials.yml"
|
32
|
-
When I create a client with the following:
|
33
|
-
| name | Client Projects |
|
34
|
-
| details | Building API Widgets across the country |
|
35
|
-
When I create a project for the client "Client Projects" with the following:
|
36
|
-
| name | Test Project |
|
37
|
-
| active | true |
|
38
|
-
| notes | project to test the api |
|
39
|
-
Then there should be a project "Test Project"
|
40
|
-
When I create a task with the following:
|
41
|
-
| name | Test Task1 |
|
42
|
-
When I create a task with the following:
|
43
|
-
| name | Test Task2 |
|
44
|
-
Then there should be a task "Test Task1"
|
45
|
-
Then there should be a task "Test Task2"
|
46
|
-
When I assign the task "Test Task1" to the project "Test Project"
|
47
|
-
When I assign the task "Test Task2" to the project "Test Project"
|
48
|
-
Then the task "Test Task1" should be assigned to the project "Test Project"
|
49
|
-
Then the task "Test Task2" should be assigned to the project "Test Project"
|
50
|
-
When I remove the task "Test Task1" from the project "Test Project"
|
51
|
-
Then the task "Test Task1" should not be assigned to the project "Test Project"
|
52
|
-
When I try to remove the task "Test Task2" from the project "Test Project"
|
53
|
-
Then a 400 error should be raised
|
54
|
-
|
55
|
-
Scenario: Removing a task that has recorded hours
|
56
|
-
|
57
|
-
Scenario: Creating a task and immediately assigning it
|
58
|
-
Given I am using the credentials from "./support/harvest_credentials.yml"
|
59
|
-
When I create a client with the following:
|
60
|
-
| name | Client Projects |
|
61
|
-
| details | Building API Widgets across the country |
|
62
|
-
When I create a project for the client "Client Projects" with the following:
|
63
|
-
| name | Test Project |
|
64
|
-
| active | true |
|
65
|
-
| notes | project to test the api |
|
66
|
-
Then there should be a project "Test Project"
|
67
|
-
When I create and assign a task "Created Task" to the project "Test Project"
|
68
|
-
Then there should be a task "Created Task"
|
69
|
-
Then the task "Created Task" should be assigned to the project "Test Project"
|