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.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +3 -0
  6. data/README.md +241 -0
  7. data/Rakefile +28 -0
  8. data/bin/mavenlink-console +18 -0
  9. data/doc/ml_logo_lb-primary.png +0 -0
  10. data/lib/config/specification.yml +1665 -0
  11. data/lib/mavenlink.rb +134 -0
  12. data/lib/mavenlink/account_invitation.rb +4 -0
  13. data/lib/mavenlink/account_membership.rb +4 -0
  14. data/lib/mavenlink/additional_item.rb +4 -0
  15. data/lib/mavenlink/assignment.rb +5 -0
  16. data/lib/mavenlink/attachment.rb +11 -0
  17. data/lib/mavenlink/backup_approver_association.rb +4 -0
  18. data/lib/mavenlink/client.rb +116 -0
  19. data/lib/mavenlink/concerns/custom_fieldable.rb +9 -0
  20. data/lib/mavenlink/concerns/indestructible.rb +11 -0
  21. data/lib/mavenlink/concerns/locked_record.rb +30 -0
  22. data/lib/mavenlink/cost_rate.rb +4 -0
  23. data/lib/mavenlink/custom_field.rb +4 -0
  24. data/lib/mavenlink/custom_field_choice.rb +5 -0
  25. data/lib/mavenlink/custom_field_value.rb +4 -0
  26. data/lib/mavenlink/errors.rb +47 -0
  27. data/lib/mavenlink/expense.rb +4 -0
  28. data/lib/mavenlink/expense_category.rb +4 -0
  29. data/lib/mavenlink/expense_report_submission.rb +7 -0
  30. data/lib/mavenlink/external_payment.rb +4 -0
  31. data/lib/mavenlink/external_reference.rb +24 -0
  32. data/lib/mavenlink/fixed_fee_item.rb +4 -0
  33. data/lib/mavenlink/holiday.rb +4 -0
  34. data/lib/mavenlink/holiday_calendar.rb +4 -0
  35. data/lib/mavenlink/holiday_calendar_association.rb +4 -0
  36. data/lib/mavenlink/holiday_calendar_membership.rb +4 -0
  37. data/lib/mavenlink/invoice.rb +4 -0
  38. data/lib/mavenlink/logger.rb +62 -0
  39. data/lib/mavenlink/model.rb +279 -0
  40. data/lib/mavenlink/organization.rb +4 -0
  41. data/lib/mavenlink/organization_membership.rb +4 -0
  42. data/lib/mavenlink/participation.rb +4 -0
  43. data/lib/mavenlink/post.rb +4 -0
  44. data/lib/mavenlink/project_template.rb +4 -0
  45. data/lib/mavenlink/project_template_assignment.rb +4 -0
  46. data/lib/mavenlink/railtie.rb +7 -0
  47. data/lib/mavenlink/rate_card.rb +4 -0
  48. data/lib/mavenlink/rate_card_role.rb +4 -0
  49. data/lib/mavenlink/rate_card_set.rb +4 -0
  50. data/lib/mavenlink/rate_card_set_version.rb +30 -0
  51. data/lib/mavenlink/rate_card_version.rb +4 -0
  52. data/lib/mavenlink/request.rb +241 -0
  53. data/lib/mavenlink/resolution.rb +4 -0
  54. data/lib/mavenlink/response.rb +22 -0
  55. data/lib/mavenlink/role.rb +5 -0
  56. data/lib/mavenlink/settings.rb +11 -0
  57. data/lib/mavenlink/skill.rb +4 -0
  58. data/lib/mavenlink/skill_category.rb +4 -0
  59. data/lib/mavenlink/skill_membership.rb +4 -0
  60. data/lib/mavenlink/specificators/association.rb +13 -0
  61. data/lib/mavenlink/specificators/attribute.rb +13 -0
  62. data/lib/mavenlink/specificators/base.rb +24 -0
  63. data/lib/mavenlink/specificators/validation.rb +27 -0
  64. data/lib/mavenlink/status_report.rb +4 -0
  65. data/lib/mavenlink/story.rb +8 -0
  66. data/lib/mavenlink/story_allocation_day.rb +5 -0
  67. data/lib/mavenlink/story_dependency.rb +5 -0
  68. data/lib/mavenlink/story_task.rb +5 -0
  69. data/lib/mavenlink/tag.rb +5 -0
  70. data/lib/mavenlink/time_adjustment.rb +4 -0
  71. data/lib/mavenlink/time_entry.rb +4 -0
  72. data/lib/mavenlink/time_off_entry.rb +4 -0
  73. data/lib/mavenlink/timesheet_submission.rb +4 -0
  74. data/lib/mavenlink/user.rb +5 -0
  75. data/lib/mavenlink/vendor.rb +4 -0
  76. data/lib/mavenlink/workspace.rb +21 -0
  77. data/lib/mavenlink/workspace_group.rb +5 -0
  78. data/lib/mavenlink/workspace_invoice_preference.rb +4 -0
  79. data/lib/mavenlink/workweek.rb +4 -0
  80. data/lib/mavenlink/workweek_membership.rb +4 -0
  81. data/mavenlink.gemspec +29 -0
  82. data/spec/lib/mavenlink/account_membership_spec.rb +8 -0
  83. data/spec/lib/mavenlink/assignment_spec.rb +17 -0
  84. data/spec/lib/mavenlink/attachment_spec.rb +30 -0
  85. data/spec/lib/mavenlink/backup_approver_association_spec.rb +9 -0
  86. data/spec/lib/mavenlink/client_spec.rb +187 -0
  87. data/spec/lib/mavenlink/concerns/indestructible_spec.rb +13 -0
  88. data/spec/lib/mavenlink/concerns/locked_record_spec.rb +28 -0
  89. data/spec/lib/mavenlink/cost_rate_spec.rb +9 -0
  90. data/spec/lib/mavenlink/custom_field_value_spec.rb +10 -0
  91. data/spec/lib/mavenlink/expense_report_submission_spec.rb +16 -0
  92. data/spec/lib/mavenlink/expense_spec.rb +23 -0
  93. data/spec/lib/mavenlink/external_references_spec.rb +144 -0
  94. data/spec/lib/mavenlink/holiday_calendar_association_spec.rb +8 -0
  95. data/spec/lib/mavenlink/holiday_calendar_membership_spec.rb +8 -0
  96. data/spec/lib/mavenlink/holiday_spec.rb +7 -0
  97. data/spec/lib/mavenlink/invalid_request_error_spec.rb +9 -0
  98. data/spec/lib/mavenlink/invoice_spec.rb +176 -0
  99. data/spec/lib/mavenlink/model_spec.rb +439 -0
  100. data/spec/lib/mavenlink/post_spec.rb +23 -0
  101. data/spec/lib/mavenlink/rate_card_set_version_spec.rb +119 -0
  102. data/spec/lib/mavenlink/record_invalid_error_spec.rb +16 -0
  103. data/spec/lib/mavenlink/record_not_found_error_spec.rb +9 -0
  104. data/spec/lib/mavenlink/request_spec.rb +381 -0
  105. data/spec/lib/mavenlink/response_spec.rb +50 -0
  106. data/spec/lib/mavenlink/role_spec.rb +9 -0
  107. data/spec/lib/mavenlink/settings_spec.rb +23 -0
  108. data/spec/lib/mavenlink/skill_category_spec.rb +7 -0
  109. data/spec/lib/mavenlink/skill_membership_spec.rb +9 -0
  110. data/spec/lib/mavenlink/skill_spec.rb +8 -0
  111. data/spec/lib/mavenlink/specificators/association_spec.rb +25 -0
  112. data/spec/lib/mavenlink/specificators/attribute_spec.rb +25 -0
  113. data/spec/lib/mavenlink/specificators/validation_spec.rb +39 -0
  114. data/spec/lib/mavenlink/story_allocation_day_spec.rb +64 -0
  115. data/spec/lib/mavenlink/story_dependency_spec.rb +16 -0
  116. data/spec/lib/mavenlink/story_spec.rb +69 -0
  117. data/spec/lib/mavenlink/time_adjustment_spec.rb +13 -0
  118. data/spec/lib/mavenlink/time_entry_spec.rb +43 -0
  119. data/spec/lib/mavenlink/time_off_entry_spec.rb +9 -0
  120. data/spec/lib/mavenlink/user_spec.rb +138 -0
  121. data/spec/lib/mavenlink/workspace_group_spec.rb +25 -0
  122. data/spec/lib/mavenlink/workspace_spec.rb +431 -0
  123. data/spec/lib/mavenlink_spec.rb +43 -0
  124. data/spec/spec_helper.rb +31 -0
  125. data/spec/support/shared_examples.rb +148 -0
  126. metadata +267 -0
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class StatusReport < Model
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module Mavenlink
2
+ class Story < Model
3
+ include Concerns::CustomFieldable
4
+
5
+ validates :title, :story_type, :workspace_id, presence: true
6
+ validates :story_type, inclusion: {in: %w(task deliverable milestone issue)}
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Mavenlink
2
+ class StoryAllocationDay < Model
3
+ validates :assignment_id, :date, :minutes, presence: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Mavenlink
2
+ class StoryDependency < Model
3
+ validates :workspace_id, presence: true, on: :create
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Mavenlink
2
+ class StoryTask < Model
3
+ # include Concerns::Indestructible
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Mavenlink
2
+ class Tag < Model
3
+ # include Concerns::Indestructible
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class TimeAdjustment < Model
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class TimeEntry < Model
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class TimeOffEntry < Model
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class TimesheetSubmission < Model
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Mavenlink
2
+ class User < Model
3
+ include Concerns::CustomFieldable
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class Vendor < Model
3
+ end
4
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ module Mavenlink
2
+ class WorkspaceGroup < Model
3
+ include Mavenlink::Concerns::CustomFieldable
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class WorkspaceInvoicePreference < Model
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class Workweek < Model
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mavenlink
2
+ class WorkweekMembership < Model
3
+ end
4
+ 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,8 @@
1
+ require "spec_helper"
2
+
3
+ describe Mavenlink::AccountMembership, stub_requests: true do
4
+ describe "associations" do
5
+ it { should respond_to "cost_rates" }
6
+ it { should respond_to "backup_approver_associations" }
7
+ end
8
+ 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,9 @@
1
+ require "spec_helper"
2
+
3
+ describe Mavenlink::BackupApproverAssociation, stub_requests: true do
4
+ it_should_behave_like "model", "backup_approver_associations"
5
+
6
+ describe "association" do
7
+ it { should respond_to :account_membership }
8
+ end
9
+ 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