jiralicious 0.3.0 → 0.4.0
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.
- data/README.md +3 -0
- data/jiralicious.gemspec +0 -2
- data/lib/jiralicious.rb +4 -0
- data/lib/jiralicious/avatar.rb +101 -0
- data/lib/jiralicious/base.rb +53 -15
- data/lib/jiralicious/configuration.rb +30 -4
- data/lib/jiralicious/custom_field_option.rb +7 -3
- data/lib/jiralicious/errors.rb +10 -0
- data/lib/jiralicious/field.rb +23 -12
- data/lib/jiralicious/issue.rb +69 -11
- data/lib/jiralicious/issue/comment.rb +54 -12
- data/lib/jiralicious/issue/fields.rb +44 -3
- data/lib/jiralicious/issue/transitions.rb +42 -11
- data/lib/jiralicious/issue/watchers.rb +19 -2
- data/lib/jiralicious/parsers/field_parser.rb +12 -0
- data/lib/jiralicious/project.rb +7 -1
- data/lib/jiralicious/project/avatar.rb +126 -0
- data/lib/jiralicious/search.rb +9 -0
- data/lib/jiralicious/search_result.rb +15 -7
- data/lib/jiralicious/session.rb +5 -0
- data/lib/jiralicious/user.rb +154 -0
- data/lib/jiralicious/user/avatar.rb +130 -0
- data/lib/jiralicious/version.rb +1 -1
- data/spec/avatar_spec.rb +50 -0
- data/spec/basic_session_spec.rb +4 -0
- data/spec/comment_spec.rb +2 -2
- data/spec/fixtures/avatar.json +7 -0
- data/spec/fixtures/avatar_custom.json +16 -0
- data/spec/fixtures/avatar_list.json +16 -0
- data/spec/fixtures/avatar_temp.json +7 -0
- data/spec/fixtures/avatar_test.png +0 -0
- data/spec/fixtures/user.json +27 -0
- data/spec/fixtures/user_array.json +26 -0
- data/spec/fixtures/user_picker.json +18 -0
- data/spec/issue_spec.rb +10 -9
- data/spec/project_avatar_spec.rb +66 -0
- data/spec/project_spec.rb +2 -2
- data/spec/search_spec.rb +2 -1
- data/spec/support/http.rb +24 -0
- data/spec/user_avatar_spec.rb +66 -0
- data/spec/user_spec.rb +79 -0
- data/spec/watchers_spec.rb +2 -2
- 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
|
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
|
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) }
|
data/lib/jiralicious/project.rb
CHANGED
@@ -9,7 +9,10 @@ module Jiralicious
|
|
9
9
|
##
|
10
10
|
# Initialization Method
|
11
11
|
#
|
12
|
-
|
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
|
data/lib/jiralicious/search.rb
CHANGED
@@ -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
|
-
|
23
|
-
|
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
|
-
|
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
|
data/lib/jiralicious/session.rb
CHANGED
@@ -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
|