mavenlink 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/README.md +241 -0
- data/Rakefile +28 -0
- data/bin/mavenlink-console +18 -0
- data/doc/ml_logo_lb-primary.png +0 -0
- data/lib/config/specification.yml +1665 -0
- data/lib/mavenlink.rb +134 -0
- data/lib/mavenlink/account_invitation.rb +4 -0
- data/lib/mavenlink/account_membership.rb +4 -0
- data/lib/mavenlink/additional_item.rb +4 -0
- data/lib/mavenlink/assignment.rb +5 -0
- data/lib/mavenlink/attachment.rb +11 -0
- data/lib/mavenlink/backup_approver_association.rb +4 -0
- data/lib/mavenlink/client.rb +116 -0
- data/lib/mavenlink/concerns/custom_fieldable.rb +9 -0
- data/lib/mavenlink/concerns/indestructible.rb +11 -0
- data/lib/mavenlink/concerns/locked_record.rb +30 -0
- data/lib/mavenlink/cost_rate.rb +4 -0
- data/lib/mavenlink/custom_field.rb +4 -0
- data/lib/mavenlink/custom_field_choice.rb +5 -0
- data/lib/mavenlink/custom_field_value.rb +4 -0
- data/lib/mavenlink/errors.rb +47 -0
- data/lib/mavenlink/expense.rb +4 -0
- data/lib/mavenlink/expense_category.rb +4 -0
- data/lib/mavenlink/expense_report_submission.rb +7 -0
- data/lib/mavenlink/external_payment.rb +4 -0
- data/lib/mavenlink/external_reference.rb +24 -0
- data/lib/mavenlink/fixed_fee_item.rb +4 -0
- data/lib/mavenlink/holiday.rb +4 -0
- data/lib/mavenlink/holiday_calendar.rb +4 -0
- data/lib/mavenlink/holiday_calendar_association.rb +4 -0
- data/lib/mavenlink/holiday_calendar_membership.rb +4 -0
- data/lib/mavenlink/invoice.rb +4 -0
- data/lib/mavenlink/logger.rb +62 -0
- data/lib/mavenlink/model.rb +279 -0
- data/lib/mavenlink/organization.rb +4 -0
- data/lib/mavenlink/organization_membership.rb +4 -0
- data/lib/mavenlink/participation.rb +4 -0
- data/lib/mavenlink/post.rb +4 -0
- data/lib/mavenlink/project_template.rb +4 -0
- data/lib/mavenlink/project_template_assignment.rb +4 -0
- data/lib/mavenlink/railtie.rb +7 -0
- data/lib/mavenlink/rate_card.rb +4 -0
- data/lib/mavenlink/rate_card_role.rb +4 -0
- data/lib/mavenlink/rate_card_set.rb +4 -0
- data/lib/mavenlink/rate_card_set_version.rb +30 -0
- data/lib/mavenlink/rate_card_version.rb +4 -0
- data/lib/mavenlink/request.rb +241 -0
- data/lib/mavenlink/resolution.rb +4 -0
- data/lib/mavenlink/response.rb +22 -0
- data/lib/mavenlink/role.rb +5 -0
- data/lib/mavenlink/settings.rb +11 -0
- data/lib/mavenlink/skill.rb +4 -0
- data/lib/mavenlink/skill_category.rb +4 -0
- data/lib/mavenlink/skill_membership.rb +4 -0
- data/lib/mavenlink/specificators/association.rb +13 -0
- data/lib/mavenlink/specificators/attribute.rb +13 -0
- data/lib/mavenlink/specificators/base.rb +24 -0
- data/lib/mavenlink/specificators/validation.rb +27 -0
- data/lib/mavenlink/status_report.rb +4 -0
- data/lib/mavenlink/story.rb +8 -0
- data/lib/mavenlink/story_allocation_day.rb +5 -0
- data/lib/mavenlink/story_dependency.rb +5 -0
- data/lib/mavenlink/story_task.rb +5 -0
- data/lib/mavenlink/tag.rb +5 -0
- data/lib/mavenlink/time_adjustment.rb +4 -0
- data/lib/mavenlink/time_entry.rb +4 -0
- data/lib/mavenlink/time_off_entry.rb +4 -0
- data/lib/mavenlink/timesheet_submission.rb +4 -0
- data/lib/mavenlink/user.rb +5 -0
- data/lib/mavenlink/vendor.rb +4 -0
- data/lib/mavenlink/workspace.rb +21 -0
- data/lib/mavenlink/workspace_group.rb +5 -0
- data/lib/mavenlink/workspace_invoice_preference.rb +4 -0
- data/lib/mavenlink/workweek.rb +4 -0
- data/lib/mavenlink/workweek_membership.rb +4 -0
- data/mavenlink.gemspec +29 -0
- data/spec/lib/mavenlink/account_membership_spec.rb +8 -0
- data/spec/lib/mavenlink/assignment_spec.rb +17 -0
- data/spec/lib/mavenlink/attachment_spec.rb +30 -0
- data/spec/lib/mavenlink/backup_approver_association_spec.rb +9 -0
- data/spec/lib/mavenlink/client_spec.rb +187 -0
- data/spec/lib/mavenlink/concerns/indestructible_spec.rb +13 -0
- data/spec/lib/mavenlink/concerns/locked_record_spec.rb +28 -0
- data/spec/lib/mavenlink/cost_rate_spec.rb +9 -0
- data/spec/lib/mavenlink/custom_field_value_spec.rb +10 -0
- data/spec/lib/mavenlink/expense_report_submission_spec.rb +16 -0
- data/spec/lib/mavenlink/expense_spec.rb +23 -0
- data/spec/lib/mavenlink/external_references_spec.rb +144 -0
- data/spec/lib/mavenlink/holiday_calendar_association_spec.rb +8 -0
- data/spec/lib/mavenlink/holiday_calendar_membership_spec.rb +8 -0
- data/spec/lib/mavenlink/holiday_spec.rb +7 -0
- data/spec/lib/mavenlink/invalid_request_error_spec.rb +9 -0
- data/spec/lib/mavenlink/invoice_spec.rb +176 -0
- data/spec/lib/mavenlink/model_spec.rb +439 -0
- data/spec/lib/mavenlink/post_spec.rb +23 -0
- data/spec/lib/mavenlink/rate_card_set_version_spec.rb +119 -0
- data/spec/lib/mavenlink/record_invalid_error_spec.rb +16 -0
- data/spec/lib/mavenlink/record_not_found_error_spec.rb +9 -0
- data/spec/lib/mavenlink/request_spec.rb +381 -0
- data/spec/lib/mavenlink/response_spec.rb +50 -0
- data/spec/lib/mavenlink/role_spec.rb +9 -0
- data/spec/lib/mavenlink/settings_spec.rb +23 -0
- data/spec/lib/mavenlink/skill_category_spec.rb +7 -0
- data/spec/lib/mavenlink/skill_membership_spec.rb +9 -0
- data/spec/lib/mavenlink/skill_spec.rb +8 -0
- data/spec/lib/mavenlink/specificators/association_spec.rb +25 -0
- data/spec/lib/mavenlink/specificators/attribute_spec.rb +25 -0
- data/spec/lib/mavenlink/specificators/validation_spec.rb +39 -0
- data/spec/lib/mavenlink/story_allocation_day_spec.rb +64 -0
- data/spec/lib/mavenlink/story_dependency_spec.rb +16 -0
- data/spec/lib/mavenlink/story_spec.rb +69 -0
- data/spec/lib/mavenlink/time_adjustment_spec.rb +13 -0
- data/spec/lib/mavenlink/time_entry_spec.rb +43 -0
- data/spec/lib/mavenlink/time_off_entry_spec.rb +9 -0
- data/spec/lib/mavenlink/user_spec.rb +138 -0
- data/spec/lib/mavenlink/workspace_group_spec.rb +25 -0
- data/spec/lib/mavenlink/workspace_spec.rb +431 -0
- data/spec/lib/mavenlink_spec.rb +43 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/shared_examples.rb +148 -0
- metadata +267 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Mavenlink
|
|
2
|
+
class Workspace < Model
|
|
3
|
+
include Mavenlink::Concerns::CustomFieldable
|
|
4
|
+
include Mavenlink::Concerns::Indestructible
|
|
5
|
+
|
|
6
|
+
# validates :due_date, format: 'YYYY-MM-DD'
|
|
7
|
+
# ...
|
|
8
|
+
|
|
9
|
+
# @todo Raise argument errors...
|
|
10
|
+
# @todo Return invitation model?
|
|
11
|
+
# @param invitation [Hash]
|
|
12
|
+
# @option invitation [String] :full_name (required) the full name of the person being invited
|
|
13
|
+
# @option invitation [String] :email_address (required) the email address of the person being invited
|
|
14
|
+
# @option invitation [String] :invitee_role (required) the role for the invited user, either __maven__ (consultant role) or __buyer__ (client role)
|
|
15
|
+
# @option invitation [String] :subject (optional) the subject message of the invitation email
|
|
16
|
+
# @option invitation [String] :message (optional) the text content of the invitation email; if you don't provide this, your default will be used
|
|
17
|
+
def invite(invitation)
|
|
18
|
+
client.post("workspaces/#@id/invite", invitation: invitation) if persisted?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/mavenlink.gemspec
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = %q{mavenlink}
|
|
5
|
+
s.version = "0.0.1"
|
|
6
|
+
|
|
7
|
+
s.date = %q{2014-04-01}
|
|
8
|
+
s.authors = ["Mavenlink"]
|
|
9
|
+
s.email = %q{opensource@mavenlink.com}
|
|
10
|
+
s.homepage = %q{http://github.com/mavenlink/mavenlink_gem}
|
|
11
|
+
|
|
12
|
+
s.licenses = ["MIT"]
|
|
13
|
+
|
|
14
|
+
s.files = `git ls-files`.split("\n")
|
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
16
|
+
s.require_paths = ["lib"]
|
|
17
|
+
s.extra_rdoc_files = ["README.md"]
|
|
18
|
+
|
|
19
|
+
s.description = %q{Simple Ruby API for the Mavenlink API}
|
|
20
|
+
s.summary = %q{Mavenlink API Ruby Wrapper}
|
|
21
|
+
|
|
22
|
+
s.add_runtime_dependency 'activesupport', ">= 4.0.4"
|
|
23
|
+
s.add_runtime_dependency 'activemodel', ">= 4.0.4"
|
|
24
|
+
s.add_runtime_dependency 'brainstem-adaptor', ">= 0.0.3"
|
|
25
|
+
s.add_runtime_dependency 'faraday', ">= 0.9.0"
|
|
26
|
+
s.add_development_dependency 'rspec', "2.14.1"
|
|
27
|
+
s.add_development_dependency 'shoulda-matchers', "2.5.0"
|
|
28
|
+
s.add_development_dependency 'awesome_print'
|
|
29
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Mavenlink::Assignment, stub_requests: true do
|
|
4
|
+
it_should_behave_like 'model', 'assignments'
|
|
5
|
+
|
|
6
|
+
it { should be_a Mavenlink::Concerns::Indestructible }
|
|
7
|
+
|
|
8
|
+
describe 'associations' do
|
|
9
|
+
it { should respond_to :story }
|
|
10
|
+
it { should respond_to :assignee }
|
|
11
|
+
it { should respond_to :story_allocation_days }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe '#destroy' do
|
|
15
|
+
specify { expect { subject.destroy }.to raise_error Mavenlink::RecordLockedError }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Mavenlink::Attachment, stub_requests: true do
|
|
4
|
+
it_should_behave_like 'model', 'attachments'
|
|
5
|
+
|
|
6
|
+
describe 'validations' do
|
|
7
|
+
it { should validate_presence_of :data }
|
|
8
|
+
it { should validate_presence_of :type }
|
|
9
|
+
it { should ensure_inclusion_of(:type).in_array(%w[receipt post_attachment]) }
|
|
10
|
+
it { should_not allow_value(nil).for(:type) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '#save' do
|
|
14
|
+
context 'persisted record' do
|
|
15
|
+
subject { described_class.new(id: 1, data: 'some data', type: 'receipt') }
|
|
16
|
+
|
|
17
|
+
it { should be_persisted }
|
|
18
|
+
|
|
19
|
+
specify do
|
|
20
|
+
expect { subject.save }.to raise_error Mavenlink::RecordLockedError
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'new record' do
|
|
25
|
+
specify do
|
|
26
|
+
expect { subject.save }.not_to raise_error
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Mavenlink::Client, stub_requests: true do
|
|
4
|
+
it { should respond_to :assignments }
|
|
5
|
+
it { should respond_to :expense_categories }
|
|
6
|
+
it { should respond_to :stories }
|
|
7
|
+
it { should respond_to :story_allocation_days }
|
|
8
|
+
it { should respond_to :users }
|
|
9
|
+
it { should respond_to :workspaces }
|
|
10
|
+
|
|
11
|
+
context 'oauth token is not set' do
|
|
12
|
+
specify do
|
|
13
|
+
expect { described_class.new({}) }.to raise_error ArgumentError, /token/
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'overriding the enpoint URL' do
|
|
18
|
+
specify do
|
|
19
|
+
endpoint = "http://api.mavenlink.test/api/v1"
|
|
20
|
+
client = described_class.new(oauth_token: '12345', endpoint: endpoint)
|
|
21
|
+
|
|
22
|
+
expect(client.send(:endpoint)).to eq endpoint
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'association calls' do
|
|
27
|
+
subject(:client) { described_class.new(oauth_token: '12345') }
|
|
28
|
+
let(:record) { client.workspaces.find(7) }
|
|
29
|
+
let(:response) {
|
|
30
|
+
{
|
|
31
|
+
'count' => 1,
|
|
32
|
+
'results' => [{'key' => 'workspaces', 'id' => '7'}, {'key' => 'users', 'id' => '2'}],
|
|
33
|
+
'users' => {
|
|
34
|
+
'2' => {
|
|
35
|
+
'id' => 2,
|
|
36
|
+
'full_name' => 'John Doe'
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
'workspaces' => {
|
|
40
|
+
'7' => {
|
|
41
|
+
'title' => 'My new project', 'id' => '7',
|
|
42
|
+
'participant_ids' => ['2'],
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
before do
|
|
49
|
+
stub_request :get, '/api/v1/workspaces?only=7', response
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
specify do
|
|
53
|
+
expect(record.participants.count).to eq(1)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
specify do
|
|
57
|
+
expect(record.participants.first).to be_a(Mavenlink::User)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'saves the client scope' do
|
|
61
|
+
expect(record.participants.first.client).to eq(client)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe '#assignments' do
|
|
66
|
+
let(:response) { { 'count' => 0, 'results' => [], 'assignments' => {} } }
|
|
67
|
+
|
|
68
|
+
before do
|
|
69
|
+
stub_request :get, '/api/v1/assignments', response
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
specify do
|
|
73
|
+
expect(subject.assignments).to be_a(Mavenlink::Request)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
specify do
|
|
77
|
+
expect(subject.assignments.collection_name).to eq('assignments')
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe '#stories' do
|
|
82
|
+
let(:response) { { 'count' => 0, 'results' => [], 'stories' => {} } }
|
|
83
|
+
|
|
84
|
+
before do
|
|
85
|
+
stub_request :get, '/api/v1/stories', response
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
specify do
|
|
89
|
+
expect(subject.stories).to be_a(Mavenlink::Request)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
specify do
|
|
93
|
+
expect(subject.stories.collection_name).to eq('stories')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe '#story_allocation_days' do
|
|
98
|
+
let(:response) { { 'count' => 0, 'results' => [], 'story_allocation_days' => {} } }
|
|
99
|
+
|
|
100
|
+
before do
|
|
101
|
+
stub_request :get, '/api/v1/story_allocation_days', response
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
specify do
|
|
105
|
+
expect(subject.story_allocation_days).to be_a(Mavenlink::Request)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
specify do
|
|
109
|
+
expect(subject.story_allocation_days.collection_name).to eq('story_allocation_days')
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe '#users' do
|
|
114
|
+
let(:response) { { 'count' => 0, 'results' => [], 'users' => {} } }
|
|
115
|
+
|
|
116
|
+
before do
|
|
117
|
+
stub_request :get, '/api/v1/users', response
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
specify do
|
|
121
|
+
expect(subject.users).to be_a(Mavenlink::Request)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
specify do
|
|
125
|
+
expect(subject.users.collection_name).to eq('users')
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe '#workspaces' do
|
|
130
|
+
let(:response) { { 'count' => 0, 'results' => [], 'workspaces' => {} } }
|
|
131
|
+
|
|
132
|
+
before do
|
|
133
|
+
stub_request :get, '/api/v1/workspaces', response
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
specify do
|
|
137
|
+
expect(subject.workspaces).to be_a(Mavenlink::Request)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
specify do
|
|
141
|
+
expect(subject.workspaces.collection_name).to eq('workspaces')
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
describe 'plain requests' do
|
|
146
|
+
let(:get_path) { '/get_something' }
|
|
147
|
+
let(:post_path) { '/post_something' }
|
|
148
|
+
let(:put_path) { '/put_something' }
|
|
149
|
+
let(:delete_path) { '/delete_something' }
|
|
150
|
+
|
|
151
|
+
let(:get_response) { {'get' => true} }
|
|
152
|
+
let(:post_response) { {'post' => true} }
|
|
153
|
+
let(:put_response) { {'put' => true} }
|
|
154
|
+
let(:delete_response) { {'delete' => true} }
|
|
155
|
+
|
|
156
|
+
before do
|
|
157
|
+
stub_request :get, get_path, get_response
|
|
158
|
+
stub_request :post, post_path, post_response
|
|
159
|
+
stub_request :put, put_path, put_response
|
|
160
|
+
stub_request :delete, delete_path, delete_response
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
describe '#get' do
|
|
164
|
+
specify do
|
|
165
|
+
expect(subject.get(get_path)).to eq(get_response)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe '#post' do
|
|
170
|
+
specify do
|
|
171
|
+
expect(subject.post(post_path)).to eq(post_response)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
describe '#put' do
|
|
176
|
+
specify do
|
|
177
|
+
expect(subject.put(put_path)).to eq(put_response)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
describe '#delete' do
|
|
182
|
+
specify do
|
|
183
|
+
expect(subject.delete(delete_path)).to eq(delete_response)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Mavenlink::Concerns::Indestructible do
|
|
4
|
+
subject do
|
|
5
|
+
Class.new do
|
|
6
|
+
include Mavenlink::Concerns::Indestructible
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
specify do
|
|
11
|
+
expect { subject.send(:new).destroy }.to raise_error Mavenlink::RecordLockedError, /locked.*deleted/
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Mavenlink::Concerns::LockedRecord do
|
|
4
|
+
subject do
|
|
5
|
+
Class.new do
|
|
6
|
+
def self.create
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
include Mavenlink::Concerns::LockedRecord
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
specify do
|
|
14
|
+
expect { subject.send(:new).save }.to raise_error Mavenlink::RecordLockedError, /locked.*changed/
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
specify do
|
|
18
|
+
expect { subject.send(:new).destroy }.to raise_error Mavenlink::RecordLockedError, /locked.*deleted/
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
specify do
|
|
22
|
+
expect { subject.new }.to raise_error NameError, /method.*new/
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
specify do
|
|
26
|
+
expect { subject.create }.to raise_error NameError, /method.*create/
|
|
27
|
+
end
|
|
28
|
+
end
|