tracker_api 0.2.9 → 0.2.10

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/README.md +1 -0
  4. data/lib/core_ext/object/blank.rb +132 -0
  5. data/lib/tracker_api/client.rb +1 -1
  6. data/lib/tracker_api/endpoints/comments.rb +1 -1
  7. data/lib/tracker_api/endpoints/epic.rb +2 -2
  8. data/lib/tracker_api/endpoints/labels.rb +26 -0
  9. data/lib/tracker_api/endpoints/memberships.rb +6 -0
  10. data/lib/tracker_api/endpoints/story.rb +4 -4
  11. data/lib/tracker_api/endpoints/task.rb +16 -0
  12. data/lib/tracker_api/endpoints/tasks.rb +1 -1
  13. data/lib/tracker_api/resources/account.rb +1 -2
  14. data/lib/tracker_api/resources/activity.rb +6 -4
  15. data/lib/tracker_api/resources/base.rb +5 -60
  16. data/lib/tracker_api/resources/change.rb +1 -2
  17. data/lib/tracker_api/resources/comment.rb +1 -2
  18. data/lib/tracker_api/resources/epic.rb +1 -2
  19. data/lib/tracker_api/resources/iteration.rb +2 -0
  20. data/lib/tracker_api/resources/label.rb +8 -2
  21. data/lib/tracker_api/resources/me.rb +1 -2
  22. data/lib/tracker_api/resources/membership_summary.rb +1 -2
  23. data/lib/tracker_api/resources/notification.rb +1 -2
  24. data/lib/tracker_api/resources/person.rb +1 -2
  25. data/lib/tracker_api/resources/primary_resource.rb +1 -2
  26. data/lib/tracker_api/resources/project.rb +45 -8
  27. data/lib/tracker_api/resources/project_membership.rb +1 -2
  28. data/lib/tracker_api/resources/story.rb +36 -10
  29. data/lib/tracker_api/resources/task.rb +1 -2
  30. data/lib/tracker_api/version.rb +1 -1
  31. data/lib/tracker_api.rb +8 -2
  32. data/test/project_test.rb +29 -1
  33. data/test/story_test.rb +56 -1
  34. data/test/vcr/cassettes/client_done_iterations_with_pagination.json +1 -1
  35. data/test/vcr/cassettes/client_get_all_stories_with_pagination.json +1 -1
  36. data/test/vcr/cassettes/client_get_limited_stories_with_no_pagination.json +1 -1
  37. data/test/vcr/cassettes/client_get_single_story_by_story_id.json +1 -1
  38. data/test/vcr/cassettes/create_story.json +1 -1
  39. data/test/vcr/cassettes/create_story_with_lengthy_params.json +1 -1
  40. data/test/vcr/cassettes/create_task.json +1 -0
  41. data/test/vcr/cassettes/get_all_projects.json +1 -1
  42. data/test/vcr/cassettes/get_another_story.json +1 -0
  43. data/test/vcr/cassettes/get_current_iteration.json +1 -1
  44. data/test/vcr/cassettes/get_done_iterations.json +1 -1
  45. data/test/vcr/cassettes/get_epics.json +1 -1
  46. data/test/vcr/cassettes/get_iteration_by_number.json +1 -1
  47. data/test/vcr/cassettes/get_labels.json +1 -0
  48. data/test/vcr/cassettes/get_me.json +1 -46
  49. data/test/vcr/cassettes/get_my_activities.json +1 -1
  50. data/test/vcr/cassettes/get_project.json +1 -1
  51. data/test/vcr/cassettes/get_project_activity.json +1 -1
  52. data/test/vcr/cassettes/get_project_with_epics.json +1 -1
  53. data/test/vcr/cassettes/get_project_with_labels.json +1 -0
  54. data/test/vcr/cassettes/get_story.json +1 -1
  55. data/test/vcr/cassettes/get_story_activity.json +1 -1
  56. data/test/vcr/cassettes/get_story_with_tasks.json +1 -0
  57. data/test/vcr/cassettes/get_tasks.json +1 -1
  58. data/test/vcr/cassettes/get_tasks_for_story.json +1 -0
  59. data/test/vcr/cassettes/get_tasks_when_stories_filtered.json +1 -1
  60. data/test/vcr/cassettes/get_unscheduled_stories.json +1 -1
  61. data/test/vcr/cassettes/get_unscheduled_story.json +1 -1
  62. data/test/vcr/cassettes/save_story.json +1 -1
  63. data/test/vcr/cassettes/save_story_with_multiple_changes.json +1 -1
  64. data/test/vcr/cassettes/save_story_with_new_label.json +1 -0
  65. data/test/vcr/cassettes/update_story_to_create_activity.json +1 -1
  66. data/tracker_api.gemspec +3 -2
  67. metadata +35 -6
  68. data/test/vcr/cassettes/get_activity.json +0 -148
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb0f996134be9b6af61da9dbb41f47c23bbc79fd
4
- data.tar.gz: 3172bee693120381ce20b5f83c2037e604d7edd7
3
+ metadata.gz: a617d2b19c294a813a8edf94eed605c18daa6969
4
+ data.tar.gz: 8d05e8a155dcdf15e84c0efaba86dcd6b1914e86
5
5
  SHA512:
6
- metadata.gz: 95c7d010ab3c59f30944c14a760736d5f3ebab13caeac8c8eed4471347a464b26bb34af3094e10af131ff254a8b2fedc4bc532717058853033cfd0c5b63dd2ac
7
- data.tar.gz: 4d1a3bd5ac33807a8219c05e7ad995b905857e960d4dee6ddf582e19a255c346102c0385b304d903672eb4fc098dee9579b6b255154fdf86808512491c1a98a6
6
+ metadata.gz: 374ec16671b186d2309513d2419e7839f98b0e71e88fee635660a18f2f5a406e5133cc24252fc8cebb6a5094d2b3cdc725edf879ad94c4bf585aa79ded685fd9
7
+ data.tar.gz: b8b668d588b2e6ffc4fd8455d0ef0b288e5f25c8ed896385fc707e35f608639e93781aef742aec4ef9483b48ef54a9ae8cf9e01fba4cc38dd43f2563d5f47de4
data/.travis.yml CHANGED
@@ -3,6 +3,7 @@ rvm:
3
3
  - "1.9.3"
4
4
  - "2.0.0"
5
5
  - "2.1.0"
6
+ - "2.2.2"
6
7
  # Faraday::ConnectionFailed: Could not generate DH keypair (Java::JavaLang::RuntimeException)
7
8
  # http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7044060
8
9
  # - jruby-19mode # JRuby in 1.9 mode
data/README.md CHANGED
@@ -53,6 +53,7 @@ story.activity # Get
53
53
 
54
54
  story.name = 'Save the Ewoks' # Update a single story attribute
55
55
  story.attributes = { name: 'Save the Ewoks', description: '...' } # Update multiple story attributes
56
+ story.labels << Label.new(name: 'Endor') # Add a new label to an existing story
56
57
  story.save # Save changes made to a story
57
58
 
58
59
  epics = project.epics # Get all epics for a project
@@ -0,0 +1,132 @@
1
+ # encoding: utf-8
2
+
3
+ # Borrowed from: activesupport-4.2.2/lib/active_support/core_ext/object/blank.rb
4
+ class Object
5
+ # An object is blank if it's false, empty, or a whitespace string.
6
+ # For example, '', ' ', +nil+, [], and {} are all blank.
7
+ #
8
+ # This simplifies
9
+ #
10
+ # address.nil? || address.empty?
11
+ #
12
+ # to
13
+ #
14
+ # address.blank?
15
+ #
16
+ # @return [true, false]
17
+ def blank?
18
+ respond_to?(:empty?) ? !!empty? : !self
19
+ end
20
+
21
+ # An object is present if it's not blank.
22
+ #
23
+ # @return [true, false]
24
+ def present?
25
+ !blank?
26
+ end
27
+
28
+ # Returns the receiver if it's present otherwise returns +nil+.
29
+ # <tt>object.presence</tt> is equivalent to
30
+ #
31
+ # object.present? ? object : nil
32
+ #
33
+ # For example, something like
34
+ #
35
+ # state = params[:state] if params[:state].present?
36
+ # country = params[:country] if params[:country].present?
37
+ # region = state || country || 'US'
38
+ #
39
+ # becomes
40
+ #
41
+ # region = params[:state].presence || params[:country].presence || 'US'
42
+ #
43
+ # @return [Object]
44
+ def presence
45
+ self if present?
46
+ end
47
+ end
48
+
49
+ class NilClass
50
+ # +nil+ is blank:
51
+ #
52
+ # nil.blank? # => true
53
+ #
54
+ # @return [true]
55
+ def blank?
56
+ true
57
+ end
58
+ end
59
+
60
+ class FalseClass
61
+ # +false+ is blank:
62
+ #
63
+ # false.blank? # => true
64
+ #
65
+ # @return [true]
66
+ def blank?
67
+ true
68
+ end
69
+ end
70
+
71
+ class TrueClass
72
+ # +true+ is not blank:
73
+ #
74
+ # true.blank? # => false
75
+ #
76
+ # @return [false]
77
+ def blank?
78
+ false
79
+ end
80
+ end
81
+
82
+ class Array
83
+ # An array is blank if it's empty:
84
+ #
85
+ # [].blank? # => true
86
+ # [1,2,3].blank? # => false
87
+ #
88
+ # @return [true, false]
89
+ alias_method :blank?, :empty?
90
+ end
91
+
92
+ class Hash
93
+ # A hash is blank if it's empty:
94
+ #
95
+ # {}.blank? # => true
96
+ # { key: 'value' }.blank? # => false
97
+ #
98
+ # @return [true, false]
99
+ alias_method :blank?, :empty?
100
+ end
101
+
102
+ class String
103
+ BLANK_RE = /\A[[:space:]]*\z/
104
+
105
+ # A string is blank if it's empty or contains whitespaces only:
106
+ #
107
+ # ''.blank? # => true
108
+ # ' '.blank? # => true
109
+ # "\t\n\r".blank? # => true
110
+ # ' blah '.blank? # => false
111
+ #
112
+ # Unicode whitespace is supported:
113
+ #
114
+ # "\u00a0".blank? # => true
115
+ #
116
+ # @return [true, false]
117
+ def blank?
118
+ BLANK_RE === self
119
+ end
120
+ end
121
+
122
+ class Numeric #:nodoc:
123
+ # No number is blank:
124
+ #
125
+ # 1.blank? # => false
126
+ # 0.blank? # => false
127
+ #
128
+ # @return [false]
129
+ def blank?
130
+ false
131
+ end
132
+ end
@@ -187,7 +187,7 @@ module TrackerApi
187
187
  headers = options[:headers]
188
188
 
189
189
  if (method == :post || method == :put) && options[:body].blank?
190
- body = params.to_json
190
+ body = Oj.dump(params)
191
191
  headers['Content-Type'] = 'application/json'
192
192
 
193
193
  params = {}
@@ -7,7 +7,7 @@ module TrackerApi
7
7
  @client = client
8
8
  end
9
9
 
10
- def get(project_id, story_id, params={})
10
+ def get(project_id, story_id, params={})
11
11
  data = client.paginate("/projects/#{project_id}/stories/#{story_id}/comments", params: params)
12
12
  raise TrackerApi::Errors::UnexpectedData, 'Array of comments expected' unless data.is_a? Array
13
13
 
@@ -7,8 +7,8 @@ module TrackerApi
7
7
  @client = client
8
8
  end
9
9
 
10
- def get(project_id, id)
11
- data = client.get("/projects/#{project_id}/epics/#{id}").body
10
+ def get(project_id, id, params={})
11
+ data = client.get("/projects/#{project_id}/epics/#{id}", params: params).body
12
12
 
13
13
  Resources::Epic.new({ project_id: project_id }.merge(data))
14
14
  end
@@ -0,0 +1,26 @@
1
+ module TrackerApi
2
+ module Endpoints
3
+ class Labels
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def get(project_id, params={})
11
+ data = client.paginate("/projects/#{project_id}/labels", params: params)
12
+ raise TrackerApi::Errors::UnexpectedData, 'Array of labels expected' unless data.is_a? Array
13
+
14
+ data.map do |label|
15
+ Resources::Label.new({ project_id: project_id }.merge(label))
16
+ end
17
+ end
18
+
19
+ def add(project_id, params={})
20
+ data = client.post("/projects/#{project_id}/labels", params: params).body
21
+
22
+ Resources::Label.new({ project_id: project_id }.merge(data))
23
+ end
24
+ end
25
+ end
26
+ end
@@ -15,6 +15,12 @@ module TrackerApi
15
15
  Resources::ProjectMembership.new({ project_id: project_id }.merge(membership))
16
16
  end
17
17
  end
18
+
19
+ def add(project_id, params={})
20
+ data = client.post("/projects/#{project_id}/memberships", params: params).body
21
+
22
+ Resources::ProjectMembership.new({ project_id: project_id }.merge(data))
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -7,14 +7,14 @@ module TrackerApi
7
7
  @client = client
8
8
  end
9
9
 
10
- def get(project_id, id)
11
- data = client.get("/projects/#{project_id}/stories/#{id}").body
10
+ def get(project_id, id, params={})
11
+ data = client.get("/projects/#{project_id}/stories/#{id}", params: params).body
12
12
 
13
13
  Resources::Story.new({ client: client, project_id: project_id }.merge(data))
14
14
  end
15
15
 
16
- def get_story(story_id)
17
- data = client.get("/stories/#{story_id}").body
16
+ def get_story(story_id, params={})
17
+ data = client.get("/stories/#{story_id}", params: params).body
18
18
 
19
19
  Resources::Story.new({ client: client }.merge(data))
20
20
  end
@@ -0,0 +1,16 @@
1
+ module TrackerApi
2
+ module Endpoints
3
+ class Task
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def create(project_id, story_id, params={})
11
+ data = client.post("/projects/#{project_id}/stories/#{story_id}/tasks", params: params).body
12
+ Resources::Task.new(data)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -7,7 +7,7 @@ module TrackerApi
7
7
  @client = client
8
8
  end
9
9
 
10
- def get(project_id, story_id, params={})
10
+ def get(project_id, story_id, params={})
11
11
  data = client.paginate("/projects/#{project_id}/stories/#{story_id}/tasks", params: params)
12
12
  raise TrackerApi::Errors::UnexpectedData, 'Array of tasks expected' unless data.is_a? Array
13
13
 
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Account
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :created_at, DateTime
8
7
  attribute :status, String
9
8
  attribute :kind, String
@@ -3,6 +3,8 @@ module TrackerApi
3
3
  class Activity
4
4
  include Virtus.model
5
5
 
6
+ include Equalizer.new(:guid)
7
+
6
8
  attribute :client
7
9
 
8
10
  attribute :kind, String
@@ -10,10 +12,10 @@ module TrackerApi
10
12
  attribute :project_version, Integer
11
13
  attribute :message, String
12
14
  attribute :highlight, String
13
- attribute :changes, Array[TrackerApi::Resources::Change]
14
- attribute :primary_resources, Array[TrackerApi::Resources::PrimaryResource]
15
- attribute :project, TrackerApi::Resources::Project
16
- attribute :performed_by, TrackerApi::Resources::Person
15
+ attribute :changes, Array[Resources::Change]
16
+ attribute :primary_resources, Array[Resources::PrimaryResource]
17
+ attribute :project, Resources::Project
18
+ attribute :performed_by, Resources::Person
17
19
  attribute :occurred_at, DateTime
18
20
 
19
21
  def project=(data)
@@ -1,69 +1,14 @@
1
1
  require 'virtus'
2
- require 'active_support/concern'
3
- require 'active_model'
4
2
 
5
3
  module TrackerApi
6
4
  module Resources
7
5
  module Base
8
- extend ActiveSupport::Concern
6
+ def self.included(base)
7
+ base.class_eval do
8
+ include Virtus.model
9
+ include Equalizer.new(:id)
9
10
 
10
- include ActiveModel::Model
11
- include ActiveModel::Dirty
12
-
13
- included do
14
- include Virtus.model
15
- include OverrideAttributes
16
-
17
- attribute :id, Integer
18
-
19
- def initialize(attrs)
20
- super
21
-
22
- # always reset dirty tracking on initialize
23
- clear_changes_information
24
- end
25
-
26
- private
27
-
28
- # @return [Hash] key value pairs for just the changed attributes with their new values.
29
- def just_changes
30
- # @see changes in ActiveModel::Dirty in active_model/dirty.rb
31
- # { attr => [original value, new value] }
32
- changes.inject({}) do |h, (k, v)|
33
- h[k] = v[1]; h;
34
- end
35
- end
36
- end
37
-
38
- module OverrideAttributes
39
- extend ActiveSupport::Concern
40
-
41
- module ClassMethods
42
- def attribute(name, type, options = {})
43
- define_attribute_methods name
44
-
45
- attribute = super
46
- create_writer_with_dirty_tracking(name)
47
- attribute
48
- end
49
-
50
- private
51
-
52
- def create_writer_with_dirty_tracking(name)
53
- method_str = <<-RUBY
54
- def #{name}=(value)
55
- prev_value = #{name}
56
- new_value = value
57
- if prev_value != new_value
58
- #{name}_will_change!
59
- new_value = super(value)
60
- end
61
- new_value
62
- end
63
- RUBY
64
-
65
- class_eval method_str, __FILE__, __LINE__ + 1
66
- end
11
+ attribute :id, Integer
67
12
  end
68
13
  end
69
14
  end
@@ -1,10 +1,9 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Change
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
6
  attribute :change_type, String
7
- attribute :id, Integer
8
7
  attribute :kind, String
9
8
  attribute :name, String
10
9
  attribute :new_values, Hash
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Comment
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :story_id, Integer
8
7
  attribute :epic_id, Integer
9
8
  attribute :text, String
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Epic
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :created_at, DateTime
8
7
  attribute :description, String
9
8
  attribute :kind, String
@@ -3,6 +3,8 @@ module TrackerApi
3
3
  class Iteration
4
4
  include Virtus.model
5
5
 
6
+ include Equalizer.new(:number, :project_id)
7
+
6
8
  attribute :client
7
9
 
8
10
  attribute :finish, DateTime
@@ -1,14 +1,20 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Label
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :created_at, DateTime
8
7
  attribute :kind, String
9
8
  attribute :name, String
10
9
  attribute :project_id, Integer
11
10
  attribute :updated_at, DateTime
11
+
12
+ class UpdateRepresenter < Representable::Decorator
13
+ include Representable::JSON
14
+
15
+ property :id
16
+ property :name
17
+ end
12
18
  end
13
19
  end
14
20
  end
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Me
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :name, String
8
7
  attribute :initials, String
9
8
  attribute :username, String
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class MembershipSummary
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :kind, String
8
7
  attribute :last_viewed_at, DateTime
9
8
  attribute :project_color, String
@@ -1,11 +1,10 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Notification
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
6
  attribute :client
7
7
 
8
- attribute :id, Integer
9
8
  attribute :message, String
10
9
  attribute :kind, String
11
10
  attribute :project, TrackerApi::Resources::Project
@@ -1,10 +1,9 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Person
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
6
  attribute :kind, String
7
- attribute :id, Integer
8
7
  attribute :name, String
9
8
  attribute :email, String
10
9
  attribute :initials, String
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class PrimaryResource
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :kind, String
8
7
  attribute :name, String
9
8
  attribute :story_type, String
@@ -1,7 +1,7 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class Project
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
6
  attribute :client
7
7
 
@@ -20,7 +20,6 @@ module TrackerApi
20
20
  attribute :epic_ids, Array[Integer]
21
21
  attribute :epics, Array[TrackerApi::Resources::Epic]
22
22
  attribute :has_google_domain, Boolean
23
- attribute :id, Integer
24
23
  attribute :initial_velocity, Integer
25
24
  attribute :iteration_length, Integer
26
25
  attribute :kind, String
@@ -45,6 +44,25 @@ module TrackerApi
45
44
  @label_list ||= labels.collect(&:name).join(',')
46
45
  end
47
46
 
47
+ # @return [Integer] comma separated list of label_ids
48
+ def label_ids
49
+ @label_ids ||= labels.collect(&:id).join(',')
50
+ end
51
+
52
+ # Provides a list of all the labels on the project.
53
+ #
54
+ # @param [Hash] params
55
+ # @return [Array[Label]] labels of this project
56
+ def labels(params = {})
57
+ if @labels && @labels.any?
58
+ @labels
59
+ else
60
+ @labels = Endpoints::Labels.new(client).get(id, params)
61
+ end
62
+ end
63
+
64
+ # Provides a list of all the epics in the project.
65
+ #
48
66
  # @param [Hash] params
49
67
  # @return [Array[Epic]] epics associated with this project
50
68
  def epics(params={})
@@ -54,6 +72,8 @@ module TrackerApi
54
72
  @epics = Endpoints::Epics.new(client).get(id, params)
55
73
  end
56
74
 
75
+ # Provides a list of all the iterations in the project.
76
+ #
57
77
  # @param [Hash] params
58
78
  # @option params [String] :scope Restricts the state of iterations to return.
59
79
  # If not specified, it defaults to all iterations including done.
@@ -63,7 +83,7 @@ module TrackerApi
63
83
  # set of iterations specified by 'scope', with zero being the first iteration in the scope.
64
84
  # @option params [Integer] :limit The number of iterations to return relative to the offset.
65
85
  # @return [Array[Iteration]] iterations associated with this project
66
- def iterations(params = {})
86
+ def iterations(params={})
67
87
  if params.include?(:number)
68
88
  number = params[:number].to_i
69
89
  raise ArgumentError, ':number must be > 0' unless number > 0
@@ -78,6 +98,9 @@ module TrackerApi
78
98
  Endpoints::Iterations.new(client).get(id, params)
79
99
  end
80
100
 
101
+
102
+ # Provides a list of all the stories in the project.
103
+ #
81
104
  # @param [Hash] params
82
105
  # @option params [String] :with_label A label name which all returned stories must match.
83
106
  # @option params [String] :with_state A story's current_state which all returned stories must match.
@@ -90,13 +113,15 @@ module TrackerApi
90
113
  # the index of the first story you want returned.
91
114
  # @option params [Integer] :limit The number of stories you want returned.
92
115
  # @return [Array[Story]] stories associated with this project
93
- def stories(params = {})
116
+ def stories(params={})
94
117
  Endpoints::Stories.new(client).get(id, params)
95
118
  end
96
119
 
120
+ # Provides a list of all the memberships in the project.
121
+ #
97
122
  # @param [Hash] params
98
123
  # @return [Array[ProjectMembership]] memberships of this project
99
- def memberships(params = {})
124
+ def memberships(params={})
100
125
  Endpoints::Memberships.new(client).get(id, params)
101
126
  end
102
127
 
@@ -104,21 +129,33 @@ module TrackerApi
104
129
  #
105
130
  # @param [Hash] params
106
131
  # @return [Array[Activity]]
107
- def activity(params = {})
132
+ def activity(params={})
108
133
  Endpoints::Activity.new(client).get_project(id, params)
109
134
  end
110
135
 
136
+ # Find a story by id for the project.
137
+ #
111
138
  # @param [Fixnum] story_id id of story to get
112
139
  # @return [Story] story with given id
113
- def story(story_id)
114
- Endpoints::Story.new(client).get(id, story_id)
140
+ def story(story_id, params={})
141
+ Endpoints::Story.new(client).get(id, story_id, params)
115
142
  end
116
143
 
144
+ # Create a new story in the project.
145
+ #
117
146
  # @param [Hash] params attributes to create the story with
118
147
  # @return [Story] newly created Story
119
148
  def create_story(params)
120
149
  Endpoints::Story.new(client).create(id, params)
121
150
  end
151
+
152
+ # Add a new membership for the project.
153
+ #
154
+ # @param [Hash] params attributes to add a member; must have at least email or user_id
155
+ # @return [ProjectMembership] member that was added to project
156
+ def add_membership(params)
157
+ Endpoints::Memberships.new(client).add(id, params)
158
+ end
122
159
  end
123
160
  end
124
161
  end
@@ -1,9 +1,8 @@
1
1
  module TrackerApi
2
2
  module Resources
3
3
  class ProjectMembership
4
- include Virtus.model
4
+ include Resources::Base
5
5
 
6
- attribute :id, Integer
7
6
  attribute :person_id, Integer
8
7
  attribute :project_id, Integer
9
8
  attribute :role, String