harvested2 5.0.3
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.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +35 -0
- data/.rspec +1 -0
- data/.rubocop.yml +34 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +20 -0
- data/HISTORY.md +118 -0
- data/MIT-LICENSE +21 -0
- data/README.md +66 -0
- data/Rakefile +24 -0
- data/harvested2.gemspec +30 -0
- 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/account.rb +13 -0
- data/lib/harvest/api/account.rb +25 -0
- data/lib/harvest/api/base.rb +72 -0
- data/lib/harvest/api/clients.rb +10 -0
- data/lib/harvest/api/company.rb +12 -0
- data/lib/harvest/api/contacts.rb +9 -0
- data/lib/harvest/api/expense_categories.rb +9 -0
- data/lib/harvest/api/expenses.rb +26 -0
- data/lib/harvest/api/invoice_categories.rb +9 -0
- data/lib/harvest/api/invoice_messages.rb +86 -0
- data/lib/harvest/api/invoice_payments.rb +41 -0
- data/lib/harvest/api/invoices.rb +9 -0
- data/lib/harvest/api/projects.rb +9 -0
- data/lib/harvest/api/task_assignments.rb +75 -0
- data/lib/harvest/api/tasks.rb +9 -0
- data/lib/harvest/api/time_entry.rb +19 -0
- data/lib/harvest/api/user_assignments.rb +75 -0
- data/lib/harvest/api/users.rb +10 -0
- data/lib/harvest/base.rb +333 -0
- data/lib/harvest/behavior/activatable.rb +31 -0
- data/lib/harvest/behavior/crud.rb +80 -0
- data/lib/harvest/client.rb +23 -0
- data/lib/harvest/company.rb +8 -0
- data/lib/harvest/contact.rb +20 -0
- data/lib/harvest/credentials.rb +34 -0
- data/lib/harvest/errors.rb +27 -0
- data/lib/harvest/expense.rb +54 -0
- data/lib/harvest/expense_category.rb +10 -0
- data/lib/harvest/hardy_client.rb +80 -0
- data/lib/harvest/invoice.rb +75 -0
- data/lib/harvest/invoice_category.rb +8 -0
- data/lib/harvest/invoice_message.rb +8 -0
- data/lib/harvest/invoice_payment.rb +8 -0
- data/lib/harvest/line_item.rb +21 -0
- data/lib/harvest/model.rb +133 -0
- data/lib/harvest/project.rb +41 -0
- data/lib/harvest/receipt.rb +12 -0
- data/lib/harvest/task.rb +21 -0
- data/lib/harvest/task_assignment.rb +27 -0
- data/lib/harvest/time_entry.rb +57 -0
- data/lib/harvest/timezones.rb +130 -0
- data/lib/harvest/user.rb +58 -0
- data/lib/harvest/user_assignment.rb +27 -0
- data/lib/harvest/version.rb +3 -0
- data/lib/harvested2.rb +96 -0
- data/spec/factories/client.rb +14 -0
- data/spec/factories/contact.rb +8 -0
- data/spec/factories/expense.rb +10 -0
- data/spec/factories/expenses_category.rb +7 -0
- data/spec/factories/invoice.rb +25 -0
- data/spec/factories/invoice_category.rb +5 -0
- data/spec/factories/invoice_message.rb +9 -0
- data/spec/factories/invoice_payment.rb +7 -0
- data/spec/factories/line_item.rb +9 -0
- data/spec/factories/project.rb +15 -0
- data/spec/factories/task.rb +8 -0
- data/spec/factories/task_assignment.rb +8 -0
- data/spec/factories/time_entry.rb +13 -0
- data/spec/factories/user.rb +19 -0
- data/spec/factories/user_assigment.rb +7 -0
- data/spec/functional/clients_spec.rb +105 -0
- data/spec/functional/errors_spec.rb +42 -0
- data/spec/functional/expenses_spec.rb +97 -0
- data/spec/functional/invoice_messages_spec.rb +48 -0
- data/spec/functional/invoice_payments_spec.rb +51 -0
- data/spec/functional/invoice_spec.rb +138 -0
- data/spec/functional/project_spec.rb +76 -0
- data/spec/functional/tasks_spec.rb +119 -0
- data/spec/functional/time_entries_spec.rb +87 -0
- data/spec/functional/users_spec.rb +72 -0
- data/spec/harvest/base_spec.rb +10 -0
- data/spec/harvest/basic_auth_credentials_spec.rb +12 -0
- data/spec/harvest/expense_category_spec.rb +5 -0
- data/spec/harvest/expense_spec.rb +18 -0
- data/spec/harvest/invoice_message_spec.rb +5 -0
- data/spec/harvest/invoice_payment_spec.rb +5 -0
- data/spec/harvest/invoice_spec.rb +5 -0
- data/spec/harvest/oauth_credentials_spec.rb +11 -0
- data/spec/harvest/project_spec.rb +5 -0
- data/spec/harvest/task_assignment_spec.rb +5 -0
- data/spec/harvest/task_spec.rb +5 -0
- data/spec/harvest/time_entry_spec.rb +23 -0
- data/spec/harvest/user_assignment_spec.rb +5 -0
- data/spec/harvest/user_spec.rb +34 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/factory_bot.rb +5 -0
- data/spec/support/harvested_helpers.rb +28 -0
- data/spec/support/json_examples.rb +9 -0
- metadata +238 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'harvest errors' do
|
|
4
|
+
let(:harvest) { Harvest.client(access_token: 'mytoken', account_id: '123') }
|
|
5
|
+
|
|
6
|
+
before { WebMock.disable_net_connect! }
|
|
7
|
+
|
|
8
|
+
context 'wraps errors' do
|
|
9
|
+
it 'sould returns a Harvest::BadRequest error' do
|
|
10
|
+
stub_request(:get, /\/clients/).to_return({ status: ['400', 'Bad Request']},
|
|
11
|
+
{ body: '[]', status: 200})
|
|
12
|
+
expect { harvest.clients.all }.to raise_error(Harvest::BadRequest)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'sould returns a Harvest::NotFound error' do
|
|
16
|
+
stub_request(:get, /\/clients/)
|
|
17
|
+
.to_return({ status: ['404', 'Not Found'] }, { body: '[]', status: 200})
|
|
18
|
+
expect { harvest.clients.all }.to raise_error(Harvest::NotFound)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'sould returns a Harvest::ServerError error' do
|
|
22
|
+
stub_request(:get, /\/clients/)
|
|
23
|
+
.to_return({ status: ['500', 'Server Error'] },
|
|
24
|
+
{ body: '[]', status: 200 })
|
|
25
|
+
expect { harvest.clients.all }.to raise_error(Harvest::ServerError)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'sould returns a Harvest::Unavailable error' do
|
|
29
|
+
stub_request(:get, /\/clients/)
|
|
30
|
+
.to_return({ status: ['502', 'Bad Gateway'] },
|
|
31
|
+
{ body: '[]', status: 200 })
|
|
32
|
+
expect { harvest.clients.all }.to raise_error(Harvest::Unavailable)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'sould returns a Harvest::RateLimited error' do
|
|
36
|
+
stub_request(:get, /\/clients/)
|
|
37
|
+
.to_return({ status: ['503', 'Rate Limited'] },
|
|
38
|
+
{ body: '[]', status: 200 })
|
|
39
|
+
expect { harvest.clients.all }.to raise_error(Harvest::RateLimited)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'harvest expenses' do
|
|
4
|
+
let(:harvest) { Harvest.client(access_token: 'mytoken', account_id: '123') }
|
|
5
|
+
|
|
6
|
+
describe 'categories' do
|
|
7
|
+
let(:expense_category) { create(:expense_category) }
|
|
8
|
+
let(:expense_category_attributes) do
|
|
9
|
+
FactoryBot.attributes_for(:expense_category)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context 'allows to add clients' do
|
|
13
|
+
before do
|
|
14
|
+
allow(harvest.expense_categories).to receive(:create)
|
|
15
|
+
.and_return(expense_category)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'returns true' do
|
|
19
|
+
expect(expense_category.name).to eql('Mileage')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'allows to update clients' do
|
|
24
|
+
before do
|
|
25
|
+
allow(harvest.expense_categories).to receive(:update)
|
|
26
|
+
.and_return(expense_category)
|
|
27
|
+
expense_category.name = 'Travel'
|
|
28
|
+
expense_category = harvest.expense_categories.update(expense_category)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'returns true' do
|
|
32
|
+
expect(expense_category.name).to eql('Travel')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'allows to delete clients' do
|
|
37
|
+
before do
|
|
38
|
+
allow(harvest.expense_categories).to receive(:delete).and_return([])
|
|
39
|
+
allow(harvest.expense_categories).to receive(:all).and_return([])
|
|
40
|
+
harvest.expense_categories.delete(expense_category)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'returns true' do
|
|
44
|
+
expect(harvest.expense_categories.all.select do |e|
|
|
45
|
+
e.name == 'Travel'
|
|
46
|
+
end).to eql([])
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe 'expenses' do
|
|
52
|
+
let(:client) { create(:client) }
|
|
53
|
+
let(:project) { create(:project, client: client) }
|
|
54
|
+
let(:expense_category) { create(:expense_category) }
|
|
55
|
+
let(:expense) do
|
|
56
|
+
create(:expense, project: project, expense_category: expense_category)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context 'allows to add expense' do
|
|
60
|
+
before do
|
|
61
|
+
allow(harvest.expenses).to receive(:create)
|
|
62
|
+
.and_return(expense)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'returns true' do
|
|
66
|
+
expect(expense.notes).to eql('Drive to Chicago')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context 'allows to update expense' do
|
|
71
|
+
before do
|
|
72
|
+
allow(harvest.expenses).to receive(:update)
|
|
73
|
+
.and_return(expense)
|
|
74
|
+
expense.notes = 'Off to Chicago'
|
|
75
|
+
expense = harvest.expenses.update(expense)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'returns true' do
|
|
79
|
+
expect(expense.notes).to eql('Off to Chicago')
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'allows to delete clients' do
|
|
84
|
+
before do
|
|
85
|
+
allow(harvest.expenses).to receive(:delete).and_return([])
|
|
86
|
+
allow(harvest.expenses).to receive(:all).and_return([])
|
|
87
|
+
harvest.expenses.delete(expense)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'returns true' do
|
|
91
|
+
expect(harvest.expenses.all(Time.utc(2009, 12, 28)).select do |e|
|
|
92
|
+
e.notes == 'Off to Chicago'
|
|
93
|
+
end).to eql([])
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'harvest invoice messages' do
|
|
4
|
+
let(:harvest) { Harvest.client(access_token: 'mytoken', account_id: '123') }
|
|
5
|
+
|
|
6
|
+
describe 'invoice messages' do
|
|
7
|
+
let(:invoice) { create(:invoice) }
|
|
8
|
+
let(:invoice_message) { create(:invoice_message) }
|
|
9
|
+
|
|
10
|
+
context 'allows to add invoice_messages' do
|
|
11
|
+
before do
|
|
12
|
+
allow(harvest.invoice_messages).to receive(:create)
|
|
13
|
+
.and_return(invoice_message)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns true' do
|
|
17
|
+
expect(invoice_message.body).to eql('The message body goes here')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'allows to update invoice_messages' do
|
|
22
|
+
before do
|
|
23
|
+
allow(harvest.invoice_messages).to receive(:update)
|
|
24
|
+
.and_return(invoice_message)
|
|
25
|
+
invoice_message.body = 'New body text'
|
|
26
|
+
invoice_message = harvest.invoice_messages.update(invoice_message)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'returns true' do
|
|
30
|
+
expect(invoice_message.body).to eql('New body text')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'allows to remove invoice_messages' do
|
|
35
|
+
before do
|
|
36
|
+
allow(harvest.invoice_messages).to receive(:delete).and_return([])
|
|
37
|
+
allow(harvest.invoice_messages).to receive(:all).and_return([])
|
|
38
|
+
harvest.invoice_messages.delete(invoice_message)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'returns true' do
|
|
42
|
+
expect(harvest.invoice_messages.all.select do |i|
|
|
43
|
+
i.body == 'New body text'
|
|
44
|
+
end).to eql([])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'harvest invoice payments' do
|
|
4
|
+
let(:harvest) { Harvest.client(access_token: 'mytoken', account_id: '123') }
|
|
5
|
+
|
|
6
|
+
describe 'invoice payments' do
|
|
7
|
+
let(:invoice) { create(:invoice) }
|
|
8
|
+
let(:invoice_payment) { create(:invoice_payment, amount: invoice.amount) }
|
|
9
|
+
let(:invoice_payment_attributes) do
|
|
10
|
+
FactoryBot.attributes_for(:invoice_payment)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'allows to add invoice_payments' do
|
|
14
|
+
before do
|
|
15
|
+
allow(harvest.invoice_payments).to receive(:create)
|
|
16
|
+
.and_return(invoice_payment)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'returns true' do
|
|
20
|
+
expect(invoice_payment.amount).to eql(invoice.amount)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'allows to update invoice_payments' do
|
|
25
|
+
before do
|
|
26
|
+
allow(harvest.invoice_payments).to receive(:update)
|
|
27
|
+
.and_return(invoice_payment)
|
|
28
|
+
invoice_payment.amount = 200
|
|
29
|
+
invoice_payment = harvest.invoice_payments.update(invoice_payment)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'returns true' do
|
|
33
|
+
expect(invoice_payment.amount).to eql(200)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'allows to remove invoice_payments' do
|
|
38
|
+
before do
|
|
39
|
+
allow(harvest.invoice_payments).to receive(:delete).and_return([])
|
|
40
|
+
allow(harvest.invoice_payments).to receive(:all).and_return([])
|
|
41
|
+
harvest.invoice_payments.delete(invoice_payment)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'returns true' do
|
|
45
|
+
expect(harvest.invoice_payments.all.select do |i|
|
|
46
|
+
i.amount == 200
|
|
47
|
+
end).to eql([])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'harvest invoices' do
|
|
4
|
+
let(:harvest) { Harvest.client(access_token: 'mytoken', account_id: '123') }
|
|
5
|
+
|
|
6
|
+
describe 'categories' do
|
|
7
|
+
let(:invoice_category) { create(:invoice_category) }
|
|
8
|
+
|
|
9
|
+
context 'allows to add invoice categories' do
|
|
10
|
+
before do
|
|
11
|
+
allow(harvest.invoice_categories).to receive(:create)
|
|
12
|
+
.and_return(invoice_category)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'returns true' do
|
|
16
|
+
expect(invoice_category.name).to eql('New Category')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'allows to update invoice categories' do
|
|
21
|
+
before do
|
|
22
|
+
allow(harvest.invoice_categories).to receive(:update)
|
|
23
|
+
.and_return(invoice_category)
|
|
24
|
+
invoice_category.name = 'Updated Category'
|
|
25
|
+
invoice_category = harvest.invoice_categories.update(invoice_category)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'returns true' do
|
|
29
|
+
expect(invoice_category.name).to eql('Updated Category')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'allows to remove invoice categories' do
|
|
34
|
+
before do
|
|
35
|
+
allow(harvest.invoice_categories).to receive(:delete).and_return([])
|
|
36
|
+
allow(harvest.invoice_categories).to receive(:all).and_return([])
|
|
37
|
+
harvest.invoice_categories.delete(invoice_category)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'returns true' do
|
|
41
|
+
expect(harvest.invoice_categories.all.select do |p|
|
|
42
|
+
p.name == 'Updated Category'
|
|
43
|
+
end).to eql([])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe 'invoices' do
|
|
49
|
+
let(:invoice_category) { create(:invoice_category) }
|
|
50
|
+
let(:invoice) { create(:invoice) }
|
|
51
|
+
let(:line_item) { create(:line_item) }
|
|
52
|
+
|
|
53
|
+
context 'allows to add invoice invoices' do
|
|
54
|
+
before do
|
|
55
|
+
allow(harvest.invoices).to receive(:create)
|
|
56
|
+
.and_return(invoice)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'returns true' do
|
|
60
|
+
expect(invoice.subject)
|
|
61
|
+
.to eql("Invoice for Joe's Stream Cleaning")
|
|
62
|
+
expect(invoice.amount).to eql(2400.0)
|
|
63
|
+
expect(invoice.line_items.size).to eql(0)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'allows to update invoices' do
|
|
68
|
+
before do
|
|
69
|
+
allow(harvest.invoices).to receive(:update)
|
|
70
|
+
.and_return(invoice)
|
|
71
|
+
invoice.subject = 'Updated Invoice for Joe'
|
|
72
|
+
invoice.line_items << line_item
|
|
73
|
+
invoice.update_line_items = true
|
|
74
|
+
invoice.amount = 4800.0
|
|
75
|
+
invoice = harvest.invoices.update(invoice)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'returns true' do
|
|
79
|
+
expect(invoice.subject).to eql('Updated Invoice for Joe')
|
|
80
|
+
expect(invoice.amount).to eql(4800.0)
|
|
81
|
+
expect(invoice.line_items.size).to eql(1)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context 'allows to remove invoices' do
|
|
86
|
+
before do
|
|
87
|
+
allow(harvest.invoices).to receive(:delete).and_return([])
|
|
88
|
+
allow(harvest.invoices).to receive(:all).and_return([])
|
|
89
|
+
harvest.invoices.delete(invoice)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'returns true' do
|
|
93
|
+
expect(harvest.invoices.all.select do |i|
|
|
94
|
+
i.number == '1000'
|
|
95
|
+
end).to eql([])
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe 'read' do
|
|
101
|
+
let(:invoice_category) { create(:invoice_category) }
|
|
102
|
+
let(:invoice) { create(:invoice) }
|
|
103
|
+
let(:line_item) { create(:line_item) }
|
|
104
|
+
let(:invoice_attributes) { FactoryBot.attributes_for(:invoice) }
|
|
105
|
+
let(:invoices) { [invoice] }
|
|
106
|
+
|
|
107
|
+
context 'allows finding one invoice with parameters' do
|
|
108
|
+
before do
|
|
109
|
+
allow(harvest.invoices).to receive(:create)
|
|
110
|
+
.and_return(invoice)
|
|
111
|
+
allow(harvest.invoices).to receive(:find)
|
|
112
|
+
.and_return(invoice)
|
|
113
|
+
allow(harvest.invoices).to receive(:all).and_return(invoices)
|
|
114
|
+
|
|
115
|
+
invoice = harvest.invoices.create(invoice_attributes)
|
|
116
|
+
invoice.line_items << line_item
|
|
117
|
+
result = harvest.invoices.find(invoice.id)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'returns a specific invoice' do
|
|
121
|
+
expect(invoice.subject).to eql("Invoice for Joe's Stream Cleaning")
|
|
122
|
+
expect(invoice.amount).to eql(2400.0)
|
|
123
|
+
expect(invoice.line_items.size).to eql(1)
|
|
124
|
+
expect(invoice.due_at).to eql('2011-03-31')
|
|
125
|
+
expect(invoices.count).to eql(1)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'returns invoices' do
|
|
129
|
+
invoices = harvest.invoices.all(status: 'draft')
|
|
130
|
+
expect(invoice.subject).to eql("Invoice for Joe's Stream Cleaning")
|
|
131
|
+
expect(invoice.amount).to eql(2400.0)
|
|
132
|
+
expect(invoice.line_items.size).to eql(1)
|
|
133
|
+
expect(invoice.due_at).to eql('2011-03-31')
|
|
134
|
+
expect(invoices.count).to eql(1)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'harvest projects' do
|
|
4
|
+
let(:harvest) { Harvest.client(access_token: 'mytoken', account_id: '123') }
|
|
5
|
+
|
|
6
|
+
describe 'projects' do
|
|
7
|
+
let(:client) { create(:client) }
|
|
8
|
+
let(:project) { create(:project, client: client) }
|
|
9
|
+
let(:project_attributes) { FactoryBot.attributes_for(:project) }
|
|
10
|
+
|
|
11
|
+
context 'allows to add projects' do
|
|
12
|
+
before do
|
|
13
|
+
allow(harvest.projects).to receive(:create).and_return(project)
|
|
14
|
+
project = harvest.projects.create(project_attributes)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should return true' do
|
|
18
|
+
expect(project.name).to eql('Project Test')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'allows to update projects' do
|
|
23
|
+
before do
|
|
24
|
+
allow(harvest.projects).to receive(:update).and_return(project)
|
|
25
|
+
project.name = 'Updated Project'
|
|
26
|
+
project = harvest.projects.update(project)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should return true' do
|
|
30
|
+
expect(project.name).to eql('Updated Project')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'allows to remove projects' do
|
|
35
|
+
before do
|
|
36
|
+
allow(harvest.projects).to receive(:delete).and_return([])
|
|
37
|
+
allow(harvest.projects).to receive(:all).and_return([])
|
|
38
|
+
harvest.projects.delete(project)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'returns true' do
|
|
42
|
+
expect(harvest.projects.all.select do |p|
|
|
43
|
+
p.name == 'Updated Project'
|
|
44
|
+
end).to eql([])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe 'clients' do
|
|
50
|
+
context 'allows activating and deactivating clients' do
|
|
51
|
+
let(:active_project) { create(:project, :active) }
|
|
52
|
+
let(:deactive_project) { create(:project, :deactive) }
|
|
53
|
+
|
|
54
|
+
before do
|
|
55
|
+
allow(harvest.projects).to receive(:deactivate)
|
|
56
|
+
.and_return(deactive_project)
|
|
57
|
+
allow(harvest.projects).to receive(:activate)
|
|
58
|
+
.and_return(active_project)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'should be active' do
|
|
62
|
+
expect(active_project).to be_active
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'should be deactive' do
|
|
66
|
+
project = harvest.projects.deactivate(project)
|
|
67
|
+
expect(deactive_project).not_to be_active
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'should reactive a project' do
|
|
71
|
+
project = harvest.projects.activate(project)
|
|
72
|
+
expect(active_project).to be_active
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|