jiralicious 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README.md +3 -0
  2. data/jiralicious.gemspec +0 -2
  3. data/lib/jiralicious.rb +4 -0
  4. data/lib/jiralicious/avatar.rb +101 -0
  5. data/lib/jiralicious/base.rb +53 -15
  6. data/lib/jiralicious/configuration.rb +30 -4
  7. data/lib/jiralicious/custom_field_option.rb +7 -3
  8. data/lib/jiralicious/errors.rb +10 -0
  9. data/lib/jiralicious/field.rb +23 -12
  10. data/lib/jiralicious/issue.rb +69 -11
  11. data/lib/jiralicious/issue/comment.rb +54 -12
  12. data/lib/jiralicious/issue/fields.rb +44 -3
  13. data/lib/jiralicious/issue/transitions.rb +42 -11
  14. data/lib/jiralicious/issue/watchers.rb +19 -2
  15. data/lib/jiralicious/parsers/field_parser.rb +12 -0
  16. data/lib/jiralicious/project.rb +7 -1
  17. data/lib/jiralicious/project/avatar.rb +126 -0
  18. data/lib/jiralicious/search.rb +9 -0
  19. data/lib/jiralicious/search_result.rb +15 -7
  20. data/lib/jiralicious/session.rb +5 -0
  21. data/lib/jiralicious/user.rb +154 -0
  22. data/lib/jiralicious/user/avatar.rb +130 -0
  23. data/lib/jiralicious/version.rb +1 -1
  24. data/spec/avatar_spec.rb +50 -0
  25. data/spec/basic_session_spec.rb +4 -0
  26. data/spec/comment_spec.rb +2 -2
  27. data/spec/fixtures/avatar.json +7 -0
  28. data/spec/fixtures/avatar_custom.json +16 -0
  29. data/spec/fixtures/avatar_list.json +16 -0
  30. data/spec/fixtures/avatar_temp.json +7 -0
  31. data/spec/fixtures/avatar_test.png +0 -0
  32. data/spec/fixtures/user.json +27 -0
  33. data/spec/fixtures/user_array.json +26 -0
  34. data/spec/fixtures/user_picker.json +18 -0
  35. data/spec/issue_spec.rb +10 -9
  36. data/spec/project_avatar_spec.rb +66 -0
  37. data/spec/project_spec.rb +2 -2
  38. data/spec/search_spec.rb +2 -1
  39. data/spec/support/http.rb +24 -0
  40. data/spec/user_avatar_spec.rb +66 -0
  41. data/spec/user_spec.rb +79 -0
  42. data/spec/watchers_spec.rb +2 -2
  43. metadata +30 -18
@@ -2,7 +2,8 @@
2
2
  module Jiralicious
3
3
  class Issue
4
4
  ##
5
- # The Watchers class is used to manage the watchers on an issue.
5
+ # The Watchers class is used to manage the
6
+ # watchers on an issue.
6
7
  #
7
8
  class Watchers < Jiralicious::Base
8
9
  ##
@@ -13,7 +14,7 @@ module Jiralicious
13
14
  ##
14
15
  # Initialization Method
15
16
  #
16
- def initialize(decoded_json = nil, default = nil, &blk)
17
+ def initialize(decoded_json = nil)
17
18
  if (decoded_json != nil)
18
19
  properties_from_hash(decoded_json)
19
20
  super(decoded_json)
@@ -25,6 +26,9 @@ module Jiralicious
25
26
  ##
26
27
  # Finds all watchers based on the provided Issue Key
27
28
  #
29
+ # [Arguments]
30
+ # :key (required) issue key to find
31
+ #
28
32
  def find_by_key(key)
29
33
  response = fetch({:parent => parent_name, :parent_key => key})
30
34
  a = new(response)
@@ -35,6 +39,11 @@ module Jiralicious
35
39
  ##
36
40
  # Adds a new Watcher to the Issue
37
41
  #
42
+ # [Arguments]
43
+ # :name (required) name of the watcher
44
+ #
45
+ # :key (required) issue key
46
+ #
38
47
  def add(name, key)
39
48
  fetch({:method => :post, :body => name, :body_override => true, :parent => parent_name, :parent_key => key})
40
49
  end
@@ -42,6 +51,11 @@ module Jiralicious
42
51
  ##
43
52
  # Removes/Deletes a Watcher from the Issue
44
53
  #
54
+ # [Arguments]
55
+ # :name (required) name of the watcher
56
+ #
57
+ # :key (required) issue key
58
+ #
45
59
  def remove(name, key)
46
60
  fetch({:method => :delete, :body_to_params => true, :body => {:username => name}, :parent => parent_name, :parent_key => key})
47
61
  end
@@ -57,6 +71,9 @@ module Jiralicious
57
71
  ##
58
72
  # Adds a new Watcher to the Issue
59
73
  #
74
+ # [Arguments]
75
+ # :name (required) name of the watcher
76
+ #
60
77
  def add(name)
61
78
  self.class.add(name, @jira_key)
62
79
  end
@@ -1,5 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module Jiralicious
3
+ ##
4
+ # Parsing module contains all of the parser functionality
5
+ #
3
6
  module Parsers
4
7
  ##
5
8
  # The FieldParser module is an extention that assists in
@@ -9,6 +12,9 @@ module Jiralicious
9
12
  ##
10
13
  # Parses an Array or Hash into the current class object.
11
14
  #
15
+ # [Arguments]
16
+ # :fields (required) fields to be parsed
17
+ #
12
18
  def parse!(fields)
13
19
  unless fields.is_a?(Hash)
14
20
  raise ArgumentError
@@ -42,6 +48,9 @@ module Jiralicious
42
48
  ##
43
49
  # Normalizes key names
44
50
  #
51
+ # [Arguments]
52
+ # :name (required) name to be normalized
53
+ #
45
54
  def normalize(name)
46
55
  name.gsub(/(\w+)([A-Z].*)/, '\1_\2').
47
56
  gsub(/\W/, "_").
@@ -51,6 +60,9 @@ module Jiralicious
51
60
  ##
52
61
  # Converts Array or Hash to a Mash object
53
62
  #
63
+ # [Arguments]
64
+ # :data (required) data be be mashified
65
+ #
54
66
  def mashify(data)
55
67
  if data.is_a?(Array)
56
68
  data.map { |d| mashify(d) }
@@ -9,7 +9,10 @@ module Jiralicious
9
9
  ##
10
10
  # Initialization Method
11
11
  #
12
- def initialize(decoded_json, default = nil, &blk)
12
+ # [Arguments]
13
+ # :decoded_json (optional) rubyized json object
14
+ #
15
+ def initialize(decoded_json)
13
16
  @loaded = false
14
17
  if decoded_json.is_a? Hash
15
18
  properties_from_hash(decoded_json)
@@ -30,6 +33,9 @@ module Jiralicious
30
33
  # to only return the issue ID and KEY values to minimize the amount of
31
34
  # data being returned This is used in lazy loading methodology.
32
35
  #
36
+ # [Arguments]
37
+ # :key (required) project key
38
+ #
33
39
  def issue_list(key)
34
40
  response = Jiralicious.search("project=#{key}", {:fields => ["id", "key"]})
35
41
  i_out = Issue.new
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+ module Jiralicious
3
+ class Project
4
+ ##
5
+ # Avatars in the Project class.
6
+ #
7
+ class Avatar < Jiralicious::Base
8
+
9
+ ##
10
+ # Initialization Method
11
+ #
12
+ # [Arguments]
13
+ # :decoded_json (optional) decoded json object
14
+ #
15
+ def initialize(decoded_json = nil)
16
+ @loaded = false
17
+ if !decoded_json.nil?
18
+ if decoded_json.is_a? Hash
19
+ decoded_json = properties_from_hash(decoded_json)
20
+ super(decoded_json)
21
+ parse!(decoded_json)
22
+ self.each do |k, v|
23
+ if v.is_a? Hash
24
+ self[k] = self.class.new(v)
25
+ elsif v.is_a? Array
26
+ v.each_index do |i|
27
+ if v[i].is_a? Hash
28
+ v[i] = self.class.new(v[i])
29
+ end
30
+ end
31
+ self[k] = v
32
+ end
33
+ end
34
+ @loaded = true
35
+ else
36
+ i = 0;
37
+ decoded_json.each do |list|
38
+ if !list['id'].nil?
39
+ if numeric? list['id']
40
+ id = :"id_#{list['id']}"
41
+ else
42
+ id = :"#{list['id']}"
43
+ end
44
+ else
45
+ id = :"_#{i}"
46
+ i += 1
47
+ end
48
+ self.class.property id
49
+ self[id] = self.class.new(list)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ class << self
56
+ ##
57
+ # Converts the temporary avatar to a real avatar
58
+ #
59
+ # [Arguments]
60
+ # :key (required) project key
61
+ #
62
+ # :cropperWidth (optional) width of the avatar
63
+ #
64
+ # :cropperOffsetX (optional) X offset on image
65
+ #
66
+ # :cropperOffsetY (optional) Y offset on image
67
+ #
68
+ # :needsCropping (optional) boolean if it needs cropping
69
+ #
70
+ def post(key, options = {})
71
+ response = fetch({:method => :post, :parent => true, :parent_key => key, :body => options})
72
+ end
73
+
74
+ ##
75
+ # Update Avatar information
76
+ #
77
+ # [Arguments]
78
+ # :key (required) project key
79
+ #
80
+ # :options (optional) not documented
81
+ #
82
+ def put(key, options = {})
83
+ response = fetch({:method => :put, :parent => true, :parent_key => key, :body => options})
84
+ end
85
+
86
+ ##
87
+ # Creates tempoary avatar
88
+ #
89
+ # [Arguments]
90
+ # :key (required) project key
91
+ #
92
+ # :filename (required) file to upload
93
+ #
94
+ # :size (required) size of the file
95
+ #
96
+ def temporary(key, options = {})
97
+ response = fetch({:method => :post, :parent => true, :parent_key => key, :key => 'temporary', :body => options})
98
+ return self.new(response.parsed_response)
99
+ end
100
+
101
+ ##
102
+ # Deletes or removes the avatar from the project
103
+ #
104
+ # [Arguments]
105
+ # :key (required) project key
106
+ #
107
+ # :id (required) avatar id
108
+ #
109
+ def remove(key, id)
110
+ response = fetch({:method => :delete, :body_to_params => true, :parent => true, :parent_key => key, :key => "#{id}"})
111
+ end
112
+
113
+ ##
114
+ # Gets a list of available avatars
115
+ #
116
+ # [Arguments]
117
+ # :key (required) project key
118
+ #
119
+ def avatars(key, options = {})
120
+ response = fetch({:method => :get, :url => "#{Jiralicious.rest_path}/#{parent_name}/#{key}/#{endpoint_name}s/", :body_to_params => true, :body => options})
121
+ return self.new(response.parsed_response)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -4,6 +4,15 @@ module Jiralicious
4
4
  # Provides the interface to access the JQL search functionality.
5
5
  # Uses the same syntax as Rest interface for JQL criteria.
6
6
  #
7
+ # [Arguments]
8
+ # :jql (required) JQL string
9
+ #
10
+ # :start_at (optional) offset to start at
11
+ #
12
+ # :max_results (optional) maximum number to return
13
+ #
14
+ # :fields (optional) field options
15
+ #
7
16
  def search(jql, options = {})
8
17
  options[:start_at] ||= 0
9
18
  options[:max_results] ||= 50
@@ -12,25 +12,33 @@ module Jiralicious
12
12
  #
13
13
  # Parses the hash into attributes.
14
14
  #
15
+ # [Arguments]
16
+ # :search_data (required) hash data to be parsed
17
+ #
15
18
  def initialize(search_data)
16
19
  @issues = search_data["issues"]
17
20
  @offset = search_data["startAt"]
18
21
  @num_results = search_data["total"]
19
22
  end
20
23
 
21
- ##
22
- # Loads the different issues through the map. This is not recommended for large objects
23
- # as it can be troublesome to load multiple Issues to locate the desired one. If the user needs to have all of the information available on each issue this method works perfectly for that process.
24
- #
24
+ ##
25
+ # Loads the different issues through the map. This is not recommended
26
+ # for large objects as it can be troublesome to load multiple Issues
27
+ # to locate the desired one. If the user needs to have all of the
28
+ # information available on each issue this method works perfectly for
29
+ # that process.
30
+ #
25
31
  def issues
26
32
  @issues.map do |issue|
27
33
  Jiralicious::Issue.find(issue["key"])
28
34
  end
29
35
  end
30
36
 
31
- ##
32
- # Returns the Issues attribute without loading the extra information. Ideal for a quick scan of the Hash prior to selecting the correct Issue. This method is also used in the lazy loading methodology.
33
- #
37
+ ##
38
+ # Returns the Issues attribute without loading the extra information.
39
+ # Ideal for a quick scan of the Hash prior to selecting the correct
40
+ # Issue. This method is also used in the lazy loading methodology.
41
+ #
34
42
  def issues_raw
35
43
  @issues
36
44
  end
@@ -17,6 +17,11 @@ module Jiralicious
17
17
  ##
18
18
  # Main access method to request data from the Jira API
19
19
  #
20
+ # [Arguments]
21
+ # :method (required) http method type
22
+ #
23
+ # :options (required) request specific options
24
+ #
20
25
  def request(method, *options)
21
26
  if options.last.is_a?(Hash) && options.last[:handler]
22
27
  response_handler = options.last.delete(:handler)
@@ -0,0 +1,154 @@
1
+ # encoding: utf-8
2
+ module Jiralicious
3
+ ##
4
+ # The User class rolls up the functionality of user management.
5
+ # This class contains methods to manage Users from Ruby via the
6
+ # API.
7
+ #
8
+ class User < Jiralicious::Base
9
+
10
+ ##
11
+ # Initialization Method
12
+ #
13
+ # [Arguments]
14
+ # :decoded_json (optional) rubyized json object
15
+ #
16
+ def initialize(decoded_json = nil)
17
+ @loaded = false
18
+ if !decoded_json.nil?
19
+ if decoded_json.is_a? Hash
20
+ decoded_json = properties_from_hash(decoded_json)
21
+ super(decoded_json)
22
+ parse!(decoded_json)
23
+ self.each do |k, v|
24
+ if v.is_a? Hash
25
+ self[k] = self.class.new(v)
26
+ elsif v.is_a? Array
27
+ v.each_index do |i|
28
+ if v[i].is_a? Hash
29
+ v[i] = self.class.new(v[i])
30
+ end
31
+ end
32
+ self[k] = v
33
+ end
34
+ end
35
+ @loaded = true
36
+ else
37
+ i = 0;
38
+ decoded_json.each do |list|
39
+ if !list['id'].nil?
40
+ if numeric? list['id']
41
+ id = :"id_#{list['id']}"
42
+ else
43
+ id = :"#{list['id']}"
44
+ end
45
+ else
46
+ id = :"_#{i}"
47
+ i += 1
48
+ end
49
+ self.class.property id
50
+ self[id] = self.class.new(list)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ class << self
57
+ ##
58
+ # Retrieves the user by UserName.
59
+ #
60
+ # A valid request will return the user details.
61
+ # An invalid request will throw an error.
62
+ #
63
+ # [Arguments]
64
+ # :username (required) Must be correct username, no partials
65
+ #
66
+ def find(username)
67
+ response = fetch({:url => "#{Jiralicious.rest_path}/#{endpoint_name}", :method => :get, :body_to_params => true, :body => {:username => username}})
68
+ return self.new(response.parsed_response)
69
+ end
70
+
71
+ ##
72
+ # Returns a list of users matching the criteria
73
+ #
74
+ # [Arguments]
75
+ # :projectKey (required) Should be upper case
76
+ #
77
+ # :username (optional) Must be correct username, no partials
78
+ #
79
+ # :startAt (optional) Integer
80
+ #
81
+ # :maxResults (optional) Integer
82
+ #
83
+ def assignable_multiProjectSearch(projectKeys, options = {})
84
+ options.merge!({:projectKeys=>projectKeys.upcase})
85
+ response = fetch({:method => :get, :key => "assignable/multiProjectSearch", :body_to_params => true, :body => options})
86
+ return self.new(response.parsed_response)
87
+ end
88
+
89
+ ##
90
+ # Returns a list of users matching the criteria
91
+ #
92
+ # [Arguments]
93
+ # :project (required) Should be upper case
94
+ #
95
+ # OR
96
+ #
97
+ # :issueKey (required) Should be upper case
98
+ #
99
+ # :username (optional) Must be correct username,
100
+ # no partials, cannot be by itself
101
+ #
102
+ # :startAt (optional) Integer
103
+ #
104
+ # :maxResults (optional) Integer
105
+ #
106
+ # :ActionDescriptorId (optional) Integer
107
+ #
108
+ def assignable_search(options = {})
109
+ options[:project] = options[:project].upcase unless options[:project].nil?
110
+ options[:issueKey] = options[:issueKey].upcase unless options[:issueKey].nil?
111
+ response = fetch({:method => :get, :key => "assignable/search", :body_to_params => true, :body => options})
112
+ return self.new(response.parsed_response)
113
+ end
114
+
115
+ ##
116
+ # Uses the user picker to find specified users
117
+ #
118
+ # [Arguments]
119
+ # :query (required) Name of user or username part or full
120
+ #
121
+ # :maxResults (optional) Integer
122
+ #
123
+ # :showAvatar (optional) Boolean, default false
124
+ #
125
+ # :exclude (optional) Users to exclude
126
+ #
127
+ def picker(query, options ={})
128
+ options.merge!({:query => query})
129
+ response = fetch({:method => :get, :key => "picker", :body_to_params => true, :body => options})
130
+ return self.new(response.parsed_response)
131
+ end
132
+
133
+ ##
134
+ # Uses the user search to find specified users by username
135
+ #
136
+ # [Arguments]
137
+ # :username (required) Name of user or username part or full
138
+ #
139
+ # :startAt (optional) Integer
140
+ #
141
+ # :maxResults (optional) Integer
142
+ #
143
+ # :includeActive (optional) Boolean, default true
144
+ #
145
+ # :includeInactive (optional) Boolean, default true
146
+ #
147
+ def search(username, options ={})
148
+ options.merge!({:username => username})
149
+ response = fetch({:method => :get, :key => "search", :body_to_params => true, :body => options})
150
+ return self.new(response.parsed_response)
151
+ end
152
+ end
153
+ end
154
+ end